Search in sources :

Example 11 with Race

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

the class KernelTransactionsTest method shouldBeAbleToSnapshotDuringHeavyLoad.

@Test
public void shouldBeAbleToSnapshotDuringHeavyLoad() throws Throwable {
    // GIVEN
    final KernelTransactions transactions = newKernelTransactions();
    Race race = new Race();
    final int threads = 50;
    final AtomicBoolean end = new AtomicBoolean();
    final AtomicReferenceArray<KernelTransactionsSnapshot> snapshots = new AtomicReferenceArray<>(threads);
    // Representing "transaction" threads
    for (int i = 0; i < threads; i++) {
        final int threadIndex = i;
        race.addContestant(() -> {
            ThreadLocalRandom random = ThreadLocalRandom.current();
            while (!end.get()) {
                try (KernelTransaction transaction = getKernelTransaction(transactions)) {
                    parkNanos(MILLISECONDS.toNanos(random.nextInt(3)));
                    if (snapshots.get(threadIndex) == null) {
                        snapshots.set(threadIndex, transactions.get());
                        parkNanos(MILLISECONDS.toNanos(random.nextInt(3)));
                    }
                } catch (TransactionFailureException e) {
                    throw new RuntimeException(e);
                }
            }
        });
    }
    // Just checks snapshots
    race.addContestant(() -> {
        ThreadLocalRandom random = ThreadLocalRandom.current();
        int snapshotsLeft = 1_000;
        while (snapshotsLeft > 0) {
            int threadIndex = random.nextInt(threads);
            KernelTransactionsSnapshot snapshot = snapshots.get(threadIndex);
            if (snapshot != null && snapshot.allClosed()) {
                snapshotsLeft--;
                snapshots.set(threadIndex, null);
            }
        }
        // End condition of this test can be described as:
        //   when 1000 snapshots have been seen as closed.
        // setting this boolean to true will have all other threads end as well so that race.go() will end
        end.set(true);
    });
    // WHEN
    race.go();
}
Also used : AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) KernelTransaction(org.neo4j.kernel.api.KernelTransaction) TransactionFailureException(org.neo4j.kernel.api.exceptions.TransactionFailureException) Race(org.neo4j.test.Race) AtomicReferenceArray(java.util.concurrent.atomic.AtomicReferenceArray) ThreadLocalRandom(java.util.concurrent.ThreadLocalRandom) Test(org.junit.Test)

Example 12 with Race

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

the class LegacyBatchIndexApplierTest method shouldOrderTransactionsMakingLegacyIndexChanges.

