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