@Test public void shouldDeleteDynamicLabelsForDeletedNode() throws Throwable { // GIVEN a store that has got a node with a dynamic label record NeoStores store = neoStoresRule.builder().build(); BatchTransactionApplier applier = new NeoStoreBatchTransactionApplier( store, mock( CacheAccessBackDoor.class ), LockService.NO_LOCK_SERVICE ); AtomicLong nodeId = new AtomicLong(); AtomicLong dynamicLabelRecordId = new AtomicLong(); apply( applier, transaction( nodeWithDynamicLabelRecord( store, nodeId, dynamicLabelRecordId ) ) ); assertDynamicLabelRecordInUse( store, dynamicLabelRecordId.get(), true ); // WHEN applying a transaction where the node is deleted apply( applier, transaction( deleteNode( store, nodeId.get() ) ) ); // THEN the dynamic label record should also be deleted assertDynamicLabelRecordInUse( store, dynamicLabelRecordId.get(), false ); }
private NeoStores open( FileSystemAbstraction fs, PageCache pageCache, RecordFormats format, Function<FileSystemAbstraction,IdGeneratorFactory> idGeneratorFactory, String... config ) throws IOException { assert neoStores == null : "Already opened"; TestDirectory testDirectory = TestDirectory.testDirectory( fs ); testDirectory.prepareDirectory( testClass, null ); Config configuration = configOf( config ); StoreFactory storeFactory = new StoreFactory( testDirectory.databaseLayout(), configuration, idGeneratorFactory.apply( fs ), pageCache, fs, format, NullLogProvider.getInstance(), EmptyVersionContextSupplier.EMPTY ); return neoStores = stores.length == 0 ? storeFactory.openAllNeoStores( true ) : storeFactory.openNeoStores( true, stores ); }
private PageCache rulePageCache( Config dbConfig, FileSystemAbstraction fs, JobScheduler scheduler ) { return rulePageCache = getOrCreatePageCache( dbConfig, fs, scheduler ); }
@SuppressWarnings( "unchecked" ) @Test public void shouldProcessAllTheRecordsInAStore() throws Exception { // given RecordStore<NodeRecord> nodeStore = stores.builder().build().getNodeStore(); ConsistencyReport.Reporter reporter = mock( ConsistencyReport.Reporter.class ); StoreProcessor processor = new StoreProcessor( CheckDecorator.NONE, reporter, Stage.SEQUENTIAL_FORWARD, CacheAccess.EMPTY ); nodeStore.updateRecord( node( 0, false, 0, 0 ) ); nodeStore.updateRecord( node( 1, false, 0, 0 ) ); nodeStore.updateRecord( node( 2, false, 0, 0 ) ); nodeStore.setHighestPossibleIdInUse( 2 ); // when processor.applyFiltered( nodeStore ); // then verify( reporter, times( 3 ) ).forNode( any( NodeRecord.class ), any( RecordCheck.class ) ); }
@Test public void shouldExtractCreatedCommandsInCorrectOrder() throws Throwable { // GIVEN NeoStores neoStores = neoStoresRule.builder() .with( GraphDatabaseSettings.dense_node_threshold.name(), "1" ).build(); TransactionRecordState recordState = newTransactionRecordState( neoStores ); long nodeId = 0; long relId = 1; recordState.nodeCreate( nodeId ); recordState.relCreate( relId++, 0, nodeId, nodeId ); recordState.relCreate( relId, 0, nodeId, nodeId ); recordState.nodeAddProperty( nodeId, 0, value2 ); // WHEN Collection<StorageCommand> commands = new ArrayList<>(); recordState.extractCommands( commands ); // THEN Iterator<StorageCommand> commandIterator = commands.iterator(); assertCommand( commandIterator.next(), PropertyCommand.class ); assertCommand( commandIterator.next(), RelationshipCommand.class ); assertCommand( commandIterator.next(), RelationshipCommand.class ); assertCommand( commandIterator.next(), Command.RelationshipGroupCommand.class ); assertCommand( commandIterator.next(), NodeCommand.class ); assertFalse( commandIterator.hasNext() ); }
@Test public void shouldDeleteDynamicLabelsForDeletedNodeForRecoveredTransaction() throws Throwable { // GIVEN a store that has got a node with a dynamic label record NeoStores store = neoStoresRule.builder().build(); BatchTransactionApplier applier = new NeoStoreBatchTransactionApplier( store, mock( CacheAccessBackDoor.class ), LockService.NO_LOCK_SERVICE ); AtomicLong nodeId = new AtomicLong(); AtomicLong dynamicLabelRecordId = new AtomicLong(); apply( applier, transaction( nodeWithDynamicLabelRecord( store, nodeId, dynamicLabelRecordId ) ) ); assertDynamicLabelRecordInUse( store, dynamicLabelRecordId.get(), true ); // WHEN applying a transaction, which has first round-tripped through a log (written then read) TransactionRepresentation transaction = transaction( deleteNode( store, nodeId.get() ) ); InMemoryVersionableReadableClosablePositionAwareChannel channel = new InMemoryVersionableReadableClosablePositionAwareChannel(); writeToChannel( transaction, channel ); CommittedTransactionRepresentation recoveredTransaction = readFromChannel( channel ); // and applying that recovered transaction apply( applier, recoveredTransaction.getTransactionRepresentation() ); // THEN should have the dynamic label record should be deleted as well assertDynamicLabelRecordInUse( store, dynamicLabelRecordId.get(), false ); }
@Test public void shouldValidateConstraintIndexAsPartOfExtraction() throws Throwable { // GIVEN NeoStores neoStores = neoStoresRule.builder().build(); TransactionRecordState recordState = newTransactionRecordState( neoStores ); final long indexId = neoStores.getSchemaStore().nextId(); final long constraintId = neoStores.getSchemaStore().nextId(); recordState.createSchemaRule( constraintRule( constraintId, uniqueForLabel( 1, 1 ), indexId ) ); // WHEN recordState.extractCommands( new ArrayList<>() ); // THEN verify( integrityValidator ).validateSchemaRule( any() ); }
NeoStores neoStores = neoStoresRule.builder().build(); NodeStore nodeStore = neoStores.getNodeStore(); long[] nodes = { // allocate ids
NeoStores neoStores = neoStoresRule.builder() .with( GraphDatabaseSettings.dense_node_threshold.name(), "1" ).build(); TransactionRecordState recordState = newTransactionRecordState( neoStores );
reporter, Stage.SEQUENTIAL_FORWARD, CacheAccess.EMPTY ); RecordStore<NodeRecord> nodeStore = new RecordStore.Delegator<NodeRecord>( stores.builder().build().getNodeStore() )
NeoStores neoStores = neoStoresRule.builder() .with( GraphDatabaseSettings.dense_node_threshold.name(), "1" ).build(); TransactionRecordState recordState = newTransactionRecordState( neoStores );
@Test public void shouldCreateProperBeforeAndAfterPropertyCommandsWhenAddingProperty() throws Exception { // GIVEN NeoStores neoStores = neoStoresRule.builder().build(); TransactionRecordState recordState = newTransactionRecordState( neoStores ); int nodeId = 1; recordState.nodeCreate( nodeId ); // WHEN recordState.nodeAddProperty( nodeId, propertyId1, value1 ); Collection<StorageCommand> commands = new ArrayList<>(); recordState.extractCommands( commands ); PropertyCommand propertyCommand = singlePropertyCommand( commands ); // THEN PropertyRecord before = propertyCommand.getBefore(); assertFalse( before.inUse() ); assertFalse( before.iterator().hasNext() ); PropertyRecord after = propertyCommand.getAfter(); assertTrue( after.inUse() ); assertEquals( 1, count( after ) ); }
@Test public void shouldMaintainCorrectDataWhenDeletingFromDenseNodeWithOneType() throws Exception { // GIVEN a node with a total of denseNodeThreshold-1 relationships NeoStores neoStores = neoStoresRule.builder() .with( GraphDatabaseSettings.dense_node_threshold.name(), "13" ).build(); TransactionRecordState tx = newTransactionRecordState( neoStores ); int nodeId = (int) neoStores.getNodeStore().nextId(); int typeA = 0; tx.nodeCreate( nodeId ); tx.createRelationshipTypeToken( "A", typeA ); long[] relationshipsCreated = createRelationships( neoStores, tx, nodeId, typeA, INCOMING, 15 ); //WHEN tx.relDelete( relationshipsCreated[0] ); // THEN the node should have been converted into a dense node assertDenseRelationshipCounts( recordChangeSet, nodeId, typeA, 0, 14 ); }
@Test public void shouldConvertLabelAdditionToNodePropertyUpdates() throws Exception { // GIVEN NeoStores neoStores = neoStoresRule.builder().build(); long nodeId = 0; TransactionRecordState recordState = newTransactionRecordState( neoStores ); Value value1 = Values.of( LONG_STRING ); Value value2 = Values.of( LONG_STRING.getBytes() ); recordState.nodeCreate( nodeId ); recordState.nodeAddProperty( nodeId, propertyId1, value1 ); recordState.nodeAddProperty( nodeId, propertyId2, value2 ); apply( neoStores, recordState ); // WHEN recordState = newTransactionRecordState( neoStores ); addLabelsToNode( recordState, nodeId, oneLabelId ); Iterable<EntityUpdates> indexUpdates = indexUpdatesOf( neoStores, recordState ); // THEN EntityUpdates expected = EntityUpdates.forEntity( nodeId ).withTokens( noLabels ).withTokensAfter( oneLabelId ).build(); assertEquals( expected, Iterables.single( indexUpdates ) ); }
NeoStores neoStores = neoStoresRule.builder() .with( GraphDatabaseSettings.dense_node_threshold.name(), "10" ).build(); TransactionRecordState tx = newTransactionRecordState( neoStores );
@Test public void shouldConvertAddedPropertyToNodePropertyUpdates() throws Exception { // GIVEN NeoStores neoStores = neoStoresRule.builder().build(); long nodeId = 0; TransactionRecordState recordState = newTransactionRecordState( neoStores ); // WHEN recordState.nodeCreate( nodeId ); addLabelsToNode( recordState, nodeId, oneLabelId ); recordState.nodeAddProperty( nodeId, propertyId1, value1 ); recordState.nodeAddProperty( nodeId, propertyId2, value2 ); Iterable<EntityUpdates> updates = indexUpdatesOf( neoStores, recordState ); // THEN EntityUpdates expected = EntityUpdates.forEntity( nodeId ).withTokens( noLabels ).withTokensAfter( oneLabelId ) .added( propertyId1, value1 ) .added( propertyId2, value2 ).build(); assertEquals( expected, Iterables.single( updates ) ); }
@Test public void shouldConvertLabelRemovalToNodePropertyUpdates() throws Exception { // GIVEN NeoStores neoStores = neoStoresRule.builder().build(); long nodeId = 0; TransactionRecordState recordState = newTransactionRecordState( neoStores ); recordState.nodeCreate( nodeId ); recordState.nodeAddProperty( nodeId, propertyId1, value1 ); recordState.nodeAddProperty( nodeId, propertyId2, value2 ); addLabelsToNode( recordState, nodeId, oneLabelId ); apply( neoStores, recordState ); // WHEN recordState = newTransactionRecordState( neoStores ); removeLabelsFromNode( recordState, nodeId, oneLabelId ); Iterable<EntityUpdates> indexUpdates = indexUpdatesOf( neoStores, recordState ); // THEN EntityUpdates expected = EntityUpdates.forEntity( nodeId ).withTokens( oneLabelId ).withTokensAfter( noLabels ).build(); assertEquals( expected, Iterables.single( indexUpdates ) ); }
NeoStores neoStore = neoStoresRule.builder() .with( GraphDatabaseSettings.dense_node_threshold.name(), "5" ).build(); int relationshipA = 0;
NeoStores neoStores = neoStoresRule.builder().build(); TransactionRecordState recordState = newTransactionRecordState( neoStores ); int nodeId = 0;
@Test public void shouldConvertMixedLabelRemovalAndRemovePropertyToNodePropertyUpdates() throws Exception { // GIVEN NeoStores neoStores = neoStoresRule.builder().build(); long nodeId = 0; TransactionRecordState recordState = newTransactionRecordState( neoStores ); recordState.nodeCreate( nodeId ); recordState.nodeAddProperty( nodeId, propertyId1, value1 ); addLabelsToNode( recordState, nodeId, bothLabelIds ); apply( neoStores, recordState ); // WHEN recordState = newTransactionRecordState( neoStores ); recordState.nodeRemoveProperty( nodeId, propertyId1 ); removeLabelsFromNode( recordState, nodeId, secondLabelId ); Iterable<EntityUpdates> indexUpdates = indexUpdatesOf( neoStores, recordState ); // THEN EntityUpdates expected = EntityUpdates.forEntity( nodeId ).withTokens( bothLabelIds ).withTokensAfter( oneLabelId ) .removed( propertyId1, value1 ) .build(); assertEquals( expected, Iterables.single( indexUpdates ) ); }