1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase.mapreduce;
20
21 import com.google.common.collect.ImmutableList;
22 import com.google.common.collect.ImmutableMap;
23 import com.google.common.collect.Lists;
24 import com.google.common.collect.Maps;
25 import org.apache.hadoop.conf.Configuration;
26 import org.apache.hadoop.fs.FileSystem;
27 import org.apache.hadoop.fs.Path;
28 import org.apache.hadoop.hbase.client.Scan;
29 import org.apache.hadoop.hbase.testclassification.SmallTests;
30 import org.apache.hadoop.hbase.util.Bytes;
31 import org.apache.hadoop.hbase.util.FSUtils;
32 import org.junit.Before;
33 import org.junit.Test;
34 import org.junit.experimental.categories.Category;
35 import org.mockito.Mockito;
36
37 import java.io.IOException;
38 import java.util.Collection;
39 import java.util.List;
40 import java.util.Map;
41
42 import static org.junit.Assert.assertEquals;
43 import static org.mockito.Matchers.any;
44 import static org.mockito.Matchers.eq;
45 import static org.mockito.Mockito.doNothing;
46 import static org.mockito.Mockito.verify;
47
48 @Category({ SmallTests.class })
49 public class TestMultiTableSnapshotInputFormatImpl {
50
51 private MultiTableSnapshotInputFormatImpl subject;
52 private Map<String, Collection<Scan>> snapshotScans;
53 private Path restoreDir;
54 private Configuration conf;
55 private Path rootDir;
56
57 @Before
58 public void setUp() throws Exception {
59 this.subject = Mockito.spy(new MultiTableSnapshotInputFormatImpl());
60
61
62
63
64
65
66
67
68
69 doNothing().when(this.subject).
70 restoreSnapshot(any(Configuration.class), any(String.class), any(Path.class),
71 any(Path.class), any(FileSystem.class));
72
73 this.conf = new Configuration();
74 this.rootDir = new Path("file:///test-root-dir");
75 FSUtils.setRootDir(conf, rootDir);
76 this.snapshotScans = ImmutableMap.<String, Collection<Scan>>of("snapshot1",
77 ImmutableList.of(new Scan(Bytes.toBytes("1"), Bytes.toBytes("2"))), "snapshot2",
78 ImmutableList.of(new Scan(Bytes.toBytes("3"), Bytes.toBytes("4")),
79 new Scan(Bytes.toBytes("5"), Bytes.toBytes("6"))));
80
81 this.restoreDir = new Path(FSUtils.getRootDir(conf), "restore-dir");
82
83 }
84
85 public void callSetInput() throws IOException {
86 subject.setInput(this.conf, snapshotScans, restoreDir);
87 }
88
89 public Map<String, Collection<ScanWithEquals>> toScanWithEquals(
90 Map<String, Collection<Scan>> snapshotScans) throws IOException {
91 Map<String, Collection<ScanWithEquals>> rtn = Maps.newHashMap();
92
93 for (Map.Entry<String, Collection<Scan>> entry : snapshotScans.entrySet()) {
94 List<ScanWithEquals> scans = Lists.newArrayList();
95
96 for (Scan scan : entry.getValue()) {
97 scans.add(new ScanWithEquals(scan));
98 }
99 rtn.put(entry.getKey(), scans);
100 }
101
102 return rtn;
103 }
104
105 public static class ScanWithEquals {
106
107 private final String startRow;
108 private final String stopRow;
109
110
111
112
113
114
115
116 public ScanWithEquals(Scan scan) throws IOException {
117 this.startRow = Bytes.toStringBinary(scan.getStartRow());
118 this.stopRow = Bytes.toStringBinary(scan.getStopRow());
119 }
120
121 @Override
122 public boolean equals(Object obj) {
123 if (!(obj instanceof ScanWithEquals)) {
124 return false;
125 }
126 ScanWithEquals otherScan = (ScanWithEquals) obj;
127 return this.startRow.equals(otherScan.startRow) &&
128 this.stopRow.equals(otherScan.stopRow);
129 }
130
131 @Override
132 public String toString() {
133 return com.google.common.base.Objects.toStringHelper(this).add("startRow", startRow)
134 .add("stopRow", stopRow).toString();
135 }
136 }
137
138 @Test
139 public void testSetInputSetsSnapshotToScans() throws Exception {
140
141 callSetInput();
142
143 Map<String, Collection<Scan>> actual = subject.getSnapshotsToScans(conf);
144
145
146 Map<String, Collection<ScanWithEquals>> actualWithEquals = toScanWithEquals(actual);
147 Map<String, Collection<ScanWithEquals>> expectedWithEquals = toScanWithEquals(snapshotScans);
148
149 assertEquals(expectedWithEquals, actualWithEquals);
150 }
151
152 @Test
153 public void testSetInputPushesRestoreDirectories() throws Exception {
154 callSetInput();
155
156 Map<String, Path> restoreDirs = subject.getSnapshotDirs(conf);
157
158 assertEquals(this.snapshotScans.keySet(), restoreDirs.keySet());
159 }
160
161 @Test
162 public void testSetInputCreatesRestoreDirectoriesUnderRootRestoreDir() throws Exception {
163 callSetInput();
164
165 Map<String, Path> restoreDirs = subject.getSnapshotDirs(conf);
166
167 for (Path snapshotDir : restoreDirs.values()) {
168 assertEquals("Expected " + snapshotDir + " to be a child of " + restoreDir, restoreDir,
169 snapshotDir.getParent());
170 }
171 }
172
173 @Test
174 public void testSetInputRestoresSnapshots() throws Exception {
175 callSetInput();
176
177 Map<String, Path> snapshotDirs = subject.getSnapshotDirs(conf);
178
179 for (Map.Entry<String, Path> entry : snapshotDirs.entrySet()) {
180 verify(this.subject).restoreSnapshot(eq(this.conf), eq(entry.getKey()), eq(this.rootDir),
181 eq(entry.getValue()), any(FileSystem.class));
182 }
183 }
184 }