Skip to content

Commit 5a35e0d

Browse files
adoroszlainandakumar131
authored andcommitted
HDDS-12139. Refactor TestSnapshotChainRepair. (apache#7752)
1 parent bdc0e8e commit 5a35e0d

File tree

1 file changed

+87
-159
lines changed

1 file changed

+87
-159
lines changed

hadoop-ozone/tools/src/test/java/org/apache/hadoop/ozone/repair/om/TestSnapshotChainRepair.java

Lines changed: 87 additions & 159 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,14 @@
1818

1919
package org.apache.hadoop.ozone.repair.om;
2020

21+
import org.apache.commons.lang3.RandomStringUtils;
2122
import org.apache.hadoop.hdds.utils.IOUtils;
2223
import org.apache.hadoop.hdds.utils.db.StringCodec;
2324
import org.apache.hadoop.hdds.utils.db.managed.ManagedRocksDB;
2425
import org.apache.hadoop.ozone.debug.RocksDBUtils;
2526
import org.apache.hadoop.ozone.om.helpers.SnapshotInfo;
2627
import org.apache.hadoop.ozone.repair.OzoneRepair;
2728
import org.apache.ozone.test.GenericTestUtils;
28-
import org.assertj.core.api.Assertions;
2929
import org.junit.jupiter.api.AfterEach;
3030
import org.junit.jupiter.api.BeforeEach;
3131
import org.junit.jupiter.api.Test;
@@ -34,6 +34,7 @@
3434
import org.mockito.MockedStatic;
3535
import org.rocksdb.ColumnFamilyHandle;
3636
import org.rocksdb.RocksDB;
37+
import org.rocksdb.RocksDBException;
3738
import org.rocksdb.RocksIterator;
3839
import org.rocksdb.ColumnFamilyDescriptor;
3940

@@ -47,13 +48,13 @@
4748

4849
import static org.apache.ozone.test.IntLambda.withTextFromSystemIn;
4950
import static org.apache.hadoop.ozone.OzoneConsts.SNAPSHOT_INFO_TABLE;
50-
import static org.junit.jupiter.api.Assertions.assertTrue;
51+
import static org.assertj.core.api.Assertions.assertThat;
5152
import static org.mockito.ArgumentMatchers.anyList;
5253
import static org.mockito.ArgumentMatchers.anyString;
5354
import static org.mockito.ArgumentMatchers.eq;
5455
import static org.mockito.Mockito.mock;
5556
import static org.mockito.Mockito.mockStatic;
56-
import static org.mockito.Mockito.never;
57+
import static org.mockito.Mockito.times;
5758
import static org.mockito.Mockito.verify;
5859
import static org.mockito.Mockito.when;
5960

@@ -62,12 +63,14 @@
6263
*/
6364
public class TestSnapshotChainRepair {
6465

66+
private static final String VOLUME_NAME = "vol1";
67+
private static final String BUCKET_NAME = "bucket1";
68+
private static final String DB_PATH = "testDBPath";
69+
6570
private ManagedRocksDB managedRocksDB;
6671
private RocksDB rocksDB;
6772
private ColumnFamilyHandle columnFamilyHandle;
6873

69-
private static final String DB_PATH = "testDBPath";
70-
7174
private MockedStatic<ManagedRocksDB> mockedDB;
7275
private MockedStatic<RocksDBUtils> mockedUtils;
7376

@@ -86,18 +89,11 @@ public void setup() throws Exception {
8689

8790
@AfterEach
8891
public void tearDown() {
89-
IOUtils.closeQuietly(out, err);
90-
91-
if (mockedDB != null) {
92-
mockedDB.close();
93-
}
94-
if (mockedUtils != null) {
95-
mockedUtils.close();
96-
}
92+
IOUtils.closeQuietly(out, err, mockedDB, mockedUtils);
9793
}
9894

9995
private void setupMockDB(SnapshotInfo snapshotInfo,
100-
List<SnapshotInfo> iteratorSnapshots) throws Exception {
96+
SnapshotInfo... snapshots) throws Exception {
10197

10298
managedRocksDB = mock(ManagedRocksDB.class);
10399
rocksDB = mock(RocksDB.class);
@@ -134,28 +130,22 @@ private void setupMockDB(SnapshotInfo snapshotInfo,
134130
when(rocksDB.newIterator(columnFamilyHandle)).thenReturn(rocksIterator);
135131

136132
// Setup iterator behavior based on provided snapshots
137-
if (iteratorSnapshots.isEmpty()) {
133+
if (snapshots.length == 0) {
138134
when(rocksIterator.isValid()).thenReturn(false);
139135
} else {
140-
Boolean[] remainingValidResponses = new Boolean[iteratorSnapshots.size()];
141-
for (int i = 0; i < iteratorSnapshots.size() - 1; i++) {
142-
remainingValidResponses[i] = true;
143-
}
144-
remainingValidResponses[iteratorSnapshots.size() - 1] = false;
136+
Boolean[] remainingValidResponses = new Boolean[snapshots.length + 1];
137+
Arrays.fill(remainingValidResponses, true);
138+
remainingValidResponses[remainingValidResponses.length - 1] = false;
145139

146140
when(rocksIterator.isValid())
147141
.thenReturn(true, remainingValidResponses);
148142

149143
ArrayList<byte[]> valueResponses = new ArrayList<>();
150-
for (SnapshotInfo snap : iteratorSnapshots) {
151-
try {
152-
valueResponses.add(SnapshotInfo.getCodec().toPersistedFormat(snap));
153-
} catch (IOException e) {
154-
Assertions.fail("Failed to serialize snapshot info");
155-
}
144+
for (SnapshotInfo snap : snapshots) {
145+
valueResponses.add(SnapshotInfo.getCodec().toPersistedFormat(snap));
156146
}
157-
byte[] firstValue = valueResponses.get(0);
158-
byte[][] remainingValueResponses = valueResponses.subList(1, valueResponses.size()).toArray(new byte[0][]);
147+
byte[] firstValue = SnapshotInfo.getCodec().toPersistedFormat(snapshotInfo);
148+
byte[][] remainingValueResponses = valueResponses.toArray(new byte[0][]);
159149
when(rocksIterator.value())
160150
.thenReturn(firstValue, remainingValueResponses);
161151
}
@@ -164,213 +154,151 @@ private void setupMockDB(SnapshotInfo snapshotInfo,
164154
@ParameterizedTest
165155
@ValueSource(booleans = {true, false})
166156
public void testSuccessfulRepair(boolean dryRun) throws Exception {
167-
String volumeName = "vol1";
168-
String bucketName = "bucket1";
169-
String snapshotName = "snap1";
170-
String globalPrevSnapshotName = "global-prev-snap1";
171-
String pathPrevSnapshotName = "path-prev-snap1";
172-
173-
UUID snapshotId = UUID.randomUUID();
174-
UUID globalPrevSnapshotId = UUID.randomUUID();
175-
UUID pathPrevSnapshotId = UUID.randomUUID();
176-
177-
SnapshotInfo snapshotInfo = SnapshotInfo.newInstance(volumeName, bucketName, snapshotName, snapshotId, 0);
178-
SnapshotInfo globalPrevSnapshot = SnapshotInfo.newInstance(volumeName, bucketName, globalPrevSnapshotName,
179-
globalPrevSnapshotId, 0);
180-
SnapshotInfo pathPrevSnapshot = SnapshotInfo.newInstance(volumeName, bucketName, pathPrevSnapshotName,
181-
pathPrevSnapshotId, 0);
182-
183-
List<SnapshotInfo> iteratorSnapshots = Arrays.asList(
184-
snapshotInfo, globalPrevSnapshot, pathPrevSnapshot);
157+
SnapshotInfo snapshotInfo = newSnapshot();
158+
SnapshotInfo globalPrevSnapshot = newSnapshot();
159+
SnapshotInfo pathPrevSnapshot = newSnapshot();
185160

186161
List<String> argsList = new ArrayList<>(Arrays.asList(
187162
"om", "snapshot", "chain",
188-
volumeName + "/" + bucketName,
189-
snapshotName,
163+
VOLUME_NAME + "/" + BUCKET_NAME,
164+
snapshotInfo.getName(),
190165
"--db", DB_PATH,
191-
"--global-previous", globalPrevSnapshotId.toString(),
192-
"--path-previous", pathPrevSnapshotId.toString()));
166+
"--global-previous", globalPrevSnapshot.getSnapshotId().toString(),
167+
"--path-previous", pathPrevSnapshot.getSnapshotId().toString()));
193168

194169
if (dryRun) {
195170
argsList.add("--dry-run");
196171
}
197172

198-
setupMockDB(snapshotInfo, iteratorSnapshots);
173+
setupMockDB(snapshotInfo, globalPrevSnapshot, pathPrevSnapshot);
199174

200175
CommandLine cli = new OzoneRepair().getCmd();
201176
withTextFromSystemIn("y")
202177
.execute(() -> cli.execute(argsList.toArray(new String[0])));
203178

204-
String output = out.getOutput();
205-
assertTrue(output.contains("Updating SnapshotInfo to"));
179+
assertThat(out.getOutput()).contains("Updating SnapshotInfo to");
206180

207-
if (dryRun) {
208-
// Verify DB update was NOT called in dry run mode
209-
verify(rocksDB, never()).put(
210-
eq(columnFamilyHandle),
211-
eq(StringCodec.get().toPersistedFormat(snapshotInfo.getTableKey())),
212-
eq(SnapshotInfo.getCodec().toPersistedFormat(snapshotInfo)));
213-
} else {
214-
// Verify DB update was called with correct parameters
215-
verify(rocksDB).put(
216-
eq(columnFamilyHandle),
217-
eq(StringCodec.get().toPersistedFormat(snapshotInfo.getTableKey())),
218-
eq(SnapshotInfo.getCodec().toPersistedFormat(snapshotInfo)));
219-
assertTrue(output.contains("Snapshot Info is updated"));
220-
}
181+
verifyDbWrite(snapshotInfo, !dryRun);
221182
}
222183

223184
@Test
224185
public void testGlobalPreviousMatchesSnapshotId() throws Exception {
225-
String volumeName = "vol1";
226-
String bucketName = "bucket1";
227-
String snapshotName = "snap1";
228-
229-
UUID snapshotId = UUID.randomUUID();
230-
// Use same ID for global previous to trigger error
231-
UUID globalPrevSnapshotId = snapshotId;
232-
UUID pathPrevSnapshotId = UUID.randomUUID();
233-
234-
SnapshotInfo snapshotInfo = SnapshotInfo.newInstance(volumeName, bucketName,
235-
snapshotName, snapshotId, 0);
236-
SnapshotInfo pathPrevSnapshot = SnapshotInfo.newInstance(volumeName, bucketName,
237-
"path-prev", pathPrevSnapshotId, 0);
238-
239-
List<SnapshotInfo> iteratorSnapshots = Arrays.asList(
240-
snapshotInfo, pathPrevSnapshot);
186+
SnapshotInfo snapshotInfo = newSnapshot();
187+
SnapshotInfo pathPrevSnapshot = newSnapshot();
241188

242189
String[] args = new String[] {
243190
"om", "snapshot", "chain",
244-
volumeName + "/" + bucketName,
245-
snapshotName,
191+
VOLUME_NAME + "/" + BUCKET_NAME,
192+
snapshotInfo.getName(),
246193
"--db", DB_PATH,
247-
"--global-previous", globalPrevSnapshotId.toString(),
248-
"--path-previous", pathPrevSnapshotId.toString(),
194+
// Use same ID for global previous to trigger error
195+
"--global-previous", snapshotInfo.getSnapshotId().toString(),
196+
"--path-previous", pathPrevSnapshot.getSnapshotId().toString(),
249197
};
250198

251-
setupMockDB(snapshotInfo, iteratorSnapshots);
199+
setupMockDB(snapshotInfo, pathPrevSnapshot);
252200

253201
CommandLine cli = new OzoneRepair().getCmd();
254202
withTextFromSystemIn("y")
255203
.execute(() -> cli.execute(args));
256204

257-
String errorOutput = err.getOutput();
258-
assertTrue(errorOutput.contains("globalPreviousSnapshotId: '" + globalPrevSnapshotId +
259-
"' is equal to given snapshot's ID"));
205+
assertThat(err.getOutput()).contains("globalPreviousSnapshotId: '" + snapshotInfo.getSnapshotId() +
206+
"' is equal to given snapshot's ID");
207+
verifyDbWrite(snapshotInfo, false);
260208
}
261209

262210
@Test
263211
public void testPathPreviousMatchesSnapshotId() throws Exception {
264-
String volumeName = "vol1";
265-
String bucketName = "bucket1";
266-
String snapshotName = "snap1";
267-
268-
UUID snapshotId = UUID.randomUUID();
269-
UUID globalPrevSnapshotId = UUID.randomUUID();
270-
// Use same ID for path previous to trigger error
271-
UUID pathPrevSnapshotId = snapshotId;
272-
273-
SnapshotInfo snapshotInfo = SnapshotInfo.newInstance(volumeName, bucketName,
274-
snapshotName, snapshotId, 0);
275-
SnapshotInfo globalPrevSnapshot = SnapshotInfo.newInstance(volumeName, bucketName,
276-
"global-prev", globalPrevSnapshotId, 0);
277-
278-
List<SnapshotInfo> iteratorSnapshots = Arrays.asList(
279-
snapshotInfo, globalPrevSnapshot);
212+
SnapshotInfo snapshotInfo = newSnapshot();
213+
SnapshotInfo globalPrevSnapshot = newSnapshot();
280214

281215
String[] args = new String[] {
282216
"om", "snapshot", "chain",
283-
volumeName + "/" + bucketName,
284-
snapshotName,
217+
VOLUME_NAME + "/" + BUCKET_NAME,
218+
snapshotInfo.getName(),
285219
"--db", DB_PATH,
286-
"--global-previous", globalPrevSnapshotId.toString(),
287-
"--path-previous", pathPrevSnapshotId.toString(),
220+
"--global-previous", globalPrevSnapshot.getSnapshotId().toString(),
221+
// Use same ID for path previous to trigger error
222+
"--path-previous", snapshotInfo.getSnapshotId().toString(),
288223
};
289224

290-
setupMockDB(snapshotInfo, iteratorSnapshots);
225+
setupMockDB(snapshotInfo, globalPrevSnapshot);
291226

292227
CommandLine cli = new OzoneRepair().getCmd();
293228
withTextFromSystemIn("y")
294229
.execute(() -> cli.execute(args));
295230

296-
String errorOutput = err.getOutput();
297-
assertTrue(errorOutput.contains("pathPreviousSnapshotId: '" + pathPrevSnapshotId +
298-
"' is equal to given snapshot's ID"));
231+
assertThat(err.getOutput()).contains("pathPreviousSnapshotId: '" + snapshotInfo.getSnapshotId() +
232+
"' is equal to given snapshot's ID");
233+
verifyDbWrite(snapshotInfo, false);
299234
}
300235

301236
@Test
302237
public void testGlobalPreviousDoesNotExist() throws Exception {
303-
String volumeName = "vol1";
304-
String bucketName = "bucket1";
305-
String snapshotName = "snap1";
306-
307-
UUID snapshotId = UUID.randomUUID();
308-
UUID globalPrevSnapshotId = UUID.randomUUID();
309-
UUID pathPrevSnapshotId = UUID.randomUUID();
238+
String nonexistent = UUID.randomUUID().toString();
310239

311-
SnapshotInfo snapshotInfo = SnapshotInfo.newInstance(volumeName, bucketName,
312-
snapshotName, snapshotId, 0);
313-
SnapshotInfo pathPrevSnapshot = SnapshotInfo.newInstance(volumeName, bucketName,
314-
"path-prev", pathPrevSnapshotId, 0);
315-
316-
List<SnapshotInfo> iteratorSnapshots = Arrays.asList(
317-
snapshotInfo, pathPrevSnapshot);
240+
SnapshotInfo snapshotInfo = newSnapshot();
241+
SnapshotInfo pathPrevSnapshot = newSnapshot();
318242

319243
String[] args = new String[] {
320244
"om", "snapshot", "chain",
321-
volumeName + "/" + bucketName,
322-
snapshotName,
245+
VOLUME_NAME + "/" + BUCKET_NAME,
246+
snapshotInfo.getName(),
323247
"--db", DB_PATH,
324-
"--global-previous", globalPrevSnapshotId.toString(),
325-
"--path-previous", pathPrevSnapshotId.toString(),
248+
"--global-previous", nonexistent,
249+
"--path-previous", pathPrevSnapshot.getSnapshotId().toString(),
326250
};
327251

328-
setupMockDB(snapshotInfo, iteratorSnapshots);
252+
setupMockDB(snapshotInfo, pathPrevSnapshot);
329253

330254
CommandLine cli = new OzoneRepair().getCmd();
331255
withTextFromSystemIn("y")
332256
.execute(() -> cli.execute(args));
333257

334-
String errorOutput = err.getOutput();
335-
assertTrue(errorOutput.contains("globalPreviousSnapshotId: '" + globalPrevSnapshotId +
336-
"' does not exist in snapshotInfoTable"));
258+
assertThat(err.getOutput()).contains("globalPreviousSnapshotId: '" + nonexistent +
259+
"' does not exist in snapshotInfoTable");
260+
verifyDbWrite(snapshotInfo, false);
337261
}
338262

339263
@Test
340264
public void testPathPreviousDoesNotExist() throws Exception {
341-
String volumeName = "vol1";
342-
String bucketName = "bucket1";
343-
String snapshotName = "snap1";
344-
345-
UUID snapshotId = UUID.randomUUID();
346-
UUID globalPrevSnapshotId = UUID.randomUUID();
347-
UUID pathPrevSnapshotId = UUID.randomUUID();
265+
String nonexistent = UUID.randomUUID().toString();
348266

349-
SnapshotInfo snapshotInfo = SnapshotInfo.newInstance(volumeName, bucketName,
350-
snapshotName, snapshotId, 0);
351-
SnapshotInfo globalPrevSnapshot = SnapshotInfo.newInstance(volumeName, bucketName,
352-
"global-prev", globalPrevSnapshotId, 0);
353-
354-
List<SnapshotInfo> iteratorSnapshots = Arrays.asList(
355-
snapshotInfo, globalPrevSnapshot);
267+
SnapshotInfo snapshotInfo = newSnapshot();
268+
SnapshotInfo globalPrevSnapshot = newSnapshot();
356269

357270
String[] args = new String[] {
358271
"om", "snapshot", "chain",
359-
volumeName + "/" + bucketName,
360-
snapshotName,
272+
VOLUME_NAME + "/" + BUCKET_NAME,
273+
snapshotInfo.getName(),
361274
"--db", DB_PATH,
362-
"--global-previous", globalPrevSnapshotId.toString(),
363-
"--path-previous", pathPrevSnapshotId.toString(),
275+
"--global-previous", globalPrevSnapshot.getSnapshotId().toString(),
276+
"--path-previous", nonexistent,
364277
};
365278

366-
setupMockDB(snapshotInfo, iteratorSnapshots);
279+
setupMockDB(snapshotInfo, globalPrevSnapshot);
367280

368281
CommandLine cli = new OzoneRepair().getCmd();
369282
withTextFromSystemIn("y")
370283
.execute(() -> cli.execute(args));
371284

372-
String errorOutput = err.getOutput();
373-
assertTrue(errorOutput.contains("pathPreviousSnapshotId: '" + pathPrevSnapshotId +
374-
"' does not exist in snapshotInfoTable"));
285+
assertThat(err.getOutput()).contains("pathPreviousSnapshotId: '" + nonexistent +
286+
"' does not exist in snapshotInfoTable");
287+
verifyDbWrite(snapshotInfo, false);
288+
}
289+
290+
private static SnapshotInfo newSnapshot() {
291+
String name = RandomStringUtils.insecure().nextAlphanumeric(10);
292+
return SnapshotInfo.newInstance(VOLUME_NAME, BUCKET_NAME, name, UUID.randomUUID(), 0);
293+
}
294+
295+
private void verifyDbWrite(SnapshotInfo snapshotInfo, boolean updateExpected) throws RocksDBException, IOException {
296+
verify(rocksDB, times(updateExpected ? 1 : 0)).put(
297+
eq(columnFamilyHandle),
298+
eq(StringCodec.get().toPersistedFormat(snapshotInfo.getTableKey())),
299+
eq(SnapshotInfo.getCodec().toPersistedFormat(snapshotInfo)));
300+
if (updateExpected) {
301+
assertThat(out.get()).contains("Snapshot Info is updated");
302+
}
375303
}
376304
}

0 commit comments

Comments
 (0)