1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.hadoop.hbase.master.snapshot;
19
20 import static org.junit.Assert.assertFalse;
21 import static org.junit.Assert.assertTrue;
22 import static org.junit.Assert.fail;
23
24 import java.io.IOException;
25
26 import org.apache.hadoop.conf.Configuration;
27 import org.apache.hadoop.fs.FileSystem;
28 import org.apache.hadoop.fs.Path;
29 import org.apache.hadoop.hbase.TableName;
30 import org.apache.hadoop.hbase.HBaseTestingUtility;
31 import org.apache.hadoop.hbase.testclassification.SmallTests;
32 import org.apache.hadoop.hbase.executor.ExecutorService;
33 import org.apache.hadoop.hbase.master.MasterFileSystem;
34 import org.apache.hadoop.hbase.master.MasterServices;
35 import org.apache.hadoop.hbase.master.cleaner.HFileCleaner;
36 import org.apache.hadoop.hbase.master.cleaner.HFileLinkCleaner;
37 import org.apache.hadoop.hbase.procedure.ProcedureCoordinator;
38 import org.apache.hadoop.hbase.snapshot.SnapshotDescriptionUtils;
39 import org.apache.zookeeper.KeeperException;
40 import org.junit.Test;
41 import org.junit.experimental.categories.Category;
42 import org.mockito.Mockito;
43
44
45
46
47 @Category(SmallTests.class)
48 public class TestSnapshotManager {
49 private static final HBaseTestingUtility UTIL = new HBaseTestingUtility();
50
51 MasterServices services = Mockito.mock(MasterServices.class);
52 ProcedureCoordinator coordinator = Mockito.mock(ProcedureCoordinator.class);
53 ExecutorService pool = Mockito.mock(ExecutorService.class);
54 MasterFileSystem mfs = Mockito.mock(MasterFileSystem.class);
55 FileSystem fs;
56 {
57 try {
58 fs = UTIL.getTestFileSystem();
59 } catch (IOException e) {
60 throw new RuntimeException("Couldn't get test filesystem", e);
61 }
62 }
63
64 private SnapshotManager getNewManager() throws IOException, KeeperException {
65 return getNewManager(UTIL.getConfiguration());
66 }
67
68 private SnapshotManager getNewManager(Configuration conf) throws IOException, KeeperException {
69 return getNewManager(conf, 1);
70 }
71
72 private SnapshotManager getNewManager(Configuration conf, int intervalSeconds)
73 throws IOException, KeeperException {
74 Mockito.reset(services);
75 Mockito.when(services.getConfiguration()).thenReturn(conf);
76 Mockito.when(services.getMasterFileSystem()).thenReturn(mfs);
77 Mockito.when(mfs.getFileSystem()).thenReturn(fs);
78 Mockito.when(mfs.getRootDir()).thenReturn(UTIL.getDataTestDir());
79 return new SnapshotManager(services, coordinator, pool, intervalSeconds);
80 }
81
82 @Test
83 public void testCleanFinishedHandler() throws Exception {
84 TableName tableName = TableName.valueOf("testCleanFinishedHandler");
85 Configuration conf = UTIL.getConfiguration();
86 try {
87 conf.setLong(SnapshotManager.HBASE_SNAPSHOT_SENTINELS_CLEANUP_TIMEOUT_MILLIS, 5 * 1000L);
88 SnapshotManager manager = getNewManager(conf, 1);
89 TakeSnapshotHandler handler = Mockito.mock(TakeSnapshotHandler.class);
90 assertFalse("Manager is in process when there is no current handler",
91 manager.isTakingSnapshot(tableName));
92 manager.setSnapshotHandlerForTesting(tableName, handler);
93 Mockito.when(handler.isFinished()).thenReturn(false);
94 assertTrue(manager.isTakingAnySnapshot());
95 assertTrue("Manager isn't in process when handler is running",
96 manager.isTakingSnapshot(tableName));
97 Mockito.when(handler.isFinished()).thenReturn(true);
98 assertFalse("Manager is process when handler isn't running",
99 manager.isTakingSnapshot(tableName));
100 assertTrue(manager.isTakingAnySnapshot());
101 Thread.sleep(6 * 1000);
102 assertFalse(manager.isTakingAnySnapshot());
103 } finally {
104 conf.unset(SnapshotManager.HBASE_SNAPSHOT_SENTINELS_CLEANUP_TIMEOUT_MILLIS);
105 }
106 }
107
108 @Test
109 public void testInProcess() throws KeeperException, IOException {
110 TableName tableName = TableName.valueOf("testTable");
111 SnapshotManager manager = getNewManager();
112 TakeSnapshotHandler handler = Mockito.mock(TakeSnapshotHandler.class);
113 assertFalse("Manager is in process when there is no current handler",
114 manager.isTakingSnapshot(tableName));
115 manager.setSnapshotHandlerForTesting(tableName, handler);
116 Mockito.when(handler.isFinished()).thenReturn(false);
117 assertTrue("Manager isn't in process when handler is running",
118 manager.isTakingSnapshot(tableName));
119 Mockito.when(handler.isFinished()).thenReturn(true);
120 assertFalse("Manager is process when handler isn't running",
121 manager.isTakingSnapshot(tableName));
122 }
123
124
125
126
127 @Test
128 public void testSnapshotSupportConfiguration() throws Exception {
129
130 Configuration conf = new Configuration();
131 SnapshotManager manager = getNewManager(conf);
132 assertFalse("Snapshot should be disabled with no configuration", isSnapshotSupported(manager));
133
134
135 conf = new Configuration();
136 conf.setBoolean(SnapshotManager.HBASE_SNAPSHOT_ENABLED, true);
137 manager = getNewManager(conf);
138 assertTrue("Snapshot should be enabled", isSnapshotSupported(manager));
139
140
141 conf = new Configuration();
142 conf.setBoolean(SnapshotManager.HBASE_SNAPSHOT_ENABLED, false);
143 manager = getNewManager(conf);
144 assertFalse("Snapshot should be disabled", isSnapshotSupported(manager));
145
146
147 conf = new Configuration();
148 conf.setStrings(HFileCleaner.MASTER_HFILE_CLEANER_PLUGINS,
149 SnapshotHFileCleaner.class.getName(), HFileLinkCleaner.class.getName());
150 conf.setBoolean(SnapshotManager.HBASE_SNAPSHOT_ENABLED, false);
151 manager = getNewManager(conf);
152 assertFalse("Snapshot should be disabled", isSnapshotSupported(manager));
153
154
155 conf = new Configuration();
156 conf.setStrings(HFileCleaner.MASTER_HFILE_CLEANER_PLUGINS,
157 SnapshotHFileCleaner.class.getName(), HFileLinkCleaner.class.getName());
158 manager = getNewManager(conf);
159 assertTrue("Snapshot should be enabled, because cleaners are present",
160 isSnapshotSupported(manager));
161
162
163 Path rootDir = UTIL.getDataTestDir();
164 Path testSnapshotDir = SnapshotDescriptionUtils.getCompletedSnapshotDir(
165 "testSnapshotSupportConfiguration", rootDir);
166 fs.mkdirs(testSnapshotDir);
167 try {
168
169 conf = new Configuration();
170 conf.setBoolean(SnapshotManager.HBASE_SNAPSHOT_ENABLED, false);
171 manager = getNewManager(conf);
172 fail("Master should not start when snapshot is disabled, but snapshots are present");
173 } catch (UnsupportedOperationException e) {
174
175 } finally {
176 fs.delete(testSnapshotDir, true);
177 }
178 }
179
180 private boolean isSnapshotSupported(final SnapshotManager manager) {
181 try {
182 manager.checkSnapshotSupport();
183 return true;
184 } catch (UnsupportedOperationException e) {
185 return false;
186 }
187 }
188 }