Search in sources :

Example 21 with Race

use of org.neo4j.test.Race in project neo4j by neo4j.

the class ArrayEncoderTest method shouldEncodeProperlyWithMultipleThreadsRacing.

@Test
public void shouldEncodeProperlyWithMultipleThreadsRacing() throws Throwable {
    // given
    String[] INPUT = { "These strings need to be longer than 57 bytes, because that is the line wrapping length of BASE64.", "This next line is also long. The number of strings in this array is the number of threads to use.", "Each thread will get a different string as input to encode, and ensure the result is always the same.", "Should the result of an encoding differ even once, the thread will yield a negative overall result.", "If any of the threads yields a negative result, the test will fail, since that should not happen.", "All threads are allowed to run together for a predetermined amount of time, to try to get contention.", "This predetermined time is the minimum runtime of the test, since the timer starts after all threads.", "The idea to use the input data as documentation for the test was just a cute thing I came up with.", "Since my imagination for coming up with test data is usually poor, I figured I'd do something useful.", "Hopefully this isn't just nonsensical drivel, and maybe, just maybe someone might actually read it." };
    Race race = new Race();
    for (String input : INPUT) {
        final String[] inputArray = new String[] { input };
        race.addContestant(() -> {
            String first = ArrayEncoder.encode(inputArray);
            for (int i = 0; i < 1000; i++) {
                String encoded = ArrayEncoder.encode(inputArray);
                assertEquals("Each attempt at encoding should yield the same result. Turns out that first one was '" + first + "', yet another one was '" + encoded + "'", first, encoded);
            }
        });
    }
    race.go();
}
Also used : Race(org.neo4j.test.Race) Test(org.junit.Test)

Example 22 with Race

use of org.neo4j.test.Race in project neo4j by neo4j.

the class KernelTransactionTerminationTest method runTwoThreads.

private void runTwoThreads(Consumer<TestKernelTransaction> thread1Action, Consumer<TestKernelTransaction> thread2Action) throws Throwable {
    TestKernelTransaction tx = TestKernelTransaction.create().initialize();
    AtomicLong t1Count = new AtomicLong();
    AtomicLong t2Count = new AtomicLong();
    long endTime = currentTimeMillis() + TEST_RUN_TIME_MS;
    int limit = 20_000;
    Race race = new Race();
    race.withEndCondition(() -> ((t1Count.get() >= limit) && (t2Count.get() >= limit)) || (currentTimeMillis() >= endTime));
    race.addContestant(() -> {
        thread1Action.accept(tx);
        t1Count.incrementAndGet();
    });
    race.addContestant(() -> {
        thread2Action.accept(tx);
        t2Count.incrementAndGet();
    });
    race.go();
}
Also used : AtomicLong(java.util.concurrent.atomic.AtomicLong) Race(org.neo4j.test.Race)

Example 23 with Race

use of org.neo4j.test.Race in project neo4j by neo4j.

the class NeoStoresIT method shouldWriteOutThePropertyRecordBeforeReferencingItFromARelationshipRecord.

@Test
public void shouldWriteOutThePropertyRecordBeforeReferencingItFromARelationshipRecord() throws Throwable {
    final long node1Id;
    final long node2Id;
    try (Transaction tx = db.beginTx()) {
        Node node1 = db.createNode();
        node1Id = node1.getId();
        Node node2 = db.createNode();
        node2Id = node2.getId();
        tx.success();
    }
    Race race = new Race();
    final long[] latestRelationshipId = new long[1];
    AtomicLong writes = new AtomicLong();
    AtomicLong reads = new AtomicLong();
    long endTime = currentTimeMillis() + SECONDS.toMillis(2);
    race.withEndCondition(() -> (writes.get() > 100 && reads.get() > 10_000) || currentTimeMillis() > endTime);
    race.addContestant(() -> {
        try (Transaction tx = db.beginTx()) {
            Node node1 = db.getGraphDatabaseAPI().getNodeById(node1Id);
            Node node2 = db.getGraphDatabaseAPI().getNodeById(node2Id);
            Relationship rel = node1.createRelationshipTo(node2, FRIEND);
            latestRelationshipId[0] = rel.getId();
            rel.setProperty("largeProperty", LONG_STRING_VALUE);
            tx.success();
        }
        writes.incrementAndGet();
    });
    race.addContestant(() -> {
        try (Transaction tx = db.getGraphDatabaseAPI().beginTx()) {
            Relationship rel = db.getGraphDatabaseAPI().getRelationshipById(latestRelationshipId[0]);
            for (String propertyKey : rel.getPropertyKeys()) {
                rel.getProperty(propertyKey);
            }
            tx.success();
        } catch (NotFoundException e) {
            if (Exceptions.contains(e, InvalidRecordException.class)) {
                throw e;
            }
        }
        reads.incrementAndGet();
    });
    race.go();
}
Also used : AtomicLong(java.util.concurrent.atomic.AtomicLong) Transaction(org.neo4j.graphdb.Transaction) Node(org.neo4j.graphdb.Node) Race(org.neo4j.test.Race) Relationship(org.neo4j.graphdb.Relationship) NotFoundException(org.neo4j.graphdb.NotFoundException) Test(org.junit.Test)

Example 24 with Race

use of org.neo4j.test.Race in project neo4j by neo4j.

the class NeoStoresIT method shouldWriteOutTheDynamicChainBeforeUpdatingThePropertyRecord.

