1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase.snapshot;
20
21 import static org.junit.Assert.assertEquals;
22
23 import java.io.IOException;
24 import java.util.concurrent.atomic.AtomicInteger;
25
26 import org.apache.commons.logging.Log;
27 import org.apache.commons.logging.LogFactory;
28 import org.apache.hadoop.hbase.HBaseTestingUtility;
29 import org.apache.hadoop.hbase.HTableDescriptor;
30 import org.apache.hadoop.hbase.TableName;
31 import org.apache.hadoop.hbase.coprocessor.BaseMasterObserver;
32 import org.apache.hadoop.hbase.coprocessor.CoprocessorHost;
33 import org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment;
34 import org.apache.hadoop.hbase.coprocessor.ObserverContext;
35 import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.SnapshotDescription;
36 import org.apache.hadoop.hbase.testclassification.MediumTests;
37 import org.apache.hadoop.hbase.util.TestTableName;
38 import org.junit.After;
39 import org.junit.Before;
40 import org.junit.Rule;
41 import org.junit.Test;
42 import org.junit.experimental.categories.Category;
43
44 @Category({ MediumTests.class })
45 public class TestSnapshotClientRetries {
46 private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
47 private static final Log LOG = LogFactory.getLog(TestSnapshotClientRetries.class);
48
49 @Rule public TestTableName TEST_TABLE = new TestTableName();
50
51 @Before
52 public void setUp() throws Exception {
53 TEST_UTIL.getConfiguration().set(CoprocessorHost.MASTER_COPROCESSOR_CONF_KEY,
54 MasterSyncObserver.class.getName());
55 TEST_UTIL.startMiniCluster(1);
56 }
57
58 @After
59 public void tearDown() throws Exception {
60 TEST_UTIL.shutdownMiniCluster();
61 }
62
63 @Test(timeout = 60000, expected=SnapshotExistsException.class)
64 public void testSnapshotAlreadyExist() throws Exception {
65 final String snapshotName = "testSnapshotAlreadyExist";
66 TEST_UTIL.createTable(TEST_TABLE.getTableName(), "f");
67 TEST_UTIL.getHBaseAdmin().snapshot(snapshotName, TEST_TABLE.getTableName());
68 snapshotAndAssertOneRetry(snapshotName, TEST_TABLE.getTableName());
69 }
70
71 @Test(timeout = 60000, expected=SnapshotDoesNotExistException.class)
72 public void testCloneNonExistentSnapshot() throws Exception {
73 final String snapshotName = "testCloneNonExistentSnapshot";
74 cloneAndAssertOneRetry(snapshotName, TEST_TABLE.getTableName());
75 }
76
77 public static class MasterSyncObserver extends BaseMasterObserver {
78 volatile AtomicInteger snapshotCount = null;
79 volatile AtomicInteger cloneCount = null;
80
81 @Override
82 public void preSnapshot(final ObserverContext<MasterCoprocessorEnvironment> ctx,
83 final SnapshotDescription snapshot, final HTableDescriptor hTableDescriptor)
84 throws IOException {
85 if (snapshotCount != null) {
86 snapshotCount.incrementAndGet();
87 }
88 }
89
90 @Override
91 public void preCloneSnapshot(final ObserverContext<MasterCoprocessorEnvironment> ctx,
92 final SnapshotDescription snapshot, final HTableDescriptor hTableDescriptor)
93 throws IOException {
94 if (cloneCount != null) {
95 cloneCount.incrementAndGet();
96 }
97 }
98 }
99
100 public void snapshotAndAssertOneRetry(final String snapshotName, final TableName tableName)
101 throws Exception {
102 MasterSyncObserver observer = getMasterSyncObserver();
103 observer.snapshotCount = new AtomicInteger(0);
104 TEST_UTIL.getHBaseAdmin().snapshot(snapshotName, tableName);
105 assertEquals(1, observer.snapshotCount.get());
106 }
107
108 public void cloneAndAssertOneRetry(final String snapshotName, final TableName tableName)
109 throws Exception {
110 MasterSyncObserver observer = getMasterSyncObserver();
111 observer.cloneCount = new AtomicInteger(0);
112 TEST_UTIL.getHBaseAdmin().cloneSnapshot(snapshotName, tableName);
113 assertEquals(1, observer.cloneCount.get());
114 }
115
116 private MasterSyncObserver getMasterSyncObserver() {
117 return (MasterSyncObserver)TEST_UTIL.getHBaseCluster().getMaster()
118 .getMasterCoprocessorHost().findCoprocessor(MasterSyncObserver.class.getName());
119 }
120 }