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