/**
* Copyright (c) 2002-2012 "Neo Technology,"
* Network Engine for Objects in Lund AB [http://neotechnology.com]
*
* This file is part of Neo4j.
*
* Neo4j is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.neo4j.consistency.checking.full;
import org.junit.Test;
import org.neo4j.consistency.RecordType;
import org.neo4j.consistency.checking.DynamicStore;
import org.neo4j.consistency.checking.PrimitiveRecordCheck;
import org.neo4j.consistency.checking.RecordCheck;
import org.neo4j.consistency.report.ConsistencyReport;
import org.neo4j.consistency.store.RecordAccessStub;
import org.neo4j.helpers.progress.ProgressMonitorFactory;
import org.neo4j.kernel.impl.nioneo.store.DynamicRecord;
import org.neo4j.kernel.impl.nioneo.store.NeoStoreRecord;
import org.neo4j.kernel.impl.nioneo.store.NodeRecord;
import org.neo4j.kernel.impl.nioneo.store.PropertyIndexRecord;
import org.neo4j.kernel.impl.nioneo.store.PropertyRecord;
import org.neo4j.kernel.impl.nioneo.store.PropertyType;
import org.neo4j.kernel.impl.nioneo.store.RelationshipRecord;
import org.neo4j.kernel.impl.nioneo.store.RelationshipTypeRecord;
import static org.junit.Assert.assertSame;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.neo4j.consistency.checking.DynamicRecordCheckTest.configureDynamicStore;
import static org.neo4j.consistency.checking.RecordCheckTestBase.NONE;
import static org.neo4j.consistency.checking.RecordCheckTestBase.array;
import static org.neo4j.consistency.checking.RecordCheckTestBase.check;
import static org.neo4j.consistency.checking.RecordCheckTestBase.dummyDynamicCheck;
import static org.neo4j.consistency.checking.RecordCheckTestBase.dummyNeoStoreCheck;
import static org.neo4j.consistency.checking.RecordCheckTestBase.dummyNodeCheck;
import static org.neo4j.consistency.checking.RecordCheckTestBase.dummyPropertyChecker;
import static org.neo4j.consistency.checking.RecordCheckTestBase.dummyPropertyKeyCheck;
import static org.neo4j.consistency.checking.RecordCheckTestBase.dummyRelationshipChecker;
import static org.neo4j.consistency.checking.RecordCheckTestBase.dummyRelationshipLabelCheck;
import static org.neo4j.consistency.checking.RecordCheckTestBase.inUse;
import static org.neo4j.consistency.checking.RecordCheckTestBase.notInUse;
import static org.neo4j.consistency.checking.RecordCheckTestBase.propertyBlock;
import static org.neo4j.consistency.checking.RecordCheckTestBase.string;
import static org.neo4j.consistency.checking.RecordCheckTestBase.verifyOnlyReferenceDispatch;
public class OwnerCheckTest
{
@Test
public void shouldNotDecorateCheckerWhenInactive() throws Exception
{
// given
OwnerCheck decorator = new OwnerCheck( false );
PrimitiveRecordCheck<NodeRecord, ConsistencyReport.NodeConsistencyReport> checker = dummyNodeCheck();
// when
RecordCheck<NodeRecord, ConsistencyReport.NodeConsistencyReport> decorated =
decorator.decorateNodeChecker( checker );
// then
assertSame( checker, decorated );
}
@Test
public void shouldNotReportAnythingForNodesWithDifferentPropertyChains() throws Exception
{
// given
OwnerCheck decorator = new OwnerCheck( true );
RecordCheck<NodeRecord, ConsistencyReport.NodeConsistencyReport> nodeChecker =
decorator.decorateNodeChecker( dummyNodeCheck() );
RecordAccessStub records = new RecordAccessStub();
NodeRecord node1 = records.add( inUse( new NodeRecord( 1, NONE, 7 ) ) );
NodeRecord node2 = records.add( inUse( new NodeRecord( 2, NONE, 8 ) ) );
// when
ConsistencyReport.NodeConsistencyReport report1 =
check( ConsistencyReport.NodeConsistencyReport.class, nodeChecker, node1, records );
ConsistencyReport.NodeConsistencyReport report2 =
check( ConsistencyReport.NodeConsistencyReport.class, nodeChecker, node2, records );
// then
verifyZeroInteractions( report1 );
verifyZeroInteractions( report2 );
}
@Test
public void shouldNotReportAnythingForNodesNotInUse() throws Exception
{
// given
OwnerCheck decorator = new OwnerCheck( true );
RecordCheck<NodeRecord, ConsistencyReport.NodeConsistencyReport> nodeChecker =
decorator.decorateNodeChecker( dummyNodeCheck() );
RecordAccessStub records = new RecordAccessStub();
NodeRecord node1 = records.add( notInUse( new NodeRecord( 1, NONE, 6 ) ) );
NodeRecord node2 = records.add( notInUse( new NodeRecord( 2, NONE, 6 ) ) );
// when
ConsistencyReport.NodeConsistencyReport report1 =
check( ConsistencyReport.NodeConsistencyReport.class, nodeChecker, node1, records );
ConsistencyReport.NodeConsistencyReport report2 =
check( ConsistencyReport.NodeConsistencyReport.class, nodeChecker, node2, records );
// then
verifyZeroInteractions( report1 );
verifyZeroInteractions( report2 );
}
@Test
public void shouldNotReportAnythingForRelationshipsWithDifferentPropertyChains() throws Exception
{
// given
OwnerCheck decorator = new OwnerCheck( true );
RecordCheck<RelationshipRecord, ConsistencyReport.RelationshipConsistencyReport> relationshipChecker =
decorator.decorateRelationshipChecker( dummyRelationshipChecker() );
RecordAccessStub records = new RecordAccessStub();
RelationshipRecord relationship1 = records.add( inUse( new RelationshipRecord( 1, 0, 1, 0 ) ) );
relationship1.setNextProp( 7 );
RelationshipRecord relationship2 = records.add( inUse( new RelationshipRecord( 2, 0, 1, 0 ) ) );
relationship2.setNextProp( 8 );
// when
ConsistencyReport.RelationshipConsistencyReport report1 =
check( ConsistencyReport.RelationshipConsistencyReport.class,
relationshipChecker, relationship1, records );
ConsistencyReport.RelationshipConsistencyReport report2 =
check( ConsistencyReport.RelationshipConsistencyReport.class,
relationshipChecker, relationship2, records );
// then
verifyZeroInteractions( report1 );
verifyZeroInteractions( report2 );
}
@Test
public void shouldReportTwoNodesWithSamePropertyChain() throws Exception
{
// given
OwnerCheck decorator = new OwnerCheck( true );
RecordCheck<NodeRecord, ConsistencyReport.NodeConsistencyReport> nodeChecker =
decorator.decorateNodeChecker( dummyNodeCheck() );
RecordAccessStub records = new RecordAccessStub();
NodeRecord node1 = records.add( inUse( new NodeRecord( 1, NONE, 7 ) ) );
NodeRecord node2 = records.add( inUse( new NodeRecord( 2, NONE, 7 ) ) );
// when
ConsistencyReport.NodeConsistencyReport report1 =
check( ConsistencyReport.NodeConsistencyReport.class, nodeChecker, node1, records );
ConsistencyReport.NodeConsistencyReport report2 =
check( ConsistencyReport.NodeConsistencyReport.class, nodeChecker, node2, records );
// then
verifyZeroInteractions( report1 );
verify( report2 ).multipleOwners( node1 );
}
@Test
public void shouldReportTwoRelationshipsWithSamePropertyChain() throws Exception
{
// given
OwnerCheck decorator = new OwnerCheck( true );
RecordCheck<RelationshipRecord, ConsistencyReport.RelationshipConsistencyReport> relationshipChecker =
decorator.decorateRelationshipChecker( dummyRelationshipChecker() );
RecordAccessStub records = new RecordAccessStub();
RelationshipRecord relationship1 = records.add( inUse( new RelationshipRecord( 1, 0, 1, 0 ) ) );
relationship1.setNextProp( 7 );
RelationshipRecord relationship2 = records.add( inUse( new RelationshipRecord( 2, 0, 1, 0 ) ) );
relationship2.setNextProp( relationship1.getNextProp() );
// when
ConsistencyReport.RelationshipConsistencyReport report1 =
check( ConsistencyReport.RelationshipConsistencyReport.class,
relationshipChecker, relationship1, records );
ConsistencyReport.RelationshipConsistencyReport report2 =
check( ConsistencyReport.RelationshipConsistencyReport.class,
relationshipChecker, relationship2, records );
// then
verifyZeroInteractions( report1 );
verify( report2 ).multipleOwners( relationship1 );
}
@Test
public void shouldReportRelationshipWithSamePropertyChainAsNode() throws Exception
{
// given
OwnerCheck decorator = new OwnerCheck( true );
RecordCheck<NodeRecord, ConsistencyReport.NodeConsistencyReport> nodeChecker =
decorator.decorateNodeChecker( dummyNodeCheck() );
RecordCheck<RelationshipRecord, ConsistencyReport.RelationshipConsistencyReport> relationshipChecker =
decorator.decorateRelationshipChecker( dummyRelationshipChecker() );
RecordAccessStub records = new RecordAccessStub();
NodeRecord node = records.add( inUse( new NodeRecord( 1, NONE, 7 ) ) );
RelationshipRecord relationship = records.add( inUse( new RelationshipRecord( 1, 0, 1, 0 ) ) );
relationship.setNextProp( node.getNextProp() );
// when
ConsistencyReport.NodeConsistencyReport nodeReport =
check( ConsistencyReport.NodeConsistencyReport.class, nodeChecker, node, records );
ConsistencyReport.RelationshipConsistencyReport relationshipReport =
check( ConsistencyReport.RelationshipConsistencyReport.class,
relationshipChecker, relationship, records );
// then
verifyZeroInteractions( nodeReport );
verify( relationshipReport ).multipleOwners( node );
}
@Test
public void shouldReportRelationshipWithReferenceToTheGraphGlobalChain() throws Exception
{
// given
OwnerCheck decorator = new OwnerCheck( true );
RecordCheck<RelationshipRecord, ConsistencyReport.RelationshipConsistencyReport> relationshipChecker =
decorator.decorateRelationshipChecker( dummyRelationshipChecker() );
RecordCheck<NeoStoreRecord, ConsistencyReport.NeoStoreConsistencyReport> neoStoreCheck =
decorator.decorateNeoStoreChecker( dummyNeoStoreCheck() );
RecordAccessStub records = new RecordAccessStub();
NeoStoreRecord master = records.add( new NeoStoreRecord() );
master.setNextProp( 7 );
RelationshipRecord relationship = records.add( inUse( new RelationshipRecord( 1, 0, 1, 0 ) ) );
relationship.setNextProp( 7 );
// when
ConsistencyReport.NeoStoreConsistencyReport masterReport =
check( ConsistencyReport.NeoStoreConsistencyReport.class, neoStoreCheck, master, records );
ConsistencyReport.RelationshipConsistencyReport relationshipReport =
check( ConsistencyReport.RelationshipConsistencyReport.class,
relationshipChecker, relationship, records );
// then
verifyZeroInteractions( masterReport );
verify( relationshipReport ).multipleOwners( master );
}
@Test
public void shouldReportNodeWithSamePropertyChainAsRelationship() throws Exception
{
// given
OwnerCheck decorator = new OwnerCheck( true );
RecordCheck<NodeRecord, ConsistencyReport.NodeConsistencyReport> nodeChecker =
decorator.decorateNodeChecker( dummyNodeCheck() );
RecordCheck<RelationshipRecord, ConsistencyReport.RelationshipConsistencyReport> relationshipChecker =
decorator.decorateRelationshipChecker( dummyRelationshipChecker() );
RecordAccessStub records = new RecordAccessStub();
NodeRecord node = records.add( inUse( new NodeRecord( 1, NONE, 7 ) ) );
RelationshipRecord relationship = records.add( inUse( new RelationshipRecord( 1, 0, 1, 0 ) ) );
relationship.setNextProp( node.getNextProp() );
// when
ConsistencyReport.RelationshipConsistencyReport relationshipReport =
check( ConsistencyReport.RelationshipConsistencyReport.class,
relationshipChecker, relationship, records );
ConsistencyReport.NodeConsistencyReport nodeReport =
check( ConsistencyReport.NodeConsistencyReport.class, nodeChecker, node, records );
// then
verifyZeroInteractions( relationshipReport );
verify( nodeReport ).multipleOwners( relationship );
}
@Test
public void shouldReportNodeWithReferenceToTheGraphGlobalChain() throws Exception
{
// given
OwnerCheck decorator = new OwnerCheck( true );
RecordCheck<NodeRecord, ConsistencyReport.NodeConsistencyReport> nodeChecker =
decorator.decorateNodeChecker( dummyNodeCheck() );
RecordCheck<NeoStoreRecord, ConsistencyReport.NeoStoreConsistencyReport> neoStoreCheck =
decorator.decorateNeoStoreChecker( dummyNeoStoreCheck() );
RecordAccessStub records = new RecordAccessStub();
NodeRecord node = records.add( inUse( new NodeRecord( 1, NONE, 7 ) ) );
NeoStoreRecord master = records.add( new NeoStoreRecord() );
master.setNextProp( node.getNextProp() );
// when
ConsistencyReport.NeoStoreConsistencyReport masterReport =
check( ConsistencyReport.NeoStoreConsistencyReport.class, neoStoreCheck, master, records );
ConsistencyReport.NodeConsistencyReport nodeReport =
check( ConsistencyReport.NodeConsistencyReport.class, nodeChecker, node, records );
// then
verifyZeroInteractions( masterReport );
verify( nodeReport ).multipleOwners( master );
}
@Test
public void shouldReportNodeStoreReferencingSameChainAsNode() throws Exception
{
// given
OwnerCheck decorator = new OwnerCheck( true );
RecordCheck<NodeRecord, ConsistencyReport.NodeConsistencyReport> nodeChecker =
decorator.decorateNodeChecker( dummyNodeCheck() );
RecordCheck<NeoStoreRecord, ConsistencyReport.NeoStoreConsistencyReport> neoStoreCheck =
decorator.decorateNeoStoreChecker( dummyNeoStoreCheck() );
RecordAccessStub records = new RecordAccessStub();
NodeRecord node = records.add( inUse( new NodeRecord( 1, NONE, 7 ) ) );
NeoStoreRecord master = records.add( new NeoStoreRecord() );
master.setNextProp( node.getNextProp() );
// when
ConsistencyReport.NodeConsistencyReport nodeReport =
check( ConsistencyReport.NodeConsistencyReport.class, nodeChecker, node, records );
ConsistencyReport.NeoStoreConsistencyReport masterReport =
check( ConsistencyReport.NeoStoreConsistencyReport.class, neoStoreCheck, master, records );
// then
verifyZeroInteractions( nodeReport );
verify( masterReport ).multipleOwners( node );
}
@Test
public void shouldReportNodeStoreReferencingSameChainAsRelationship() throws Exception
{
// given
OwnerCheck decorator = new OwnerCheck( true );
RecordCheck<RelationshipRecord, ConsistencyReport.RelationshipConsistencyReport> relationshipChecker =
decorator.decorateRelationshipChecker( dummyRelationshipChecker() );
RecordCheck<NeoStoreRecord, ConsistencyReport.NeoStoreConsistencyReport> neoStoreCheck =
decorator.decorateNeoStoreChecker( dummyNeoStoreCheck() );
RecordAccessStub records = new RecordAccessStub();
NeoStoreRecord master = records.add( new NeoStoreRecord() );
master.setNextProp( 7 );
RelationshipRecord relationship = records.add( inUse( new RelationshipRecord( 1, 0, 1, 0 ) ) );
relationship.setNextProp( 7 );
// when
ConsistencyReport.RelationshipConsistencyReport relationshipReport =
check( ConsistencyReport.RelationshipConsistencyReport.class,
relationshipChecker, relationship, records );
ConsistencyReport.NeoStoreConsistencyReport masterReport =
check( ConsistencyReport.NeoStoreConsistencyReport.class, neoStoreCheck, master, records );
// then
verifyZeroInteractions( relationshipReport );
verify( masterReport ).multipleOwners( relationship );
}
@Test
public void shouldReportOrphanPropertyChain() throws Exception
{
// given
RecordAccessStub records = new RecordAccessStub();
OwnerCheck decorator = new OwnerCheck( true );
RecordCheck<PropertyRecord, ConsistencyReport.PropertyConsistencyReport> checker = decorator
.decoratePropertyChecker( dummyPropertyChecker() );
PropertyRecord record = inUse( new PropertyRecord( 42 ) );
ConsistencyReport.PropertyConsistencyReport report = check(
ConsistencyReport.PropertyConsistencyReport.class, checker, record, records );
// when
decorator.scanForOrphanChains( ProgressMonitorFactory.NONE );
records.checkDeferred();
// then
verify( report ).orphanPropertyChain();
}
@Test
public void shouldNotReportOrphanIfOwnedByNode() throws Exception
{
// given
RecordAccessStub records = new RecordAccessStub();
OwnerCheck decorator = new OwnerCheck( true );
PropertyRecord record = inUse( new PropertyRecord( 42 ) );
ConsistencyReport.PropertyConsistencyReport report =
check( ConsistencyReport.PropertyConsistencyReport.class,
decorator.decoratePropertyChecker( dummyPropertyChecker() ),
record, records );
ConsistencyReport.NodeConsistencyReport nodeReport =
check( ConsistencyReport.NodeConsistencyReport.class,
decorator.decorateNodeChecker( dummyNodeCheck() ),
inUse( new NodeRecord( 10, NONE, 42 ) ), records );
// when
decorator.scanForOrphanChains( ProgressMonitorFactory.NONE );
records.checkDeferred();
// then
verifyOnlyReferenceDispatch( report );
verifyOnlyReferenceDispatch( nodeReport );
}
@Test
public void shouldNotReportOrphanIfOwnedByRelationship() throws Exception
{
// given
RecordAccessStub records = new RecordAccessStub();
OwnerCheck decorator = new OwnerCheck( true );
PropertyRecord record = inUse( new PropertyRecord( 42 ) );
ConsistencyReport.PropertyConsistencyReport report =
check( ConsistencyReport.PropertyConsistencyReport.class,
decorator.decoratePropertyChecker( dummyPropertyChecker() ),
record, records );
RelationshipRecord relationship = inUse( new RelationshipRecord( 10, 1, 1, 0 ) );
relationship.setNextProp( 42 );
ConsistencyReport.RelationshipConsistencyReport relationshipReport =
check( ConsistencyReport.RelationshipConsistencyReport.class,
decorator.decorateRelationshipChecker( dummyRelationshipChecker() ),
relationship, records );
// when
decorator.scanForOrphanChains( ProgressMonitorFactory.NONE );
records.checkDeferred();
// then
verifyOnlyReferenceDispatch( report );
verifyOnlyReferenceDispatch( relationshipReport );
}
@Test
public void shouldNotReportOrphanIfOwnedByNeoStore() throws Exception
{
// given
RecordAccessStub records = new RecordAccessStub();
OwnerCheck decorator = new OwnerCheck( true );
PropertyRecord record = inUse( new PropertyRecord( 42 ) );
ConsistencyReport.PropertyConsistencyReport report =
check( ConsistencyReport.PropertyConsistencyReport.class,
decorator.decoratePropertyChecker( dummyPropertyChecker() ),
record, records );
NeoStoreRecord master = inUse( new NeoStoreRecord() );
master.setNextProp( 42 );
ConsistencyReport.NeoStoreConsistencyReport masterReport =
check( ConsistencyReport.NeoStoreConsistencyReport.class,
decorator.decorateNeoStoreChecker( dummyNeoStoreCheck() ),
master, records );
// when
decorator.scanForOrphanChains( ProgressMonitorFactory.NONE );
records.checkDeferred();
// then
verifyOnlyReferenceDispatch( report );
verifyOnlyReferenceDispatch( masterReport );
}
@Test
public void shouldReportDynamicRecordOwnedByTwoOtherDynamicRecords() throws Exception
{
// given
RecordAccessStub records = new RecordAccessStub();
OwnerCheck decorator = new OwnerCheck( true, DynamicStore.STRING );
RecordCheck<DynamicRecord, ConsistencyReport.DynamicConsistencyReport> checker = decorator
.decorateDynamicChecker( RecordType.STRING_PROPERTY,
dummyDynamicCheck( configureDynamicStore( 50 ), DynamicStore.STRING ) );
DynamicRecord record1 = records.add( inUse( string( new DynamicRecord( 1 ) ) ) );
DynamicRecord record2 = records.add( inUse( string( new DynamicRecord( 2 ) ) ) );
DynamicRecord record3 = records.add( inUse( string( new DynamicRecord( 3 ) ) ) );
record1.setNextBlock( record3.getId() );
record2.setNextBlock( record3.getId() );
// when
ConsistencyReport.DynamicConsistencyReport report1 = check( ConsistencyReport.DynamicConsistencyReport.class,
checker, record1, records );
ConsistencyReport.DynamicConsistencyReport report2 = check( ConsistencyReport.DynamicConsistencyReport.class,
checker, record2, records );
// then
verifyOnlyReferenceDispatch( report1 );
verify( report2 ).nextMultipleOwners( record1 );
verifyOnlyReferenceDispatch( report2 );
}
@Test
public void shouldReportDynamicStringRecordOwnedByTwoPropertyRecords() throws Exception
{
// given
RecordAccessStub records = new RecordAccessStub();
OwnerCheck decorator = new OwnerCheck( true, DynamicStore.STRING );
RecordCheck<PropertyRecord, ConsistencyReport.PropertyConsistencyReport> propChecker = decorator
.decoratePropertyChecker( dummyPropertyChecker() );
DynamicRecord dynamic = records.add( inUse( string( new DynamicRecord( 42 ) ) ) );
PropertyRecord property1 = records.add( inUse( new PropertyRecord( 1 ) ) );
PropertyRecord property2 = records.add( inUse( new PropertyRecord( 2 ) ) );
PropertyIndexRecord key = records.add( inUse( new PropertyIndexRecord( 10 ) ) );
property1.addPropertyBlock( propertyBlock( key, PropertyType.STRING, dynamic.getId() ) );
property2.addPropertyBlock( propertyBlock( key, PropertyType.STRING, dynamic.getId() ) );
// when
ConsistencyReport.PropertyConsistencyReport report1 = check( ConsistencyReport.PropertyConsistencyReport.class,
propChecker, property1, records );
ConsistencyReport.PropertyConsistencyReport report2 = check( ConsistencyReport.PropertyConsistencyReport.class,
propChecker, property2, records );
// then
verifyOnlyReferenceDispatch( report1 );
verify( report2 ).stringMultipleOwners( property1 );
verifyOnlyReferenceDispatch( report2 );
}
@Test
public void shouldReportDynamicArrayRecordOwnedByTwoPropertyRecords() throws Exception
{
// given
RecordAccessStub records = new RecordAccessStub();
OwnerCheck decorator = new OwnerCheck( true, DynamicStore.ARRAY );
RecordCheck<PropertyRecord, ConsistencyReport.PropertyConsistencyReport> propChecker = decorator
.decoratePropertyChecker( dummyPropertyChecker() );
DynamicRecord dynamic = records.add( inUse( array( new DynamicRecord( 42 ) ) ) );
PropertyRecord property1 = records.add( inUse( new PropertyRecord( 1 ) ) );
PropertyRecord property2 = records.add( inUse( new PropertyRecord( 2 ) ) );
PropertyIndexRecord key = records.add( inUse( new PropertyIndexRecord( 10 ) ) );
property1.addPropertyBlock( propertyBlock( key, PropertyType.ARRAY, dynamic.getId() ) );
property2.addPropertyBlock( propertyBlock( key, PropertyType.ARRAY, dynamic.getId() ) );
// when
ConsistencyReport.PropertyConsistencyReport report1 = check( ConsistencyReport.PropertyConsistencyReport.class,
propChecker, property1, records );
ConsistencyReport.PropertyConsistencyReport report2 = check( ConsistencyReport.PropertyConsistencyReport.class,
propChecker, property2, records );
// then
verifyOnlyReferenceDispatch( report1 );
verify( report2 ).arrayMultipleOwners( property1 );
verifyOnlyReferenceDispatch( report2 );
}
@Test
public void shouldReportDynamicRecordOwnedByPropertyAndOtherDynamic() throws Exception
{
// given
RecordAccessStub records = new RecordAccessStub();
OwnerCheck decorator = new OwnerCheck( true, DynamicStore.STRING );
RecordCheck<DynamicRecord, ConsistencyReport.DynamicConsistencyReport> dynChecker = decorator
.decorateDynamicChecker( RecordType.STRING_PROPERTY,
dummyDynamicCheck( configureDynamicStore( 50 ), DynamicStore.STRING ) );
RecordCheck<PropertyRecord, ConsistencyReport.PropertyConsistencyReport> propChecker = decorator
.decoratePropertyChecker( dummyPropertyChecker() );
DynamicRecord owned = records.add( inUse( string( new DynamicRecord( 42 ) ) ) );
DynamicRecord dynamic = records.add( inUse( string( new DynamicRecord( 100 ) ) ) );
dynamic.setNextBlock( owned.getId() );
PropertyRecord property = records.add( inUse( new PropertyRecord( 1 ) ) );
PropertyIndexRecord key = records.add( inUse( new PropertyIndexRecord( 10 ) ) );
property.addPropertyBlock( propertyBlock( key, PropertyType.STRING, owned.getId() ) );
// when
ConsistencyReport.PropertyConsistencyReport propReport = check(
ConsistencyReport.PropertyConsistencyReport.class, propChecker, property, records );
ConsistencyReport.DynamicConsistencyReport dynReport = check(
ConsistencyReport.DynamicConsistencyReport.class, dynChecker, dynamic, records );
// then
verifyOnlyReferenceDispatch( propReport );
verify( dynReport ).nextMultipleOwners( property );
verifyOnlyReferenceDispatch( dynReport );
}
@Test
public void shouldReportDynamicStringRecordOwnedByOtherDynamicAndProperty() throws Exception
{
// given
RecordAccessStub records = new RecordAccessStub();
OwnerCheck decorator = new OwnerCheck( true, DynamicStore.STRING );
RecordCheck<DynamicRecord, ConsistencyReport.DynamicConsistencyReport> dynChecker = decorator
.decorateDynamicChecker( RecordType.STRING_PROPERTY,
dummyDynamicCheck( configureDynamicStore( 50 ), DynamicStore.STRING ) );
RecordCheck<PropertyRecord, ConsistencyReport.PropertyConsistencyReport> propChecker = decorator
.decoratePropertyChecker( dummyPropertyChecker() );
DynamicRecord owned = records.add( inUse( string( new DynamicRecord( 42 ) ) ) );
DynamicRecord dynamic = records.add( inUse( string( new DynamicRecord( 100 ) ) ) );
dynamic.setNextBlock( owned.getId() );
PropertyRecord property = records.add( inUse( new PropertyRecord( 1 ) ) );
PropertyIndexRecord key = records.add( inUse( new PropertyIndexRecord( 10 ) ) );
property.addPropertyBlock( propertyBlock( key, PropertyType.STRING, owned.getId() ) );
// when
ConsistencyReport.DynamicConsistencyReport dynReport = check(
ConsistencyReport.DynamicConsistencyReport.class, dynChecker, dynamic, records );
ConsistencyReport.PropertyConsistencyReport propReport = check(
ConsistencyReport.PropertyConsistencyReport.class, propChecker, property, records );
// then
verifyOnlyReferenceDispatch( dynReport );
verify( propReport ).stringMultipleOwners( dynamic );
verifyOnlyReferenceDispatch( dynReport );
}
@Test
public void shouldReportDynamicArrayRecordOwnedByOtherDynamicAndProperty() throws Exception
{
// given
RecordAccessStub records = new RecordAccessStub();
OwnerCheck decorator = new OwnerCheck( true, DynamicStore.ARRAY );
RecordCheck<DynamicRecord, ConsistencyReport.DynamicConsistencyReport> dynChecker = decorator
.decorateDynamicChecker( RecordType.ARRAY_PROPERTY,
dummyDynamicCheck( configureDynamicStore( 50 ), DynamicStore.ARRAY ) );
RecordCheck<PropertyRecord, ConsistencyReport.PropertyConsistencyReport> propChecker = decorator
.decoratePropertyChecker( dummyPropertyChecker() );
DynamicRecord owned = records.add( inUse( array( new DynamicRecord( 42 ) ) ) );
DynamicRecord dynamic = records.add( inUse( array( new DynamicRecord( 100 ) ) ) );
dynamic.setNextBlock( owned.getId() );
PropertyRecord property = records.add( inUse( new PropertyRecord( 1 ) ) );
PropertyIndexRecord key = records.add( inUse( new PropertyIndexRecord( 10 ) ) );
property.addPropertyBlock( propertyBlock( key, PropertyType.ARRAY, owned.getId() ) );
// when
ConsistencyReport.DynamicConsistencyReport dynReport = check(
ConsistencyReport.DynamicConsistencyReport.class, dynChecker, dynamic, records );
ConsistencyReport.PropertyConsistencyReport propReport = check(
ConsistencyReport.PropertyConsistencyReport.class, propChecker, property, records );
// then
verifyOnlyReferenceDispatch( dynReport );
verify( propReport ).arrayMultipleOwners( dynamic );
verifyOnlyReferenceDispatch( dynReport );
}
@Test
public void shouldReportDynamicRecordOwnedByTwoRelationshipLabels() throws Exception
{
// given
RecordAccessStub records = new RecordAccessStub();
OwnerCheck decorator = new OwnerCheck( true, DynamicStore.RELATIONSHIP_LABEL );
RecordCheck<RelationshipTypeRecord, ConsistencyReport.LabelConsistencyReport> checker =
decorator.decorateLabelChecker( dummyRelationshipLabelCheck() );
DynamicRecord dynamic = records.addLabelName( inUse( string( new DynamicRecord( 42 ) ) ) );
RelationshipTypeRecord record1 = records.add( inUse( new RelationshipTypeRecord( 1 ) ) );
RelationshipTypeRecord record2 = records.add( inUse( new RelationshipTypeRecord( 2 ) ) );
record1.setNameId( (int) dynamic.getId() );
record2.setNameId( (int) dynamic.getId() );
// when
ConsistencyReport.LabelConsistencyReport report1 = check( ConsistencyReport.LabelConsistencyReport.class,
checker,record1, records );
ConsistencyReport.LabelConsistencyReport report2 = check( ConsistencyReport.LabelConsistencyReport.class,
checker,record2, records );
// then
verifyOnlyReferenceDispatch( report1 );
verify( report2 ).nameMultipleOwners( record1 );
verifyOnlyReferenceDispatch( report2 );
}
@Test
public void shouldReportDynamicRecordOwnedByRelationshipLabelAndOtherDynamicRecord() throws Exception
{
// given
RecordAccessStub records = new RecordAccessStub();
OwnerCheck decorator = new OwnerCheck( true, DynamicStore.RELATIONSHIP_LABEL );
RecordCheck<DynamicRecord, ConsistencyReport.DynamicConsistencyReport> dynChecker =
decorator.decorateDynamicChecker(
RecordType.RELATIONSHIP_LABEL_NAME,
dummyDynamicCheck( configureDynamicStore( 50 ), DynamicStore.RELATIONSHIP_LABEL ) );
RecordCheck<RelationshipTypeRecord, ConsistencyReport.LabelConsistencyReport> labelCheck =
decorator.decorateLabelChecker( dummyRelationshipLabelCheck() );
DynamicRecord owned = records.addLabelName( inUse( string( new DynamicRecord( 42 ) ) ) );
DynamicRecord dynamic = records.addLabelName( inUse( string( new DynamicRecord( 1 ) ) ) );
RelationshipTypeRecord label = records.add( inUse( new RelationshipTypeRecord( 1 ) ) );
dynamic.setNextBlock( owned.getId() );
label.setNameId( (int) owned.getId() );
// when
ConsistencyReport.LabelConsistencyReport labelReport = check( ConsistencyReport.LabelConsistencyReport.class,
labelCheck, label, records );
ConsistencyReport.DynamicConsistencyReport dynReport = check( ConsistencyReport.DynamicConsistencyReport.class,
dynChecker, dynamic, records );
// then
verifyOnlyReferenceDispatch( labelReport );
verify( dynReport ).nextMultipleOwners( label );
verifyOnlyReferenceDispatch( dynReport );
}
@Test
public void shouldReportDynamicRecordOwnedByOtherDynamicRecordAndRelationshipLabel() throws Exception
{
// given
RecordAccessStub records = new RecordAccessStub();
OwnerCheck decorator = new OwnerCheck( true, DynamicStore.RELATIONSHIP_LABEL );
RecordCheck<DynamicRecord, ConsistencyReport.DynamicConsistencyReport> dynChecker =
decorator.decorateDynamicChecker(
RecordType.RELATIONSHIP_LABEL_NAME,
dummyDynamicCheck( configureDynamicStore( 50 ), DynamicStore.RELATIONSHIP_LABEL ) );
RecordCheck<RelationshipTypeRecord, ConsistencyReport.LabelConsistencyReport> labelCheck =
decorator.decorateLabelChecker( dummyRelationshipLabelCheck() );
DynamicRecord owned = records.addLabelName( inUse( string( new DynamicRecord( 42 ) ) ) );
DynamicRecord dynamic = records.addLabelName( inUse( string( new DynamicRecord( 1 ) ) ) );
RelationshipTypeRecord label = records.add( inUse( new RelationshipTypeRecord( 1 ) ) );
dynamic.setNextBlock( owned.getId() );
label.setNameId( (int) owned.getId() );
// when
ConsistencyReport.DynamicConsistencyReport dynReport = check( ConsistencyReport.DynamicConsistencyReport.class,
dynChecker, dynamic, records );
ConsistencyReport.LabelConsistencyReport labelReport = check( ConsistencyReport.LabelConsistencyReport.class,
labelCheck, label, records );
// then
verifyOnlyReferenceDispatch( dynReport );
verify( labelReport ).nameMultipleOwners( dynamic );
verifyOnlyReferenceDispatch( labelReport );
}
@Test
public void shouldReportDynamicRecordOwnedByTwoPropertyKeys() throws Exception
{
// given
RecordAccessStub records = new RecordAccessStub();
OwnerCheck decorator = new OwnerCheck( true, DynamicStore.PROPERTY_KEY );
RecordCheck<PropertyIndexRecord, ConsistencyReport.PropertyKeyConsistencyReport> checker =
decorator.decoratePropertyKeyChecker( dummyPropertyKeyCheck() );
DynamicRecord dynamic = records.addKeyName( inUse( string( new DynamicRecord( 42 ) ) ) );
PropertyIndexRecord record1 = records.add( inUse( new PropertyIndexRecord( 1 ) ) );
PropertyIndexRecord record2 = records.add( inUse( new PropertyIndexRecord( 2 ) ) );
record1.setNameId( (int) dynamic.getId() );
record2.setNameId( (int) dynamic.getId() );
// when
ConsistencyReport.PropertyKeyConsistencyReport report1 = check(
ConsistencyReport.PropertyKeyConsistencyReport.class, checker,record1, records );
ConsistencyReport.PropertyKeyConsistencyReport report2 = check(
ConsistencyReport.PropertyKeyConsistencyReport.class, checker,record2, records );
// then
verifyOnlyReferenceDispatch( report1 );
verify( report2 ).nameMultipleOwners( record1 );
verifyOnlyReferenceDispatch( report2 );
}
@Test
public void shouldReportDynamicRecordOwnedByPropertyKeyAndOtherDynamicRecord() throws Exception
{
// given
RecordAccessStub records = new RecordAccessStub();
OwnerCheck decorator = new OwnerCheck( true, DynamicStore.PROPERTY_KEY );
RecordCheck<DynamicRecord, ConsistencyReport.DynamicConsistencyReport> dynChecker =
decorator.decorateDynamicChecker(
RecordType.PROPERTY_KEY_NAME,
dummyDynamicCheck( configureDynamicStore( 50 ), DynamicStore.PROPERTY_KEY ) );
RecordCheck<PropertyIndexRecord, ConsistencyReport.PropertyKeyConsistencyReport> keyCheck =
decorator.decoratePropertyKeyChecker( dummyPropertyKeyCheck() );
DynamicRecord owned = records.addKeyName( inUse( string( new DynamicRecord( 42 ) ) ) );
DynamicRecord dynamic = records.addKeyName( inUse( string( new DynamicRecord( 1 ) ) ) );
PropertyIndexRecord key = records.add( inUse( new PropertyIndexRecord( 1 ) ) );
dynamic.setNextBlock( owned.getId() );
key.setNameId( (int) owned.getId() );
// when
ConsistencyReport.PropertyKeyConsistencyReport keyReport = check(
ConsistencyReport.PropertyKeyConsistencyReport.class, keyCheck, key, records );
ConsistencyReport.DynamicConsistencyReport dynReport = check(
ConsistencyReport.DynamicConsistencyReport.class, dynChecker, dynamic, records );
// then
verifyOnlyReferenceDispatch( keyReport );
verify( dynReport ).nextMultipleOwners( key );
verifyOnlyReferenceDispatch( dynReport );
}
@Test
public void shouldReportDynamicRecordOwnedByOtherDynamicRecordAndPropertyKey() throws Exception
{
// given
RecordAccessStub records = new RecordAccessStub();
OwnerCheck decorator = new OwnerCheck( true, DynamicStore.PROPERTY_KEY );
RecordCheck<DynamicRecord, ConsistencyReport.DynamicConsistencyReport> dynChecker =
decorator.decorateDynamicChecker(
RecordType.PROPERTY_KEY_NAME,
dummyDynamicCheck( configureDynamicStore( 50 ), DynamicStore.PROPERTY_KEY ) );
RecordCheck<PropertyIndexRecord, ConsistencyReport.PropertyKeyConsistencyReport> keyCheck =
decorator.decoratePropertyKeyChecker( dummyPropertyKeyCheck() );
DynamicRecord owned = records.addKeyName( inUse( string( new DynamicRecord( 42 ) ) ) );
DynamicRecord dynamic = records.addKeyName( inUse( string( new DynamicRecord( 1 ) ) ) );
PropertyIndexRecord key = records.add( inUse( new PropertyIndexRecord( 1 ) ) );
dynamic.setNextBlock( owned.getId() );
key.setNameId( (int) owned.getId() );
// when
ConsistencyReport.DynamicConsistencyReport dynReport = check(
ConsistencyReport.DynamicConsistencyReport.class,dynChecker, dynamic, records );
ConsistencyReport.PropertyKeyConsistencyReport keyReport = check(
ConsistencyReport.PropertyKeyConsistencyReport.class, keyCheck, key, records );
// then
verifyOnlyReferenceDispatch( dynReport );
verify( keyReport ).nameMultipleOwners( dynamic );
verifyOnlyReferenceDispatch( keyReport );
}
@Test
public void shouldReportOrphanedDynamicStringRecord() throws Exception
{
// given
RecordAccessStub records = new RecordAccessStub();
OwnerCheck owners = new OwnerCheck( true, DynamicStore.STRING );
RecordCheck<DynamicRecord, ConsistencyReport.DynamicConsistencyReport> stringCheck =
owners.decorateDynamicChecker( RecordType.STRING_PROPERTY,
dummyDynamicCheck( configureDynamicStore( 60 ),
DynamicStore.STRING ) );
DynamicRecord record = string( inUse( new DynamicRecord( 42 ) ) );
// when
ConsistencyReport.DynamicConsistencyReport report = check( ConsistencyReport.DynamicConsistencyReport.class,
stringCheck, record, records );
owners.scanForOrphanChains( ProgressMonitorFactory.NONE );
records.checkDeferred();
// then
verify( report ).orphanDynamicRecord();
}
@Test
public void shouldReportOrphanedDynamicArrayRecord() throws Exception
{
// given
RecordAccessStub records = new RecordAccessStub();
OwnerCheck owners = new OwnerCheck( true, DynamicStore.ARRAY );
RecordCheck<DynamicRecord, ConsistencyReport.DynamicConsistencyReport> stringCheck =
owners.decorateDynamicChecker( RecordType.ARRAY_PROPERTY,
dummyDynamicCheck( configureDynamicStore( 60 ),
DynamicStore.ARRAY ) );
DynamicRecord record = string( inUse( new DynamicRecord( 42 ) ) );
// when
ConsistencyReport.DynamicConsistencyReport report = check( ConsistencyReport.DynamicConsistencyReport.class,
stringCheck, record, records );
owners.scanForOrphanChains( ProgressMonitorFactory.NONE );
records.checkDeferred();
// then
verify( report ).orphanDynamicRecord();
}
@Test
public void shouldReportOrphanedDynamicRelationshipLabelRecord() throws Exception
{
// given
RecordAccessStub records = new RecordAccessStub();
OwnerCheck owners = new OwnerCheck( true, DynamicStore.RELATIONSHIP_LABEL );
RecordCheck<DynamicRecord, ConsistencyReport.DynamicConsistencyReport> stringCheck =
owners.decorateDynamicChecker( RecordType.RELATIONSHIP_LABEL_NAME,
dummyDynamicCheck( configureDynamicStore( 60 ),
DynamicStore.RELATIONSHIP_LABEL ) );
DynamicRecord record = string( inUse( new DynamicRecord( 42 ) ) );
// when
ConsistencyReport.DynamicConsistencyReport report = check( ConsistencyReport.DynamicConsistencyReport.class,
stringCheck, record, records );
owners.scanForOrphanChains( ProgressMonitorFactory.NONE );
records.checkDeferred();
// then
verify( report ).orphanDynamicRecord();
}
@Test
public void shouldReportOrphanedDynamicPropertyKeyRecord() throws Exception
{
// given
RecordAccessStub records = new RecordAccessStub();
OwnerCheck owners = new OwnerCheck( true, DynamicStore.PROPERTY_KEY );
RecordCheck<DynamicRecord, ConsistencyReport.DynamicConsistencyReport> stringCheck =
owners.decorateDynamicChecker( RecordType.PROPERTY_KEY_NAME,
dummyDynamicCheck( configureDynamicStore( 60 ),
DynamicStore.PROPERTY_KEY ) );
DynamicRecord record = string( inUse( new DynamicRecord( 42 ) ) );
// when
ConsistencyReport.DynamicConsistencyReport report = check( ConsistencyReport.DynamicConsistencyReport.class,
stringCheck, record, records );
owners.scanForOrphanChains( ProgressMonitorFactory.NONE );
records.checkDeferred();
// then
verify( report ).orphanDynamicRecord();
}
}