Skip to content

Commit e2e00cd

Browse files
authored
Fix MetaStateFormat tests
It's not safe to continue writing state using MetaDataStateFormat after dirty WriteStateException occurred if it's not recovered by successful subsequent state write. We've encountered test failure of testFailRandomlyAndReadAnyState. The test breaks in the following way. There are 3 state paths. And what happens next Successful write at the beginning of the test yields 0 0 0 state files in the directories. 1st write in the loop is unsuccessful, but not dirty - 0 0 0. 2nd write in the loop is not successful and dirty (failure during fsync), however before removing new files we have 1 1 1. But now during deletion, the first deletion fails and we get - 1 0 0. 3rd write in the loop is unsuccessful, but not dirty - so we want to keep old generation, which happens to be the 1st generation, so now we have 1 x x in state folders. Now we assert that we either load 0 or 1 state from the state folders and select only 2rd and 3th folder to emulate disk failures - this results in NPE because there is nothing in these folders. Fortunately, this won’t be a problem in real life, because if there is a dirty exception, we shut down the node and make sure we perform a successful write on the node startup.
1 parent 942fc13 commit e2e00cd

File tree

2 files changed

+12
-0
lines changed

2 files changed

+12
-0
lines changed

server/src/test/java/org/elasticsearch/gateway/GatewayMetaStateTests.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,12 @@ public void testAtomicityWithFailures() throws IOException {
412412
} catch (WriteStateException e) {
413413
if (e.isDirty()) {
414414
possibleMetaData.add(metaData);
415+
/*
416+
* If dirty WriteStateException occurred, it's only safe to proceed if there is subsequent
417+
* successful write of metadata and Manifest. We prefer to break here, not to over complicate test logic.
418+
* See also MetaDataStateFormat#testFailRandomlyAndReadAnyState, that does not break.
419+
*/
420+
break;
415421
}
416422
}
417423
}

server/src/test/java/org/elasticsearch/gateway/MetaDataStateFormatTests.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,12 @@ public void testFailRandomlyAndReadAnyState() throws IOException {
408408
Path[] randomPaths = randomSubsetOf(randomIntBetween(1, paths.length), paths).toArray(new Path[0]);
409409
DummyState stateOnDisk = format.loadLatestState(logger, NamedXContentRegistry.EMPTY, randomPaths);
410410
assertTrue(possibleStates.contains(stateOnDisk));
411+
if (possibleStates.size() > 1) {
412+
//if there was a WriteStateException we need to override current state before we continue
413+
newState = writeAndReadStateSuccessfully(format, paths);
414+
possibleStates.clear();
415+
possibleStates.add(newState);
416+
}
411417
}
412418

413419
writeAndReadStateSuccessfully(format, paths);

0 commit comments

Comments
 (0)