@Test
public void shouldOrderTransactionsMakingLegacyIndexChanges() throws Throwable {
    // GIVEN
    Map<String, Integer> names = MapUtil.genericMap("first", 0, "second", 1);
    Map<String, Integer> keys = MapUtil.genericMap("key", 0);
    String applierName = "test-applier";
    LegacyIndexApplierLookup applierLookup = mock(LegacyIndexApplierLookup.class);
    when(applierLookup.newApplier(anyString(), anyBoolean())).thenReturn(mock(TransactionApplier.class));
    IndexConfigStore config = newIndexConfigStore(names, applierName);
    // WHEN multiple legacy index transactions are running, they should be done in order
    SynchronizedArrayIdOrderingQueue queue = new SynchronizedArrayIdOrderingQueue(10);
    final AtomicLong lastAppliedTxId = new AtomicLong(-1);
    Race race = new Race();
    for (long i = 0; i < 100; i++) {
        final long txId = i;
        race.addContestant(() -> {
            try (LegacyBatchIndexApplier applier = new LegacyBatchIndexApplier(config, applierLookup, queue, INTERNAL)) {
                TransactionToApply txToApply = new TransactionToApply(new PhysicalTransactionRepresentation(new ArrayList<>()));
                FakeCommitment commitment = new FakeCommitment(txId, mock(TransactionIdStore.class));
                commitment.setHasLegacyIndexChanges(true);
                txToApply.commitment(commitment, txId);
                TransactionApplier txApplier = applier.startTx(txToApply);
                // Make sure threads are unordered
                Thread.sleep(ThreadLocalRandom.current().nextInt(5));
                // THEN
                assertTrue(lastAppliedTxId.compareAndSet(txId - 1, txId));
                // Closing manually instead of using try-with-resources since we have no additional work to do in
                // txApplier
                txApplier.close();
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        });
        queue.offer(txId);
    }
    race.go();
}
Also used : TransactionIdStore(org.neo4j.kernel.impl.transaction.log.TransactionIdStore) IndexConfigStore(org.neo4j.kernel.impl.index.IndexConfigStore) ArrayList(java.util.ArrayList) Matchers.anyString(org.mockito.Matchers.anyString) AtomicLong(java.util.concurrent.atomic.AtomicLong) SynchronizedArrayIdOrderingQueue(org.neo4j.kernel.impl.util.SynchronizedArrayIdOrderingQueue) Race(org.neo4j.test.Race) FakeCommitment(org.neo4j.kernel.impl.transaction.log.FakeCommitment) PhysicalTransactionRepresentation(org.neo4j.kernel.impl.transaction.log.PhysicalTransactionRepresentation) Test(org.junit.Test)

Example 13 with Race

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

the class NodeLabelsCacheTest method shouldSupportConcurrentGet.

@Test
public void shouldSupportConcurrentGet() throws Throwable {
    // GIVEN
    int highLabelId = 10, numberOfNodes = 100;
    int[][] expectedLabels = new int[numberOfNodes][];
    NodeLabelsCache cache = new NodeLabelsCache(NumberArrayFactory.AUTO, highLabelId);
    for (int i = 0; i < numberOfNodes; i++) {
        cache.put(i, asLongArray(expectedLabels[i] = randomLabels(random.nextInt(5), highLabelId)));
    }
    // WHEN
    Race getRace = new Race();
    for (int i = 0; i < 10; i++) {
        getRace.addContestant(new LabelGetter(cache, expectedLabels, numberOfNodes));
    }
    // THEN expected labels should be had (asserted in LabelGetter), and no exceptions (propagated by go())
    getRace.go();
}
Also used : Race(org.neo4j.test.Race) Test(org.junit.Test)

Example 14 with Race

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

the class TerminationOfSlavesDuringPullUpdatesTest method slavesTerminateOrReadConsistentDataWhenApplyingBatchLargerThanSafeZone.

@Test
public void slavesTerminateOrReadConsistentDataWhenApplyingBatchLargerThanSafeZone() throws Throwable {
    long safeZone = TimeUnit.MILLISECONDS.toMillis(0);
    clusterRule.withSharedSetting(HaSettings.id_reuse_safe_zone_time, String.valueOf(safeZone));
    // given
    final ClusterManager.ManagedCluster cluster = clusterRule.startCluster();
    HighlyAvailableGraphDatabase master = cluster.getMaster();
    // when
    // ... slaves and master has node with long string property
    long entityId = action.createInitialEntity(master);
    cluster.sync();
    // ... and property is removed on master
    action.removeProperties(master, entityId);
    Thread.sleep(100);
    // ... and maintenance is called to make sure "safe" ids are freed to be reused
    forceMaintenance(master);
    // ... and a new property is created on master that
    action.setNewProperties(master, entityId);
    final HighlyAvailableGraphDatabase slave = cluster.getAnySlave();
    Race race = new Race();
    final AtomicBoolean end = new AtomicBoolean(false);
    for (int i = 0; i < READER_CONTESTANTS; i++) {
        race.addContestant(readContestant(action, entityId, slave, end));
    }
    race.addContestant(pullUpdatesContestant(slave, end));
    race.go();
}
Also used : AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) HighlyAvailableGraphDatabase(org.neo4j.kernel.ha.HighlyAvailableGraphDatabase) Race(org.neo4j.test.Race) ClusterManager(org.neo4j.kernel.impl.ha.ClusterManager) Test(org.junit.Test)

Example 15 with Race

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

the class NodeIdReuseStressIT method nodeIdsReused.

@Test
public void nodeIdsReused() throws Throwable {
    createInitialNodes(db);
    long initialHighestNodeId = highestNodeId(db);
    Race race = new Race();
    for (int i = 0; i < CONTESTANTS_COUNT; i++) {
        if (i % 2 == 0) {
            race.addContestant(new NodeCreator(db));
        } else {
            race.addContestant(new NodeRemover(db));
        }
    }
    race.go();
    int writeContestants = CONTESTANTS_COUNT / 2;
    int createdNodes = writeContestants * OPERATIONS_COUNT;
    long highestNodeIdWithoutReuse = initialHighestNodeId + createdNodes;
    long currentHighestNodeId = highestNodeId(db);
    assertThat(currentHighestNodeId, lessThan(highestNodeIdWithoutReuse));
}
Also used : Race(org.neo4j.test.Race) 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