use of org.neo4j.storageengine.api.CommandsToApply in project neo4j by neo4j.
the class RecordStorageEngineTest method panicOnExceptionDuringCommandsApply.
@Test
public void panicOnExceptionDuringCommandsApply() throws Exception {
IllegalStateException failure = new IllegalStateException("Too many open files");
RecordStorageEngine engine = storageEngineRule.getWith(fsRule.get(), pageCacheRule.getPageCache(fsRule.get())).databaseHealth(databaseHealth).transactionApplierTransformer(facade -> transactionApplierFacadeTransformer(facade, failure)).build();
CommandsToApply commandsToApply = mock(CommandsToApply.class);
try {
engine.apply(commandsToApply, TransactionApplicationMode.INTERNAL);
fail("Exception expected");
} catch (Exception exception) {
assertSame(failure, Exceptions.rootCause(exception));
}
verify(databaseHealth).panic(any(Throwable.class));
}
use of org.neo4j.storageengine.api.CommandsToApply in project neo4j by neo4j.
the class ApplyRecoveredTransactionsTest method applyExternalTransaction.
private void applyExternalTransaction(long transactionId, Command... commands) throws Exception {
LockService lockService = mock(LockService.class);
when(lockService.acquireNodeLock(anyLong(), any(LockType.class))).thenReturn(LockService.NO_LOCK);
when(lockService.acquireRelationshipLock(anyLong(), any(LockType.class))).thenReturn(LockService.NO_LOCK);
Map<IdType, WorkSync<IdGenerator, IdGeneratorUpdateWork>> idGeneratorWorkSyncs = new EnumMap<>(IdType.class);
for (IdType idType : IdType.values()) {
idGeneratorWorkSyncs.put(idType, new WorkSync<>(idGeneratorFactory.get(idType)));
}
NeoStoreTransactionApplierFactory applier = new NeoStoreTransactionApplierFactory(INTERNAL, neoStores, mock(CacheAccessBackDoor.class), lockService);
CommandsToApply tx = new GroupOfCommands(transactionId, commands);
CommandHandlerContract.apply(applier, txApplier -> {
tx.accept(txApplier);
return false;
}, new GroupOfCommands(transactionId, commands));
}
use of org.neo4j.storageengine.api.CommandsToApply in project neo4j by neo4j.
the class TransactionApplierFactoryChainTest method testStartTxCorrectOrderWithLockGroup.
@Test
void testStartTxCorrectOrderWithLockGroup() throws Exception {
// GIVEN
CommandsToApply tx = mock(CommandsToApply.class);
var batchContext = mock(BatchContext.class);
// WHEN
TransactionApplierFacade result = (TransactionApplierFacade) facade.startTx(tx, batchContext);
// THEN
InOrder inOrder = inOrder(applier1, applier2, applier3);
inOrder.verify(applier1).startTx(tx, batchContext);
inOrder.verify(applier2).startTx(tx, batchContext);
inOrder.verify(applier3).startTx(tx, batchContext);
assertEquals(txApplier1, result.appliers[0]);
assertEquals(txApplier2, result.appliers[1]);
assertEquals(txApplier3, result.appliers[2]);
assertEquals(3, result.appliers.length);
}
use of org.neo4j.storageengine.api.CommandsToApply in project neo4j by neo4j.
the class TransactionRecordStateTest method movingBilaterallyOfTheDenseNodeThresholdIsConsistent.
@Test
void movingBilaterallyOfTheDenseNodeThresholdIsConsistent() throws Exception {
neoStores = createStores(Config.defaults(dense_node_threshold, 10));
TransactionRecordState tx = newTransactionRecordState();
long nodeId = neoStores.getNodeStore().nextId(NULL);
tx.nodeCreate(nodeId);
int typeA = (int) neoStores.getRelationshipTypeTokenStore().nextId(NULL);
tx.createRelationshipTypeToken("A", typeA, false);
createRelationships(neoStores, tx, nodeId, typeA, INCOMING, 20);
TransactionApplierFactory applier = buildApplier(LockService.NO_LOCK_SERVICE);
apply(applier, transaction(tx));
tx = newTransactionRecordState();
int typeB = 1;
tx.createRelationshipTypeToken("B", typeB, false);
// WHEN
// i remove enough relationships to become dense and remove enough to become not dense
RelationshipData[] relationshipsOfTypeB = createRelationships(neoStores, tx, nodeId, typeB, OUTGOING, 5);
tx.relModify(new FlatRelationshipModifications(relationships(), relationshipsOfTypeB));
CommandsToApply ptx = transaction(tx);
apply(applier, ptx);
// THEN
// The dynamic label record in before should be the same id as in after, and should be in use
final AtomicBoolean foundRelationshipGroupInUse = new AtomicBoolean();
ptx.accept(command -> ((Command) command).handle(new CommandVisitor.Adapter() {
@Override
public boolean visitRelationshipGroupCommand(Command.RelationshipGroupCommand command) {
if (command.getAfter().inUse()) {
if (!foundRelationshipGroupInUse.get()) {
foundRelationshipGroupInUse.set(true);
} else {
fail();
}
}
return false;
}
}));
assertTrue(foundRelationshipGroupInUse.get(), "Did not create relationship group command");
}
use of org.neo4j.storageengine.api.CommandsToApply in project neo4j by neo4j.
the class TransactionRecordStateTest method shouldCreateEqualEntityPropertyUpdatesOnRecoveryOfCreatedEntities.
@Test
void shouldCreateEqualEntityPropertyUpdatesOnRecoveryOfCreatedEntities() throws Exception {
neoStores = createStores();
/* There was an issue where recovering a tx where a node with a label and a property
* was created resulted in two exact copies of NodePropertyUpdates. */
// GIVEN
long nodeId = 0;
long relId = 1;
int labelId = 5;
int relTypeId = 4;
int propertyKeyId = 7;
// -- indexes
long nodeRuleId = 0;
TransactionRecordState recordState = newTransactionRecordState();
SchemaRule nodeRule = IndexPrototype.forSchema(forLabel(labelId, propertyKeyId)).withName("index_" + nodeRuleId).materialise(nodeRuleId);
recordState.schemaRuleCreate(nodeRuleId, false, nodeRule);
long relRuleId = 1;
SchemaRule relRule = IndexPrototype.forSchema(forRelType(relTypeId, propertyKeyId)).withName("index_" + relRuleId).materialise(relRuleId);
recordState.schemaRuleCreate(relRuleId, false, relRule);
apply(recordState);
// -- and a tx creating a node and a rel for those indexes
recordState = newTransactionRecordState();
recordState.nodeCreate(nodeId);
recordState.addLabelToNode(labelId, nodeId);
recordState.nodeAddProperty(nodeId, propertyKeyId, Values.of("Neo"));
recordState.relModify(singleCreate(relId, relTypeId, nodeId, nodeId));
recordState.relAddProperty(relId, propertyKeyId, Values.of("Oen"));
// WHEN
CommandsToApply transaction = transaction(recordState);
IndexUpdatesExtractor extractor = new IndexUpdatesExtractor();
transaction.accept(extractor);
// THEN
// -- later recovering that tx, there should be only one update for each type
assertTrue(extractor.containsAnyEntityOrPropertyUpdate());
MutableLongSet recoveredNodeIds = new LongHashSet();
recoveredNodeIds.addAll(entityIds(extractor.getNodeCommands()));
assertEquals(1, recoveredNodeIds.size());
assertEquals(nodeId, recoveredNodeIds.longIterator().next());
MutableLongSet recoveredRelIds = new LongHashSet();
recoveredRelIds.addAll(entityIds(extractor.getRelationshipCommands()));
assertEquals(1, recoveredRelIds.size());
assertEquals(relId, recoveredRelIds.longIterator().next());
}
Aggregations