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