1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.hadoop.hbase.client;
19
20 import static org.junit.Assert.assertEquals;
21
22 import java.io.IOException;
23
24 import org.apache.commons.logging.Log;
25 import org.apache.commons.logging.LogFactory;
26 import org.apache.hadoop.hbase.HBaseTestingUtility;
27 import org.apache.hadoop.hbase.HConstants;
28 import org.apache.hadoop.hbase.testclassification.LargeTests;
29 import org.apache.hadoop.hbase.NamespaceDescriptor;
30 import org.apache.hadoop.hbase.NamespaceNotFoundException;
31 import org.apache.hadoop.hbase.TableName;
32 import org.apache.hadoop.hbase.master.snapshot.SnapshotManager;
33 import org.apache.hadoop.hbase.snapshot.SnapshotDoesNotExistException;
34 import org.apache.hadoop.hbase.snapshot.SnapshotTestingUtils;
35 import org.apache.hadoop.hbase.util.Bytes;
36 import org.junit.After;
37 import org.junit.AfterClass;
38 import org.junit.Before;
39 import org.junit.BeforeClass;
40 import org.junit.Test;
41 import org.junit.experimental.categories.Category;
42
43
44
45
46 @Category(LargeTests.class)
47 public class TestCloneSnapshotFromClient {
48 private static final Log LOG = LogFactory.getLog(TestCloneSnapshotFromClient.class);
49
50 private final static HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
51
52 private final byte[] FAMILY = Bytes.toBytes("cf");
53
54 private byte[] emptySnapshot;
55 private byte[] snapshotName0;
56 private byte[] snapshotName1;
57 private byte[] snapshotName2;
58 private int snapshot0Rows;
59 private int snapshot1Rows;
60 private TableName tableName;
61 private Admin admin;
62
63 @BeforeClass
64 public static void setUpBeforeClass() throws Exception {
65 TEST_UTIL.getConfiguration().setBoolean(SnapshotManager.HBASE_SNAPSHOT_ENABLED, true);
66 TEST_UTIL.getConfiguration().setBoolean("hbase.online.schema.update.enable", true);
67 TEST_UTIL.getConfiguration().setInt("hbase.hstore.compactionThreshold", 10);
68 TEST_UTIL.getConfiguration().setInt("hbase.regionserver.msginterval", 100);
69 TEST_UTIL.getConfiguration().setInt("hbase.client.pause", 250);
70 TEST_UTIL.getConfiguration().setInt(HConstants.HBASE_CLIENT_RETRIES_NUMBER, 6);
71 TEST_UTIL.getConfiguration().setBoolean(
72 "hbase.master.enabletable.roundrobin", true);
73 TEST_UTIL.startMiniCluster(3);
74 }
75
76 @AfterClass
77 public static void tearDownAfterClass() throws Exception {
78 TEST_UTIL.shutdownMiniCluster();
79 }
80
81
82
83
84
85
86 @Before
87 public void setup() throws Exception {
88 this.admin = TEST_UTIL.getHBaseAdmin();
89
90 long tid = System.currentTimeMillis();
91 tableName = TableName.valueOf("testtb-" + tid);
92 emptySnapshot = Bytes.toBytes("emptySnaptb-" + tid);
93 snapshotName0 = Bytes.toBytes("snaptb0-" + tid);
94 snapshotName1 = Bytes.toBytes("snaptb1-" + tid);
95 snapshotName2 = Bytes.toBytes("snaptb2-" + tid);
96
97
98 SnapshotTestingUtils.createTable(TEST_UTIL, tableName, getNumReplicas(), FAMILY);
99 admin.disableTable(tableName);
100
101
102 admin.snapshot(emptySnapshot, tableName);
103
104
105 admin.enableTable(tableName);
106 SnapshotTestingUtils.loadData(TEST_UTIL, tableName, 500, FAMILY);
107 try (Table table = TEST_UTIL.getConnection().getTable(tableName)){
108 snapshot0Rows = TEST_UTIL.countRows(table);
109 }
110 admin.disableTable(tableName);
111
112
113 admin.snapshot(snapshotName0, tableName);
114
115
116 admin.enableTable(tableName);
117 SnapshotTestingUtils.loadData(TEST_UTIL, tableName, 500, FAMILY);
118 try (Table table = TEST_UTIL.getConnection().getTable(tableName)){
119 snapshot1Rows = TEST_UTIL.countRows(table);
120 }
121 admin.disableTable(tableName);
122
123
124 admin.snapshot(snapshotName1, tableName);
125
126
127 admin.enableTable(tableName);
128 }
129
130 protected int getNumReplicas() {
131 return 1;
132 }
133
134 @After
135 public void tearDown() throws Exception {
136 if (admin.tableExists(tableName)) {
137 TEST_UTIL.deleteTable(tableName);
138 }
139 SnapshotTestingUtils.deleteAllSnapshots(admin);
140 SnapshotTestingUtils.deleteArchiveDirectory(TEST_UTIL);
141 }
142
143 @Test(expected=SnapshotDoesNotExistException.class)
144 public void testCloneNonExistentSnapshot() throws IOException, InterruptedException {
145 String snapshotName = "random-snapshot-" + System.currentTimeMillis();
146 TableName tableName = TableName.valueOf("random-table-" + System.currentTimeMillis());
147 admin.cloneSnapshot(snapshotName, tableName);
148 }
149
150 @Test(expected = NamespaceNotFoundException.class)
151 public void testCloneOnMissingNamespace() throws IOException, InterruptedException {
152 TableName clonedTableName = TableName.valueOf("unknownNS:clonetb");
153 admin.cloneSnapshot(snapshotName1, clonedTableName);
154 }
155
156 @Test
157 public void testCloneSnapshot() throws IOException, InterruptedException {
158 TableName clonedTableName = TableName.valueOf("clonedtb-" + System.currentTimeMillis());
159 testCloneSnapshot(clonedTableName, snapshotName0, snapshot0Rows);
160 testCloneSnapshot(clonedTableName, snapshotName1, snapshot1Rows);
161 testCloneSnapshot(clonedTableName, emptySnapshot, 0);
162 }
163
164 private void testCloneSnapshot(final TableName tableName, final byte[] snapshotName,
165 int snapshotRows) throws IOException, InterruptedException {
166
167 admin.cloneSnapshot(snapshotName, tableName);
168 SnapshotTestingUtils.verifyRowCount(TEST_UTIL, tableName, snapshotRows);
169
170 verifyReplicasCameOnline(tableName);
171 TEST_UTIL.deleteTable(tableName);
172 }
173
174 protected void verifyReplicasCameOnline(TableName tableName) throws IOException {
175 SnapshotTestingUtils.verifyReplicasCameOnline(tableName, admin, getNumReplicas());
176 }
177
178 @Test
179 public void testCloneSnapshotCrossNamespace() throws IOException, InterruptedException {
180 String nsName = "testCloneSnapshotCrossNamespace";
181 admin.createNamespace(NamespaceDescriptor.create(nsName).build());
182 TableName clonedTableName =
183 TableName.valueOf(nsName, "clonedtb-" + System.currentTimeMillis());
184 testCloneSnapshot(clonedTableName, snapshotName0, snapshot0Rows);
185 testCloneSnapshot(clonedTableName, snapshotName1, snapshot1Rows);
186 testCloneSnapshot(clonedTableName, emptySnapshot, 0);
187 }
188
189
190
191
192 @Test
193 public void testCloneLinksAfterDelete() throws IOException, InterruptedException {
194
195 TableName clonedTableName = TableName.valueOf("clonedtb1-" + System.currentTimeMillis());
196 admin.cloneSnapshot(snapshotName0, clonedTableName);
197 SnapshotTestingUtils.verifyRowCount(TEST_UTIL, clonedTableName, snapshot0Rows);
198
199
200 admin.disableTable(clonedTableName);
201 admin.snapshot(snapshotName2, clonedTableName);
202
203
204 TableName clonedTableName2 = TableName.valueOf("clonedtb2-" + System.currentTimeMillis());
205 admin.cloneSnapshot(snapshotName2, clonedTableName2);
206 SnapshotTestingUtils.verifyRowCount(TEST_UTIL, clonedTableName2, snapshot0Rows);
207 admin.disableTable(clonedTableName2);
208
209
210 TEST_UTIL.deleteTable(tableName);
211 waitCleanerRun();
212
213
214 admin.enableTable(clonedTableName);
215 SnapshotTestingUtils.verifyRowCount(TEST_UTIL, clonedTableName, snapshot0Rows);
216
217
218 admin.enableTable(clonedTableName2);
219 SnapshotTestingUtils.verifyRowCount(TEST_UTIL, clonedTableName2, snapshot0Rows);
220 admin.disableTable(clonedTableName2);
221
222
223 TEST_UTIL.deleteTable(clonedTableName);
224 waitCleanerRun();
225
226
227 admin.enableTable(clonedTableName2);
228 SnapshotTestingUtils.verifyRowCount(TEST_UTIL, clonedTableName2, snapshot0Rows);
229
230
231 TableName clonedTableName3 = TableName.valueOf("clonedtb3-" + System.currentTimeMillis());
232 admin.cloneSnapshot(snapshotName2, clonedTableName3);
233 SnapshotTestingUtils.verifyRowCount(TEST_UTIL, clonedTableName3, snapshot0Rows);
234
235
236 TEST_UTIL.deleteTable(clonedTableName2);
237 TEST_UTIL.deleteTable(clonedTableName3);
238 admin.deleteSnapshot(snapshotName2);
239 }
240
241
242
243
244
245 private void waitCleanerRun() throws InterruptedException {
246 TEST_UTIL.getMiniHBaseCluster().getMaster().getHFileCleaner().choreForTesting();
247 }
248 }