From afc9c96aa27304bb5dd2e3ce0f2e2e9ba6cd8fe9 Mon Sep 17 00:00:00 2001 From: fickludd Date: Fri, 13 Oct 2017 14:09:01 +0200 Subject: [PATCH] Change NeoLE tests to extend Kernel API tests --- .../kernel/api/PropertyCursorTestBase.java | 45 ++- .../RelationshipTraversalCursorTestBase.java | 17 +- enterprise/runtime/neole/pom.xml | 7 + .../store/prototype/neole/NeoLEKernel.java | 78 +++++ .../prototype/neole/NeoLETransaction.java | 94 ++++++ .../store/prototype/neole/ReadStore.java | 62 +--- .../DeepRelationshipTraversalCursorTest.java | 130 +------- .../store/prototype/neole/GraphSetup.java | 309 ------------------ .../prototype/neole/NeoLETestSupport.java | 85 +++++ .../store/prototype/neole/NodeCursorTest.java | 201 +----------- .../prototype/neole/PropertyCursorTest.java | 188 +---------- ...RandomRelationshipTraversalCursorTest.java | 105 +----- .../neole/RelationshipScanCursorTest.java | 194 +---------- .../RelationshipTraversalCursorTest.java | 229 +------------ .../store/prototype/neole/TestResource.java | 62 ---- 15 files changed, 359 insertions(+), 1447 deletions(-) create mode 100644 enterprise/runtime/neole/src/main/java/org/neo4j/internal/store/prototype/neole/NeoLEKernel.java create mode 100644 enterprise/runtime/neole/src/main/java/org/neo4j/internal/store/prototype/neole/NeoLETransaction.java delete mode 100644 enterprise/runtime/neole/src/test/java/org/neo4j/internal/store/prototype/neole/GraphSetup.java create mode 100644 enterprise/runtime/neole/src/test/java/org/neo4j/internal/store/prototype/neole/NeoLETestSupport.java delete mode 100644 enterprise/runtime/neole/src/test/java/org/neo4j/internal/store/prototype/neole/TestResource.java diff --git a/community/kernel-api/src/test/java/org/neo4j/internal/kernel/api/PropertyCursorTestBase.java b/community/kernel-api/src/test/java/org/neo4j/internal/kernel/api/PropertyCursorTestBase.java index 2ecd63ae76978..22a1e0a9aa829 100644 --- a/community/kernel-api/src/test/java/org/neo4j/internal/kernel/api/PropertyCursorTestBase.java +++ b/community/kernel-api/src/test/java/org/neo4j/internal/kernel/api/PropertyCursorTestBase.java @@ -40,6 +40,7 @@ public abstract class PropertyCursorTestBase extends KernelAPIReadTestBase { + @SuppressWarnings( "SpellCheckingInspection" ) private static final String LONG_STRING = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque " + "eget nibh cursus, efficitur risus non, ultrices justo. Nulla laoreet eros mi, non molestie magna " + "luctus in. Fusce nibh neque, tristique ultrices laoreet et, aliquet non dolor. Donec ultrices nisi " @@ -76,11 +77,18 @@ public abstract class PropertyCursorTestBase + "Proin massa enim, accumsan ac libero at, iaculis sodales tellus. Vivamus fringilla justo sed luctus " + "tincidunt. Sed placerat fringilla ex, vel placerat sem faucibus eget. Vestibulum semper dui sit amet " + "efficitur blandit. Donec eu tellus velit. Etiam a mi nec massa euismod posuere. Cras eget lacus leo."; + private static long bare, byteProp, shortProp, intProp, inlineLongProp, longProp, floatProp, doubleProp, trueProp, falseProp, charProp, emptyStringProp, shortStringProp, longStringProp, utf8Prop, smallArray, bigArray, allProps; + private static String chinese = "造Unicode之"; + protected boolean supportsBigProperties() + { + return true; + } + @Override void createTestGraph( GraphDatabaseService graphDb ) { @@ -127,11 +135,17 @@ void createTestGraph( GraphDatabaseService graphDb ) all.setProperty( "charProp", 'x' ); all.setProperty( "emptyStringProp", "" ); all.setProperty( "shortStringProp", "hello" ); - all.setProperty( "longStringProp", LONG_STRING ); + if ( supportsBigProperties() ) + { + all.setProperty( "longStringProp", LONG_STRING ); + } all.setProperty( "utf8Prop", chinese ); - all.setProperty( "smallArray", new int[] {1, 2, 3, 4} ); - all.setProperty( "bigArray", new String[] {LONG_STRING} ); + if ( supportsBigProperties() ) + { + all.setProperty( "smallArray", new int[] {1, 2, 3, 4} ); + all.setProperty( "bigArray", new String[] {LONG_STRING} ); + } allProps = all.getId(); @@ -183,10 +197,16 @@ public void shouldAccessSingleProperty() throws Exception assertAccessSingleProperty( charProp, Values.of( 'x' ) ); assertAccessSingleProperty( emptyStringProp, Values.of( "" ) ); assertAccessSingleProperty( shortStringProp, Values.of( "hello" ) ); - assertAccessSingleProperty( longStringProp, Values.of( LONG_STRING ) ); + if ( supportsBigProperties() ) + { + assertAccessSingleProperty( longStringProp, Values.of( LONG_STRING ) ); + } assertAccessSingleProperty( utf8Prop, Values.of( chinese ) ); - assertAccessSingleProperty( smallArray, Values.of( new int[] {1, 2, 3, 4} ) ); - assertAccessSingleProperty( bigArray, Values.of( new String[] {LONG_STRING} ) ); + if ( supportsBigProperties() ) + { + assertAccessSingleProperty( smallArray, Values.of( new int[] {1, 2, 3, 4} ) ); + assertAccessSingleProperty( bigArray, Values.of( new String[] {LONG_STRING} ) ); + } } @Test @@ -220,12 +240,15 @@ public void shouldAccessAllNodeProperties() throws Exception assertTrue( "charProp", values.contains( 'x' ) ); assertTrue( "emptyStringProp", values.contains( "" ) ); assertTrue( "shortStringProp", values.contains( "hello" ) ); - assertTrue( "longStringProp", values.contains( LONG_STRING ) ); assertTrue( "utf8Prop", values.contains( chinese ) ); - assertThat( "smallArray", values, hasItem( intArray( 1, 2, 3, 4 ) ) ); - assertThat( "bigArray", values, hasItem( arrayContaining( LONG_STRING ) ) ); - - assertEquals( "number of values", 16, values.size() ); + if ( supportsBigProperties() ) + { + assertTrue( "longStringProp", values.contains( LONG_STRING ) ); + assertThat( "smallArray", values, hasItem( intArray( 1, 2, 3, 4 ) ) ); + assertThat( "bigArray", values, hasItem( arrayContaining( LONG_STRING ) ) ); + } + int expected = supportsBigProperties() ? 16 : 13; + assertEquals( "number of values", expected, values.size() ); } } diff --git a/community/kernel-api/src/test/java/org/neo4j/internal/kernel/api/RelationshipTraversalCursorTestBase.java b/community/kernel-api/src/test/java/org/neo4j/internal/kernel/api/RelationshipTraversalCursorTestBase.java index 57f8c020f1438..8d8a362f4caf2 100644 --- a/community/kernel-api/src/test/java/org/neo4j/internal/kernel/api/RelationshipTraversalCursorTestBase.java +++ b/community/kernel-api/src/test/java/org/neo4j/internal/kernel/api/RelationshipTraversalCursorTestBase.java @@ -23,6 +23,7 @@ import java.util.Map; import java.util.function.Consumer; +import org.junit.Assume; import org.junit.Test; import org.neo4j.graphdb.GraphDatabaseService; @@ -42,6 +43,16 @@ public abstract class RelationshipTraversalCursorTestBase${project.version} test + + org.neo4j + neo4j-kernel-api + ${project.version} + test + test-jar + org.neo4j neo4j-lucene-index diff --git a/enterprise/runtime/neole/src/main/java/org/neo4j/internal/store/prototype/neole/NeoLEKernel.java b/enterprise/runtime/neole/src/main/java/org/neo4j/internal/store/prototype/neole/NeoLEKernel.java new file mode 100644 index 0000000000000..f676f7c3f0747 --- /dev/null +++ b/enterprise/runtime/neole/src/main/java/org/neo4j/internal/store/prototype/neole/NeoLEKernel.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2002-2017 "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 . + */ +package org.neo4j.internal.store.prototype.neole; + +import java.io.IOException; + +import org.neo4j.internal.kernel.api.Kernel; +import org.neo4j.internal.kernel.api.Permissions; +import org.neo4j.internal.kernel.api.Session; +import org.neo4j.internal.kernel.api.Token; +import org.neo4j.internal.kernel.api.Transaction; + +public class NeoLEKernel implements Kernel +{ + private final CursorFactory cursorFactory; + private final ReadStore readStore; + + public NeoLEKernel( ReadStore readStore ) + { + this.readStore = readStore; + this.cursorFactory = new CursorFactory( readStore ); + } + + @Override + public CursorFactory cursors() + { + return cursorFactory; + } + + @Override + public Session beginSession( Permissions permissions ) + { + return new Session() + { + + @Override + public Transaction beginTransaction() + { + try + { + return new NeoLETransaction( readStore ); + } + catch ( IOException e ) + { + throw new RuntimeException( "failed" ); + } + } + + @Override + public Token token() + { + return null; + } + + @Override + public void close() + { + } + }; + } +} diff --git a/enterprise/runtime/neole/src/main/java/org/neo4j/internal/store/prototype/neole/NeoLETransaction.java b/enterprise/runtime/neole/src/main/java/org/neo4j/internal/store/prototype/neole/NeoLETransaction.java new file mode 100644 index 0000000000000..dda11302f1176 --- /dev/null +++ b/enterprise/runtime/neole/src/main/java/org/neo4j/internal/store/prototype/neole/NeoLETransaction.java @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2002-2017 "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 . + */ +package org.neo4j.internal.store.prototype.neole; + +import java.io.IOException; + +import org.neo4j.internal.kernel.api.ExplicitIndexRead; +import org.neo4j.internal.kernel.api.ExplicitIndexWrite; +import org.neo4j.internal.kernel.api.Locks; +import org.neo4j.internal.kernel.api.Read; +import org.neo4j.internal.kernel.api.SchemaRead; +import org.neo4j.internal.kernel.api.SchemaWrite; +import org.neo4j.internal.kernel.api.Write; + +public class NeoLETransaction implements org.neo4j.internal.kernel.api.Transaction +{ + private final ReadStore read; + + public NeoLETransaction( ReadStore read ) throws IOException + { + this.read = read; + } + + @Override + public long commit() + { + return 0; + } + + @Override + public void rollback() + { + + } + + @Override + public Read dataRead() + { + return read; + } + + @Override + public Write dataWrite() + { + return null; + } + + @Override + public ExplicitIndexRead indexRead() + { + return null; + } + + @Override + public ExplicitIndexWrite indexWrite() + { + return null; + } + + @Override + public SchemaRead schemaRead() + { + return null; + } + + @Override + public SchemaWrite schemaWrite() + { + return null; + } + + @Override + public Locks locks() + { + return null; + } +} diff --git a/enterprise/runtime/neole/src/main/java/org/neo4j/internal/store/prototype/neole/ReadStore.java b/enterprise/runtime/neole/src/main/java/org/neo4j/internal/store/prototype/neole/ReadStore.java index 3a48fc8dd4191..f80990f7c97a2 100644 --- a/enterprise/runtime/neole/src/main/java/org/neo4j/internal/store/prototype/neole/ReadStore.java +++ b/enterprise/runtime/neole/src/main/java/org/neo4j/internal/store/prototype/neole/ReadStore.java @@ -190,83 +190,31 @@ public void relationshipProperties( long reference, org.neo4j.internal.kernel.ap } @Override - public void futureNodeReferenceRead( long reference ) - { - throw new UnsupportedOperationException( "not implemented" ); - } - - @Override - public void futureRelationshipsReferenceRead( long reference ) - { - throw new UnsupportedOperationException( "not implemented" ); - } - - @Override - public void futureNodePropertyReferenceRead( long reference ) - { - throw new UnsupportedOperationException( "not implemented" ); - } - - @Override - public void futureRelationshipPropertyReferenceRead( long reference ) - { - throw new UnsupportedOperationException( "not implemented" ); - } - - @Override - public IndexReference index( int label, int... properties ) + public void graphProperties( org.neo4j.internal.kernel.api.PropertyCursor cursor ) { throw new UnsupportedOperationException( "not implemented" ); } @Override - public int nodeLabel( String name ) - { - throw new UnsupportedOperationException( "not implemented" ); - } - - @Override - public int propertyKey( String name ) - { - throw new UnsupportedOperationException( "not implemented" ); - } - - @Override - public void nodeExplicitIndexLookup( - NodeExplicitIndexCursor cursor, String index, String key, Value value ) - { - throw new UnsupportedOperationException( "not implemented" ); - } - - @Override - public void nodeExplicitIndexQuery( NodeExplicitIndexCursor cursor, String index, Object query ) - { - throw new UnsupportedOperationException( "not implemented" ); - } - - @Override - public void nodeExplicitIndexQuery( NodeExplicitIndexCursor cursor, String index, String key, Object query ) + public void futureNodeReferenceRead( long reference ) { throw new UnsupportedOperationException( "not implemented" ); } @Override - public void relationshipExplicitIndexGet( - RelationshipExplicitIndexCursor cursor, String index, String key, Value value, long source, long target ) + public void futureRelationshipsReferenceRead( long reference ) { throw new UnsupportedOperationException( "not implemented" ); } @Override - public void relationshipExplicitIndexQuery( - RelationshipExplicitIndexCursor cursor, String index, Object query, long source, long target ) + public void futureNodePropertyReferenceRead( long reference ) { throw new UnsupportedOperationException( "not implemented" ); } @Override - public void relationshipExplicitIndexQuery( - RelationshipExplicitIndexCursor cursor, String index, String key, Object query, long source, long target ) + public void futureRelationshipPropertyReferenceRead( long reference ) { throw new UnsupportedOperationException( "not implemented" ); } diff --git a/enterprise/runtime/neole/src/test/java/org/neo4j/internal/store/prototype/neole/DeepRelationshipTraversalCursorTest.java b/enterprise/runtime/neole/src/test/java/org/neo4j/internal/store/prototype/neole/DeepRelationshipTraversalCursorTest.java index 6d1db2f60c7f7..10638b3050f28 100644 --- a/enterprise/runtime/neole/src/test/java/org/neo4j/internal/store/prototype/neole/DeepRelationshipTraversalCursorTest.java +++ b/enterprise/runtime/neole/src/test/java/org/neo4j/internal/store/prototype/neole/DeepRelationshipTraversalCursorTest.java @@ -19,133 +19,13 @@ */ package org.neo4j.internal.store.prototype.neole; -import org.junit.ClassRule; -import org.junit.Test; +import org.neo4j.internal.kernel.api.DeepRelationshipTraversalCursorTestBase; -import org.neo4j.collection.primitive.Primitive; -import org.neo4j.collection.primitive.PrimitiveLongSet; -import org.neo4j.graphdb.GraphDatabaseService; -import org.neo4j.graphdb.Node; -import org.neo4j.graphdb.RelationshipType; -import org.neo4j.graphdb.Transaction; -import org.neo4j.internal.kernel.api.NodeCursor; -import org.neo4j.internal.kernel.api.RelationshipGroupCursor; -import org.neo4j.internal.kernel.api.RelationshipTraversalCursor; - -import static org.hamcrest.CoreMatchers.equalTo; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.junit.Assume.assumeThat; -import static org.neo4j.graphdb.RelationshipType.withName; -import static org.neo4j.graphdb.factory.GraphDatabaseSettings.dense_node_threshold; - -public class DeepRelationshipTraversalCursorTest +public class DeepRelationshipTraversalCursorTest extends DeepRelationshipTraversalCursorTestBase { - private static long three_root; - private static int expected_total, expected_unique; - @ClassRule - public static final GraphSetup graph = new GraphSetup() - { - RelationshipType PARENT = withName( "PARENT" ); - - @Override - protected void create( GraphDatabaseService graphDb ) - { - try ( Transaction tx = graphDb.beginTx() ) - { - Node root = graphDb.createNode(); - three_root = root.getId(); - - Node[] leafs = new Node[32]; - for ( int i = 0; i < leafs.length; i++ ) - { - leafs[i] = graphDb.createNode(); - } - int offset = 0, duplicate = 12; - - Node interdup = graphDb.createNode(); - interdup.createRelationshipTo( root, PARENT ); - offset = relate( duplicate, leafs, offset, interdup ); - for ( int i = 0; i < 5; i++ ) - { - Node inter = graphDb.createNode(); - inter.createRelationshipTo( root, PARENT ); - offset = relate( 3 + i, leafs, offset, inter ); - } - interdup.createRelationshipTo( root, PARENT ); - for ( int i = 0; i < 4; i++ ) - { - Node inter = graphDb.createNode(); - inter.createRelationshipTo( root, PARENT ); - offset = relate( 2 + i, leafs, offset, inter ); - } - - Node inter = graphDb.createNode(); - inter.createRelationshipTo( root, PARENT ); - offset = relate( 1, leafs, offset, inter ); - - expected_total = offset + duplicate; - expected_unique = leafs.length; - - tx.success(); - } - } - - int relate( int count, Node[] selection, int offset, Node parent ) - { - for ( int i = 0; i < count; i++ ) - { - selection[offset++ % selection.length].createRelationshipTo( parent, PARENT ); - } - return offset; - } - }.withConfig( dense_node_threshold, "1" ); - - @Test - public void shouldTraverseTreeOfDepthThree() throws Exception + @Override + public NeoLETestSupport newTestSupport() { - assumeThat( "x86_64", equalTo( System.getProperty( "os.arch" ) ) ); - try ( NodeCursor node = graph.allocateNodeCursor(); - RelationshipGroupCursor group = graph.allocateRelationshipGroupCursor(); - RelationshipTraversalCursor relationship1 = graph.allocateRelationshipTraversalCursor(); - RelationshipTraversalCursor relationship2 = graph.allocateRelationshipTraversalCursor(); - PrimitiveLongSet leafs = Primitive.longSet() ) - { - long total = 0; - - // when - graph.singleNode( three_root, node ); - assertTrue( "access root node", node.next() ); - node.relationships( group ); - assertFalse( "single root", node.next() ); - - assertTrue( "access group of root", group.next() ); - group.incoming( relationship1 ); - assertFalse( "single group of root", group.next() ); - - while ( relationship1.next() ) - { - relationship1.neighbour( node ); - - assertTrue( "child level 1", node.next() ); - node.relationships( group ); - assertFalse( "single node", node.next() ); - - assertTrue( "group of level 1 child", group.next() ); - group.incoming( relationship2 ); - assertFalse( "single group of level 1 child", group.next() ); - - while ( relationship2.next() ) - { - leafs.add( relationship2.neighbourNodeReference() ); - total++; - } - } - - // then - assertEquals( "total number of leaf nodes", expected_total, total ); - assertEquals( "number of distinct leaf nodes", expected_unique, leafs.size() ); - } + return new NeoLETestSupport(); } } diff --git a/enterprise/runtime/neole/src/test/java/org/neo4j/internal/store/prototype/neole/GraphSetup.java b/enterprise/runtime/neole/src/test/java/org/neo4j/internal/store/prototype/neole/GraphSetup.java deleted file mode 100644 index e6b5dc0d65db4..0000000000000 --- a/enterprise/runtime/neole/src/test/java/org/neo4j/internal/store/prototype/neole/GraphSetup.java +++ /dev/null @@ -1,309 +0,0 @@ -/* - * Copyright (c) 2002-2017 "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 . - */ -package org.neo4j.internal.store.prototype.neole; - -import org.junit.rules.TemporaryFolder; -import org.junit.runner.Description; - -import java.io.IOException; -import java.util.HashMap; -import java.util.Map; - -import org.neo4j.graphdb.GraphDatabaseService; -import org.neo4j.graphdb.config.Setting; -import org.neo4j.graphdb.factory.GraphDatabaseBuilder; -import org.neo4j.graphdb.factory.GraphDatabaseFactory; -import org.neo4j.internal.kernel.api.IndexQuery; -import org.neo4j.internal.kernel.api.IndexReference; -import org.neo4j.internal.kernel.api.NodeCursor; -import org.neo4j.internal.kernel.api.NodeLabelIndexCursor; -import org.neo4j.internal.kernel.api.NodeExplicitIndexCursor; -import org.neo4j.internal.kernel.api.NodeValueIndexCursor; -import org.neo4j.internal.kernel.api.PropertyCursor; -import org.neo4j.internal.kernel.api.Read; -import org.neo4j.internal.kernel.api.RelationshipGroupCursor; -import org.neo4j.internal.kernel.api.RelationshipExplicitIndexCursor; -import org.neo4j.internal.kernel.api.RelationshipScanCursor; -import org.neo4j.internal.kernel.api.RelationshipTraversalCursor; -import org.neo4j.internal.kernel.api.Scan; - -public abstract class GraphSetup extends TestResource implements Read, org.neo4j.internal.kernel.api.CursorFactory -{ - private final TemporaryFolder folder = new TemporaryFolder(); - private ReadStore store; - private CursorFactory cursors; - private final Map,String> config = new HashMap<>(); - - @Override - protected void before( Description description ) throws IOException - { - folder.create(); - GraphDatabaseService graphDb = null; - try - { - GraphDatabaseBuilder builder = new GraphDatabaseFactory().newEmbeddedDatabaseBuilder( folder.getRoot() ); - for ( Map.Entry,String> conf : config.entrySet() ) - { - builder.setConfig( conf.getKey(), conf.getValue() ); - } - create( graphDb = builder.newGraphDatabase() ); - } - finally - { - if ( graphDb != null ) - { - graphDb.shutdown(); - } - } - store = new ReadStore( folder.getRoot() ); - cursors = new CursorFactory( store ); - } - - public final GraphSetup withConfig( Setting setting, String value ) - { - config.put( setting, value ); - return this; - } - - protected abstract void create( GraphDatabaseService graphDb ); - - @Override - protected void afterFailure( Description description, Throwable failure ) - { - after(); - } - - @Override - protected void afterSuccess( Description description ) - { - after(); - } - - private void after() - { - try - { - store.shutdown(); - folder.delete(); - cleanup(); - } - finally - { - cursors = null; - store = null; - } - } - - protected void cleanup() - { - } - - @Override - public void nodeIndexSeek( IndexReference index, NodeValueIndexCursor cursor, IndexQuery... query ) - { - store.nodeIndexSeek( index, cursor, query ); - } - - @Override - public void nodeIndexScan( IndexReference index, NodeValueIndexCursor cursor ) - { - store.nodeIndexScan( index, cursor ); - } - - @Override - public void nodeLabelScan( int label, NodeLabelIndexCursor cursor ) - { - store.nodeLabelScan( label, cursor ); - } - - @Override - public Scan nodeLabelScan( int label ) - { - return store.nodeLabelScan( label ); - } - - @Override - public void allNodesScan( NodeCursor cursor ) - { - store.allNodesScan( cursor ); - } - - @Override - public Scan allNodesScan() - { - return store.allNodesScan(); - } - - @Override - public void singleNode( long reference, NodeCursor cursor ) - { - store.singleNode( reference, cursor ); - } - - @Override - public void singleRelationship( long reference, RelationshipScanCursor cursor ) - { - store.singleRelationship( reference, cursor ); - } - - @Override - public void allRelationshipsScan( RelationshipScanCursor cursor ) - { - store.allRelationshipsScan( cursor ); - } - - @Override - public Scan allRelationshipsScan() - { - return store.allRelationshipsScan(); - } - - @Override - public void relationshipLabelScan( int label, RelationshipScanCursor cursor ) - { - store.relationshipLabelScan( label, cursor ); - } - - @Override - public Scan relationshipLabelScan( int label ) - { - return store.relationshipLabelScan( label ); - } - - @Override - public void relationshipGroups( long nodeReference, long reference, RelationshipGroupCursor cursor ) - { - store.relationshipGroups( nodeReference, reference, cursor ); - } - - @Override - public void relationships( long nodeReference, long reference, RelationshipTraversalCursor cursor ) - { - store.relationships( nodeReference, reference, cursor ); - } - - @Override - public void nodeProperties( long reference, PropertyCursor cursor ) - { - store.nodeProperties( reference, cursor ); - } - - @Override - public void relationshipProperties( long reference, PropertyCursor cursor ) - { - store.relationshipProperties( reference, cursor ); - } - - @Override - public void futureNodeReferenceRead( long reference ) - { - store.futureNodeReferenceRead( reference ); - } - - @Override - public void futureRelationshipsReferenceRead( long reference ) - { - store.futureRelationshipsReferenceRead( reference ); - } - - @Override - public void futureNodePropertyReferenceRead( long reference ) - { - store.futureNodePropertyReferenceRead( reference ); - } - - @Override - public void futureRelationshipPropertyReferenceRead( long reference ) - { - store.futureRelationshipPropertyReferenceRead( reference ); - } - - @Override - public IndexReference index( int label, int... properties ) - { - return store.index( label, properties ); - } - - @Override - public int nodeLabel( String name ) - { - return store.nodeLabel( name ); - } - - @Override - public int propertyKey( String name ) - { - return store.propertyKey( name ); - } - - @Override - public NodeCursor allocateNodeCursor() - { - return cursors.allocateNodeCursor(); - } - - @Override - public RelationshipScanCursor allocateRelationshipScanCursor() - { - return cursors.allocateRelationshipScanCursor(); - } - - @Override - public RelationshipTraversalCursor allocateRelationshipTraversalCursor() - { - return cursors.allocateRelationshipTraversalCursor(); - } - - @Override - public PropertyCursor allocatePropertyCursor() - { - return cursors.allocatePropertyCursor(); - } - - @Override - public RelationshipGroupCursor allocateRelationshipGroupCursor() - { - return cursors.allocateRelationshipGroupCursor(); - } - - @Override - public NodeValueIndexCursor allocateNodeValueIndexCursor() - { - return cursors.allocateNodeValueIndexCursor(); - } - - @Override - public NodeLabelIndexCursor allocateNodeLabelIndexCursor() - { - return cursors.allocateNodeLabelIndexCursor(); - } - - @Override - public NodeExplicitIndexCursor allocateNodeManualIndexCursor() - { - return cursors.allocateNodeManualIndexCursor(); - } - - @Override - public RelationshipExplicitIndexCursor allocateRelationshipManualIndexCursor() - { - return cursors.allocateRelationshipManualIndexCursor(); - } -} diff --git a/enterprise/runtime/neole/src/test/java/org/neo4j/internal/store/prototype/neole/NeoLETestSupport.java b/enterprise/runtime/neole/src/test/java/org/neo4j/internal/store/prototype/neole/NeoLETestSupport.java new file mode 100644 index 0000000000000..3b11c8b091c2e --- /dev/null +++ b/enterprise/runtime/neole/src/test/java/org/neo4j/internal/store/prototype/neole/NeoLETestSupport.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2002-2017 "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 . + */ +package org.neo4j.internal.store.prototype.neole; + +import java.io.File; +import java.io.IOException; +import java.util.function.Consumer; + +import org.neo4j.graphdb.GraphDatabaseService; +import org.neo4j.graphdb.factory.GraphDatabaseBuilder; +import org.neo4j.graphdb.factory.GraphDatabaseFactory; +import org.neo4j.internal.kernel.api.Kernel; +import org.neo4j.internal.kernel.api.KernelAPIReadTestSupport; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.junit.Assume.assumeThat; +import static org.neo4j.graphdb.factory.GraphDatabaseSettings.dense_node_threshold; + +public class NeoLETestSupport implements KernelAPIReadTestSupport +{ + private File storeDir; + + @Override + public void setup( File storeDir, Consumer create ) throws IOException + { + GraphDatabaseService graphDb = null; + try + { + GraphDatabaseBuilder builder = new GraphDatabaseFactory().newEmbeddedDatabaseBuilder( storeDir ); + builder.setConfig( dense_node_threshold, "1" ); + graphDb = builder.newGraphDatabase(); + create.accept( graphDb ); + } + finally + { + if ( graphDb != null ) + { + graphDb.shutdown(); + } + } + this.storeDir = storeDir; + } + + @Override + public void beforeEachTest() + { + assumeThat( "x86_64", equalTo( System.getProperty( "os.arch" ) ) ); + } + + @Override + public Kernel kernelToTest() + { + try + { + return new NeoLEKernel( new ReadStore( storeDir ) ); + } + catch ( IOException e ) + { + throw new RuntimeException( "Failed to start kernel", e ); + } + } + + @Override + public void tearDown() + { + // runtime is closed by test + } +} diff --git a/enterprise/runtime/neole/src/test/java/org/neo4j/internal/store/prototype/neole/NodeCursorTest.java b/enterprise/runtime/neole/src/test/java/org/neo4j/internal/store/prototype/neole/NodeCursorTest.java index 88a1dfc303ded..2d961d5bc6a42 100644 --- a/enterprise/runtime/neole/src/test/java/org/neo4j/internal/store/prototype/neole/NodeCursorTest.java +++ b/enterprise/runtime/neole/src/test/java/org/neo4j/internal/store/prototype/neole/NodeCursorTest.java @@ -19,204 +19,13 @@ */ package org.neo4j.internal.store.prototype.neole; -import org.junit.ClassRule; -import org.junit.Test; +import org.neo4j.internal.kernel.api.NodeCursorTestBase; -import java.util.ArrayList; -import java.util.List; - -import org.neo4j.graphdb.GraphDatabaseService; -import org.neo4j.graphdb.Node; -import org.neo4j.graphdb.Transaction; -import org.neo4j.internal.kernel.api.LabelSet; -import org.neo4j.internal.kernel.api.NodeCursor; - -import static org.hamcrest.CoreMatchers.equalTo; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertTrue; -import static org.junit.Assume.assumeThat; -import static org.neo4j.graphdb.Label.label; -import static org.neo4j.graphdb.factory.GraphDatabaseSettings.dense_node_threshold; - -public class NodeCursorTest +public class NodeCursorTest extends NodeCursorTestBase { - private static List NODE_IDS; - private static long foo, bar, baz, barbaz, bare, gone; - @ClassRule - public static final GraphSetup graph = new GraphSetup() - { - @Override - protected void create( GraphDatabaseService graphDb ) - { - Node deleted; - try ( Transaction tx = graphDb.beginTx() ) - { - foo = graphDb.createNode( label( "Foo" ) ).getId(); - bar = graphDb.createNode( label( "Bar" ) ).getId(); - baz = graphDb.createNode( label( "Baz" ) ).getId(); - barbaz = graphDb.createNode( label( "Bar" ), label( "Baz" ) ).getId(); - gone = (deleted = graphDb.createNode()).getId(); - bare = graphDb.createNode().getId(); - - tx.success(); - } - - try ( Transaction tx = graphDb.beginTx() ) - { - deleted.delete(); - - tx.success(); - } - - try ( Transaction tx = graphDb.beginTx() ) - { - NODE_IDS = new ArrayList<>(); - long time = System.nanoTime(); - for ( Node node : graphDb.getAllNodes() ) - { - NODE_IDS.add( node.getId() ); - } - time = System.nanoTime() - time; - System.out.printf( "neo4j scan time: %.3fms%n", time / 1_000_000.0 ); - tx.success(); - } - } - - @Override - protected void cleanup() - { - NODE_IDS = null; - } - } - .withConfig( dense_node_threshold, "1" ); - - @Test - public void shouldScanNodes() throws Exception + @Override + public NeoLETestSupport newTestSupport() { - // given - List ids = new ArrayList<>(); - try ( NodeCursor nodes = graph.allocateNodeCursor() ) - { - // when - long time = System.nanoTime(); - graph.allNodesScan( nodes ); - while ( nodes.next() ) - { - ids.add( nodes.nodeReference() ); - } - time = System.nanoTime() - time; - System.out.printf( "cursor scan time: %.3fms%n", time / 1_000_000.0 ); - } - - // then - assertEquals( NODE_IDS, ids ); - } - - @Test - public void shouldAccessNodesByReference() throws Exception - { - // given - try ( NodeCursor nodes = graph.allocateNodeCursor() ) - { - for ( long id : NODE_IDS ) - { - // when - graph.singleNode( id, nodes ); - - // then - assertTrue( "should access defined node", nodes.next() ); - assertEquals( "should access the correct node", id, nodes.nodeReference() ); - assertFalse( "should only access a single node", nodes.next() ); - } - } - } - - @Test - public void shouldNotFindDeletedNode() throws Exception - { - // given - try ( NodeCursor nodes = graph.allocateNodeCursor() ) - { - // when - graph.singleNode( gone, nodes ); - - // then - assertFalse( "should not access deleted node", nodes.next() ); - } - } - - @Test - public void shouldReadLabels() throws Exception - { - assumeThat( "x86_64", equalTo( System.getProperty( "os.arch" ) ) ); - - // given - try ( NodeCursor nodes = graph.allocateNodeCursor() ) - { - LabelSet labels; - - // when - graph.singleNode( foo, nodes ); - - // then - assertTrue( "should access defined node", nodes.next() ); - labels = nodes.labels(); - assertEquals( "number of labels", 1, labels.numberOfLabels() ); - int _foo = labels.label( 0 ); - assertFalse( "should only access a single node", nodes.next() ); - - // when - graph.singleNode( bar, nodes ); - - // then - assertTrue( "should access defined node", nodes.next() ); - labels = nodes.labels(); - assertEquals( "number of labels", 1, labels.numberOfLabels() ); - int _bar = labels.label( 0 ); - assertFalse( "should only access a single node", nodes.next() ); - - // when - graph.singleNode( baz, nodes ); - - // then - assertTrue( "should access defined node", nodes.next() ); - labels = nodes.labels(); - assertEquals( "number of labels", 1, labels.numberOfLabels() ); - int _baz = labels.label( 0 ); - assertFalse( "should only access a single node", nodes.next() ); - - assertNotEquals( "distinct labels", _foo, _bar ); - assertNotEquals( "distinct labels", _foo, _baz ); - assertNotEquals( "distinct labels", _bar, _baz ); - - // when - graph.singleNode( barbaz, nodes ); - - // then - assertTrue( "should access defined node", nodes.next() ); - labels = nodes.labels(); - assertEquals( "number of labels", 2, labels.numberOfLabels() ); - if ( labels.label( 0 ) == _bar ) - { - assertEquals( _baz, labels.label( 1 ) ); - } - else - { - assertEquals( _baz, labels.label( 0 ) ); - assertEquals( _bar, labels.label( 1 ) ); - } - assertFalse( "should only access a single node", nodes.next() ); - - // when - graph.singleNode( bare, nodes ); - - // then - assertTrue( "should access defined node", nodes.next() ); - labels = nodes.labels(); - assertEquals( "number of labels", 0, labels.numberOfLabels() ); - assertFalse( "should only access a single node", nodes.next() ); - } + return new NeoLETestSupport(); } } diff --git a/enterprise/runtime/neole/src/test/java/org/neo4j/internal/store/prototype/neole/PropertyCursorTest.java b/enterprise/runtime/neole/src/test/java/org/neo4j/internal/store/prototype/neole/PropertyCursorTest.java index 2139c3121d181..c55670dc39140 100644 --- a/enterprise/runtime/neole/src/test/java/org/neo4j/internal/store/prototype/neole/PropertyCursorTest.java +++ b/enterprise/runtime/neole/src/test/java/org/neo4j/internal/store/prototype/neole/PropertyCursorTest.java @@ -19,191 +19,19 @@ */ package org.neo4j.internal.store.prototype.neole; -import org.junit.ClassRule; -import org.junit.Test; +import org.neo4j.internal.kernel.api.PropertyCursorTestBase; -import java.util.HashSet; -import java.util.Set; - -import org.neo4j.graphdb.GraphDatabaseService; -import org.neo4j.graphdb.Node; -import org.neo4j.graphdb.Transaction; -import org.neo4j.internal.kernel.api.NodeCursor; -import org.neo4j.internal.kernel.api.PropertyCursor; -import org.neo4j.values.storable.Values; - -import static org.hamcrest.CoreMatchers.equalTo; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.junit.Assume.assumeThat; -import static org.neo4j.graphdb.factory.GraphDatabaseSettings.dense_node_threshold; - -public class PropertyCursorTest +public class PropertyCursorTest extends PropertyCursorTestBase { - private static long bare, byteProp, shortProp, intProp, inlineLongProp, longProp, - floatProp, doubleProp, trueProp, falseProp, charProp, shortStringProp, utf8Prop, allProps; - - private static String chinese = "造Unicode之"; - @ClassRule - public static final GraphSetup graph = new GraphSetup() - { - @Override - protected void create( GraphDatabaseService graphDb ) - { - try ( Transaction tx = graphDb.beginTx() ) - { - bare = graphDb.createNode().getId(); - - byteProp = createNodeWithProperty( graphDb, "byteProp", (byte)13 ); - shortProp = createNodeWithProperty( graphDb, "shortProp", (short)13 ); - intProp = createNodeWithProperty( graphDb, "intProp", 13 ); - inlineLongProp = createNodeWithProperty( graphDb, "inlineLongProp", 13L ); - longProp = createNodeWithProperty( graphDb, "longProp", Long.MAX_VALUE ); - - floatProp = createNodeWithProperty( graphDb, "floatProp", 13.0f ); - doubleProp = createNodeWithProperty( graphDb, "doubleProp", 13.0 ); - - trueProp = createNodeWithProperty( graphDb, "trueProp", true ); - falseProp = createNodeWithProperty( graphDb, "falseProp", false ); - - charProp = createNodeWithProperty( graphDb, "charProp", 'x' ); - shortStringProp = createNodeWithProperty( graphDb, "shortStringProp", "hello" ); - utf8Prop = createNodeWithProperty( graphDb, "utf8Prop", chinese ); - - Node all = graphDb.createNode(); - // first property record - all.setProperty( "byteProp", (byte)13 ); - all.setProperty( "shortProp", (short)13 ); - all.setProperty( "intProp", 13 ); - all.setProperty( "inlineLongProp", 13L ); - // second property record - all.setProperty( "longProp", Long.MAX_VALUE ); - all.setProperty( "floatProp", 13.0f ); - all.setProperty( "doubleProp", 13.0 ); - // ^^^ - // third property record halfway through double? - all.setProperty( "trueProp", true ); - all.setProperty( "falseProp", false ); - - all.setProperty( "charProp", 'x' ); - all.setProperty( "shortStringProp", "hello" ); - all.setProperty( "utf8Prop", chinese ); - - allProps = all.getId(); - - tx.success(); - } - } - - private long createNodeWithProperty( GraphDatabaseService graphDb, String propertyKey, Object value ) - { - Node p = graphDb.createNode(); - p.setProperty( propertyKey, value ); - return p.getId(); - } - } - .withConfig( dense_node_threshold, "1" ); - - @Test - public void shouldNotAccessNonExistentProperties() throws Exception + @Override + public NeoLETestSupport newTestSupport() { - // given - try ( NodeCursor node = graph.allocateNodeCursor(); - PropertyCursor props = graph.allocatePropertyCursor() ) - { - // when - graph.singleNode( bare, node ); - assertTrue( "node by reference", node.next() ); - assertFalse( "no properties", node.hasProperties() ); - - node.properties( props ); - assertFalse( "no properties by direct method", props.next() ); - - graph.nodeProperties( node.propertiesReference(), props ); - assertFalse( "no properties via property ref", props.next() ); - - assertFalse( "only one node", node.next() ); - } - } - - @Test - public void shouldAccessSingleProperty() throws Exception - { - assumeThat( "x86_64", equalTo( System.getProperty( "os.arch" ) ) ); - - assertAccessSingleProperty( byteProp, Values.of( (byte)13 ) ); - assertAccessSingleProperty( shortProp, Values.of( (short)13 ) ); - assertAccessSingleProperty( intProp, Values.of( 13 ) ); - assertAccessSingleProperty( inlineLongProp, Values.of( 13L ) ); - assertAccessSingleProperty( longProp, Values.of( Long.MAX_VALUE ) ); - assertAccessSingleProperty( floatProp, Values.of( 13.0f ) ); - assertAccessSingleProperty( doubleProp, Values.of( 13.0 ) ); - assertAccessSingleProperty( trueProp, Values.of( true ) ); - assertAccessSingleProperty( falseProp, Values.of( false ) ); - assertAccessSingleProperty( charProp, Values.of( 'x' ) ); - assertAccessSingleProperty( shortStringProp, Values.of( "hello" ) ); - assertAccessSingleProperty( utf8Prop, Values.of( chinese ) ); - } - - @Test - public void shouldAccessAllNodeProperties() throws Exception - { - assumeThat( "x86_64", equalTo( System.getProperty( "os.arch" ) ) ); - - // given - try ( NodeCursor node = graph.allocateNodeCursor(); - PropertyCursor props = graph.allocatePropertyCursor() ) - { - // when - graph.singleNode( allProps, node ); - assertTrue( "node by reference", node.next() ); - assertTrue( "has properties", node.hasProperties() ); - - node.properties( props ); - Set values = new HashSet<>(); - while ( props.next() ) - { - values.add( props.propertyValue().asObject() ); - } - - assertTrue( "byteProp", values.contains( (byte)13 ) ); - assertTrue( "shortProp", values.contains( (short)13 ) ); - assertTrue( "intProp", values.contains( 13 ) ); - assertTrue( "inlineLongProp", values.contains( 13L ) ); - assertTrue( "longProp", values.contains( Long.MAX_VALUE ) ); - assertTrue( "floatProp", values.contains( 13.0f ) ); - assertTrue( "doubleProp", values.contains( 13.0 ) ); - assertTrue( "trueProp", values.contains( true ) ); - assertTrue( "falseProp", values.contains( false ) ); - assertTrue( "charProp", values.contains( 'x' ) ); - assertTrue( "shortStringProp", values.contains( "hello" ) ); - assertTrue( "utf8Prop", values.contains( chinese ) ); - - assertEquals( "number of values", 12, values.size() ); - } + return new NeoLETestSupport(); } - private void assertAccessSingleProperty( long nodeId, Object expectedValue ) + @Override + protected boolean supportsBigProperties() { - // given - try ( NodeCursor node = graph.allocateNodeCursor(); - PropertyCursor props = graph.allocatePropertyCursor() ) - { - // when - graph.singleNode( nodeId, node ); - assertTrue( "node by reference", node.next() ); - assertTrue( "has properties", node.hasProperties() ); - - node.properties( props ); - assertTrue( "has properties by direct method", props.next() ); - assertEquals( "correct value", expectedValue, props.propertyValue() ); - assertFalse( "single property", props.next() ); - - graph.nodeProperties( node.propertiesReference(), props ); - assertTrue( "has properties via property ref", props.next() ); - assertEquals( "correct value", expectedValue, props.propertyValue() ); - assertFalse( "single property", props.next() ); - } + return false; } } diff --git a/enterprise/runtime/neole/src/test/java/org/neo4j/internal/store/prototype/neole/RandomRelationshipTraversalCursorTest.java b/enterprise/runtime/neole/src/test/java/org/neo4j/internal/store/prototype/neole/RandomRelationshipTraversalCursorTest.java index 89e0f364039c8..8b767841fd5e4 100644 --- a/enterprise/runtime/neole/src/test/java/org/neo4j/internal/store/prototype/neole/RandomRelationshipTraversalCursorTest.java +++ b/enterprise/runtime/neole/src/test/java/org/neo4j/internal/store/prototype/neole/RandomRelationshipTraversalCursorTest.java @@ -19,107 +19,14 @@ */ package org.neo4j.internal.store.prototype.neole; -import org.junit.ClassRule; -import org.junit.Test; +import org.neo4j.internal.kernel.api.RandomRelationshipTraversalCursorTestBase; -import java.util.ArrayList; -import java.util.List; -import java.util.Random; - -import org.neo4j.graphdb.GraphDatabaseService; -import org.neo4j.graphdb.Label; -import org.neo4j.graphdb.RelationshipType; -import org.neo4j.graphdb.Transaction; -import org.neo4j.internal.kernel.api.NodeCursor; -import org.neo4j.internal.kernel.api.RelationshipGroupCursor; -import org.neo4j.internal.kernel.api.RelationshipTraversalCursor; - -import static org.hamcrest.CoreMatchers.equalTo; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.junit.Assume.assumeThat; -import static org.neo4j.graphdb.factory.GraphDatabaseSettings.dense_node_threshold; - -public class RandomRelationshipTraversalCursorTest +public class RandomRelationshipTraversalCursorTest extends RandomRelationshipTraversalCursorTestBase { - private static final int N_TRAVERSALS = 10_000; - private static int N_NODES = 100; - private static int N_RELATIONSHIPS = 1000; - private static Random random = new Random( 666 ); - private static List nodeIds = new ArrayList<>(); - - @ClassRule - public static final GraphSetup graph = new GraphSetup() - { - @Override - protected void create( GraphDatabaseService graphDb ) - { - try ( Transaction tx = graphDb.beginTx() ) - { - for ( int i = 0; i < N_NODES; i++ ) - { - nodeIds.add( graphDb.createNode( Label.label( "LABEL" + i ) ).getId() ); - } - tx.success(); - } - - try ( Transaction tx = graphDb.beginTx() ) - { - for ( int i = 0; i < N_RELATIONSHIPS; i++ ) - { - Long source = nodeIds.get( random.nextInt( N_NODES ) ); - Long target = nodeIds.get( random.nextInt( N_NODES ) ); - graphDb.getNodeById( source ).createRelationshipTo( graphDb.getNodeById( target ), - RelationshipType.withName( "REL" + (i % 10) ) ); - } - tx.success(); - } - } - }.withConfig( dense_node_threshold, "1" ); - - @Test - public void shouldManageRandomTraversals() throws Exception + @Override + public NeoLETestSupport newTestSupport() { - assumeThat( "x86_64", equalTo( System.getProperty( "os.arch" ) ) ); - - // given - try ( NodeCursor node = graph.allocateNodeCursor(); - RelationshipGroupCursor group = graph.allocateRelationshipGroupCursor(); - RelationshipTraversalCursor relationship = graph.allocateRelationshipTraversalCursor() ) - { - for ( int i = 0; i < N_TRAVERSALS; i++ ) - { - // when - long nodeId = nodeIds.get( random.nextInt( N_NODES ) ); - graph.singleNode( nodeId, node ); - assertTrue( "access root node", node.next() ); - node.relationships( group ); - assertFalse( "single root", node.next() ); - - // then - while ( group.next() ) - { - group.incoming( relationship ); - while ( relationship.next() ) - { - assertEquals( "incoming origin", nodeId, relationship.originNodeReference() ); - relationship.neighbour( node ); - } - group.outgoing( relationship ); - while ( relationship.next() ) - { - assertEquals( "outgoing origin", nodeId, relationship.originNodeReference() ); - relationship.neighbour( node ); - } - group.loops( relationship ); - while ( relationship.next() ) - { - assertEquals( "loop origin", nodeId, relationship.originNodeReference() ); - relationship.neighbour( node ); - } - } - } - } + return new NeoLETestSupport(); } } + diff --git a/enterprise/runtime/neole/src/test/java/org/neo4j/internal/store/prototype/neole/RelationshipScanCursorTest.java b/enterprise/runtime/neole/src/test/java/org/neo4j/internal/store/prototype/neole/RelationshipScanCursorTest.java index 5d84f624ca8b9..502e20518aba7 100644 --- a/enterprise/runtime/neole/src/test/java/org/neo4j/internal/store/prototype/neole/RelationshipScanCursorTest.java +++ b/enterprise/runtime/neole/src/test/java/org/neo4j/internal/store/prototype/neole/RelationshipScanCursorTest.java @@ -19,197 +19,13 @@ */ package org.neo4j.internal.store.prototype.neole; -import org.junit.ClassRule; -import org.junit.Test; +import org.neo4j.internal.kernel.api.RelationshipScanCursorTestBase; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.neo4j.graphdb.GraphDatabaseService; -import org.neo4j.graphdb.Node; -import org.neo4j.graphdb.Relationship; -import org.neo4j.graphdb.Transaction; -import org.neo4j.internal.kernel.api.RelationshipScanCursor; - -import static org.hamcrest.CoreMatchers.equalTo; -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.junit.Assume.assumeThat; -import static org.neo4j.graphdb.RelationshipType.withName; -import static org.neo4j.graphdb.factory.GraphDatabaseSettings.dense_node_threshold; - -public class RelationshipScanCursorTest +public class RelationshipScanCursorTest extends RelationshipScanCursorTestBase { - private static List RELATIONSHIP_IDS; - private static long none, loop, one, c, d; - @ClassRule - public static final GraphSetup graph = new GraphSetup() - { - @Override - protected void create( GraphDatabaseService graphDb ) - { - Relationship deleted; - try ( Transaction tx = graphDb.beginTx() ) - { - Node a = graphDb.createNode(), b = graphDb.createNode(), c = graphDb.createNode(), - d = graphDb.createNode(), e = graphDb.createNode(), f = graphDb.createNode(); - - a.createRelationshipTo( b, withName( "CIRCLE" ) ); - b.createRelationshipTo( c, withName( "CIRCLE" ) ); - one = c.createRelationshipTo( d, withName( "CIRCLE" ) ).getId(); - d.createRelationshipTo( e, withName( "CIRCLE" ) ); - e.createRelationshipTo( f, withName( "CIRCLE" ) ); - f.createRelationshipTo( a, withName( "CIRCLE" ) ); - - a.createRelationshipTo( b, withName( "TRIANGLE" ) ); - a.createRelationshipTo( c, withName( "TRIANGLE" ) ); - b.createRelationshipTo( c, withName( "TRIANGLE" ) ); - none = (deleted = c.createRelationshipTo( b, withName( "TRIANGLE" ) )).getId(); - RelationshipScanCursorTest.c = c.getId(); - RelationshipScanCursorTest.d = d.getId(); - - d.createRelationshipTo( e, withName( "TRIANGLE" ) ); - e.createRelationshipTo( f, withName( "TRIANGLE" ) ); - f.createRelationshipTo( d, withName( "TRIANGLE" ) ); - - loop = a.createRelationshipTo( a, withName( "LOOP" ) ).getId(); - - tx.success(); - } - - RELATIONSHIP_IDS = new ArrayList<>(); - try ( Transaction tx = graphDb.beginTx() ) - { - deleted.delete(); - long time = System.nanoTime(); - for ( Relationship relationship : graphDb.getAllRelationships() ) - { - RELATIONSHIP_IDS.add( relationship.getId() ); - } - time = System.nanoTime() - time; - System.out.printf( "neo4j scan time: %.3fms%n", time / 1_000_000.0 ); - - tx.success(); - } - } - - @Override - protected void cleanup() - { - RELATIONSHIP_IDS = null; - } - }.withConfig( dense_node_threshold, "1" ); - - @Test - public void shouldScanRelationships() throws Exception - { - // given - List ids = new ArrayList<>(); - try ( RelationshipScanCursor relationships = graph.allocateRelationshipScanCursor() ) - { - // when - long time = System.nanoTime(); - graph.allRelationshipsScan( relationships ); - while ( relationships.next() ) - { - ids.add( relationships.relationshipReference() ); - } - time = System.nanoTime() - time; - System.out.printf( "cursor scan time: %.3fms%n", time / 1_000_000.0 ); - } - - assertEquals( RELATIONSHIP_IDS, ids ); - } - - @Test - public void shouldAccessRelationshipByReference() throws Exception + @Override + public NeoLETestSupport newTestSupport() { - // given - try ( RelationshipScanCursor relationships = graph.allocateRelationshipScanCursor() ) - { - for ( long id : RELATIONSHIP_IDS ) - { - // when - graph.singleRelationship( id, relationships ); - - // then - assertTrue( "should access defined relationship", relationships.next() ); - assertEquals( "should access the correct relationship", id, relationships.relationshipReference() ); - assertFalse( "should only access a single relationship", relationships.next() ); - } - } - } - - @Test - public void shouldNotAccessDeletedRelationship() throws Exception - { - // given - try ( RelationshipScanCursor relationships = graph.allocateRelationshipScanCursor() ) - { - // when - graph.singleRelationship( none, relationships ); - - // then - assertFalse( "should not access deleted relationship", relationships.next() ); - } - } - - @Test - public void shouldAccessRelationshipLabels() throws Exception - { - // given - Map counts = new HashMap<>(); - - try ( RelationshipScanCursor relationships = graph.allocateRelationshipScanCursor() ) - { - // when - graph.allRelationshipsScan( relationships ); - while ( relationships.next() ) - { - counts.compute( relationships.label(), ( k, v ) -> v == null ? 1 : v + 1 ); - } - } - - // then - assertEquals( 3, counts.size() ); - int[] values = new int[3]; - int i = 0; - for ( int value : counts.values() ) - { - values[i++] = value; - } - Arrays.sort( values ); - assertArrayEquals( new int[]{1, 6, 6}, values ); - } - - @Test - public void shouldAccessNodes() throws Exception - { - assumeThat( "x86_64", equalTo( System.getProperty( "os.arch" ) ) ); - // given - try ( RelationshipScanCursor relationships = graph.allocateRelationshipScanCursor() ) - { - // when - graph.singleRelationship( one, relationships ); - - // then - assertTrue( relationships.next() ); - assertEquals( c, relationships.sourceNodeReference() ); - assertEquals( d, relationships.targetNodeReference() ); - assertFalse( relationships.next() ); - - // when - graph.singleRelationship( loop, relationships ); - - // then - assertTrue( relationships.next() ); - assertEquals( relationships.sourceNodeReference(), relationships.targetNodeReference() ); - assertFalse( relationships.next() ); - } + return new NeoLETestSupport(); } } diff --git a/enterprise/runtime/neole/src/test/java/org/neo4j/internal/store/prototype/neole/RelationshipTraversalCursorTest.java b/enterprise/runtime/neole/src/test/java/org/neo4j/internal/store/prototype/neole/RelationshipTraversalCursorTest.java index eeb0d282976b6..755ac7f40e3d4 100644 --- a/enterprise/runtime/neole/src/test/java/org/neo4j/internal/store/prototype/neole/RelationshipTraversalCursorTest.java +++ b/enterprise/runtime/neole/src/test/java/org/neo4j/internal/store/prototype/neole/RelationshipTraversalCursorTest.java @@ -19,232 +19,25 @@ */ package org.neo4j.internal.store.prototype.neole; -import org.junit.ClassRule; -import org.junit.Test; +import org.neo4j.internal.kernel.api.RelationshipTraversalCursorTestBase; -import org.neo4j.graphdb.GraphDatabaseService; -import org.neo4j.graphdb.Node; -import org.neo4j.graphdb.Relationship; -import org.neo4j.graphdb.Transaction; -import org.neo4j.internal.kernel.api.NodeCursor; -import org.neo4j.internal.kernel.api.RelationshipGroupCursor; -import org.neo4j.internal.kernel.api.RelationshipTraversalCursor; - -import static org.hamcrest.CoreMatchers.equalTo; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertTrue; -import static org.junit.Assume.assumeThat; -import static org.neo4j.graphdb.RelationshipType.withName; -import static org.neo4j.graphdb.factory.GraphDatabaseSettings.dense_node_threshold; - -public class RelationshipTraversalCursorTest +public class RelationshipTraversalCursorTest extends RelationshipTraversalCursorTestBase { - private static long bare, start, end; - @ClassRule - public static final GraphSetup graph = new GraphSetup() + @Override + public NeoLETestSupport newTestSupport() { - @Override - protected void create( GraphDatabaseService graphDb ) - { - Relationship dead; - try ( Transaction tx = graphDb.beginTx() ) - { - Node a = graphDb.createNode(), - b = graphDb.createNode(), - c = graphDb.createNode(), - d = graphDb.createNode(); - - a.createRelationshipTo( a, withName( "ALPHA" ) ); - a.createRelationshipTo( b, withName( "BETA" ) ); - a.createRelationshipTo( c, withName( "GAMMA" ) ); - a.createRelationshipTo( d, withName( "DELTA" ) ); - - bare = graphDb.createNode().getId(); - - Node x = graphDb.createNode(), y = graphDb.createNode(); - start = x.getId(); - end = y.getId(); - x.createRelationshipTo( y, withName( "GEN" ) ); - - graphDb.createNode().createRelationshipTo( a, withName( "BETA" ) ); - a.createRelationshipTo( graphDb.createNode(), withName( "BETA" ) ); - dead = a.createRelationshipTo( graphDb.createNode(), withName( "BETA" ) ); - a.createRelationshipTo( graphDb.createNode(), withName( "BETA" ) ); - - Node clump = graphDb.createNode(); - clump.createRelationshipTo( clump, withName( "REL" ) ); - clump.createRelationshipTo( clump, withName( "REL" ) ); - clump.createRelationshipTo( clump, withName( "REL" ) ); - clump.createRelationshipTo( graphDb.createNode(), withName( "REL" ) ); - clump.createRelationshipTo( graphDb.createNode(), withName( "REL" ) ); - clump.createRelationshipTo( graphDb.createNode(), withName( "REL" ) ); - graphDb.createNode().createRelationshipTo( clump, withName( "REL" ) ); - graphDb.createNode().createRelationshipTo( clump, withName( "REL" ) ); - graphDb.createNode().createRelationshipTo( clump, withName( "REL" ) ); - - tx.success(); - } - - try ( Transaction tx = graphDb.beginTx() ) - { - Node node = dead.getEndNode(); - dead.delete(); - node.delete(); - - tx.success(); - } - } - }.withConfig( dense_node_threshold, "1" ); - - @Test - public void shouldNotAccessGroupsOfBareNode() throws Exception - { - // given - try ( NodeCursor node = graph.allocateNodeCursor(); - RelationshipGroupCursor group = graph.allocateRelationshipGroupCursor() ) - { - // when - graph.singleNode( bare, node ); - assertTrue( "access node", node.next() ); - node.relationships( group ); - - // then - assertFalse( "access group", group.next() ); - } + return new NeoLETestSupport(); } - @Test - public void shouldTraverseRelationshipsOfGivenType() throws Exception + @Override + protected boolean supportsDirectTraversal() { - assumeThat( "x86_64", equalTo( System.getProperty( "os.arch" ) ) ); - - // given - try ( NodeCursor node = graph.allocateNodeCursor(); - RelationshipGroupCursor group = graph.allocateRelationshipGroupCursor(); - RelationshipTraversalCursor relationship = graph.allocateRelationshipTraversalCursor() ) - { - int empty = 0; - // when - graph.allNodesScan( node ); - while ( node.next() ) - { - node.relationships( group ); - boolean none = true; - while ( group.next() ) - { - none = false; - Sizes degree = new Sizes(); - group.outgoing( relationship ); - while ( relationship.next() ) - { - assertEquals( "relationship should have same label as group", group.relationshipLabel(), - relationship.label() ); - degree.outgoing++; - } - group.incoming( relationship ); - while ( relationship.next() ) - { - assertEquals( "relationship should have same label as group", group.relationshipLabel(), - relationship.label() ); - degree.incoming++; - } - group.loops( relationship ); - while ( relationship.next() ) - { - assertEquals( "relationship should have same label as group", group.relationshipLabel(), - relationship.label() ); - degree.loop++; - } - - // then - assertNotEquals( "all", 0, degree.incoming + degree.outgoing + degree.loop ); - assertEquals( "outgoing", group.outgoingCount(), degree.outgoing ); - assertEquals( "incoming", group.incomingCount(), degree.incoming ); - assertEquals( "loop", group.loopCount(), degree.loop ); - assertEquals( "all = incoming + outgoing - loop", - group.totalCount(), degree.incoming + degree.outgoing - degree.loop ); - } - if ( none ) - { - empty++; - } - } - - // then - assertEquals( "number of empty nodes", 1, empty ); - } - } - - @Test - public void shouldFollowSpecificRelationship() throws Exception - { - assumeThat( "x86_64", equalTo( System.getProperty( "os.arch" ) ) ); - - // given - try ( NodeCursor node = graph.allocateNodeCursor(); - RelationshipGroupCursor group = graph.allocateRelationshipGroupCursor(); - RelationshipTraversalCursor relationship = graph.allocateRelationshipTraversalCursor() ) - { - // when - traversing from start to end - graph.singleNode( start, node ); - assertTrue( "access start node", node.next() ); - node.relationships( group ); - assertTrue( "access relationship group", group.next() ); - group.outgoing( relationship ); - assertTrue( "access outgoing relationships", relationship.next() ); - - // then - assertEquals( "source node", start, relationship.sourceNodeReference() ); - assertEquals( "target node", end, relationship.targetNodeReference() ); - - assertEquals( "node of origin", start, relationship.originNodeReference() ); - assertEquals( "neighbouring node", end, relationship.neighbourNodeReference() ); - - assertEquals( "relationship should have same label as group", group.relationshipLabel(), - relationship.label() ); - - assertFalse( "only a single relationship", relationship.next() ); - - group.incoming( relationship ); - assertFalse( "no incoming relationships", relationship.next() ); - group.loops( relationship ); - assertFalse( "no loop relationships", relationship.next() ); - - assertFalse( "only a single group", group.next() ); - - // when - traversing from end to start - graph.singleNode( end, node ); - assertTrue( "access start node", node.next() ); - node.relationships( group ); - assertTrue( "access relationship group", group.next() ); - group.incoming( relationship ); - assertTrue( "access incoming relationships", relationship.next() ); - - // then - assertEquals( "source node", start, relationship.sourceNodeReference() ); - assertEquals( "target node", end, relationship.targetNodeReference() ); - - assertEquals( "node of origin", end, relationship.originNodeReference() ); - assertEquals( "neighbouring node", start, relationship.neighbourNodeReference() ); - - assertEquals( "relationship should have same label as group", group.relationshipLabel(), - relationship.label() ); - - assertFalse( "only a single relationship", relationship.next() ); - - group.outgoing( relationship ); - assertFalse( "no outgoing relationships", relationship.next() ); - group.loops( relationship ); - assertFalse( "no loop relationships", relationship.next() ); - - assertFalse( "only a single group", group.next() ); - } + return false; } - private class Sizes + @Override + protected boolean supportsSparseNodes() { - int incoming, outgoing, loop; + return false; } } diff --git a/enterprise/runtime/neole/src/test/java/org/neo4j/internal/store/prototype/neole/TestResource.java b/enterprise/runtime/neole/src/test/java/org/neo4j/internal/store/prototype/neole/TestResource.java deleted file mode 100644 index 2f425472a9447..0000000000000 --- a/enterprise/runtime/neole/src/test/java/org/neo4j/internal/store/prototype/neole/TestResource.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2002-2017 "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 . - */ -package org.neo4j.internal.store.prototype.neole; - -import org.junit.rules.TestRule; -import org.junit.runner.Description; -import org.junit.runners.model.Statement; - -public abstract class TestResource implements TestRule -{ - @Override - public final Statement apply( Statement base, Description description ) - { - return new Statement() - { - @Override - public void evaluate() throws Throwable - { - before( description ); - try - { - base.evaluate(); - } - catch ( Throwable failure ) - { - afterFailure( description, failure ); - throw failure; - } - afterSuccess( description ); - } - }; - } - - protected void before( Description description ) throws Throwable - { - } - - protected void afterFailure( Description description, Throwable failure ) throws Throwable - { - } - - protected void afterSuccess( Description description ) throws Throwable - { - } -}