You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by te...@apache.org on 2016/11/14 17:22:49 UTC
[03/11] hbase git commit: HBASE-14123 HBase Backup/Restore Phase 2
(Vladimir Rodionov)
http://git-wip-us.apache.org/repos/asf/hbase/blob/2725fb25/hbase-server/src/test/java/org/apache/hadoop/hbase/backup/TestBackupBase.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/backup/TestBackupBase.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/backup/TestBackupBase.java
new file mode 100644
index 0000000..c95fdb0
--- /dev/null
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/backup/TestBackupBase.java
@@ -0,0 +1,299 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.hbase.backup;
+
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map.Entry;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.LocatedFileStatus;
+import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.fs.RemoteIterator;
+import org.apache.hadoop.hbase.HBaseConfiguration;
+import org.apache.hadoop.hbase.HBaseTestingUtility;
+import org.apache.hadoop.hbase.HColumnDescriptor;
+import org.apache.hadoop.hbase.HConstants;
+import org.apache.hadoop.hbase.HTableDescriptor;
+import org.apache.hadoop.hbase.NamespaceDescriptor;
+import org.apache.hadoop.hbase.TableName;
+import org.apache.hadoop.hbase.backup.BackupInfo.BackupState;
+import org.apache.hadoop.hbase.backup.impl.BackupSystemTable;
+import org.apache.hadoop.hbase.backup.impl.HBaseBackupAdmin;
+import org.apache.hadoop.hbase.client.Admin;
+import org.apache.hadoop.hbase.client.Connection;
+import org.apache.hadoop.hbase.client.ConnectionFactory;
+import org.apache.hadoop.hbase.client.Durability;
+import org.apache.hadoop.hbase.client.HBaseAdmin;
+import org.apache.hadoop.hbase.client.HTable;
+import org.apache.hadoop.hbase.client.Put;
+import org.apache.hadoop.hbase.client.Table;
+import org.apache.hadoop.hbase.snapshot.SnapshotTestingUtils;
+import org.apache.hadoop.hbase.util.Bytes;
+import org.apache.hadoop.hbase.wal.WALFactory;
+import org.apache.hadoop.hbase.zookeeper.MiniZooKeeperCluster;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+
+
+/**
+ * This class is only a base for other integration-level backup tests. Do not add tests here.
+ * TestBackupSmallTests is where tests that don't require bring machines up/down should
+ * go All other tests should have their own classes and extend this one
+ */
+public class TestBackupBase {
+
+ private static final Log LOG = LogFactory.getLog(TestBackupBase.class);
+
+ protected static Configuration conf1;
+ protected static Configuration conf2;
+
+ protected static HBaseTestingUtility TEST_UTIL;
+ protected static HBaseTestingUtility TEST_UTIL2;
+ protected static TableName table1 = TableName.valueOf("table1");
+ protected static HTableDescriptor table1Desc;
+ protected static TableName table2 = TableName.valueOf("table2");
+ protected static TableName table3 = TableName.valueOf("table3");
+ protected static TableName table4 = TableName.valueOf("table4");
+
+ protected static TableName table1_restore = TableName.valueOf("ns1:table1_restore");
+ protected static TableName table2_restore = TableName.valueOf("ns2:table2_restore");
+ protected static TableName table3_restore = TableName.valueOf("ns3:table3_restore");
+ protected static TableName table4_restore = TableName.valueOf("ns4:table4_restore");
+
+ protected static final int NB_ROWS_IN_BATCH = 99;
+ protected static final byte[] qualName = Bytes.toBytes("q1");
+ protected static final byte[] famName = Bytes.toBytes("f");
+
+ protected static String BACKUP_ROOT_DIR = "/backupUT";
+ protected static String BACKUP_REMOTE_ROOT_DIR = "/backupUT";
+ protected static String provider = "defaultProvider";
+
+ /**
+ * @throws java.lang.Exception
+ */
+ @BeforeClass
+ public static void setUpBeforeClass() throws Exception {
+ TEST_UTIL = new HBaseTestingUtility();
+ conf1 = TEST_UTIL.getConfiguration();
+ conf1.setBoolean(BackupRestoreConstants.BACKUP_ENABLE_KEY, true);
+ conf1.set(HConstants.ZOOKEEPER_ZNODE_PARENT, "/1");
+ // Set MultiWAL (with 2 default WAL files per RS)
+ conf1.set(WALFactory.WAL_PROVIDER, provider);
+ TEST_UTIL.startMiniZKCluster();
+ MiniZooKeeperCluster miniZK = TEST_UTIL.getZkCluster();
+
+ conf2 = HBaseConfiguration.create(conf1);
+ conf2.set(HConstants.ZOOKEEPER_ZNODE_PARENT, "/2");
+ TEST_UTIL2 = new HBaseTestingUtility(conf2);
+ TEST_UTIL2.setZkCluster(miniZK);
+ TEST_UTIL.startMiniCluster();
+ TEST_UTIL2.startMiniCluster();
+ conf1 = TEST_UTIL.getConfiguration();
+
+ TEST_UTIL.startMiniMapReduceCluster();
+ BACKUP_ROOT_DIR = TEST_UTIL.getConfiguration().get("fs.defaultFS") + "/backupUT";
+ LOG.info("ROOTDIR " + BACKUP_ROOT_DIR);
+ BACKUP_REMOTE_ROOT_DIR = TEST_UTIL2.getConfiguration().get("fs.defaultFS") + "/backupUT";
+ LOG.info("REMOTE ROOTDIR " + BACKUP_REMOTE_ROOT_DIR);
+ waitForSystemTable();
+ createTables();
+ populateFromMasterConfig(TEST_UTIL.getHBaseCluster().getMaster().getConfiguration(), conf1);
+ }
+
+ private static void populateFromMasterConfig(Configuration masterConf, Configuration conf) {
+ Iterator<Entry<String,String>> it = masterConf.iterator();
+ while(it.hasNext()) {
+ Entry<String,String> e = it.next();
+ conf.set(e.getKey(), e.getValue());
+ }
+ }
+
+ public static void waitForSystemTable() throws Exception
+ {
+ try (Admin admin = TEST_UTIL.getAdmin();) {
+ while (!admin.tableExists(BackupSystemTable.getTableName())
+ || !admin.isTableAvailable(BackupSystemTable.getTableName())) {
+ Thread.sleep(1000);
+ }
+ }
+ LOG.debug("backup table exists and available");
+
+ }
+
+ /**
+ * @throws java.lang.Exception
+ */
+ @AfterClass
+ public static void tearDownAfterClass() throws Exception {
+ SnapshotTestingUtils.deleteAllSnapshots(TEST_UTIL.getHBaseAdmin());
+ SnapshotTestingUtils.deleteArchiveDirectory(TEST_UTIL);
+ TEST_UTIL2.shutdownMiniCluster();
+ TEST_UTIL.shutdownMiniCluster();
+ TEST_UTIL.shutdownMiniMapReduceCluster();
+ }
+
+ HTable insertIntoTable(Connection conn, TableName table, byte[] family, int id, int numRows)
+ throws IOException {
+ HTable t = (HTable) conn.getTable(table);
+ Put p1;
+ for (int i = 0; i < numRows; i++) {
+ p1 = new Put(Bytes.toBytes("row-" + table + "-" + id + "-"+ i));
+ p1.addColumn(family, qualName, Bytes.toBytes("val" + i));
+ t.put(p1);
+ }
+ return t;
+ }
+
+ protected String backupTables(BackupType type, List<TableName> tables, String path)
+ throws IOException {
+ Connection conn = null;
+ BackupAdmin badmin = null;
+ String backupId;
+ try {
+ conn = ConnectionFactory.createConnection(conf1);
+ badmin = new HBaseBackupAdmin(conn);
+ BackupRequest request = new BackupRequest();
+ request.setBackupType(type).setTableList(tables).setTargetRootDir(path);
+ backupId = badmin.backupTables(request);
+ } finally {
+ if(badmin != null){
+ badmin.close();
+ }
+ if (conn != null) {
+ conn.close();
+ }
+ }
+ return backupId;
+ }
+
+ protected String fullTableBackup(List<TableName> tables) throws IOException {
+ return backupTables(BackupType.FULL, tables, BACKUP_ROOT_DIR);
+ }
+
+ protected String incrementalTableBackup(List<TableName> tables) throws IOException {
+ return backupTables(BackupType.INCREMENTAL, tables, BACKUP_ROOT_DIR);
+ }
+
+ protected static void loadTable(Table table) throws Exception {
+
+ Put p; // 100 + 1 row to t1_syncup
+ for (int i = 0; i < NB_ROWS_IN_BATCH; i++) {
+ p = new Put(Bytes.toBytes("row" + i));
+ p.setDurability(Durability.SKIP_WAL);
+ p.addColumn(famName, qualName, Bytes.toBytes("val" + i));
+ table.put(p);
+ }
+ }
+
+ protected static void createTables() throws Exception {
+
+ long tid = System.currentTimeMillis();
+ table1 = TableName.valueOf("ns1:test-" + tid);
+ HBaseAdmin ha = TEST_UTIL.getHBaseAdmin();
+
+ // Create namespaces
+ NamespaceDescriptor desc1 = NamespaceDescriptor.create("ns1").build();
+ NamespaceDescriptor desc2 = NamespaceDescriptor.create("ns2").build();
+ NamespaceDescriptor desc3 = NamespaceDescriptor.create("ns3").build();
+ NamespaceDescriptor desc4 = NamespaceDescriptor.create("ns4").build();
+
+ ha.createNamespace(desc1);
+ ha.createNamespace(desc2);
+ ha.createNamespace(desc3);
+ ha.createNamespace(desc4);
+
+
+ HTableDescriptor desc = new HTableDescriptor(table1);
+ HColumnDescriptor fam = new HColumnDescriptor(famName);
+ desc.addFamily(fam);
+ ha.createTable(desc);
+ table1Desc = desc;
+ Connection conn = ConnectionFactory.createConnection(conf1);
+ Table table = conn.getTable(table1);
+ loadTable(table);
+ table.close();
+ table2 = TableName.valueOf("ns2:test-" + tid + 1);
+ desc = new HTableDescriptor(table2);
+ desc.addFamily(fam);
+ ha.createTable(desc);
+ table = conn.getTable(table2);
+ loadTable(table);
+ table.close();
+ table3 = TableName.valueOf("ns3:test-" + tid + 2);
+ table = TEST_UTIL.createTable(table3, famName);
+ table.close();
+ table4 = TableName.valueOf("ns4:test-" + tid + 3);
+ table = TEST_UTIL.createTable(table4, famName);
+ table.close();
+ ha.close();
+ conn.close();
+ }
+
+ protected boolean checkSucceeded(String backupId) throws IOException {
+ BackupInfo status = getBackupContext(backupId);
+ if (status == null) return false;
+ return status.getState() == BackupState.COMPLETE;
+ }
+
+ protected boolean checkFailed(String backupId) throws IOException {
+ BackupInfo status = getBackupContext(backupId);
+ if (status == null) return false;
+ return status.getState() == BackupState.FAILED;
+ }
+
+ private BackupInfo getBackupContext(String backupId) throws IOException {
+ try (BackupSystemTable table = new BackupSystemTable(TEST_UTIL.getConnection())) {
+ BackupInfo status = table.readBackupInfo(backupId);
+ return status;
+ }
+ }
+
+ protected BackupAdmin getBackupAdmin() throws IOException {
+ return new HBaseBackupAdmin(TEST_UTIL.getConnection());
+ }
+
+ /**
+ * Helper method
+ */
+ protected List<TableName> toList(String... args){
+ List<TableName> ret = new ArrayList<>();
+ for(int i=0; i < args.length; i++){
+ ret.add(TableName.valueOf(args[i]));
+ }
+ return ret;
+ }
+
+ protected void dumpBackupDir() throws IOException
+ {
+ // Dump Backup Dir
+ FileSystem fs = FileSystem.get(conf1);
+ RemoteIterator<LocatedFileStatus> it = fs.listFiles( new Path(BACKUP_ROOT_DIR), true);
+ while(it.hasNext()){
+ LOG.debug(it.next().getPath());
+ }
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/hbase/blob/2725fb25/hbase-server/src/test/java/org/apache/hadoop/hbase/backup/TestBackupBoundaryTests.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/backup/TestBackupBoundaryTests.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/backup/TestBackupBoundaryTests.java
new file mode 100644
index 0000000..280314b
--- /dev/null
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/backup/TestBackupBoundaryTests.java
@@ -0,0 +1,97 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.hbase.backup;
+
+import java.io.IOException;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.hbase.TableName;
+import org.apache.hadoop.hbase.testclassification.LargeTests;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import com.google.common.collect.Lists;
+
+@Category(LargeTests.class)
+public class TestBackupBoundaryTests extends TestBackupBase {
+
+ private static final Log LOG = LogFactory.getLog(TestBackupBoundaryTests.class);
+
+ /**
+ * Verify that full backup is created on a single empty table correctly.
+ * @throws Exception
+ */
+ @Test
+ public void testFullBackupSingleEmpty() throws Exception {
+
+ LOG.info("create full backup image on single table");
+ List<TableName> tables = Lists.newArrayList(table3);
+ LOG.info("Finished Backup " + fullTableBackup(tables));
+ }
+
+ /**
+ * Verify that full backup is created on multiple empty tables correctly.
+ * @throws Exception
+ */
+ @Test
+ public void testFullBackupMultipleEmpty() throws Exception {
+ LOG.info("create full backup image on mulitple empty tables");
+
+ List<TableName> tables = Lists.newArrayList(table3, table4);
+ fullTableBackup(tables);
+ }
+
+ /**
+ * Verify that full backup fails on a single table that does not exist.
+ * @throws Exception
+ */
+ @Test(expected = IOException.class)
+ public void testFullBackupSingleDNE() throws Exception {
+
+ LOG.info("test full backup fails on a single table that does not exist");
+ List<TableName> tables = toList("tabledne");
+ fullTableBackup(tables);
+ }
+
+ /**
+ * Verify that full backup fails on multiple tables that do not exist.
+ * @throws Exception
+ */
+ @Test(expected = IOException.class)
+ public void testFullBackupMultipleDNE() throws Exception {
+
+ LOG.info("test full backup fails on multiple tables that do not exist");
+ List<TableName> tables = toList("table1dne", "table2dne");
+ fullTableBackup(tables);
+ }
+
+ /**
+ * Verify that full backup fails on tableset containing real and fake tables.
+ * @throws Exception
+ */
+ @Test(expected = IOException.class)
+ public void testFullBackupMixExistAndDNE() throws Exception {
+ LOG.info("create full backup fails on tableset containing real and fake table");
+
+ List<TableName> tables = toList(table1.getNameAsString(), "tabledne");
+ fullTableBackup(tables);
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/hbase/blob/2725fb25/hbase-server/src/test/java/org/apache/hadoop/hbase/backup/TestBackupCommandLineTool.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/backup/TestBackupCommandLineTool.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/backup/TestBackupCommandLineTool.java
new file mode 100644
index 0000000..3a632fc
--- /dev/null
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/backup/TestBackupCommandLineTool.java
@@ -0,0 +1,413 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.hbase.backup;
+
+import static org.junit.Assert.assertTrue;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.hbase.HBaseConfiguration;
+import org.apache.hadoop.hbase.testclassification.SmallTests;
+import org.apache.hadoop.util.ToolRunner;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+@Category(SmallTests.class)
+public class TestBackupCommandLineTool {
+ Configuration conf;
+ @Before
+ public void setUpBefore() throws Exception {
+ conf = HBaseConfiguration.create();
+ conf.setBoolean(BackupRestoreConstants.BACKUP_ENABLE_KEY, true);
+ }
+
+ @Test
+ public void testBackupDriverDescribeHelp() throws Exception {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ System.setOut(new PrintStream(baos));
+ String[] args = new String[]{"describe", "-help" };
+ ToolRunner.run(conf, new BackupDriver(), args);
+
+ String output = baos.toString();
+ System.out.println(baos.toString());
+ assertTrue(output.indexOf("Usage: bin/hbase backup describe <backupId>") >= 0);
+
+ baos = new ByteArrayOutputStream();
+ System.setOut(new PrintStream(baos));
+ args = new String[]{"describe", "-h" };
+ ToolRunner.run(conf, new BackupDriver(), args);
+
+ output = baos.toString();
+ System.out.println(baos.toString());
+ assertTrue(output.indexOf("Usage: bin/hbase backup describe <backupId>") >= 0);
+
+ baos = new ByteArrayOutputStream();
+ System.setOut(new PrintStream(baos));
+ args = new String[]{"describe" };
+ ToolRunner.run(conf, new BackupDriver(), args);
+
+ output = baos.toString();
+ System.out.println(baos.toString());
+ assertTrue(output.indexOf("Usage: bin/hbase backup describe <backupId>") >= 0);
+ }
+
+ @Test
+ public void testBackupDriverCreateHelp() throws Exception {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ System.setOut(new PrintStream(baos));
+ String[] args = new String[]{"create", "-help" };
+ ToolRunner.run(conf, new BackupDriver(), args);
+
+ String output = baos.toString();
+ System.out.println(baos.toString());
+ assertTrue(output.indexOf("Usage: bin/hbase backup create") >= 0);
+
+ baos = new ByteArrayOutputStream();
+ System.setOut(new PrintStream(baos));
+ args = new String[]{"create", "-h" };
+ ToolRunner.run(conf, new BackupDriver(), args);
+
+ output = baos.toString();
+ System.out.println(baos.toString());
+ assertTrue(output.indexOf("Usage: bin/hbase backup create") >= 0);
+
+ baos = new ByteArrayOutputStream();
+ System.setOut(new PrintStream(baos));
+ args = new String[]{"create"};
+ ToolRunner.run(conf, new BackupDriver(), args);
+
+ output = baos.toString();
+ System.out.println(baos.toString());
+ assertTrue(output.indexOf("Usage: bin/hbase backup create") >= 0);
+ }
+
+ @Test
+ public void testBackupDriverHistoryHelp () throws Exception {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ System.setOut(new PrintStream(baos));
+ String[] args = new String[]{"history", "-help" };
+ ToolRunner.run(conf, new BackupDriver(), args);
+
+ String output = baos.toString();
+ System.out.println(baos.toString());
+ assertTrue(output.indexOf("Usage: bin/hbase backup history") >= 0);
+
+ baos = new ByteArrayOutputStream();
+ System.setOut(new PrintStream(baos));
+ args = new String[]{"history", "-h" };
+ ToolRunner.run(conf, new BackupDriver(), args);
+
+ output = baos.toString();
+ System.out.println(baos.toString());
+ assertTrue(output.indexOf("Usage: bin/hbase backup history") >= 0);
+
+ }
+
+ @Test
+ public void testBackupDriverDeleteHelp () throws Exception {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ System.setOut(new PrintStream(baos));
+ String[] args = new String[]{"delete", "-help" };
+ ToolRunner.run(conf, new BackupDriver(), args);
+
+ String output = baos.toString();
+ System.out.println(baos.toString());
+ assertTrue(output.indexOf("Usage: bin/hbase backup delete") >= 0);
+
+ baos = new ByteArrayOutputStream();
+ System.setOut(new PrintStream(baos));
+ args = new String[]{"delete", "-h" };
+ ToolRunner.run(conf, new BackupDriver(), args);
+
+ output = baos.toString();
+ System.out.println(baos.toString());
+ assertTrue(output.indexOf("Usage: bin/hbase backup delete") >= 0);
+
+ baos = new ByteArrayOutputStream();
+ System.setOut(new PrintStream(baos));
+ args = new String[]{"delete" };
+ ToolRunner.run(conf, new BackupDriver(), args);
+
+ output = baos.toString();
+ System.out.println(baos.toString());
+ assertTrue(output.indexOf("Usage: bin/hbase backup delete") >= 0);
+ }
+
+ @Test
+ public void testBackupDriverProgressHelp() throws Exception {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ System.setOut(new PrintStream(baos));
+ String[] args = new String[]{"progress", "-help" };
+ ToolRunner.run(conf, new BackupDriver(), args);
+
+ String output = baos.toString();
+ System.out.println(baos.toString());
+ assertTrue(output.indexOf("Usage: bin/hbase backup progress") >= 0);
+
+ baos = new ByteArrayOutputStream();
+ System.setOut(new PrintStream(baos));
+ args = new String[]{"progress", "-h" };
+ ToolRunner.run(conf, new BackupDriver(), args);
+
+ output = baos.toString();
+ System.out.println(baos.toString());
+ assertTrue(output.indexOf("Usage: bin/hbase backup progress") >= 0);
+ }
+
+ @Test
+ public void testBackupDriverSetHelp () throws Exception {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ System.setOut(new PrintStream(baos));
+ String[] args = new String[]{"set", "-help" };
+ ToolRunner.run(conf, new BackupDriver(), args);
+
+ String output = baos.toString();
+ System.out.println(baos.toString());
+ assertTrue(output.indexOf("Usage: bin/hbase backup set") >= 0);
+
+ baos = new ByteArrayOutputStream();
+ System.setOut(new PrintStream(baos));
+ args = new String[]{"set", "-h" };
+ ToolRunner.run(conf, new BackupDriver(), args);
+
+ output = baos.toString();
+ System.out.println(baos.toString());
+ assertTrue(output.indexOf("Usage: bin/hbase backup set") >= 0);
+
+ baos = new ByteArrayOutputStream();
+ System.setOut(new PrintStream(baos));
+ args = new String[]{"set"};
+ ToolRunner.run(conf, new BackupDriver(), args);
+
+ output = baos.toString();
+ System.out.println(baos.toString());
+ assertTrue(output.indexOf("Usage: bin/hbase backup set") >= 0);
+
+ }
+
+ @Test
+ public void testBackupDriverHelp () throws Exception {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ System.setOut(new PrintStream(baos));
+ String[] args = new String[]{"-help" };
+ ToolRunner.run(conf, new BackupDriver(), args);
+
+ String output = baos.toString();
+ System.out.println(baos.toString());
+ assertTrue(output.indexOf("Usage: bin/hbase backup") >= 0);
+
+ baos = new ByteArrayOutputStream();
+ System.setOut(new PrintStream(baos));
+ args = new String[]{"-h" };
+ ToolRunner.run(conf, new BackupDriver(), args);
+
+ output = baos.toString();
+ System.out.println(baos.toString());
+ assertTrue(output.indexOf("Usage: bin/hbase backup") >= 0);
+ }
+
+ @Test
+ public void testRestoreDriverHelp () throws Exception {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ System.setOut(new PrintStream(baos));
+ String[] args = new String[]{"-help" };
+ ToolRunner.run(conf, new RestoreDriver(), args);
+
+ String output = baos.toString();
+ System.out.println(baos.toString());
+ assertTrue(output.indexOf("Usage: bin/hbase restore") >= 0);
+
+ baos = new ByteArrayOutputStream();
+ System.setOut(new PrintStream(baos));
+ args = new String[]{"-h" };
+ ToolRunner.run(conf, new RestoreDriver(), args);
+
+ output = baos.toString();
+ System.out.println(baos.toString());
+ assertTrue(output.indexOf("Usage: bin/hbase restore") >= 0);
+ }
+
+ @Test
+ public void testBackupDriverUnrecognizedCommand () throws Exception {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ System.setOut(new PrintStream(baos));
+ String[] args = new String[]{"command" };
+ ToolRunner.run(conf, new BackupDriver(), args);
+
+ String output = baos.toString();
+ System.out.println(baos.toString());
+ assertTrue(output.indexOf("Usage: bin/hbase backup") >= 0);
+
+ baos = new ByteArrayOutputStream();
+ System.setOut(new PrintStream(baos));
+ args = new String[]{"command" };
+ ToolRunner.run(conf, new BackupDriver(), args);
+
+ output = baos.toString();
+ System.out.println(baos.toString());
+ assertTrue(output.indexOf("Usage: bin/hbase backup") >= 0);
+ }
+
+
+
+ @Test
+ public void testBackupDriverUnrecognizedOption () throws Exception {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ System.setOut(new PrintStream(baos));
+ String[] args = new String[]{"create", "-xx" };
+ ToolRunner.run(conf, new BackupDriver(), args);
+
+ String output = baos.toString();
+ System.out.println(baos.toString());
+ assertTrue(output.indexOf("Usage: bin/hbase backup") >= 0);
+
+ baos = new ByteArrayOutputStream();
+ System.setOut(new PrintStream(baos));
+ args = new String[]{"describe", "-xx" };
+ ToolRunner.run(conf, new BackupDriver(), args);
+
+ output = baos.toString();
+ System.out.println(baos.toString());
+ assertTrue(output.indexOf("Usage: bin/hbase backup") >= 0);
+
+ baos = new ByteArrayOutputStream();
+ System.setOut(new PrintStream(baos));
+ args = new String[]{"history", "-xx" };
+ ToolRunner.run(conf, new BackupDriver(), args);
+
+ output = baos.toString();
+ System.out.println(baos.toString());
+ assertTrue(output.indexOf("Usage: bin/hbase backup") >= 0);
+
+ baos = new ByteArrayOutputStream();
+ System.setOut(new PrintStream(baos));
+ args = new String[]{"delete", "-xx" };
+ ToolRunner.run(conf, new BackupDriver(), args);
+
+ output = baos.toString();
+ System.out.println(baos.toString());
+ assertTrue(output.indexOf("Usage: bin/hbase backup") >= 0);
+
+ baos = new ByteArrayOutputStream();
+ System.setOut(new PrintStream(baos));
+ args = new String[]{"set", "-xx" };
+ ToolRunner.run(conf, new BackupDriver(), args);
+
+ output = baos.toString();
+ System.out.println(baos.toString());
+ assertTrue(output.indexOf("Usage: bin/hbase backup") >= 0);
+ }
+
+ @Test
+ public void testRestoreDriverUnrecognizedOption () throws Exception {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ System.setOut(new PrintStream(baos));
+ String[] args = new String[]{"-xx" };
+ ToolRunner.run(conf, new RestoreDriver(), args);
+
+ String output = baos.toString();
+ System.out.println(baos.toString());
+ assertTrue(output.indexOf("Usage: bin/hbase restore") >= 0);
+
+ }
+
+ @Test
+ public void testBackupDriverCreateWrongArgNumber () throws Exception {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ System.setOut(new PrintStream(baos));
+ String[] args = new String[]{"create" };
+ ToolRunner.run(conf, new BackupDriver(), args);
+
+ String output = baos.toString();
+ System.out.println(baos.toString());
+ assertTrue(output.indexOf("Usage: bin/hbase backup create") >= 0);
+
+ baos = new ByteArrayOutputStream();
+ System.setOut(new PrintStream(baos));
+ args = new String[]{"create", "22" };
+ ToolRunner.run(conf, new BackupDriver(), args);
+
+ output = baos.toString();
+ System.out.println(baos.toString());
+ assertTrue(output.indexOf("Usage: bin/hbase backup create") >= 0);
+
+ baos = new ByteArrayOutputStream();
+ System.setOut(new PrintStream(baos));
+ args = new String[]{"create", "22", "22", "22", "22", "22" };
+ ToolRunner.run(conf, new BackupDriver(), args);
+
+ output = baos.toString();
+ System.out.println(baos.toString());
+ assertTrue(output.indexOf("Usage: bin/hbase backup create") >= 0);
+ }
+
+ @Test
+ public void testBackupDriverDeleteWrongArgNumber () throws Exception {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ System.setOut(new PrintStream(baos));
+ String[] args = new String[]{"delete" };
+ ToolRunner.run(conf, new BackupDriver(), args);
+
+ String output = baos.toString();
+ System.out.println(baos.toString());
+ assertTrue(output.indexOf("Usage: bin/hbase backup delete") >= 0);
+
+ }
+
+ @Test
+ public void testBackupDriverHistoryWrongArgs () throws Exception {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ System.setOut(new PrintStream(baos));
+ String[] args = new String[]{"history", "-n", "xx" };
+ ToolRunner.run(conf, new BackupDriver(), args);
+
+ String output = baos.toString();
+ System.out.println(baos.toString());
+ assertTrue(output.indexOf("Usage: bin/hbase backup history") >= 0);
+
+ }
+
+ @Test
+ public void testBackupDriverWrongBackupDestination () throws Exception {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ System.setOut(new PrintStream(baos));
+ String[] args = new String[]{"create", "full", "clicks" };
+ ToolRunner.run(conf, new BackupDriver(), args);
+
+ String output = baos.toString();
+ System.out.println(baos.toString());
+ assertTrue(output.indexOf("ERROR: invalid backup destination") >= 0);
+
+ }
+
+ @Test
+ public void testBackupDriverBackupSetAndList () throws Exception {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ System.setOut(new PrintStream(baos));
+ String[] args = new String[]{"create", "full", "file:/", "clicks", "-s", "s" };
+ ToolRunner.run(conf, new BackupDriver(), args);
+
+ String output = baos.toString();
+ System.out.println(baos.toString());
+ assertTrue(output.indexOf("ERROR: You can specify either backup set or list") >= 0);
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/hbase/blob/2725fb25/hbase-server/src/test/java/org/apache/hadoop/hbase/backup/TestBackupDelete.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/backup/TestBackupDelete.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/backup/TestBackupDelete.java
new file mode 100644
index 0000000..07a22ce
--- /dev/null
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/backup/TestBackupDelete.java
@@ -0,0 +1,102 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.hbase.backup;
+
+import static org.junit.Assert.assertTrue;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.hbase.TableName;
+import org.apache.hadoop.hbase.backup.impl.BackupSystemTable;
+import org.apache.hadoop.hbase.testclassification.LargeTests;
+import org.apache.hadoop.util.ToolRunner;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import com.google.common.collect.Lists;
+
+@Category(LargeTests.class)
+public class TestBackupDelete extends TestBackupBase {
+
+ private static final Log LOG = LogFactory.getLog(TestBackupDelete.class);
+
+ /**
+ * Verify that full backup is created on a single table with data correctly. Verify that history
+ * works as expected
+ * @throws Exception
+ */
+ @Test
+ public void testBackupDelete() throws Exception {
+ LOG.info("test backup delete on a single table with data");
+ List<TableName> tableList = Lists.newArrayList(table1);
+ String backupId = fullTableBackup(tableList);
+ assertTrue(checkSucceeded(backupId));
+ LOG.info("backup complete");
+ String[] backupIds = new String[] { backupId };
+ BackupSystemTable table = new BackupSystemTable(TEST_UTIL.getConnection());
+ BackupInfo info = table.readBackupInfo(backupId);
+ Path path = new Path(info.getTargetRootDir(), backupId);
+ FileSystem fs = FileSystem.get(path.toUri(), conf1);
+ assertTrue(fs.exists(path));
+ int deleted = getBackupAdmin().deleteBackups(backupIds);
+
+ assertTrue(!fs.exists(path));
+ assertTrue(fs.exists(new Path(info.getTargetRootDir())));
+ assertTrue(1 == deleted);
+ table.close();
+ LOG.info("delete_backup");
+ }
+
+ /**
+ * Verify that full backup is created on a single table with data correctly. Verify that history
+ * works as expected
+ * @throws Exception
+ */
+ @Test
+ public void testBackupDeleteCommand() throws Exception {
+ LOG.info("test backup delete on a single table with data: command-line");
+ List<TableName> tableList = Lists.newArrayList(table1);
+ String backupId = fullTableBackup(tableList);
+ assertTrue(checkSucceeded(backupId));
+ LOG.info("backup complete");
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ System.setOut(new PrintStream(baos));
+
+ String[] args = new String[]{"delete", backupId };
+ // Run backup
+
+ try{
+ int ret = ToolRunner.run(conf1, new BackupDriver(), args);
+ assertTrue(ret == 0);
+ } catch(Exception e){
+ LOG.error("failed", e);
+ }
+ LOG.info("delete_backup");
+ String output = baos.toString();
+ LOG.info(baos.toString());
+ assertTrue(output.indexOf("Deleted 1 backups") >= 0);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/hbase/blob/2725fb25/hbase-server/src/test/java/org/apache/hadoop/hbase/backup/TestBackupDeleteRestore.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/backup/TestBackupDeleteRestore.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/backup/TestBackupDeleteRestore.java
new file mode 100644
index 0000000..34360ed
--- /dev/null
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/backup/TestBackupDeleteRestore.java
@@ -0,0 +1,70 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable
+ * law or agreed to in writing, software distributed under the License is distributed on an "AS IS"
+ * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
+ * for the specific language governing permissions and limitations under the License.
+ */
+
+package org.apache.hadoop.hbase.backup;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.hbase.TableName;
+import org.apache.hadoop.hbase.backup.util.RestoreServerUtil;
+import org.apache.hadoop.hbase.client.Delete;
+import org.apache.hadoop.hbase.client.HBaseAdmin;
+import org.apache.hadoop.hbase.client.Table;
+import org.apache.hadoop.hbase.testclassification.MediumTests;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import com.google.common.collect.Lists;
+
+@Category(MediumTests.class)
+public class TestBackupDeleteRestore extends TestBackupBase {
+
+ private static final Log LOG = LogFactory.getLog(TestBackupDeleteRestore.class);
+
+ /**
+ * Verify that load data- backup - delete some data - restore
+ * works as expected - deleted data get restored.
+ * @throws Exception
+ */
+ @Test
+ public void testBackupDeleteRestore() throws Exception {
+
+ LOG.info("test full restore on a single table empty table");
+
+ List<TableName> tables = Lists.newArrayList(table1);
+ String backupId = fullTableBackup(tables);
+ assertTrue(checkSucceeded(backupId));
+ LOG.info("backup complete");
+ int numRows = TEST_UTIL.countRows(table1);
+ HBaseAdmin hba = TEST_UTIL.getHBaseAdmin();
+ // delete row
+ try ( Table table = TEST_UTIL.getConnection().getTable(table1);) {
+ Delete delete = new Delete("row0".getBytes());
+ table.delete(delete);
+ hba.flush(table1);
+ }
+
+ TableName[] tableset = new TableName[] { table1 };
+ TableName[] tablemap = null;//new TableName[] { table1_restore };
+ BackupAdmin client = getBackupAdmin();
+ client.restore(RestoreServerUtil.createRestoreRequest(BACKUP_ROOT_DIR, backupId, false,
+ tableset, tablemap, true));
+
+ int numRowsAfterRestore = TEST_UTIL.countRows(table1);
+ assertEquals( numRows, numRowsAfterRestore);
+ hba.close();
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/hbase/blob/2725fb25/hbase-server/src/test/java/org/apache/hadoop/hbase/backup/TestBackupDescribe.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/backup/TestBackupDescribe.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/backup/TestBackupDescribe.java
new file mode 100644
index 0000000..6db3bf3
--- /dev/null
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/backup/TestBackupDescribe.java
@@ -0,0 +1,111 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.hbase.backup;
+
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.hbase.TableName;
+import org.apache.hadoop.hbase.backup.BackupInfo.BackupState;
+import org.apache.hadoop.hbase.backup.impl.BackupCommands;
+import org.apache.hadoop.hbase.backup.impl.BackupSystemTable;
+import org.apache.hadoop.hbase.testclassification.LargeTests;
+import org.apache.hadoop.util.ToolRunner;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import com.google.common.collect.Lists;
+
+@Category(LargeTests.class)
+public class TestBackupDescribe extends TestBackupBase {
+
+ private static final Log LOG = LogFactory.getLog(TestBackupDescribe.class);
+
+ /**
+ * Verify that describe works as expected if incorrect backup Id is supplied
+ * @throws Exception
+ */
+ @Test
+ public void testBackupDescribe() throws Exception {
+
+ LOG.info("test backup describe on a single table with data");
+
+ String[] args = new String[]{"describe", "backup_2" };
+ int ret = ToolRunner.run(conf1, new BackupDriver(), args);
+ assertTrue(ret < 0);
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ System.setOut(new PrintStream(baos));
+ args = new String[]{"progress" };
+ ToolRunner.run(TEST_UTIL.getConfiguration(), new BackupDriver(), args);
+
+ String output = baos.toString();
+ LOG.info("Output from progress: " + output);
+ assertTrue(output.indexOf(BackupCommands.NO_INFO_FOUND) >= 0);
+ }
+
+ @Test
+ public void testBackupSetCommandWithNonExistentTable() throws Exception {
+ String[] args = new String[]{"set", "add", "some_set", "table" };
+ // Run backup
+ int ret = ToolRunner.run(conf1, new BackupDriver(), args);
+ assertNotEquals(ret, 0);
+ }
+
+ @Test
+ public void testBackupDescribeCommand() throws Exception {
+
+ LOG.info("test backup describe on a single table with data: command-line");
+
+ List<TableName> tableList = Lists.newArrayList(table1);
+ String backupId = fullTableBackup(tableList);
+
+ LOG.info("backup complete");
+ assertTrue(checkSucceeded(backupId));
+
+ BackupInfo info = getBackupAdmin().getBackupInfo(backupId);
+ assertTrue(info.getState() == BackupState.COMPLETE);
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ System.setOut(new PrintStream(baos));
+
+ String[] args = new String[]{"describe", backupId };
+ // Run backup
+ int ret = ToolRunner.run(conf1, new BackupDriver(), args);
+ assertTrue(ret == 0);
+ String response = baos.toString();
+ assertTrue(response.indexOf(backupId) > 0);
+ assertTrue(response.indexOf("COMPLETE") > 0);
+
+ BackupSystemTable table = new BackupSystemTable(TEST_UTIL.getConnection());
+ BackupInfo status = table.readBackupInfo(backupId);
+ String desc = status.getShortDescription();
+ table.close();
+ assertTrue(response.indexOf(desc) >= 0);
+
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/hbase/blob/2725fb25/hbase-server/src/test/java/org/apache/hadoop/hbase/backup/TestBackupMultipleDeletes.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/backup/TestBackupMultipleDeletes.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/backup/TestBackupMultipleDeletes.java
new file mode 100644
index 0000000..1caba22
--- /dev/null
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/backup/TestBackupMultipleDeletes.java
@@ -0,0 +1,173 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.hbase.backup;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.hbase.TableName;
+import org.apache.hadoop.hbase.backup.impl.HBaseBackupAdmin;
+import org.apache.hadoop.hbase.client.Connection;
+import org.apache.hadoop.hbase.client.ConnectionFactory;
+import org.apache.hadoop.hbase.client.HBaseAdmin;
+import org.apache.hadoop.hbase.client.HTable;
+import org.apache.hadoop.hbase.client.Put;
+import org.apache.hadoop.hbase.testclassification.LargeTests;
+import org.apache.hadoop.hbase.util.Bytes;
+import org.hamcrest.CoreMatchers;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import com.google.common.collect.Lists;
+
+
+/**
+ * Create multiple backups for two tables: table1, table2
+ * then perform 1 delete
+ */
+@Category(LargeTests.class)
+public class TestBackupMultipleDeletes extends TestBackupBase {
+ private static final Log LOG = LogFactory.getLog(TestBackupMultipleDeletes.class);
+
+ @Test
+ public void testBackupMultipleDeletes() throws Exception {
+ // #1 - create full backup for all tables
+ LOG.info("create full backup image for all tables");
+ List<TableName> tables = Lists.newArrayList(table1, table2);
+ HBaseAdmin admin = null;
+ Connection conn = ConnectionFactory.createConnection(conf1);
+ admin = (HBaseAdmin) conn.getAdmin();
+ BackupAdmin client = new HBaseBackupAdmin(conn);
+ BackupRequest request = new BackupRequest();
+ request.setBackupType(BackupType.FULL).setTableList(tables).setTargetRootDir(BACKUP_ROOT_DIR);
+ String backupIdFull = client.backupTables(request);
+ assertTrue(checkSucceeded(backupIdFull));
+ // #2 - insert some data to table table1
+ HTable t1 = (HTable) conn.getTable(table1);
+ Put p1;
+ for (int i = 0; i < NB_ROWS_IN_BATCH; i++) {
+ p1 = new Put(Bytes.toBytes("row-t1" + i));
+ p1.addColumn(famName, qualName, Bytes.toBytes("val" + i));
+ t1.put(p1);
+ }
+ Assert.assertThat(TEST_UTIL.countRows(t1), CoreMatchers.equalTo(NB_ROWS_IN_BATCH * 2));
+ t1.close();
+ // #3 - incremental backup for table1
+ tables = Lists.newArrayList(table1);
+ request = new BackupRequest();
+ request.setBackupType(BackupType.INCREMENTAL).setTableList(tables)
+ .setTargetRootDir(BACKUP_ROOT_DIR);
+ String backupIdInc1 = client.backupTables(request);
+ assertTrue(checkSucceeded(backupIdInc1));
+ // #4 - insert some data to table table2
+ HTable t2 = (HTable) conn.getTable(table2);
+ Put p2 = null;
+ for (int i = 0; i < NB_ROWS_IN_BATCH; i++) {
+ p2 = new Put(Bytes.toBytes("row-t2" + i));
+ p2.addColumn(famName, qualName, Bytes.toBytes("val" + i));
+ t2.put(p2);
+ }
+ // #5 - incremental backup for table1, table2
+ tables = Lists.newArrayList(table1, table2);
+ request = new BackupRequest();
+ request.setBackupType(BackupType.INCREMENTAL).setTableList(tables)
+ .setTargetRootDir(BACKUP_ROOT_DIR);
+ String backupIdInc2 = client.backupTables(request);
+ assertTrue(checkSucceeded(backupIdInc2));
+ // #6 - insert some data to table table1
+ t1 = (HTable) conn.getTable(table1);
+ for (int i = NB_ROWS_IN_BATCH; i < 2 * NB_ROWS_IN_BATCH; i++) {
+ p1 = new Put(Bytes.toBytes("row-t1" + i));
+ p1.addColumn(famName, qualName, Bytes.toBytes("val" + i));
+ t1.put(p1);
+ }
+ // #7 - incremental backup for table1
+ tables = Lists.newArrayList(table1);
+ request = new BackupRequest();
+ request.setBackupType(BackupType.INCREMENTAL).setTableList(tables)
+ .setTargetRootDir(BACKUP_ROOT_DIR);
+ String backupIdInc3 = client.backupTables(request);
+ assertTrue(checkSucceeded(backupIdInc3));
+ // #8 - insert some data to table table2
+ t2 = (HTable) conn.getTable(table2);
+ for (int i = NB_ROWS_IN_BATCH; i < 2 * NB_ROWS_IN_BATCH; i++) {
+ p2 = new Put(Bytes.toBytes("row-t1" + i));
+ p2.addColumn(famName, qualName, Bytes.toBytes("val" + i));
+ t2.put(p2);
+ }
+ // #9 - incremental backup for table1, table2
+ tables = Lists.newArrayList(table1, table2);
+ request = new BackupRequest();
+ request.setBackupType(BackupType.INCREMENTAL).setTableList(tables)
+ .setTargetRootDir(BACKUP_ROOT_DIR);
+ String backupIdInc4 = client.backupTables(request);
+ assertTrue(checkSucceeded(backupIdInc4));
+ // #10 full backup for table3
+ tables = Lists.newArrayList(table3);
+ request = new BackupRequest();
+ request.setBackupType(BackupType.FULL).setTableList(tables).setTargetRootDir(BACKUP_ROOT_DIR);
+ String backupIdFull2 = client.backupTables(request);
+ assertTrue(checkSucceeded(backupIdFull2));
+ // #11 - incremental backup for table3
+ tables = Lists.newArrayList(table3);
+ request = new BackupRequest();
+ request.setBackupType(BackupType.INCREMENTAL).setTableList(tables)
+ .setTargetRootDir(BACKUP_ROOT_DIR);
+ String backupIdInc5 = client.backupTables(request);
+ assertTrue(checkSucceeded(backupIdInc5));
+ LOG.error("Delete backupIdInc2");
+ client.deleteBackups(new String[] { backupIdInc2 });
+ LOG.error("Delete backupIdInc2 done");
+ List<BackupInfo> list = client.getHistory(100);
+ // First check number of backup images before and after
+ assertEquals(4, list.size());
+ // then verify that no backupIdInc2,3,4
+ Set<String> ids = new HashSet<String>();
+ ids.add(backupIdInc2);
+ ids.add(backupIdInc3);
+ ids.add(backupIdInc4);
+ for (BackupInfo info : list) {
+ String backupId = info.getBackupId();
+ if (ids.contains(backupId)) {
+ assertTrue(false);
+ }
+ }
+ // Verify that backupInc5 contains only table3
+ boolean found = false;
+ for (BackupInfo info : list) {
+ String backupId = info.getBackupId();
+ if (backupId.equals(backupIdInc5)) {
+ assertTrue(info.getTables().size() == 1);
+ assertEquals(table3, info.getTableNames().get(0));
+ found = true;
+ }
+ }
+ assertTrue(found);
+ admin.close();
+ conn.close();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/hbase/blob/2725fb25/hbase-server/src/test/java/org/apache/hadoop/hbase/backup/TestBackupShowHistory.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/backup/TestBackupShowHistory.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/backup/TestBackupShowHistory.java
new file mode 100644
index 0000000..b2c3324
--- /dev/null
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/backup/TestBackupShowHistory.java
@@ -0,0 +1,146 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.hbase.backup;
+
+import static org.junit.Assert.assertTrue;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.hbase.TableName;
+import org.apache.hadoop.hbase.backup.util.BackupClientUtil;
+import org.apache.hadoop.hbase.testclassification.LargeTests;
+import org.apache.hadoop.util.ToolRunner;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import com.google.common.collect.Lists;
+
+@Category(LargeTests.class)
+public class TestBackupShowHistory extends TestBackupBase {
+
+ private static final Log LOG = LogFactory.getLog(TestBackupShowHistory.class);
+
+ private boolean findBackup(List<BackupInfo> history, String backupId) {
+ assertTrue(history.size() > 0);
+ boolean success = false;
+ for (BackupInfo info: history){
+ if (info.getBackupId().equals(backupId)){
+ success = true;
+ break;
+ }
+ }
+ return success;
+ }
+
+ /**
+ * Verify that full backup is created on a single table with data correctly. Verify that history
+ * works as expected
+ * @throws Exception
+ */
+ @Test
+ public void testBackupHistory() throws Exception {
+
+ LOG.info("test backup history on a single table with data");
+
+ List<TableName> tableList = Lists.newArrayList(table1);
+ String backupId = fullTableBackup(tableList);
+ assertTrue(checkSucceeded(backupId));
+ LOG.info("backup complete");
+
+ List<BackupInfo> history = getBackupAdmin().getHistory(10);
+ assertTrue(findBackup(history, backupId));
+ BackupInfo.Filter nullFilter = new BackupInfo.Filter() {
+ @Override
+ public boolean apply(BackupInfo info) {
+ return true;
+ }
+ };
+ history = BackupClientUtil.getHistory(conf1, 10, new Path(BACKUP_ROOT_DIR), nullFilter);
+ assertTrue(findBackup(history, backupId));
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ System.setOut(new PrintStream(baos));
+
+ String[] args = new String[]{"history", "-n", "10", "-p", BACKUP_ROOT_DIR };
+ // Run backup
+ int ret = ToolRunner.run(conf1, new BackupDriver(), args);
+ assertTrue(ret == 0);
+ LOG.info("show_history");
+ String output = baos.toString();
+ LOG.info(output);
+ baos.close();
+ assertTrue(output.indexOf(backupId) > 0);
+
+ tableList = Lists.newArrayList(table2);
+ String backupId2 = fullTableBackup(tableList);
+ assertTrue(checkSucceeded(backupId2));
+ LOG.info("backup complete: "+ table2);
+ BackupInfo.Filter tableNameFilter = new BackupInfo.Filter() {
+ @Override
+ public boolean apply(BackupInfo image) {
+ if (table1 == null) return true;
+ List<TableName> names = image.getTableNames();
+ return names.contains(table1);
+ }
+ };
+ BackupInfo.Filter tableSetFilter = new BackupInfo.Filter() {
+ @Override
+ public boolean apply(BackupInfo info) {
+ String backupId = info.getBackupId();
+ return backupId.startsWith("backup");
+ }
+ };
+
+ history = getBackupAdmin().getHistory(10, tableNameFilter, tableSetFilter);
+ assertTrue(history.size() > 0);
+ boolean success = true;
+ for (BackupInfo info: history){
+ if (!info.getTableNames().contains(table1)){
+ success = false;
+ break;
+ }
+ }
+ assertTrue(success);
+
+ history = BackupClientUtil.getHistory(conf1, 10, new Path(BACKUP_ROOT_DIR),
+ tableNameFilter, tableSetFilter);
+ assertTrue(history.size() > 0);
+ success = true;
+ for (BackupInfo info: history){
+ if (!info.getTableNames().contains(table1)){
+ success = false;
+ break;
+ }
+ }
+ assertTrue(success);
+
+ args = new String[]{"history", "-n", "10", "-p", BACKUP_ROOT_DIR,
+ "-t", "table1", "-s", "backup"};
+ // Run backup
+ ret = ToolRunner.run(conf1, new BackupDriver(), args);
+ assertTrue(ret == 0);
+ LOG.info("show_history");
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/hbase/blob/2725fb25/hbase-server/src/test/java/org/apache/hadoop/hbase/backup/TestBackupStatusProgress.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/backup/TestBackupStatusProgress.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/backup/TestBackupStatusProgress.java
new file mode 100644
index 0000000..73b252a
--- /dev/null
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/backup/TestBackupStatusProgress.java
@@ -0,0 +1,98 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.hbase.backup;
+
+import static org.junit.Assert.assertTrue;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.hbase.TableName;
+import org.apache.hadoop.hbase.backup.BackupInfo.BackupState;
+import org.apache.hadoop.hbase.testclassification.LargeTests;
+import org.apache.hadoop.util.ToolRunner;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import com.google.common.collect.Lists;
+
+@Category(LargeTests.class)
+public class TestBackupStatusProgress extends TestBackupBase {
+
+ private static final Log LOG = LogFactory.getLog(TestBackupStatusProgress.class);
+
+ /**
+ * Verify that full backup is created on a single table with data correctly.
+ * @throws Exception
+ */
+ @Test
+ public void testBackupStatusProgress() throws Exception {
+
+ LOG.info("test backup status/progress on a single table with data");
+
+ List<TableName> tableList = Lists.newArrayList(table1);
+ String backupId = fullTableBackup(tableList);
+ LOG.info("backup complete");
+ assertTrue(checkSucceeded(backupId));
+
+
+ BackupInfo info = getBackupAdmin().getBackupInfo(backupId);
+ assertTrue(info.getState() == BackupState.COMPLETE);
+ int p = getBackupAdmin().getProgress(backupId);
+ LOG.debug(info.getShortDescription());
+ assertTrue(p > 0);
+
+ }
+
+ @Test
+ public void testBackupStatusProgressCommand() throws Exception {
+
+ LOG.info("test backup status/progress on a single table with data: command-line");
+
+ List<TableName> tableList = Lists.newArrayList(table1);
+ String backupId = fullTableBackup(tableList);
+ LOG.info("backup complete");
+ assertTrue(checkSucceeded(backupId));
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ System.setOut(new PrintStream(baos));
+
+ String[] args = new String[]{"describe", backupId };
+ int ret = ToolRunner.run(conf1, new BackupDriver(), args);
+ assertTrue(ret == 0);
+ String responce = baos.toString();
+ assertTrue(responce.indexOf(backupId) > 0);
+ assertTrue(responce.indexOf("COMPLETE") > 0);
+
+ baos = new ByteArrayOutputStream();
+ System.setOut(new PrintStream(baos));
+
+ args = new String[]{"progress", backupId };
+ ret = ToolRunner.run(conf1, new BackupDriver(), args);
+ assertTrue(ret ==0);
+ responce = baos.toString();
+ assertTrue(responce.indexOf(backupId) >= 0);
+ assertTrue(responce.indexOf("progress") > 0);
+ assertTrue(responce.indexOf("100") > 0);
+
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/hbase/blob/2725fb25/hbase-server/src/test/java/org/apache/hadoop/hbase/backup/TestBackupSystemTable.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/backup/TestBackupSystemTable.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/backup/TestBackupSystemTable.java
new file mode 100644
index 0000000..d8a8739
--- /dev/null
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/backup/TestBackupSystemTable.java
@@ -0,0 +1,527 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.hbase.backup;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.hbase.HBaseTestingUtility;
+import org.apache.hadoop.hbase.MiniHBaseCluster;
+import org.apache.hadoop.hbase.TableName;
+import org.apache.hadoop.hbase.backup.BackupInfo.BackupState;
+import org.apache.hadoop.hbase.backup.impl.BackupSystemTable;
+import org.apache.hadoop.hbase.client.Admin;
+import org.apache.hadoop.hbase.client.Connection;
+import org.apache.hadoop.hbase.testclassification.MediumTests;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+/**
+ * Test cases for hbase:backup API
+ *
+ */
+@Category(MediumTests.class)
+public class TestBackupSystemTable {
+
+ private static final HBaseTestingUtility UTIL = new HBaseTestingUtility();
+ protected static Configuration conf = UTIL.getConfiguration();
+ protected static MiniHBaseCluster cluster;
+ protected static Connection conn;
+ protected BackupSystemTable table;
+
+ @BeforeClass
+ public static void setUp() throws Exception {
+ conf.setBoolean(BackupRestoreConstants.BACKUP_ENABLE_KEY, true);
+ cluster = UTIL.startMiniCluster();
+ conn = UTIL.getConnection();
+ waitForSystemTable();
+ }
+
+ static void waitForSystemTable() throws Exception
+ {
+ try(Admin admin = UTIL.getAdmin();) {
+ while (!admin.tableExists(BackupSystemTable.getTableName())
+ || !admin.isTableAvailable(BackupSystemTable.getTableName())) {
+ Thread.sleep(1000);
+ }
+ }
+ }
+
+ @Before
+ public void before() throws IOException {
+ table = new BackupSystemTable(conn);
+ }
+
+ @After
+ public void after() {
+ if (table != null) {
+ table.close();
+ }
+
+ }
+
+ @Test
+ public void testUpdateReadDeleteBackupStatus() throws IOException {
+ BackupInfo ctx = createBackupContext();
+ table.updateBackupInfo(ctx);
+ BackupInfo readCtx = table.readBackupInfo(ctx.getBackupId());
+ assertTrue(compare(ctx, readCtx));
+ // try fake backup id
+ readCtx = table.readBackupInfo("fake");
+ assertNull(readCtx);
+ // delete backup context
+ table.deleteBackupInfo(ctx.getBackupId());
+ readCtx = table.readBackupInfo(ctx.getBackupId());
+ assertNull(readCtx);
+ cleanBackupTable();
+ }
+
+ @Test
+ public void testWriteReadBackupStartCode() throws IOException {
+ Long code = 100L;
+ table.writeBackupStartCode(code, "root");
+ String readCode = table.readBackupStartCode("root");
+ assertEquals(code, new Long(Long.parseLong(readCode)));
+ cleanBackupTable();
+ }
+
+ private void cleanBackupTable() throws IOException {
+ Admin admin = UTIL.getHBaseAdmin();
+ admin.disableTable(TableName.BACKUP_TABLE_NAME);
+ admin.truncateTable(TableName.BACKUP_TABLE_NAME, true);
+ if (admin.isTableDisabled(TableName.BACKUP_TABLE_NAME)) {
+ admin.enableTable(TableName.BACKUP_TABLE_NAME);
+ }
+ }
+
+ @Test
+ public void testBackupHistory() throws IOException {
+ int n = 10;
+ List<BackupInfo> list = createBackupContextList(n);
+
+ // Load data
+ for (BackupInfo bc : list) {
+ // Make sure we set right status
+ bc.setState(BackupState.COMPLETE);
+ table.updateBackupInfo(bc);
+ }
+
+ // Reverse list for comparison
+ Collections.reverse(list);
+ List<BackupInfo> history = table.getBackupHistory();
+ assertTrue(history.size() == n);
+
+ for (int i = 0; i < n; i++) {
+ BackupInfo ctx = list.get(i);
+ BackupInfo data = history.get(i);
+ assertTrue(compare(ctx, data));
+ }
+
+ cleanBackupTable();
+
+ }
+
+ @Test
+ public void testBackupDelete() throws IOException {
+
+ try (BackupSystemTable table = new BackupSystemTable(conn)) {
+
+ int n = 10;
+ List<BackupInfo> list = createBackupContextList(n);
+
+ // Load data
+ for (BackupInfo bc : list) {
+ // Make sure we set right status
+ bc.setState(BackupState.COMPLETE);
+ table.updateBackupInfo(bc);
+ }
+
+ // Verify exists
+ for (BackupInfo bc : list) {
+ assertNotNull(table.readBackupInfo(bc.getBackupId()));
+ }
+
+ // Delete all
+ for (BackupInfo bc : list) {
+ table.deleteBackupInfo(bc.getBackupId());
+ }
+
+ // Verify do not exists
+ for (BackupInfo bc : list) {
+ assertNull(table.readBackupInfo(bc.getBackupId()));
+ }
+
+ cleanBackupTable();
+ }
+
+ }
+
+
+
+ @Test
+ public void testRegionServerLastLogRollResults() throws IOException {
+ String[] servers = new String[] { "server1", "server2", "server3" };
+ Long[] timestamps = new Long[] { 100L, 102L, 107L };
+
+ for (int i = 0; i < servers.length; i++) {
+ table.writeRegionServerLastLogRollResult(servers[i], timestamps[i], "root");
+ }
+
+ HashMap<String, Long> result = table.readRegionServerLastLogRollResult("root");
+ assertTrue(servers.length == result.size());
+ Set<String> keys = result.keySet();
+ String[] keysAsArray = new String[keys.size()];
+ keys.toArray(keysAsArray);
+ Arrays.sort(keysAsArray);
+
+ for (int i = 0; i < keysAsArray.length; i++) {
+ assertEquals(keysAsArray[i], servers[i]);
+ Long ts1 = timestamps[i];
+ Long ts2 = result.get(keysAsArray[i]);
+ assertEquals(ts1, ts2);
+ }
+
+ cleanBackupTable();
+ }
+
+ @Test
+ public void testIncrementalBackupTableSet() throws IOException {
+ TreeSet<TableName> tables1 = new TreeSet<>();
+
+ tables1.add(TableName.valueOf("t1"));
+ tables1.add(TableName.valueOf("t2"));
+ tables1.add(TableName.valueOf("t3"));
+
+ TreeSet<TableName> tables2 = new TreeSet<>();
+
+ tables2.add(TableName.valueOf("t3"));
+ tables2.add(TableName.valueOf("t4"));
+ tables2.add(TableName.valueOf("t5"));
+
+ table.addIncrementalBackupTableSet(tables1, "root");
+ BackupSystemTable table = new BackupSystemTable(conn);
+ TreeSet<TableName> res1 = (TreeSet<TableName>)
+ table.getIncrementalBackupTableSet("root");
+ assertTrue(tables1.size() == res1.size());
+ Iterator<TableName> desc1 = tables1.descendingIterator();
+ Iterator<TableName> desc2 = res1.descendingIterator();
+ while (desc1.hasNext()) {
+ assertEquals(desc1.next(), desc2.next());
+ }
+
+ table.addIncrementalBackupTableSet(tables2, "root");
+ TreeSet<TableName> res2 = (TreeSet<TableName>)
+ table.getIncrementalBackupTableSet("root");
+ assertTrue((tables2.size() + tables1.size() - 1) == res2.size());
+
+ tables1.addAll(tables2);
+
+ desc1 = tables1.descendingIterator();
+ desc2 = res2.descendingIterator();
+
+ while (desc1.hasNext()) {
+ assertEquals(desc1.next(), desc2.next());
+ }
+ cleanBackupTable();
+
+ }
+
+ @Test
+ public void testRegionServerLogTimestampMap() throws IOException {
+ TreeSet<TableName> tables = new TreeSet<>();
+
+ tables.add(TableName.valueOf("t1"));
+ tables.add(TableName.valueOf("t2"));
+ tables.add(TableName.valueOf("t3"));
+
+ HashMap<String, Long> rsTimestampMap = new HashMap<String, Long>();
+
+ rsTimestampMap.put("rs1:100", 100L);
+ rsTimestampMap.put("rs2:100", 101L);
+ rsTimestampMap.put("rs3:100", 103L);
+
+ table.writeRegionServerLogTimestamp(tables, rsTimestampMap, "root");
+
+ HashMap<TableName, HashMap<String, Long>> result = table.readLogTimestampMap("root");
+
+ assertTrue(tables.size() == result.size());
+
+ for (TableName t : tables) {
+ HashMap<String, Long> rstm = result.get(t);
+ assertNotNull(rstm);
+ assertEquals(rstm.get("rs1:100"), new Long(100L));
+ assertEquals(rstm.get("rs2:100"), new Long(101L));
+ assertEquals(rstm.get("rs3:100"), new Long(103L));
+ }
+
+ Set<TableName> tables1 = new TreeSet<>();
+
+ tables1.add(TableName.valueOf("t3"));
+ tables1.add(TableName.valueOf("t4"));
+ tables1.add(TableName.valueOf("t5"));
+
+ HashMap<String, Long> rsTimestampMap1 = new HashMap<String, Long>();
+
+ rsTimestampMap1.put("rs1:100", 200L);
+ rsTimestampMap1.put("rs2:100", 201L);
+ rsTimestampMap1.put("rs3:100", 203L);
+
+ table.writeRegionServerLogTimestamp(tables1, rsTimestampMap1, "root");
+
+ result = table.readLogTimestampMap("root");
+
+ assertTrue(5 == result.size());
+
+ for (TableName t : tables) {
+ HashMap<String, Long> rstm = result.get(t);
+ assertNotNull(rstm);
+ if (t.equals(TableName.valueOf("t3")) == false) {
+ assertEquals(rstm.get("rs1:100"), new Long(100L));
+ assertEquals(rstm.get("rs2:100"), new Long(101L));
+ assertEquals(rstm.get("rs3:100"), new Long(103L));
+ } else {
+ assertEquals(rstm.get("rs1:100"), new Long(200L));
+ assertEquals(rstm.get("rs2:100"), new Long(201L));
+ assertEquals(rstm.get("rs3:100"), new Long(203L));
+ }
+ }
+
+ for (TableName t : tables1) {
+ HashMap<String, Long> rstm = result.get(t);
+ assertNotNull(rstm);
+ assertEquals(rstm.get("rs1:100"), new Long(200L));
+ assertEquals(rstm.get("rs2:100"), new Long(201L));
+ assertEquals(rstm.get("rs3:100"), new Long(203L));
+ }
+
+ cleanBackupTable();
+
+ }
+
+ @Test
+ public void testAddWALFiles() throws IOException {
+ List<String> files =
+ Arrays.asList("hdfs://server/WALs/srv1,101,15555/srv1,101,15555.default.1",
+ "hdfs://server/WALs/srv2,102,16666/srv2,102,16666.default.2",
+ "hdfs://server/WALs/srv3,103,17777/srv3,103,17777.default.3");
+ String newFile = "hdfs://server/WALs/srv1,101,15555/srv1,101,15555.default.5";
+
+ table.addWALFiles(files, "backup", "root");
+
+ assertTrue(table.isWALFileDeletable(files.get(0)));
+ assertTrue(table.isWALFileDeletable(files.get(1)));
+ assertTrue(table.isWALFileDeletable(files.get(2)));
+ assertFalse(table.isWALFileDeletable(newFile));
+
+ cleanBackupTable();
+ }
+
+
+ /**
+ * Backup set tests
+ */
+
+ @Test
+ public void testBackupSetAddNotExists() throws IOException {
+ try (BackupSystemTable table = new BackupSystemTable(conn)) {
+
+ String[] tables = new String[] { "table1", "table2", "table3" };
+ String setName = "name";
+ table.addToBackupSet(setName, tables);
+ List<TableName> tnames = table.describeBackupSet(setName);
+ assertTrue(tnames != null);
+ assertTrue(tnames.size() == tables.length);
+ for (int i = 0; i < tnames.size(); i++) {
+ assertTrue(tnames.get(i).getNameAsString().equals(tables[i]));
+ }
+ cleanBackupTable();
+ }
+
+ }
+
+ @Test
+ public void testBackupSetAddExists() throws IOException {
+ try (BackupSystemTable table = new BackupSystemTable(conn)) {
+
+ String[] tables = new String[] { "table1", "table2", "table3" };
+ String setName = "name";
+ table.addToBackupSet(setName, tables);
+ String[] addTables = new String[] { "table4", "table5", "table6" };
+ table.addToBackupSet(setName, addTables);
+
+ List<TableName> tnames = table.describeBackupSet(setName);
+ assertTrue(tnames != null);
+ assertTrue(tnames.size() == tables.length + addTables.length);
+ for (int i = 0; i < tnames.size(); i++) {
+ assertTrue(tnames.get(i).getNameAsString().equals("table" + (i + 1)));
+ }
+ cleanBackupTable();
+ }
+ }
+
+ @Test
+ public void testBackupSetAddExistsIntersects() throws IOException {
+ try (BackupSystemTable table = new BackupSystemTable(conn)) {
+
+ String[] tables = new String[] { "table1", "table2", "table3" };
+ String setName = "name";
+ table.addToBackupSet(setName, tables);
+ String[] addTables = new String[] { "table3", "table4", "table5", "table6" };
+ table.addToBackupSet(setName, addTables);
+
+ List<TableName> tnames = table.describeBackupSet(setName);
+ assertTrue(tnames != null);
+ assertTrue(tnames.size()== tables.length + addTables.length - 1);
+ for (int i = 0; i < tnames.size(); i++) {
+ assertTrue(tnames.get(i).getNameAsString().equals("table" + (i + 1)));
+ }
+ cleanBackupTable();
+ }
+ }
+
+ @Test
+ public void testBackupSetRemoveSomeNotExists() throws IOException {
+ try (BackupSystemTable table = new BackupSystemTable(conn)) {
+
+ String[] tables = new String[] { "table1", "table2", "table3", "table4" };
+ String setName = "name";
+ table.addToBackupSet(setName, tables);
+ String[] removeTables = new String[] { "table4", "table5", "table6" };
+ table.removeFromBackupSet(setName, removeTables);
+
+ List<TableName> tnames = table.describeBackupSet(setName);
+ assertTrue(tnames != null);
+ assertTrue(tnames.size() == tables.length - 1);
+ for (int i = 0; i < tnames.size(); i++) {
+ assertTrue(tnames.get(i).getNameAsString().equals("table" + (i + 1)));
+ }
+ cleanBackupTable();
+ }
+ }
+
+ @Test
+ public void testBackupSetRemove() throws IOException {
+ try (BackupSystemTable table = new BackupSystemTable(conn)) {
+
+ String[] tables = new String[] { "table1", "table2", "table3", "table4" };
+ String setName = "name";
+ table.addToBackupSet(setName, tables);
+ String[] removeTables = new String[] { "table4", "table3" };
+ table.removeFromBackupSet(setName, removeTables);
+
+ List<TableName> tnames = table.describeBackupSet(setName);
+ assertTrue(tnames != null);
+ assertTrue(tnames.size() == tables.length - 2);
+ for (int i = 0; i < tnames.size(); i++) {
+ assertTrue(tnames.get(i).getNameAsString().equals("table" + (i + 1)));
+ }
+ cleanBackupTable();
+ }
+ }
+
+ @Test
+ public void testBackupSetDelete() throws IOException {
+ try (BackupSystemTable table = new BackupSystemTable(conn)) {
+
+ String[] tables = new String[] { "table1", "table2", "table3", "table4" };
+ String setName = "name";
+ table.addToBackupSet(setName, tables);
+ table.deleteBackupSet(setName);
+
+ List<TableName> tnames = table.describeBackupSet(setName);
+ assertTrue(tnames == null);
+ cleanBackupTable();
+ }
+ }
+
+ @Test
+ public void testBackupSetList() throws IOException {
+ try (BackupSystemTable table = new BackupSystemTable(conn)) {
+
+ String[] tables = new String[] { "table1", "table2", "table3", "table4" };
+ String setName1 = "name1";
+ String setName2 = "name2";
+ table.addToBackupSet(setName1, tables);
+ table.addToBackupSet(setName2, tables);
+
+ List<String> list = table.listBackupSets();
+
+ assertTrue(list.size() == 2);
+ assertTrue(list.get(0).equals(setName1));
+ assertTrue(list.get(1).equals(setName2));
+
+ cleanBackupTable();
+ }
+ }
+
+
+ private boolean compare(BackupInfo one, BackupInfo two) {
+ return one.getBackupId().equals(two.getBackupId()) && one.getType().equals(two.getType())
+ && one.getTargetRootDir().equals(two.getTargetRootDir())
+ && one.getStartTs() == two.getStartTs() && one.getEndTs() == two.getEndTs();
+ }
+
+ private BackupInfo createBackupContext() {
+
+ BackupInfo ctxt =
+ new BackupInfo("backup_" + System.nanoTime(), BackupType.FULL,
+ new TableName[] {
+ TableName.valueOf("t1"), TableName.valueOf("t2"), TableName.valueOf("t3") },
+ "/hbase/backup");
+ ctxt.setStartTs(System.currentTimeMillis());
+ ctxt.setEndTs(System.currentTimeMillis() + 1);
+ return ctxt;
+ }
+
+ private List<BackupInfo> createBackupContextList(int size) {
+ List<BackupInfo> list = new ArrayList<BackupInfo>();
+ for (int i = 0; i < size; i++) {
+ list.add(createBackupContext());
+ try {
+ Thread.sleep(10);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ return list;
+ }
+
+ @AfterClass
+ public static void tearDown() throws IOException {
+ if (cluster != null) cluster.shutdown();
+ }
+}
http://git-wip-us.apache.org/repos/asf/hbase/blob/2725fb25/hbase-server/src/test/java/org/apache/hadoop/hbase/backup/TestFullBackup.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/backup/TestFullBackup.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/backup/TestFullBackup.java
new file mode 100644
index 0000000..46455d3
--- /dev/null
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/backup/TestFullBackup.java
@@ -0,0 +1,76 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.hbase.backup;
+
+import static org.junit.Assert.assertTrue;
+
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.hbase.backup.impl.BackupSystemTable;
+import org.apache.hadoop.hbase.testclassification.LargeTests;
+import org.apache.hadoop.util.ToolRunner;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+@Category(LargeTests.class)
+public class TestFullBackup extends TestBackupBase {
+
+ private static final Log LOG = LogFactory.getLog(TestFullBackup.class);
+
+ @Test
+ public void testFullBackupMultipleCommand() throws Exception {
+ LOG.info("test full backup on a multiple tables with data: command-line");
+ try(BackupSystemTable table = new BackupSystemTable(TEST_UTIL.getConnection())) {
+ int before = table.getBackupHistory().size();
+ String[] args = new String[]{"create", "full", BACKUP_ROOT_DIR,
+ table1.getNameAsString() +","+ table2.getNameAsString() };
+ // Run backup
+ int ret = ToolRunner.run(conf1, new BackupDriver(), args);
+ assertTrue(ret == 0);
+ List<BackupInfo> backups = table.getBackupHistory();
+ int after = table.getBackupHistory().size();
+ assertTrue(after == before +1);
+ for(BackupInfo data : backups){
+ String backupId = data.getBackupId();
+ assertTrue(checkSucceeded(backupId));
+ }
+ }
+ LOG.info("backup complete");
+ }
+
+ @Test
+ public void testFullBackupAllCommand() throws Exception {
+ LOG.info("create full backup image on all tables: command-line");
+ try(BackupSystemTable table = new BackupSystemTable(TEST_UTIL.getConnection())) {
+ int before = table.getBackupHistory().size();
+ String[] args = new String[]{"create", "full", BACKUP_ROOT_DIR };
+ // Run backup
+ int ret = ToolRunner.run(conf1, new BackupDriver(), args);
+ assertTrue(ret == 0);
+ List<BackupInfo> backups = table.getBackupHistory();
+ int after = table.getBackupHistory().size();
+ assertTrue(after == before +1);
+ for(BackupInfo data : backups){
+ String backupId = data.getBackupId();
+ assertTrue(checkSucceeded(backupId));
+ }
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/hbase/blob/2725fb25/hbase-server/src/test/java/org/apache/hadoop/hbase/backup/TestFullBackupSet.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/backup/TestFullBackupSet.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/backup/TestFullBackupSet.java
new file mode 100644
index 0000000..151151c
--- /dev/null
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/backup/TestFullBackupSet.java
@@ -0,0 +1,105 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.hbase.backup;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.hbase.TableName;
+import org.apache.hadoop.hbase.backup.impl.BackupSystemTable;
+import org.apache.hadoop.hbase.client.HBaseAdmin;
+import org.apache.hadoop.hbase.testclassification.LargeTests;
+import org.apache.hadoop.util.ToolRunner;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+@Category(LargeTests.class)
+public class TestFullBackupSet extends TestBackupBase {
+
+ private static final Log LOG = LogFactory.getLog(TestFullBackupSet.class);
+
+
+ /**
+ * Verify that full backup is created on a single table with data correctly.
+ * @throws Exception
+ */
+ @Test
+ public void testFullBackupSetExist() throws Exception {
+
+ LOG.info("Test full backup, backup set exists");
+
+ //Create set
+ try (BackupSystemTable table = new BackupSystemTable(TEST_UTIL.getConnection())) {
+ String name = "name";
+ table.addToBackupSet(name, new String[] { table1.getNameAsString() });
+ List<TableName> names = table.describeBackupSet(name);
+
+ assertNotNull(names);
+ assertTrue(names.size() == 1);
+ assertTrue(names.get(0).equals(table1));
+
+ String[] args = new String[] { "create", "full", BACKUP_ROOT_DIR, "-s", name };
+ // Run backup
+ int ret = ToolRunner.run(conf1, new BackupDriver(), args);
+ assertTrue(ret == 0);
+ List<BackupInfo> backups = table.getBackupHistory();
+ assertTrue(backups.size() == 1);
+ String backupId = backups.get(0).getBackupId();
+ assertTrue(checkSucceeded(backupId));
+ assertTrue(backupId.startsWith(name));
+
+ LOG.info("backup complete");
+
+ // Restore from set into other table
+ args = new String[]{BACKUP_ROOT_DIR, backupId,
+ "-s", name, "-m", table1_restore.getNameAsString(), "-o" };
+ // Run backup
+ ret = ToolRunner.run(conf1, new RestoreDriver(), args);
+ assertTrue(ret == 0);
+ HBaseAdmin hba = TEST_UTIL.getHBaseAdmin();
+ assertTrue(hba.tableExists(table1_restore));
+ // Verify number of rows in both tables
+ assertEquals(TEST_UTIL.countRows(table1), TEST_UTIL.countRows(table1_restore));
+ TEST_UTIL.deleteTable(table1_restore);
+ LOG.info("restore into other table is complete");
+ hba.close();
+
+
+ }
+
+ }
+
+ @Test
+ public void testFullBackupSetDoesNotExist() throws Exception {
+
+ LOG.info("test full backup, backup set does not exist");
+ String name = "name1";
+ String[] args = new String[]{"create", "full", BACKUP_ROOT_DIR, "-s", name };
+ // Run backup
+ int ret = ToolRunner.run(conf1, new BackupDriver(), args);
+ assertTrue(ret != 0);
+
+ }
+
+}
\ No newline at end of file