From 1661ef3af25f2ce3131a3bd7abfb810daa2a301d Mon Sep 17 00:00:00 2001 From: MishaDemianenko Date: Wed, 21 Mar 2018 18:58:23 +0100 Subject: [PATCH] Wait for futures to complete instead of timeouts in delete stress tests --- .../org/neo4j/cypher/DeleteNodeStressIT.java | 84 ++++++++----------- .../cypher/DeleteRelationshipStressIT.java | 80 +++++++----------- 2 files changed, 64 insertions(+), 100 deletions(-) diff --git a/community/cypher/cypher/src/test/java/org/neo4j/cypher/DeleteNodeStressIT.java b/community/cypher/cypher/src/test/java/org/neo4j/cypher/DeleteNodeStressIT.java index 36d84334e5990..d20d7da3434e3 100644 --- a/community/cypher/cypher/src/test/java/org/neo4j/cypher/DeleteNodeStressIT.java +++ b/community/cypher/cypher/src/test/java/org/neo4j/cypher/DeleteNodeStressIT.java @@ -19,28 +19,25 @@ */ package org.neo4j.cypher; +import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.Test; -import java.io.IOException; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.Future; import org.neo4j.graphdb.Node; -import org.neo4j.graphdb.Result; import org.neo4j.graphdb.Transaction; import org.neo4j.test.rule.ImpermanentDatabaseRule; -import static org.junit.Assert.assertFalse; import static org.neo4j.graphdb.Label.label; public class DeleteNodeStressIT { - private final AtomicBoolean hasFailed = new AtomicBoolean( false ); + private final ExecutorService executorService = Executors.newFixedThreadPool( 10 ); @Rule public ImpermanentDatabaseRule db = new ImpermanentDatabaseRule(); @@ -63,85 +60,74 @@ public void setup() } } - private final ExecutorService executorService = Executors.newFixedThreadPool( 10 ); + @After + public void tearDown() + { + executorService.shutdown(); + } @Test - public void shouldBeAbleToReturnNodesWhileDeletingNode() throws InterruptedException + public void shouldBeAbleToReturnNodesWhileDeletingNode() throws InterruptedException, ExecutionException { // Given - executeInThread( "MATCH (n:L {prop:42}) OPTIONAL MATCH (m:L {prop:1337}) WITH n MATCH (n) return n" ); - executeInThread( "MATCH (n:L {prop:42}) DELETE n" ); - - // When - executorService.awaitTermination( 3L, TimeUnit.SECONDS ); + Future query1 = executeInThread( "MATCH (n:L {prop:42}) OPTIONAL MATCH (m:L {prop:1337}) WITH n MATCH (n) return n" ); + Future query2 = executeInThread( "MATCH (n:L {prop:42}) DELETE n" ); // Then - assertFalse(hasFailed.get()); + query1.get(); + query2.get(); } @Test - public void shouldBeAbleToCheckPropertiesWhileDeletingNode() throws InterruptedException + public void shouldBeAbleToCheckPropertiesWhileDeletingNode() throws InterruptedException, ExecutionException { // Given - executeInThread( "MATCH (n:L {prop:42}) OPTIONAL MATCH (m:L {prop:1337}) WITH n MATCH (n) RETURN exists(n.prop)" ); - executeInThread( "MATCH (n:L {prop:42}) DELETE n" ); + Future query1 = executeInThread( "MATCH (n:L {prop:42}) OPTIONAL MATCH (m:L {prop:1337}) WITH n MATCH (n) RETURN exists(n.prop)" ); + Future query2 = executeInThread( "MATCH (n:L {prop:42}) DELETE n" ); // When - executorService.awaitTermination( 3L, TimeUnit.SECONDS ); - assertFalse(hasFailed.get()); + query1.get(); + query2.get(); } @Test - public void shouldBeAbleToRemovePropertiesWhileDeletingNode() throws InterruptedException + public void shouldBeAbleToRemovePropertiesWhileDeletingNode() throws InterruptedException, ExecutionException { // Given - executeInThread( "MATCH (n:L {prop:42}) OPTIONAL MATCH (m:L {prop:1337}) WITH n MATCH (n) REMOVE n.prop" ); - executeInThread( "MATCH (n:L {prop:42}) DELETE n" ); + Future query1 = executeInThread( "MATCH (n:L {prop:42}) OPTIONAL MATCH (m:L {prop:1337}) WITH n MATCH (n) REMOVE n.prop" ); + Future query2 = executeInThread( "MATCH (n:L {prop:42}) DELETE n" ); // When - executorService.awaitTermination( 3L, TimeUnit.SECONDS ); - assertFalse(hasFailed.get()); + query1.get(); + query2.get(); } @Test - public void shouldBeAbleToSetPropertiesWhileDeletingNode() throws InterruptedException + public void shouldBeAbleToSetPropertiesWhileDeletingNode() throws InterruptedException, ExecutionException { // Given - executeInThread( "MATCH (n:L {prop:42}) OPTIONAL MATCH (m:L {prop:1337}) WITH n MATCH (n) SET n.foo = 'bar'" ); - executeInThread( "MATCH (n:L {prop:42}) DELETE n" ); + Future query1 = executeInThread( "MATCH (n:L {prop:42}) OPTIONAL MATCH (m:L {prop:1337}) WITH n MATCH (n) SET n.foo = 'bar'" ); + Future query2 = executeInThread( "MATCH (n:L {prop:42}) DELETE n" ); // When - executorService.awaitTermination( 3L, TimeUnit.SECONDS ); - assertFalse(hasFailed.get()); + query1.get(); + query2.get(); } @Test - public void shouldBeAbleToCheckLabelsWhileDeleting() throws InterruptedException + public void shouldBeAbleToCheckLabelsWhileDeleting() throws InterruptedException, ExecutionException { // Given - executeInThread( "MATCH (n:L {prop:42}) OPTIONAL MATCH (m:L {prop:1337}) WITH n RETURN labels(n)" ); - executeInThread( "MATCH (n:L {prop:42}) DELETE n" ); + Future query1 = executeInThread( "MATCH (n:L {prop:42}) OPTIONAL MATCH (m:L {prop:1337}) WITH n RETURN labels(n)" ); + Future query2 = executeInThread( "MATCH (n:L {prop:42}) DELETE n" ); // When - executorService.awaitTermination( 3L, TimeUnit.SECONDS ); - assertFalse(hasFailed.get()); + query1.get(); + query2.get(); } - private void executeInThread( final String query ) + private Future executeInThread( final String query ) { - executorService.execute( () -> - { - Result execute = db.execute( query ); - try - { - //resultAsString is good test case since it serializes labels, types, properties etc - execute.resultAsString(); - } - catch ( Exception e ) - { - e.printStackTrace(); - hasFailed.set( true ); - } - } ); + return executorService.submit( () -> db.execute( query ).resultAsString() ); } } diff --git a/community/cypher/cypher/src/test/java/org/neo4j/cypher/DeleteRelationshipStressIT.java b/community/cypher/cypher/src/test/java/org/neo4j/cypher/DeleteRelationshipStressIT.java index 0ce7daad83bd1..12625e5c4fe2c 100644 --- a/community/cypher/cypher/src/test/java/org/neo4j/cypher/DeleteRelationshipStressIT.java +++ b/community/cypher/cypher/src/test/java/org/neo4j/cypher/DeleteRelationshipStressIT.java @@ -24,26 +24,21 @@ import org.junit.Rule; import org.junit.Test; -import java.io.IOException; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.Future; import org.neo4j.graphdb.Node; import org.neo4j.graphdb.Relationship; import org.neo4j.graphdb.RelationshipType; -import org.neo4j.graphdb.Result; import org.neo4j.graphdb.Transaction; import org.neo4j.test.rule.ImpermanentDatabaseRule; -import static org.junit.Assert.assertFalse; import static org.neo4j.graphdb.Label.label; public class DeleteRelationshipStressIT { - private final AtomicBoolean hasFailed = new AtomicBoolean( false ); private final ExecutorService executorService = Executors.newFixedThreadPool( 10 ); @Rule @@ -81,84 +76,67 @@ public void tearDown() } @Test - public void shouldBeAbleToReturnRelsWhileDeletingRelationship() throws InterruptedException + public void shouldBeAbleToReturnRelsWhileDeletingRelationship() throws InterruptedException, ExecutionException { // Given - executeInThread( "MATCH (:L)-[r:T {prop:42}]-(:L) OPTIONAL MATCH (:L)-[:T {prop:1337}]-(:L) WITH r MATCH ()-[r]-() return r" ); - executeInThread( "MATCH (:L)-[r:T {prop:42}]-(:L) DELETE r" ); + Future query1 = executeInThread( "MATCH (:L)-[r:T {prop:42}]-(:L) OPTIONAL MATCH (:L)-[:T {prop:1337}]-(:L) WITH r MATCH ()-[r]-() return r" ); + Future query2 = executeInThread( "MATCH (:L)-[r:T {prop:42}]-(:L) DELETE r" ); // When - executorService.awaitTermination( 3L, TimeUnit.SECONDS ); - - // Then - assertFalse(hasFailed.get()); + query1.get(); + query2.get(); } @Test - public void shouldBeAbleToGetPropertyWhileDeletingRelationship() throws InterruptedException + public void shouldBeAbleToGetPropertyWhileDeletingRelationship() throws InterruptedException, ExecutionException { // Given - executeInThread( "MATCH (:L)-[r:T {prop:42}]-(:L) OPTIONAL MATCH (:L)-[:T {prop:1337}]-(:L) WITH r MATCH ()-[r]-() return r.prop" ); - executeInThread( "MATCH (:L)-[r:T {prop:42}]-(:L) DELETE r" ); + Future query1 = executeInThread( "MATCH (:L)-[r:T {prop:42}]-(:L) OPTIONAL MATCH (:L)-[:T {prop:1337}]-(:L) WITH r MATCH ()-[r]-() return r.prop" ); + Future query2 = executeInThread( "MATCH (:L)-[r:T {prop:42}]-(:L) DELETE r" ); // When - executorService.awaitTermination( 3L, TimeUnit.SECONDS ); - assertFalse(hasFailed.get()); + query1.get(); + query2.get(); } @Test - public void shouldBeAbleToCheckPropertiesWhileDeletingRelationship() throws InterruptedException + public void shouldBeAbleToCheckPropertiesWhileDeletingRelationship() throws InterruptedException, ExecutionException { // Given - executeInThread( "MATCH (:L)-[r:T {prop:42}]-(:L) " + - "OPTIONAL MATCH (:L)-[:T {prop:1337}]-(:L) WITH r MATCH ()-[r]-() return exists(r.prop)" ); - executeInThread( "MATCH (:L)-[r:T {prop:42}]-(:L) DELETE r" ); + Future query1 = + executeInThread( "MATCH (:L)-[r:T {prop:42}]-(:L) OPTIONAL MATCH (:L)-[:T {prop:1337}]-(:L) WITH r MATCH ()-[r]-() return exists(r.prop)" ); + Future query2 = executeInThread( "MATCH (:L)-[r:T {prop:42}]-(:L) DELETE r" ); - // When - executorService.awaitTermination( 3L, TimeUnit.SECONDS ); - assertFalse(hasFailed.get()); + query1.get(); + query2.get(); } @Test - public void shouldBeAbleToRemovePropertiesWhileDeletingRelationship() throws InterruptedException + public void shouldBeAbleToRemovePropertiesWhileDeletingRelationship() throws InterruptedException, ExecutionException { // Given - executeInThread( "MATCH (:L)-[r:T {prop:42}]-(:L) " + - "OPTIONAL MATCH (:L)-[:T {prop:1337}]-(:L) WITH r MATCH ()-[r]-() REMOVE r.prop" ); - executeInThread( "MATCH (:L)-[r:T {prop:42}]-(:L) DELETE r" ); + Future query1 = executeInThread( "MATCH (:L)-[r:T {prop:42}]-(:L) OPTIONAL MATCH (:L)-[:T {prop:1337}]-(:L) WITH r MATCH ()-[r]-() REMOVE r.prop" ); + Future query2 = executeInThread( "MATCH (:L)-[r:T {prop:42}]-(:L) DELETE r" ); // When - executorService.awaitTermination( 3L, TimeUnit.SECONDS ); - assertFalse(hasFailed.get()); + query1.get(); + query2.get(); } @Test - public void shouldBeAbleToSetPropertiesWhileDeletingRelationship() throws InterruptedException + public void shouldBeAbleToSetPropertiesWhileDeletingRelationship() throws InterruptedException, ExecutionException { // Given - executeInThread( "MATCH (:L)-[r:T {prop:42}]-(:L) " + - "OPTIONAL MATCH (:L)-[:T {prop:1337}]-(:L) WITH r MATCH ()-[r]-() SET r.foo = 'bar'" ); - executeInThread( "MATCH (:L)-[r:T {prop:42}]-(:L) DELETE r" ); + Future query1 = executeInThread( "MATCH (:L)-[r:T {prop:42}]-(:L) OPTIONAL MATCH (:L)-[:T {prop:1337}]-(:L) WITH r MATCH ()-[r]-() SET r.foo = 'bar'" ); + Future query2 = executeInThread( "MATCH (:L)-[r:T {prop:42}]-(:L) DELETE r" ); // When - executorService.awaitTermination( 3L, TimeUnit.SECONDS ); - assertFalse(hasFailed.get()); + query1.get(); + query2.get(); } - private void executeInThread( final String query ) + private Future executeInThread( final String query ) { - executorService.execute( () -> - { - Result execute = db.execute( query ); - try - { - //resultAsString is good test case since it serializes labels, types, properties etc - execute.resultAsString(); - } - catch ( Exception e ) - { - hasFailed.set( true ); - } - } ); + return executorService.submit( () -> db.execute( query ).resultAsString() ); } }