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.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.*;
26 import java.util.concurrent.atomic.AtomicInteger;
27
28 import com.google.common.collect.Iterables;
29 import com.google.common.collect.ObjectArrays;
30 import org.apache.commons.logging.Log;
31 import org.apache.commons.logging.LogFactory;
32 import org.apache.hadoop.fs.FileStatus;
33 import org.apache.hadoop.fs.FileSystem;
34 import org.apache.hadoop.fs.Path;
35 import org.apache.hadoop.hbase.HBaseTestingUtility;
36 import org.apache.hadoop.hbase.MediumTests;
37 import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.SnapshotDescription;
38 import org.apache.hadoop.hbase.snapshot.SnapshotDescriptionUtils;
39 import org.apache.hadoop.hbase.snapshot.SnapshotReferenceUtil;
40 import org.apache.hadoop.hbase.snapshot.TakeSnapshotUtils;
41 import org.apache.hadoop.hbase.util.FSUtils;
42 import org.junit.After;
43 import org.junit.AfterClass;
44 import org.junit.BeforeClass;
45 import org.junit.Test;
46 import org.junit.experimental.categories.Category;
47
48
49
50
51 @Category(MediumTests.class)
52 public class TestSnapshotFileCache {
53
54 private static final Log LOG = LogFactory.getLog(TestSnapshotFileCache.class);
55 private static final HBaseTestingUtility UTIL = new HBaseTestingUtility();
56 private static FileSystem fs;
57 private static Path rootDir;
58
59 @BeforeClass
60 public static void startCluster() throws Exception {
61 UTIL.startMiniDFSCluster(1);
62 fs = UTIL.getDFSCluster().getFileSystem();
63 rootDir = UTIL.getDefaultRootDirPath();
64 }
65
66 @AfterClass
67 public static void stopCluster() throws Exception {
68 UTIL.shutdownMiniDFSCluster();
69 }
70
71 @After
72 public void cleanupFiles() throws Exception {
73
74 Path snapshotDir = SnapshotDescriptionUtils.getSnapshotsDir(rootDir);
75 fs.delete(snapshotDir, true);
76 }
77
78 @Test(timeout = 10000000)
79 public void testLoadAndDelete() throws Exception {
80
81 long period = Long.MAX_VALUE;
82 Path snapshotDir = SnapshotDescriptionUtils.getSnapshotsDir(rootDir);
83 SnapshotFileCache cache = new SnapshotFileCache(fs, rootDir, period, 10000000,
84 "test-snapshot-file-cache-refresh", new SnapshotFiles());
85
86 Path snapshot = new Path(snapshotDir, "snapshot");
87 Path region = new Path(snapshot, "7e91021");
88 Path family = new Path(region, "fam");
89 Path file1 = new Path(family, "file1");
90 Path file2 = new Path(family, "file2");
91
92
93
94 fs.createNewFile(file1);
95 fs.createNewFile(file2);
96
97 FSUtils.logFileSystemState(fs, rootDir, LOG);
98
99
100 Iterable<FileStatus> nonSnapshotFiles = cache.getUnreferencedFiles(
101 Arrays.asList(FSUtils.listStatus(fs, family))
102 );
103 assertFalse("Cache didn't find:" + file1, Iterables.contains(nonSnapshotFiles, file1));
104 assertFalse("Cache didn't find:" + file2, Iterables.contains(nonSnapshotFiles, file2));
105 String not = "file-shouldn't-be-found";
106 assertFalse("Cache found '" + not + "', but it shouldn't have.", Iterables.contains(nonSnapshotFiles, not));
107
108
109
110 Thread.sleep(10);
111
112 LOG.debug("Deleting snapshot.");
113
114 if (!fs.delete(snapshot, true)) {
115 throw new IOException("Couldn't delete " + snapshot + " for an unknown reason.");
116 }
117 FSUtils.logFileSystemState(fs, rootDir, LOG);
118
119
120 LOG.debug("Checking to see if file is deleted.");
121 nonSnapshotFiles = cache.getUnreferencedFiles(
122 nonSnapshotFiles
123 );
124
125 assertFalse("Cache didn't find:" + file1, Iterables.contains(nonSnapshotFiles, file1));
126 assertFalse("Cache didn't find:" + file2, Iterables.contains(nonSnapshotFiles, file2));
127
128
129 cache.triggerCacheRefreshForTesting();
130
131 nonSnapshotFiles = cache.getUnreferencedFiles(
132 nonSnapshotFiles
133 );
134
135 assertFalse("Cache found '" + file1 + "', but it shouldn't have.",
136 Iterables.contains(nonSnapshotFiles, file1));
137 assertFalse("Cache found '" + file2 + "', but it shouldn't have.",
138 Iterables.contains(nonSnapshotFiles, file2));
139
140 fs.delete(snapshotDir, true);
141 }
142
143 @Test
144 public void testWeNeverCacheTmpDirAndLoadIt() throws Exception {
145
146 final AtomicInteger count = new AtomicInteger(0);
147
148 long period = Long.MAX_VALUE;
149 Path snapshotDir = SnapshotDescriptionUtils.getSnapshotsDir(rootDir);
150 SnapshotFileCache cache = new SnapshotFileCache(fs, rootDir, period, 10000000,
151 "test-snapshot-file-cache-refresh", new SnapshotFiles()) {
152 @Override
153 List<String> getSnapshotsInProgress() throws IOException {
154 List<String> result = super.getSnapshotsInProgress();
155 count.incrementAndGet();
156 return result;
157 }
158 };
159
160
161 Path snapshot = new Path(snapshotDir, "snapshot");
162 Path region = new Path(snapshot, "7e91021");
163 Path family = new Path(region, "fam");
164 Path file1 = new Path(family, "file1");
165 fs.createNewFile(file1);
166
167 FileStatus[] completedFiles = FSUtils.listStatus(fs, family);
168
169
170 SnapshotDescription desc = SnapshotDescription.newBuilder().setName("working").build();
171 snapshot = SnapshotDescriptionUtils.getWorkingSnapshotDir(desc, rootDir);
172 region = new Path(snapshot, "7e91021");
173 family = new Path(region, "fam");
174 Path file2 = new Path(family, "file2");
175 fs.createNewFile(file2);
176 cache.triggerCacheRefreshForTesting();
177
178 Iterable<FileStatus> deletableFiles = cache.getUnreferencedFiles(Arrays.asList(
179 ObjectArrays.concat(completedFiles, FSUtils.listStatus(fs, family), FileStatus.class))
180 );
181 assertTrue(Iterables.isEmpty(deletableFiles));
182 assertEquals(1, count.get());
183
184 Path file3 = new Path(family, "file3");
185 fs.create(file3);
186 deletableFiles = cache.getUnreferencedFiles(Arrays.asList(
187 ObjectArrays.concat(completedFiles, FSUtils.listStatus(fs, family), FileStatus.class))
188 );
189 assertTrue(Iterables.isEmpty(deletableFiles));
190 assertEquals(2, count.get());
191
192 }
193
194 @Test
195 public void testLoadsTmpDir() throws Exception {
196
197 long period = Long.MAX_VALUE;
198 Path snapshotDir = SnapshotDescriptionUtils.getSnapshotsDir(rootDir);
199 SnapshotFileCache cache = new SnapshotFileCache(fs, rootDir, period, 10000000,
200 "test-snapshot-file-cache-refresh", new SnapshotFiles());
201
202
203 Path snapshot = new Path(snapshotDir, "snapshot");
204 Path region = new Path(snapshot, "7e91021");
205 Path family = new Path(region, "fam");
206 Path file1 = new Path(family, "file1");
207 fs.createNewFile(file1);
208
209
210 SnapshotDescription desc = SnapshotDescription.newBuilder().setName("working").build();
211 snapshot = SnapshotDescriptionUtils.getWorkingSnapshotDir(desc, rootDir);
212 region = new Path(snapshot, "7e91021");
213 family = new Path(region, "fam");
214 Path file2 = new Path(family, "file2");
215 fs.createNewFile(file2);
216
217 FSUtils.logFileSystemState(fs, rootDir, LOG);
218
219
220 Iterable<FileStatus> nonSnapshotFiles = cache.getUnreferencedFiles(
221 Arrays.asList(FSUtils.listStatus(fs, family))
222 );
223 assertFalse("Cache didn't find:" + file1, Iterables.contains(nonSnapshotFiles, file1));
224 assertFalse("Cache didn't find:" + file2, Iterables.contains(nonSnapshotFiles, file2));
225 }
226
227 @Test
228 public void testJustFindLogsDirectory() throws Exception {
229
230 long period = Long.MAX_VALUE;
231 Path snapshotDir = SnapshotDescriptionUtils.getSnapshotsDir(rootDir);
232 SnapshotFileCache cache = new SnapshotFileCache(fs, rootDir, period, 10000000,
233 "test-snapshot-file-cache-refresh", new SnapshotFileCache.SnapshotFileInspector() {
234 public Collection<String> filesUnderSnapshot(final Path snapshotDir)
235 throws IOException {
236 return SnapshotReferenceUtil.getHLogNames(fs, snapshotDir);
237 }
238 });
239
240
241 Path snapshot = new Path(snapshotDir, "snapshot");
242 Path region = new Path(snapshot, "7e91021");
243 Path family = new Path(region, "fam");
244 Path file1 = new Path(family, "file1");
245 fs.createNewFile(file1);
246
247
248 Path logs = TakeSnapshotUtils.getSnapshotHLogsDir(snapshot, "server");
249 Path log = new Path(logs, "me.hbase.com%2C58939%2C1350424310315.1350424315552");
250 fs.createNewFile(log);
251
252 FSUtils.logFileSystemState(fs, rootDir, LOG);
253
254 Iterable<FileStatus> nonSnapshotFiles = cache.getUnreferencedFiles(
255 Arrays.asList(FSUtils.listStatus(fs, family))
256 );
257
258 assertFalse("Cache found '" + file1 + "', but it shouldn't have.",
259 Iterables.contains(nonSnapshotFiles, file1));
260 assertFalse("Cache didn't find:" + log, Iterables.contains(nonSnapshotFiles, log));
261 }
262
263 @Test
264 public void testReloadModifiedDirectory() throws IOException {
265
266 long period = Long.MAX_VALUE;
267 Path snapshotDir = SnapshotDescriptionUtils.getSnapshotsDir(rootDir);
268 SnapshotFileCache cache = new SnapshotFileCache(fs, rootDir, period, 10000000,
269 "test-snapshot-file-cache-refresh", new SnapshotFiles());
270
271 Path snapshot = new Path(snapshotDir, "snapshot");
272 Path region = new Path(snapshot, "7e91021");
273 Path family = new Path(region, "fam");
274 Path file1 = new Path(family, "file1");
275 Path file2 = new Path(family, "file2");
276
277
278 fs.createNewFile(file1);
279 fs.createNewFile(file2);
280
281 FSUtils.logFileSystemState(fs, rootDir, LOG);
282
283 Iterable<FileStatus> nonSnapshotFiles = cache.getUnreferencedFiles(
284 Arrays.asList(FSUtils.listStatus(fs, family))
285 );
286 assertFalse("Cache didn't find " + file1, Iterables.contains(nonSnapshotFiles, file1));
287
288
289 fs.delete(snapshot, true);
290 Path file3 = new Path(family, "new_file");
291 fs.createNewFile(file3);
292
293 FSUtils.logFileSystemState(fs, rootDir, LOG);
294 nonSnapshotFiles = cache.getUnreferencedFiles(
295 Arrays.asList(FSUtils.listStatus(fs, family))
296 );
297 assertFalse("Cache didn't find new file:" + file3, Iterables.contains(nonSnapshotFiles, file3));
298 }
299
300 @Test
301 public void testSnapshotTempDirReload() throws IOException {
302 long period = Long.MAX_VALUE;
303 Path snapshotDir = new Path(SnapshotDescriptionUtils.getSnapshotsDir(rootDir),
304 SnapshotDescriptionUtils.SNAPSHOT_TMP_DIR_NAME);
305 SnapshotFileCache cache = new SnapshotFileCache(fs, rootDir, period, 10000000,
306 "test-snapshot-file-cache-refresh", new SnapshotFiles());
307
308
309 Path snapshot1 = new Path(snapshotDir, "snapshot1");
310 Path file1 = new Path(new Path(new Path(snapshot1, "7e91021"), "fam"), "file1");
311 fs.createNewFile(file1);
312 assertTrue(cache.getSnapshotsInProgress().contains(file1.getName()));
313
314
315 Path snapshot2 = new Path(snapshotDir, "snapshot2");
316 Path file2 = new Path(new Path(new Path(snapshot2, "7e91021"), "fam2"), "file2");
317 fs.createNewFile(file2);
318 assertTrue(cache.getSnapshotsInProgress().contains((file2.getName())));
319 }
320
321 class SnapshotFiles implements SnapshotFileCache.SnapshotFileInspector {
322 public Collection<String> filesUnderSnapshot(final Path snapshotDir) throws IOException {
323 Collection<String> files = new HashSet<String>();
324 files.addAll(SnapshotReferenceUtil.getHLogNames(fs, snapshotDir));
325 files.addAll(SnapshotReferenceUtil.getHFileNames(fs, snapshotDir));
326 return files;
327 }
328 };
329 }