public void addContestants( int count, Runnable contestant ) { addContestants( count, contestant, UNLIMITED ); }
@Test void shouldWaitForAllContestantsToComplete() throws Throwable { // GIVEN Race race = new Race(); final AtomicInteger completed = new AtomicInteger(); int count = 5; race.addContestants( count, throwing( () -> { sleep( current().nextInt( 100 ) ); completed.incrementAndGet(); } ) ); // WHEN race.go(); // THEN assertEquals( count, completed.get() ); }
@Test void shouldConsultEndCondition() throws Throwable { // GIVEN CallCountBooleanSupplier endCondition = new CallCountBooleanSupplier( 100 ); Race race = new Race().withEndCondition( endCondition ); race.addContestants( 20, throwing( () -> sleep( 10 ) ) ); // WHEN race.go(); // THEN assertTrue( endCondition.callCount.get() >= 100 ); }
private void tryOnce( final GraphDatabaseAPI db, final Node node ) throws Throwable { Race race = new Race().withRandomStartDelays(); race.addContestants( Runtime.getRuntime().availableProcessors(), () -> { try ( Transaction ignored = db.beginTx() ) { assertEquals( relCount, count( node.getRelationships() ) ); } } ); race.go(); }
private void raceContestantsAndVerifyResults( SchemaDescriptor newDescriptor, Runnable aliceWork, Runnable changeConfig, Runnable bobWork ) throws Throwable { race.addContestants( aliceThreads, aliceWork ); race.addContestant( changeConfig ); race.addContestants( bobThreads, bobWork ); race.go(); await( IndexDescriptorFactory.forSchema( newDescriptor, Optional.of( "nodes" ), FulltextIndexProviderFactory.DESCRIPTOR ) ); try ( Transaction tx = db.beginTx() ) { KernelTransaction ktx = kernelTransaction( tx ); ScoreEntityIterator bob = fulltextAdapter.query( ktx, "nodes", "bob" ); List<ScoreEntityIterator.ScoreEntry> list = bob.stream().collect( Collectors.toList() ); try { assertEquals( bobThreads * nodesCreatedPerThread, list.size() ); } catch ( Throwable e ) { StringBuilder sb = new StringBuilder( e.getMessage() ).append( System.lineSeparator() ).append( "Nodes found in query for bob:" ); for ( ScoreEntityIterator.ScoreEntry entry : list ) { sb.append( System.lineSeparator() ).append( "\t" ).append( db.getNodeById( entry.entityId() ) ); } throw e; } ScoreEntityIterator alice = fulltextAdapter.query( ktx, "nodes", "alice" ); assertEquals( 0, alice.stream().count() ); } }
@Test public void incrementAndGetVersionMustBeAtomic() throws Throwable { try ( MetaDataStore store = newMetaDataStore() ) { long initialVersion = store.incrementAndGetVersion(); int threads = Runtime.getRuntime().availableProcessors(); int iterations = 500; Race race = new Race(); race.addContestants( threads, () -> { for ( int i = 0; i < iterations; i++ ) { store.incrementAndGetVersion(); } } ); race.go(); assertThat( store.incrementAndGetVersion(), is( initialVersion + (threads * iterations) + 1 ) ); } }
@Test void shouldBreakOnError() throws Throwable { // GIVEN String error = "Noooo"; Race race = new Race(); race.withEndCondition( () -> false ); // <-- never end race.addContestant( () -> { throw new RuntimeException( error ); } ); race.addContestants( 3, () -> { } ); // WHEN Exception exception = assertThrows( Exception.class, () -> race.go() ); assertEquals( error, exception.getMessage() ); }
@Test void shouldHaveMultipleEndConditions() throws Throwable { // GIVEN ControlledBooleanSupplier endCondition1 = spy( new ControlledBooleanSupplier( false ) ); ControlledBooleanSupplier endCondition2 = spy( new ControlledBooleanSupplier( false ) ); ControlledBooleanSupplier endCondition3 = spy( new ControlledBooleanSupplier( false ) ); Race race = new Race().withEndCondition( endCondition1, endCondition2, endCondition3 ); race.addContestant( () -> endCondition2.set( true ) ); race.addContestants( 3, Runnables.EMPTY_RUNNABLE ); // WHEN race.go(); // THEN verify( endCondition1, atLeast( 4 ) ).getAsBoolean(); verify( endCondition2, atLeast( 4 ) ).getAsBoolean(); }
@Test public void shouldHandleMultipleConcurrentStoreCopyRequests() throws Throwable { // GIVEN Race race = new Race(); CountingAction action = new CountingAction(); int threads = Runtime.getRuntime().availableProcessors() * 10; race.addContestants( threads, throwing( () -> { parkARandomWhile(); try ( Resource lock = mutex.storeCopy( action ) ) { parkARandomWhile(); } } ) ); race.go(); // THEN // It's hard to make predictions about what should have been seen. Most importantly is that // The lock doesn't hang any requests and that number of calls to the action less than number of threads assertThat( action.count(), lessThan( threads ) ); }
/** * The test case is basically loads of concurrent CREATE/DELETE NODE or sometimes just CREATE, keeping the created node in an array * for dedicated deleter threads to pick up and delete as fast as they can see them. This concurrently with large creation transactions. */ @Test public void shouldStressIt() throws Throwable { // given Race race = new Race().withMaxDuration( 5, TimeUnit.SECONDS ); AtomicReferenceArray<Node> nodeHeads = new AtomicReferenceArray<>( NUMBER_OF_CREATORS ); for ( int i = 0; i < NUMBER_OF_CREATORS; i++ ) { race.addContestant( creator( nodeHeads, i ) ); } race.addContestants( NUMBER_OF_DELETORS, deleter( nodeHeads ) ); // when race.go(); // then DatabaseLayout dbLayout = db.databaseLayout(); db.shutdownAndKeepStore(); assertTrue( new ConsistencyCheckService().runFullConsistencyCheck( dbLayout, defaults(), NONE, toOutputStream( System.out ), false, new ConsistencyFlags( true, true, true, false ) ).isSuccessful() ); }
@Test public void concurrentCreatingUniquenessConstraint() throws Throwable { // given Race race = new Race().withMaxDuration( 10, SECONDS ); Label label = label( 0 ); race.addContestants( 10, () -> { try ( Transaction tx = db.beginTx() ) { db.schema().constraintFor( label ).assertPropertyIsUnique( KEY ).create(); tx.success(); } catch ( TransientFailureException | ConstraintViolationException e ) { // It's OK } }, 300 ); // when race.go(); try ( Transaction tx = db.beginTx() ) { // then ConstraintDefinition constraint = single( db.schema().getConstraints( label ) ); assertNotNull( constraint ); IndexDefinition index = single( db.schema().getIndexes( label ) ); assertNotNull( index ); tx.success(); } }
race.addContestants( 3, () ->