@Test
public void shouldWriteOutTheDynamicChainBeforeUpdatingThePropertyRecord() throws Throwable {
    Race race = new Race();
    long[] latestNodeId = new long[1];
    AtomicLong writes = new AtomicLong();
    AtomicLong reads = new AtomicLong();
    long endTime = currentTimeMillis() + SECONDS.toMillis(2);
    race.withEndCondition(() -> (writes.get() > 100 && reads.get() > 10_000) || currentTimeMillis() > endTime);
    race.addContestant(() -> {
        try (Transaction tx = db.beginTx()) {
            Node node = db.createNode();
            latestNodeId[0] = node.getId();
            node.setProperty("largeProperty", LONG_STRING_VALUE);
            tx.success();
        }
        writes.incrementAndGet();
    });
    race.addContestant(() -> {
        try (Transaction tx = db.getGraphDatabaseAPI().beginTx()) {
            Node node = db.getGraphDatabaseAPI().getNodeById(latestNodeId[0]);
            for (String propertyKey : node.getPropertyKeys()) {
                node.getProperty(propertyKey);
            }
            tx.success();
        } catch (NotFoundException e) {
        // This will catch nodes not found (expected) and also PropertyRecords not found (shouldn't happen
        // but handled in shouldWriteOutThePropertyRecordBeforeReferencingItFromANodeRecord)
        }
        reads.incrementAndGet();
    });
    race.go();
}
Also used : AtomicLong(java.util.concurrent.atomic.AtomicLong) Transaction(org.neo4j.graphdb.Transaction) Race(org.neo4j.test.Race) Node(org.neo4j.graphdb.Node) NotFoundException(org.neo4j.graphdb.NotFoundException) Test(org.junit.Test)

Example 25 with Race

use of org.neo4j.test.Race in project neo4j by neo4j.

the class MetaDataStoreTest method transactionClosedMustBeAtomic.

@Test
public void transactionClosedMustBeAtomic() throws Throwable {
    try (MetaDataStore store = newMetaDataStore()) {
        PagedFile pf = store.storeFile;
        int initialValue = 2;
        store.transactionClosed(initialValue, initialValue, initialValue);
        AtomicLong writeCount = new AtomicLong();
        AtomicLong fileReadCount = new AtomicLong();
        AtomicLong apiReadCount = new AtomicLong();
        int upperLimit = 10_000;
        int lowerLimit = 100;
        long endTime = currentTimeMillis() + SECONDS.toMillis(10);
        Race race = new Race();
        race.withEndCondition(() -> writeCount.get() >= upperLimit && fileReadCount.get() >= upperLimit && apiReadCount.get() >= upperLimit);
        race.withEndCondition(() -> writeCount.get() >= lowerLimit && fileReadCount.get() >= lowerLimit && apiReadCount.get() >= lowerLimit && currentTimeMillis() >= endTime);
        race.addContestants(3, () -> {
            long count = writeCount.incrementAndGet();
            store.transactionCommitted(count, count, count);
        });
        race.addContestants(3, throwing(() -> {
            try (PageCursor cursor = pf.io(0, PagedFile.PF_SHARED_READ_LOCK)) {
                assertTrue(cursor.next());
                long logVersion, byteOffset;
                do {
                    logVersion = store.getRecordValue(cursor, MetaDataStore.Position.LAST_CLOSED_TRANSACTION_LOG_VERSION);
                    byteOffset = store.getRecordValue(cursor, MetaDataStore.Position.LAST_CLOSED_TRANSACTION_LOG_BYTE_OFFSET);
                } while (cursor.shouldRetry());
                assertLogVersionEqualsByteOffset(logVersion, byteOffset, "file");
                fileReadCount.incrementAndGet();
            }
        }));
        race.addContestants(3, () -> {
            long[] transaction = store.getLastClosedTransaction();
            assertLogVersionEqualsByteOffset(transaction[0], transaction[1], "API");
            apiReadCount.incrementAndGet();
        });
        race.go();
    }
}
Also used : AtomicLong(java.util.concurrent.atomic.AtomicLong) PagedFile(org.neo4j.io.pagecache.PagedFile) DelegatingPagedFile(org.neo4j.io.pagecache.DelegatingPagedFile) Race(org.neo4j.test.Race) PageCursor(org.neo4j.io.pagecache.PageCursor) DelegatingPageCursor(org.neo4j.io.pagecache.impl.DelegatingPageCursor) Test(org.junit.Test)

Aggregations

Race (org.neo4j.test.Race)26 Test (org.junit.Test)24 AtomicLong (java.util.concurrent.atomic.AtomicLong)10 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)5 Transaction (org.neo4j.graphdb.Transaction)5 Node (org.neo4j.graphdb.Node)4 NotFoundException (org.neo4j.graphdb.NotFoundException)4 DelegatingPagedFile (org.neo4j.io.pagecache.DelegatingPagedFile)3 IOException (java.io.IOException)2 ThreadLocalRandom (java.util.concurrent.ThreadLocalRandom)2 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)2 Relationship (org.neo4j.graphdb.Relationship)2 PageCursor (org.neo4j.io.pagecache.PageCursor)2 PagedFile (org.neo4j.io.pagecache.PagedFile)2 DelegatingPageCursor (org.neo4j.io.pagecache.impl.DelegatingPageCursor)2 File (java.io.File)1 Clock (java.time.Clock)1 ArrayList (java.util.ArrayList)1 ArrayBlockingQueue (java.util.concurrent.ArrayBlockingQueue)1 CountDownLatch (java.util.concurrent.CountDownLatch)1