use of org.neo4j.internal.recordstorage.Command in project neo4j by neo4j.
the class DatabaseRecoveryIT method recoveryShouldFixPartiallyAppliedSchemaIndexUpdates.
@Test
void recoveryShouldFixPartiallyAppliedSchemaIndexUpdates() {
Label label = Label.label("Foo");
String property = "Bar";
// cause failure during 'relationship.delete()' command application
ClassGuardedAdversary adversary = new ClassGuardedAdversary(new CountingAdversary(1, true), Command.RelationshipCommand.class);
adversary.disable();
Path storeDir = directory.homePath();
DatabaseManagementService managementService = AdversarialPageCacheGraphDatabaseFactory.create(storeDir, fileSystem, adversary).build();
GraphDatabaseService db = managementService.database(DEFAULT_DATABASE_NAME);
try {
try (Transaction tx = db.beginTx()) {
tx.schema().constraintFor(label).assertPropertyIsUnique(property).create();
tx.commit();
}
long relationshipId = createRelationship(db);
TransactionFailureException txFailure = null;
try (Transaction tx = db.beginTx()) {
Node node = tx.createNode(label);
node.setProperty(property, "B");
// this should fail because of the adversary
tx.getRelationshipById(relationshipId).delete();
adversary.enable();
tx.commit();
} catch (TransactionFailureException e) {
txFailure = e;
}
assertNotNull(txFailure);
adversary.disable();
// heal the db so it is possible to inspect the data
healthOf(db).healed();
// now we can observe partially committed state: node is in the index and relationship still present
try (Transaction tx = db.beginTx()) {
assertNotNull(findNode(label, property, "B", tx));
assertNotNull(tx.getRelationshipById(relationshipId));
tx.commit();
}
// panic the db again to force recovery on the next startup
healthOf(db).panic(txFailure.getCause());
// restart the database, now with regular page cache
managementService.shutdown();
db = startDatabase(storeDir);
// now we observe correct state: node is in the index and relationship is removed
try (Transaction tx = db.beginTx()) {
assertNotNull(findNode(label, property, "B", tx));
assertRelationshipNotExist(tx, relationshipId);
tx.commit();
}
} finally {
managementService.shutdown();
}
}
Aggregations