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.assertTrue;
21 import static org.junit.Assert.fail;
22
23 import java.io.IOException;
24
25 import org.apache.commons.logging.Log;
26 import org.apache.commons.logging.LogFactory;
27 import org.apache.hadoop.conf.Configuration;
28 import org.apache.hadoop.hbase.HBaseConfiguration;
29 import org.apache.hadoop.hbase.HConstants;
30 import org.apache.hadoop.hbase.testclassification.SmallTests;
31 import org.apache.hadoop.hbase.TableName;
32 import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.SnapshotDescription;
33 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsSnapshotDoneRequest;
34 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsSnapshotDoneResponse;
35 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.SnapshotRequest;
36 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.SnapshotResponse;
37 import org.junit.Test;
38 import org.junit.experimental.categories.Category;
39 import org.mockito.Mockito;
40
41 import com.google.protobuf.RpcController;
42
43
44
45
46 @Category(SmallTests.class)
47 public class TestSnapshotFromAdmin {
48
49 private static final Log LOG = LogFactory.getLog(TestSnapshotFromAdmin.class);
50
51
52
53
54
55
56 @Test(timeout = 60000)
57 public void testBackoffLogic() throws Exception {
58 final int pauseTime = 100;
59 final int maxWaitTime =
60 HConstants.RETRY_BACKOFF[HConstants.RETRY_BACKOFF.length - 1] * pauseTime;
61 final int numRetries = HConstants.RETRY_BACKOFF.length;
62
63
64 long ignoreExpectedTime = 0;
65 for (int i = 0; i < HConstants.RETRY_BACKOFF.length; i++) {
66 ignoreExpectedTime += HConstants.RETRY_BACKOFF[i] * pauseTime;
67 }
68
69 final long time = pauseTime * 3 + ((maxWaitTime / numRetries) * 3) + 300;
70 assertTrue("Capped snapshot wait time isn't less that the uncapped backoff time "
71 + "- further testing won't prove anything.", time < ignoreExpectedTime);
72
73
74 HConnectionManager.HConnectionImplementation mockConnection = Mockito
75 .mock(HConnectionManager.HConnectionImplementation.class);
76 Configuration conf = HBaseConfiguration.create();
77
78 conf.setInt(HConstants.HBASE_CLIENT_RETRIES_NUMBER, numRetries);
79 conf.setLong("hbase.client.pause", pauseTime);
80
81 MasterKeepAliveConnection mockMaster = Mockito.mock(MasterKeepAliveConnection.class);
82 Mockito.when(mockConnection.getConfiguration()).thenReturn(conf);
83 Mockito.when(mockConnection.getKeepAliveMasterService()).thenReturn(mockMaster);
84
85 SnapshotResponse response = SnapshotResponse.newBuilder()
86 .setExpectedTimeout(maxWaitTime)
87 .build();
88 Mockito
89 .when(
90 mockMaster.snapshot((RpcController) Mockito.isNull(),
91 Mockito.any(SnapshotRequest.class))).thenReturn(response);
92
93 IsSnapshotDoneResponse.Builder builder = IsSnapshotDoneResponse.newBuilder();
94 builder.setDone(false);
95
96 Mockito.when(
97 mockMaster.isSnapshotDone((RpcController) Mockito.isNull(),
98 Mockito.any(IsSnapshotDoneRequest.class))).thenReturn(builder.build(), builder.build(),
99 builder.build(), builder.build(), builder.build(), builder.setDone(true).build());
100
101
102 HBaseAdmin admin = new HBaseAdmin(mockConnection);
103 String snapshot = "snapshot";
104 TableName table = TableName.valueOf("table");
105
106 long start = System.currentTimeMillis();
107 admin.snapshot(snapshot, table);
108 long finish = System.currentTimeMillis();
109 long elapsed = (finish - start);
110 assertTrue("Elapsed time:" + elapsed + " is more than expected max:" + time, elapsed <= time);
111 admin.close();
112 }
113
114
115
116
117
118
119 @Test
120 public void testValidateSnapshotName() throws Exception {
121 HConnectionManager.HConnectionImplementation mockConnection = Mockito
122 .mock(HConnectionManager.HConnectionImplementation.class);
123 Configuration conf = HBaseConfiguration.create();
124 Mockito.when(mockConnection.getConfiguration()).thenReturn(conf);
125 HBaseAdmin admin = new HBaseAdmin(mockConnection);
126 SnapshotDescription.Builder builder = SnapshotDescription.newBuilder();
127
128 failSnapshotStart(admin, builder.setName(HConstants.SNAPSHOT_DIR_NAME).build());
129 failSnapshotStart(admin, builder.setName("-snapshot").build());
130 failSnapshotStart(admin, builder.setName("snapshot fails").build());
131 failSnapshotStart(admin, builder.setName("snap$hot").build());
132 failSnapshotStart(admin, builder.setName("snap:hot").build());
133
134 failSnapshotStart(admin, builder.setName("snapshot").setTable(".table").build());
135 failSnapshotStart(admin, builder.setName("snapshot").setTable("-table").build());
136 failSnapshotStart(admin, builder.setName("snapshot").setTable("table fails").build());
137 failSnapshotStart(admin, builder.setName("snapshot").setTable("tab%le").build());
138
139
140 MasterKeepAliveConnection master = Mockito.mock(MasterKeepAliveConnection.class);
141 Mockito.when(mockConnection.getKeepAliveMasterService()).thenReturn(master);
142 SnapshotResponse response = SnapshotResponse.newBuilder().setExpectedTimeout(0).build();
143 Mockito.when(
144 master.snapshot((RpcController) Mockito.isNull(), Mockito.any(SnapshotRequest.class)))
145 .thenReturn(response);
146 IsSnapshotDoneResponse doneResponse = IsSnapshotDoneResponse.newBuilder().setDone(true).build();
147 Mockito.when(
148 master.isSnapshotDone((RpcController) Mockito.isNull(),
149 Mockito.any(IsSnapshotDoneRequest.class))).thenReturn(doneResponse);
150
151
152 admin.snapshot(builder.setName("snapshot").setTable("table").build());
153 }
154
155 private void failSnapshotStart(HBaseAdmin admin, SnapshotDescription snapshot) throws IOException {
156 try {
157 admin.snapshot(snapshot);
158 fail("Snapshot should not have succeed with name:" + snapshot.getName());
159 } catch (IllegalArgumentException e) {
160 LOG.debug("Correctly failed to start snapshot:" + e.getMessage());
161 }
162 }
163 }