1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.hadoop.hbase.snapshot;
19
20 import static org.junit.Assert.assertEquals;
21 import static org.junit.Assert.assertFalse;
22 import static org.junit.Assert.assertTrue;
23
24 import java.io.IOException;
25 import java.util.Collections;
26 import java.util.ArrayList;
27 import java.util.HashSet;
28 import java.util.List;
29 import java.util.Map;
30 import java.util.Set;
31 import java.util.TreeSet;
32
33 import org.apache.commons.logging.Log;
34 import org.apache.commons.logging.LogFactory;
35 import org.apache.hadoop.conf.Configuration;
36 import org.apache.hadoop.fs.FSDataOutputStream;
37 import org.apache.hadoop.fs.FileSystem;
38 import org.apache.hadoop.fs.FileStatus;
39 import org.apache.hadoop.fs.FSDataInputStream;
40 import org.apache.hadoop.fs.Path;
41 import org.apache.hadoop.fs.PathFilter;
42 import org.apache.hadoop.hbase.HBaseTestingUtility;
43 import org.apache.hadoop.hbase.HColumnDescriptor;
44 import org.apache.hadoop.hbase.HConstants;
45 import org.apache.hadoop.hbase.HRegionInfo;
46 import org.apache.hadoop.hbase.HTableDescriptor;
47 import org.apache.hadoop.hbase.TableName;
48 import org.apache.hadoop.hbase.TableNotEnabledException;
49 import org.apache.hadoop.hbase.classification.InterfaceAudience;
50 import org.apache.hadoop.hbase.client.Admin;
51 import org.apache.hadoop.hbase.client.BufferedMutator;
52 import org.apache.hadoop.hbase.client.Durability;
53 import org.apache.hadoop.hbase.client.HTable;
54 import org.apache.hadoop.hbase.client.Put;
55 import org.apache.hadoop.hbase.client.Table;
56 import org.apache.hadoop.hbase.errorhandling.ForeignExceptionDispatcher;
57 import org.apache.hadoop.hbase.client.RegionReplicaUtil;
58 import org.apache.hadoop.hbase.io.HFileLink;
59 import org.apache.hadoop.hbase.master.HMaster;
60 import org.apache.hadoop.hbase.master.MasterFileSystem;
61 import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
62 import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.SnapshotDescription;
63 import org.apache.hadoop.hbase.protobuf.generated.SnapshotProtos.SnapshotRegionManifest;
64 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsSnapshotDoneRequest;
65 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsSnapshotDoneResponse;
66 import org.apache.hadoop.hbase.regionserver.HRegionFileSystem;
67 import org.apache.hadoop.hbase.regionserver.HRegionServer;
68 import org.apache.hadoop.hbase.regionserver.Region;
69 import org.apache.hadoop.hbase.util.Bytes;
70 import org.apache.hadoop.hbase.util.FSTableDescriptors;
71 import org.apache.hadoop.hbase.util.FSVisitor;
72 import org.apache.hadoop.hbase.util.FSUtils;
73 import org.apache.hadoop.hbase.util.MD5Hash;
74 import org.junit.Assert;
75
76 import com.google.protobuf.ServiceException;
77
78
79
80
81 @InterfaceAudience.Private
82 public final class SnapshotTestingUtils {
83
84 private static final Log LOG = LogFactory.getLog(SnapshotTestingUtils.class);
85 private static byte[] KEYS = Bytes.toBytes("0123456789");
86
87 private SnapshotTestingUtils() {
88
89 }
90
91
92
93
94
95
96
97 public static void assertNoSnapshots(Admin admin) throws IOException {
98 assertEquals("Have some previous snapshots", 0, admin.listSnapshots()
99 .size());
100 }
101
102
103
104
105
106 public static List<SnapshotDescription> assertExistsMatchingSnapshot(
107 Admin admin, String snapshotName, TableName tableName)
108 throws IOException {
109
110 List<SnapshotDescription> snapshots = admin.listSnapshots();
111
112 List<SnapshotDescription> returnedSnapshots = new ArrayList<SnapshotDescription>();
113 for (SnapshotDescription sd : snapshots) {
114 if (snapshotName.equals(sd.getName()) &&
115 tableName.equals(TableName.valueOf(sd.getTable()))) {
116 returnedSnapshots.add(sd);
117 }
118 }
119
120 Assert.assertTrue("No matching snapshots found.", returnedSnapshots.size()>0);
121 return returnedSnapshots;
122 }
123
124
125
126
127 public static void assertOneSnapshotThatMatches(Admin admin,
128 SnapshotDescription snapshot) throws IOException {
129 assertOneSnapshotThatMatches(admin, snapshot.getName(),
130 TableName.valueOf(snapshot.getTable()));
131 }
132
133
134
135
136
137 public static List<SnapshotDescription> assertOneSnapshotThatMatches(
138 Admin admin, String snapshotName, TableName tableName)
139 throws IOException {
140
141 List<SnapshotDescription> snapshots = admin.listSnapshots();
142
143 assertEquals("Should only have 1 snapshot", 1, snapshots.size());
144 assertEquals(snapshotName, snapshots.get(0).getName());
145 assertEquals(tableName, TableName.valueOf(snapshots.get(0).getTable()));
146
147 return snapshots;
148 }
149
150
151
152
153
154 public static List<SnapshotDescription> assertOneSnapshotThatMatches(
155 Admin admin, byte[] snapshot, TableName tableName) throws IOException {
156 return assertOneSnapshotThatMatches(admin, Bytes.toString(snapshot),
157 tableName);
158 }
159
160 public static void confirmSnapshotValid(HBaseTestingUtility testUtil,
161 SnapshotDescription snapshotDescriptor, TableName tableName, byte[] family)
162 throws IOException {
163 MasterFileSystem mfs = testUtil.getHBaseCluster().getMaster().getMasterFileSystem();
164 confirmSnapshotValid(snapshotDescriptor, tableName, family,
165 mfs.getRootDir(), testUtil.getHBaseAdmin(), mfs.getFileSystem());
166 }
167
168
169
170
171
172 public static void confirmSnapshotValid(
173 SnapshotDescription snapshotDescriptor, TableName tableName,
174 byte[] testFamily, Path rootDir, Admin admin, FileSystem fs)
175 throws IOException {
176 ArrayList nonEmptyTestFamilies = new ArrayList(1);
177 nonEmptyTestFamilies.add(testFamily);
178 confirmSnapshotValid(snapshotDescriptor, tableName,
179 nonEmptyTestFamilies, null, rootDir, admin, fs);
180 }
181
182
183
184
185 public static void confirmEmptySnapshotValid(
186 SnapshotDescription snapshotDescriptor, TableName tableName,
187 byte[] testFamily, Path rootDir, Admin admin, FileSystem fs)
188 throws IOException {
189 ArrayList emptyTestFamilies = new ArrayList(1);
190 emptyTestFamilies.add(testFamily);
191 confirmSnapshotValid(snapshotDescriptor, tableName,
192 null, emptyTestFamilies, rootDir, admin, fs);
193 }
194
195
196
197
198
199
200
201 public static void confirmSnapshotValid(
202 SnapshotDescription snapshotDescriptor, TableName tableName,
203 List<byte[]> nonEmptyTestFamilies, List<byte[]> emptyTestFamilies,
204 Path rootDir, Admin admin, FileSystem fs) throws IOException {
205 final Configuration conf = admin.getConfiguration();
206
207
208 Path snapshotDir = SnapshotDescriptionUtils.getCompletedSnapshotDir(
209 snapshotDescriptor, rootDir);
210 assertTrue(fs.exists(snapshotDir));
211
212 SnapshotDescription desc = SnapshotDescriptionUtils.readSnapshotInfo(fs, snapshotDir);
213
214
215 final Set<byte[]> snapshotFamilies = new TreeSet<byte[]>(Bytes.BYTES_COMPARATOR);
216
217 SnapshotManifest manifest = SnapshotManifest.open(conf, fs, snapshotDir, desc);
218 Map<String, SnapshotRegionManifest> regionManifests = manifest.getRegionManifestsMap();
219 for (SnapshotRegionManifest regionManifest: regionManifests.values()) {
220 SnapshotReferenceUtil.visitRegionStoreFiles(regionManifest,
221 new SnapshotReferenceUtil.StoreFileVisitor() {
222 @Override
223 public void storeFile(final HRegionInfo regionInfo, final String family,
224 final SnapshotRegionManifest.StoreFile storeFile) throws IOException {
225 snapshotFamilies.add(Bytes.toBytes(family));
226 }
227 });
228 }
229
230
231 if (nonEmptyTestFamilies != null) {
232 for (final byte[] familyName: nonEmptyTestFamilies) {
233 assertTrue(snapshotFamilies.contains(familyName));
234 }
235 }
236
237
238 if (emptyTestFamilies != null) {
239 for (final byte[] familyName: emptyTestFamilies) {
240 assertFalse(snapshotFamilies.contains(familyName));
241 }
242 }
243
244
245 List<HRegionInfo> regions = admin.getTableRegions(tableName);
246
247 RegionReplicaUtil.removeNonDefaultRegions(regions);
248 assertEquals(regions.size(), regionManifests.size());
249
250
251 for (HRegionInfo info : regions) {
252 String regionName = info.getEncodedName();
253 assertTrue(regionManifests.containsKey(regionName));
254 }
255 }
256
257
258
259
260
261
262
263
264
265
266 public static void waitForSnapshotToComplete(HMaster master,
267 SnapshotDescription snapshot, long sleep) throws ServiceException {
268 final IsSnapshotDoneRequest request = IsSnapshotDoneRequest.newBuilder()
269 .setSnapshot(snapshot).build();
270 IsSnapshotDoneResponse done = IsSnapshotDoneResponse.newBuilder()
271 .buildPartial();
272 while (!done.getDone()) {
273 done = master.getMasterRpcServices().isSnapshotDone(null, request);
274 try {
275 Thread.sleep(sleep);
276 } catch (InterruptedException e) {
277 throw new ServiceException(e);
278 }
279 }
280 }
281
282
283
284
285
286 public static void snapshot(Admin admin,
287 final String snapshotName, final String tableName,
288 SnapshotDescription.Type type, int numTries) throws IOException {
289 int tries = 0;
290 CorruptedSnapshotException lastEx = null;
291 while (tries++ < numTries) {
292 try {
293 admin.snapshot(snapshotName, TableName.valueOf(tableName), type);
294 return;
295 } catch (CorruptedSnapshotException cse) {
296 LOG.warn("Got CorruptedSnapshotException", cse);
297 lastEx = cse;
298 }
299 }
300 throw lastEx;
301 }
302
303 public static void cleanupSnapshot(Admin admin, byte[] tableName)
304 throws IOException {
305 SnapshotTestingUtils.cleanupSnapshot(admin, Bytes.toString(tableName));
306 }
307
308 public static void cleanupSnapshot(Admin admin, String snapshotName)
309 throws IOException {
310
311 admin.deleteSnapshot(snapshotName);
312 assertNoSnapshots(admin);
313 }
314
315
316
317
318
319
320
321
322
323 public static void expectSnapshotDoneException(HMaster master,
324 IsSnapshotDoneRequest snapshot,
325 Class<? extends HBaseSnapshotException> clazz) {
326 try {
327 master.getMasterRpcServices().isSnapshotDone(null, snapshot);
328 Assert.fail("didn't fail to lookup a snapshot");
329 } catch (ServiceException se) {
330 try {
331 throw ProtobufUtil.getRemoteException(se);
332 } catch (HBaseSnapshotException e) {
333 assertEquals("Threw wrong snapshot exception!", clazz, e.getClass());
334 } catch (Throwable t) {
335 Assert.fail("Threw an unexpected exception:" + t);
336 }
337 }
338 }
339
340
341
342
343
344
345
346
347
348 public static ArrayList<String> listHFileNames(final FileSystem fs, final Path tableDir)
349 throws IOException {
350 final ArrayList<String> hfiles = new ArrayList<String>();
351 FSVisitor.visitTableStoreFiles(fs, tableDir, new FSVisitor.StoreFileVisitor() {
352 @Override
353 public void storeFile(final String region, final String family, final String hfileName)
354 throws IOException {
355 hfiles.add(hfileName);
356 }
357 });
358 Collections.sort(hfiles);
359 return hfiles;
360 }
361
362
363
364
365
366
367 public static void createSnapshotAndValidate(Admin admin,
368 TableName tableName, String familyName, String snapshotNameString,
369 Path rootDir, FileSystem fs, boolean onlineSnapshot)
370 throws Exception {
371 ArrayList<byte[]> nonEmptyFamilyNames = new ArrayList<byte[]>(1);
372 nonEmptyFamilyNames.add(Bytes.toBytes(familyName));
373 createSnapshotAndValidate(admin, tableName, nonEmptyFamilyNames,
374 snapshotNameString, rootDir, fs, onlineSnapshot);
375 }
376
377
378
379
380
381 public static void createSnapshotAndValidate(Admin admin,
382 TableName tableName, List<byte[]> nonEmptyFamilyNames, List<byte[]> emptyFamilyNames,
383 String snapshotNameString, Path rootDir, FileSystem fs, boolean onlineSnapshot)
384 throws Exception {
385 if (!onlineSnapshot) {
386 try {
387 admin.disableTable(tableName);
388 } catch (TableNotEnabledException tne) {
389 LOG.info("In attempting to disable " + tableName + " it turns out that the this table is " +
390 "already disabled.");
391 }
392 }
393 admin.snapshot(snapshotNameString, tableName);
394
395 List<SnapshotDescription> snapshots = SnapshotTestingUtils.assertExistsMatchingSnapshot(admin,
396 snapshotNameString, tableName);
397 if (snapshots == null || snapshots.size() != 1) {
398 Assert.fail("Incorrect number of snapshots for table " + tableName);
399 }
400
401 SnapshotTestingUtils.confirmSnapshotValid(snapshots.get(0), tableName, nonEmptyFamilyNames,
402 emptyFamilyNames, rootDir, admin, fs);
403 }
404
405
406
407
408
409
410
411
412
413 public static ArrayList corruptSnapshot(final HBaseTestingUtility util, final String snapshotName)
414 throws IOException {
415 final MasterFileSystem mfs = util.getHBaseCluster().getMaster().getMasterFileSystem();
416 final FileSystem fs = mfs.getFileSystem();
417
418 Path snapshotDir = SnapshotDescriptionUtils.getCompletedSnapshotDir(snapshotName,
419 mfs.getRootDir());
420 SnapshotDescription snapshotDesc = SnapshotDescriptionUtils.readSnapshotInfo(fs, snapshotDir);
421 final TableName table = TableName.valueOf(snapshotDesc.getTable());
422
423 final ArrayList corruptedFiles = new ArrayList();
424 final Configuration conf = util.getConfiguration();
425 SnapshotReferenceUtil.visitTableStoreFiles(conf, fs, snapshotDir, snapshotDesc,
426 new SnapshotReferenceUtil.StoreFileVisitor() {
427 @Override
428 public void storeFile(final HRegionInfo regionInfo, final String family,
429 final SnapshotRegionManifest.StoreFile storeFile) throws IOException {
430 String region = regionInfo.getEncodedName();
431 String hfile = storeFile.getName();
432 HFileLink link = HFileLink.build(conf, table, region, family, hfile);
433 if (corruptedFiles.size() % 2 == 0) {
434 fs.delete(link.getAvailablePath(fs), true);
435 corruptedFiles.add(hfile);
436 }
437 }
438 });
439
440 assertTrue(corruptedFiles.size() > 0);
441 return corruptedFiles;
442 }
443
444
445
446
447 public static class SnapshotMock {
448 private final static String TEST_FAMILY = "cf";
449 public final static int TEST_NUM_REGIONS = 4;
450
451 private final Configuration conf;
452 private final FileSystem fs;
453 private final Path rootDir;
454
455 static class RegionData {
456 public HRegionInfo hri;
457 public Path tableDir;
458 public Path[] files;
459
460 public RegionData(final Path tableDir, final HRegionInfo hri, final int nfiles) {
461 this.tableDir = tableDir;
462 this.hri = hri;
463 this.files = new Path[nfiles];
464 }
465 }
466
467 public static class SnapshotBuilder {
468 private final RegionData[] tableRegions;
469 private final SnapshotDescription desc;
470 private final HTableDescriptor htd;
471 private final Configuration conf;
472 private final FileSystem fs;
473 private final Path rootDir;
474 private Path snapshotDir;
475 private int snapshotted = 0;
476
477 public SnapshotBuilder(final Configuration conf, final FileSystem fs,
478 final Path rootDir, final HTableDescriptor htd,
479 final SnapshotDescription desc, final RegionData[] tableRegions)
480 throws IOException {
481 this.fs = fs;
482 this.conf = conf;
483 this.rootDir = rootDir;
484 this.htd = htd;
485 this.desc = desc;
486 this.tableRegions = tableRegions;
487 this.snapshotDir = SnapshotDescriptionUtils.getWorkingSnapshotDir(desc, rootDir);
488 new FSTableDescriptors(conf)
489 .createTableDescriptorForTableDirectory(snapshotDir, htd, false);
490 }
491
492 public HTableDescriptor getTableDescriptor() {
493 return this.htd;
494 }
495
496 public SnapshotDescription getSnapshotDescription() {
497 return this.desc;
498 }
499
500 public Path getSnapshotsDir() {
501 return this.snapshotDir;
502 }
503
504 public Path[] addRegion() throws IOException {
505 return addRegion(desc);
506 }
507
508 public Path[] addRegionV1() throws IOException {
509 return addRegion(desc.toBuilder()
510 .setVersion(SnapshotManifestV1.DESCRIPTOR_VERSION)
511 .build());
512 }
513
514 public Path[] addRegionV2() throws IOException {
515 return addRegion(desc.toBuilder()
516 .setVersion(SnapshotManifestV2.DESCRIPTOR_VERSION)
517 .build());
518 }
519
520 private Path[] addRegion(final SnapshotDescription desc) throws IOException {
521 if (this.snapshotted == tableRegions.length) {
522 throw new UnsupportedOperationException("No more regions in the table");
523 }
524
525 RegionData regionData = tableRegions[this.snapshotted++];
526 ForeignExceptionDispatcher monitor = new ForeignExceptionDispatcher(desc.getName());
527 SnapshotManifest manifest = SnapshotManifest.create(conf, fs, snapshotDir, desc, monitor);
528 manifest.addRegion(regionData.tableDir, regionData.hri);
529 return regionData.files;
530 }
531
532 private void corruptFile(Path p) throws IOException {
533 String manifestName = p.getName();
534
535
536 Path newP = new Path(p.getParent(), manifestName + "1");
537 fs.rename(p, newP);
538
539
540 FSDataOutputStream out = fs.create(p);
541
542
543
544 FSDataInputStream input = fs.open(newP);
545 byte[] buffer = new byte[25];
546 int len = input.read(0, buffer, 0, 25);
547 if (len > 1) {
548 out.write(buffer, 0, len - 1);
549 }
550 out.close();
551
552
553 fs.delete(newP);
554 }
555
556
557
558
559
560
561 public void corruptOneRegionManifest() throws IOException {
562 FileStatus[] manifestFiles = FSUtils.listStatus(fs, snapshotDir, new PathFilter() {
563 @Override public boolean accept(Path path) {
564 return path.getName().startsWith(SnapshotManifestV2.SNAPSHOT_MANIFEST_PREFIX);
565 }
566 });
567
568 if (manifestFiles.length == 0) return;
569
570
571 Path p = manifestFiles[0].getPath();
572 corruptFile(p);
573 }
574
575 public void missOneRegionSnapshotFile() throws IOException {
576 FileStatus[] manifestFiles = FSUtils.listStatus(fs, snapshotDir);
577 for (FileStatus fileStatus : manifestFiles) {
578 String fileName = fileStatus.getPath().getName();
579 if (fileName.endsWith(SnapshotDescriptionUtils.SNAPSHOTINFO_FILE)
580 || fileName.endsWith(".tabledesc")
581 || fileName.endsWith(SnapshotDescriptionUtils.SNAPSHOT_TMP_DIR_NAME)) {
582 fs.delete(fileStatus.getPath(), true);
583 }
584 }
585 }
586
587
588
589
590
591
592 public void corruptDataManifest() throws IOException {
593 FileStatus[] manifestFiles = FSUtils.listStatus(fs, snapshotDir, new PathFilter() {
594 @Override
595 public boolean accept(Path path) {
596 return path.getName().startsWith(SnapshotManifest.DATA_MANIFEST_NAME);
597 }
598 });
599
600 if (manifestFiles.length == 0) return;
601
602
603 Path p = manifestFiles[0].getPath();
604 corruptFile(p);
605 }
606
607 public Path commit() throws IOException {
608 ForeignExceptionDispatcher monitor = new ForeignExceptionDispatcher(desc.getName());
609 SnapshotManifest manifest = SnapshotManifest.create(conf, fs, snapshotDir, desc, monitor);
610 manifest.addTableDescriptor(htd);
611 manifest.consolidate();
612 SnapshotDescriptionUtils.completeSnapshot(desc, rootDir, snapshotDir, fs);
613 snapshotDir = SnapshotDescriptionUtils.getCompletedSnapshotDir(desc, rootDir);
614 return snapshotDir;
615 }
616
617 public void consolidate() throws IOException {
618 ForeignExceptionDispatcher monitor = new ForeignExceptionDispatcher(desc.getName());
619 SnapshotManifest manifest = SnapshotManifest.create(conf, fs, snapshotDir, desc, monitor);
620 manifest.addTableDescriptor(htd);
621 manifest.consolidate();
622 }
623 }
624
625 public SnapshotMock(final Configuration conf, final FileSystem fs, final Path rootDir) {
626 this.fs = fs;
627 this.conf = conf;
628 this.rootDir = rootDir;
629 }
630
631 public SnapshotBuilder createSnapshotV1(final String snapshotName, final String tableName)
632 throws IOException {
633 return createSnapshot(snapshotName, tableName, SnapshotManifestV1.DESCRIPTOR_VERSION);
634 }
635
636 public SnapshotBuilder createSnapshotV1(final String snapshotName, final String tableName,
637 final int numRegions) throws IOException {
638 return createSnapshot(snapshotName, tableName, numRegions, SnapshotManifestV1.DESCRIPTOR_VERSION);
639 }
640
641 public SnapshotBuilder createSnapshotV2(final String snapshotName, final String tableName)
642 throws IOException {
643 return createSnapshot(snapshotName, tableName, SnapshotManifestV2.DESCRIPTOR_VERSION);
644 }
645
646 public SnapshotBuilder createSnapshotV2(final String snapshotName, final String tableName,
647 final int numRegions) throws IOException {
648 return createSnapshot(snapshotName, tableName, numRegions, SnapshotManifestV2.DESCRIPTOR_VERSION);
649 }
650
651 private SnapshotBuilder createSnapshot(final String snapshotName, final String tableName,
652 final int version) throws IOException {
653 return createSnapshot(snapshotName, tableName, TEST_NUM_REGIONS, version);
654 }
655
656 private SnapshotBuilder createSnapshot(final String snapshotName, final String tableName,
657 final int numRegions, final int version) throws IOException {
658 HTableDescriptor htd = createHtd(tableName);
659 RegionData[] regions = createTable(htd, numRegions);
660
661 SnapshotDescription desc = SnapshotDescription.newBuilder()
662 .setTable(htd.getNameAsString())
663 .setName(snapshotName)
664 .setVersion(version)
665 .build();
666
667 Path workingDir = SnapshotDescriptionUtils.getWorkingSnapshotDir(desc, rootDir);
668 SnapshotDescriptionUtils.writeSnapshotInfo(desc, workingDir, fs);
669 return new SnapshotBuilder(conf, fs, rootDir, htd, desc, regions);
670 }
671
672 public HTableDescriptor createHtd(final String tableName) {
673 HTableDescriptor htd = new HTableDescriptor(tableName);
674 htd.addFamily(new HColumnDescriptor(TEST_FAMILY));
675 return htd;
676 }
677
678 private RegionData[] createTable(final HTableDescriptor htd, final int nregions)
679 throws IOException {
680 Path tableDir = FSUtils.getTableDir(rootDir, htd.getTableName());
681 new FSTableDescriptors(conf).createTableDescriptorForTableDirectory(tableDir, htd, false);
682
683 assertTrue(nregions % 2 == 0);
684 RegionData[] regions = new RegionData[nregions];
685 for (int i = 0; i < regions.length; i += 2) {
686 byte[] startKey = Bytes.toBytes(0 + i * 2);
687 byte[] endKey = Bytes.toBytes(1 + i * 2);
688
689
690 HRegionInfo hri = new HRegionInfo(htd.getTableName(), startKey, endKey);
691 HRegionFileSystem rfs = HRegionFileSystem.createRegionOnFileSystem(conf, fs, tableDir, hri);
692 regions[i] = new RegionData(tableDir, hri, 3);
693 for (int j = 0; j < regions[i].files.length; ++j) {
694 Path storeFile = createStoreFile(rfs.createTempName());
695 regions[i].files[j] = rfs.commitStoreFile(TEST_FAMILY, storeFile);
696 }
697
698
699
700 startKey = Bytes.toBytes(2 + i * 2);
701 endKey = Bytes.toBytes(3 + i * 2);
702 hri = new HRegionInfo(htd.getTableName());
703 rfs = HRegionFileSystem.createRegionOnFileSystem(conf, fs, tableDir, hri);
704 regions[i+1] = new RegionData(tableDir, hri, regions[i].files.length);
705 for (int j = 0; j < regions[i].files.length; ++j) {
706 String refName = regions[i].files[j].getName() + '.' + regions[i].hri.getEncodedName();
707 Path refFile = createStoreFile(new Path(rootDir, refName));
708 regions[i+1].files[j] = rfs.commitStoreFile(TEST_FAMILY, refFile);
709 }
710 }
711 return regions;
712 }
713
714 private Path createStoreFile(final Path storeFile)
715 throws IOException {
716 FSDataOutputStream out = fs.create(storeFile);
717 try {
718 out.write(Bytes.toBytes(storeFile.toString()));
719 } finally {
720 out.close();
721 }
722 return storeFile;
723 }
724 }
725
726
727
728
729 public static void waitForTableToBeOnline(final HBaseTestingUtility util,
730 final TableName tableName)
731 throws IOException, InterruptedException {
732 HRegionServer rs = util.getRSForFirstRegionInTable(tableName);
733 List<Region> onlineRegions = rs.getOnlineRegions(tableName);
734 for (Region region : onlineRegions) {
735 region.waitForFlushesAndCompactions();
736 }
737
738 util.waitFor(60000, util.predicateTableAvailable(tableName));
739 }
740
741 public static void createTable(final HBaseTestingUtility util, final TableName tableName,
742 int regionReplication, final byte[]... families) throws IOException, InterruptedException {
743 HTableDescriptor htd = new HTableDescriptor(tableName);
744 htd.setRegionReplication(regionReplication);
745 for (byte[] family : families) {
746 HColumnDescriptor hcd = new HColumnDescriptor(family);
747 htd.addFamily(hcd);
748 }
749 byte[][] splitKeys = getSplitKeys();
750 util.createTable(htd, splitKeys);
751 assertEquals((splitKeys.length + 1) * regionReplication,
752 util.getHBaseAdmin().getTableRegions(tableName).size());
753 }
754
755 public static byte[][] getSplitKeys() {
756 byte[][] splitKeys = new byte[KEYS.length-2][];
757 for (int i = 0; i < splitKeys.length; ++i) {
758 splitKeys[i] = new byte[] { KEYS[i+1] };
759 }
760 return splitKeys;
761 }
762
763 public static void createTable(final HBaseTestingUtility util, final TableName tableName,
764 final byte[]... families) throws IOException, InterruptedException {
765 createTable(util, tableName, 1, families);
766 }
767
768 public static void loadData(final HBaseTestingUtility util, final TableName tableName, int rows,
769 byte[]... families) throws IOException, InterruptedException {
770 try (BufferedMutator mutator = util.getConnection().getBufferedMutator(tableName)) {
771 loadData(util, mutator, rows, families);
772 }
773 }
774
775 public static void loadData(final HBaseTestingUtility util, final BufferedMutator mutator, int rows,
776 byte[]... families) throws IOException, InterruptedException {
777
778 assertTrue(rows >= KEYS.length);
779 for (byte k0: KEYS) {
780 byte[] k = new byte[] { k0 };
781 byte[] value = Bytes.add(Bytes.toBytes(System.currentTimeMillis()), k);
782 byte[] key = Bytes.add(k, Bytes.toBytes(MD5Hash.getMD5AsHex(value)));
783 final byte[][] families1 = families;
784 final byte[] key1 = key;
785 final byte[] value1 = value;
786 mutator.mutate(createPut(families1, key1, value1));
787 rows--;
788 }
789
790
791 while (rows-- > 0) {
792 byte[] value = Bytes.add(Bytes.toBytes(System.currentTimeMillis()), Bytes.toBytes(rows));
793 byte[] key = Bytes.toBytes(MD5Hash.getMD5AsHex(value));
794 final byte[][] families1 = families;
795 final byte[] key1 = key;
796 final byte[] value1 = value;
797 mutator.mutate(createPut(families1, key1, value1));
798 }
799 mutator.flush();
800
801 waitForTableToBeOnline(util, mutator.getName());
802 }
803
804 private static Put createPut(final byte[][] families, final byte[] key, final byte[] value) {
805 byte[] q = Bytes.toBytes("q");
806 Put put = new Put(key);
807 put.setDurability(Durability.SKIP_WAL);
808 for (byte[] family: families) {
809 put.add(family, q, value);
810 }
811 return put;
812 }
813
814 public static void deleteAllSnapshots(final Admin admin)
815 throws IOException {
816
817 for (SnapshotDescription snapshot: admin.listSnapshots()) {
818 admin.deleteSnapshot(snapshot.getName());
819 }
820 SnapshotTestingUtils.assertNoSnapshots(admin);
821 }
822
823 public static void deleteArchiveDirectory(final HBaseTestingUtility util)
824 throws IOException {
825
826 MasterFileSystem mfs = util.getMiniHBaseCluster().getMaster().getMasterFileSystem();
827 Path archiveDir = new Path(mfs.getRootDir(), HConstants.HFILE_ARCHIVE_DIRECTORY);
828 mfs.getFileSystem().delete(archiveDir, true);
829 }
830
831 public static void verifyRowCount(final HBaseTestingUtility util, final TableName tableName,
832 long expectedRows) throws IOException {
833 Table table = new HTable(util.getConfiguration(), tableName);
834 try {
835 assertEquals(expectedRows, util.countRows(table));
836 } finally {
837 table.close();
838 }
839 }
840
841 public static void verifyReplicasCameOnline(TableName tableName, Admin admin,
842 int regionReplication) throws IOException {
843 List<HRegionInfo> regions = admin.getTableRegions(tableName);
844 HashSet<HRegionInfo> set = new HashSet<HRegionInfo>();
845 for (HRegionInfo hri : regions) {
846 set.add(RegionReplicaUtil.getRegionInfoForDefaultReplica(hri));
847 for (int i = 0; i < regionReplication; i++) {
848 HRegionInfo replica = RegionReplicaUtil.getRegionInfoForReplica(hri, i);
849 if (!regions.contains(replica)) {
850 Assert.fail(replica + " is not contained in the list of online regions");
851 }
852 }
853 }
854 assert(set.size() == getSplitKeys().length + 1);
855 }
856 }