Search in sources :

Example 1 with DeterministicTest

use of com.radixdlt.harness.deterministic.DeterministicTest in project radixdlt by radixdlt.

the class OneProposalTimeoutResponsiveTest method run.

private void run(int numNodes, long numViews, long dropPeriod) {
    DeterministicTest test = DeterministicTest.builder().numNodes(numNodes).messageSelector(MessageSelector.randomSelector(random)).messageMutator(dropSomeProposals(dropPeriod)).buildWithoutEpochs().runUntil(DeterministicTest.hasReachedView(View.of(numViews)));
    long requiredIndirectParents = numNodes <= 3 ? // there are no indirect parents for 3 nodes (QC is always formed)
    0 : // Edge case if dropPeriod a factor of numViews
    (numViews - 1) / dropPeriod;
    long requiredTimeouts = numViews / dropPeriod * 2;
    long timeoutQuorums = numNodes <= 3 ? // no timeout quorums for 3 nodes
    0 : // otherwise, every 2nd timeout forms a TC
    requiredTimeouts / 2;
    for (int nodeIndex = 0; nodeIndex < numNodes; ++nodeIndex) {
        SystemCounters counters = test.getSystemCounters(nodeIndex);
        long numberOfIndirectParents = counters.get(CounterType.BFT_VERTEX_STORE_INDIRECT_PARENTS);
        long totalNumberOfTimeouts = counters.get(CounterType.BFT_PACEMAKER_TIMEOUTS_SENT);
        long totalNumberOfTimeoutQuorums = counters.get(CounterType.BFT_TIMEOUT_QUORUMS);
        assertThat(numberOfIndirectParents).isEqualTo(requiredIndirectParents);
        assertThat(totalNumberOfTimeouts).isEqualTo(requiredTimeouts);
        assertThat(totalNumberOfTimeoutQuorums).isBetween(timeoutQuorums - 1, timeoutQuorums);
    }
}
Also used : DeterministicTest(com.radixdlt.harness.deterministic.DeterministicTest) SystemCounters(com.radixdlt.counters.SystemCounters)

Example 2 with DeterministicTest

use of com.radixdlt.harness.deterministic.DeterministicTest in project radixdlt by radixdlt.

the class PacemakerViewUpdateRaceConditionTest method test_pacemaker_view_update_race_condition.

@Test
public void test_pacemaker_view_update_race_condition() {
    final DeterministicTest test = DeterministicTest.builder().numNodes(numNodes).messageSelector(MessageSelector.randomSelector(random)).messageMutator(messUpMessagesForNodeUnderTest()).pacemakerTimeout(pacemakerTimeout).overrideWithIncorrectModule(new AbstractModule() {

        @ProvidesIntoSet
        @ProcessOnDispatch
        private EventProcessor<BFTInsertUpdate> bftInsertUpdateProcessor() {
            final Map<HashCode, PreparedVertex> insertedVertices = new HashMap<>();
            return bftInsertUpdate -> {
                final PreparedVertex inserted = bftInsertUpdate.getInserted();
                insertedVertices.putIfAbsent(inserted.getId(), inserted);
                final Optional<PreparedVertex> maybeParent = Optional.ofNullable(insertedVertices.get(inserted.getParentId()));
                maybeParent.ifPresent(parent -> {
                    if (parent.getView().equals(inserted.getView())) {
                        throw new IllegalStateException("Vertex can't have the same view as its parent.");
                    }
                });
            };
        }

        @Provides
        public ProposerElection proposerElection(BFTValidatorSet validatorSet) {
            final var sortedValidators = validatorSet.getValidators().stream().map(BFTValidator::getNode).sorted(Comparator.comparing(BFTNode::getKey, KeyComparator.instance().reversed())).toList();
            return view -> sortedValidators.get(((int) view.number() - 1) % sortedValidators.size());
        }
    }).buildWithoutEpochs().runUntil(nodeUnderTestReachesView(View.of(3)));
    final var counters = test.getSystemCounters(nodeUnderTestIndex);
    assertThat(counters.get(SystemCounters.CounterType.BFT_VOTE_QUORUMS)).isEqualTo(// ensure that quorum was formed
    2);
    assertThat(counters.get(SystemCounters.CounterType.BFT_PACEMAKER_TIMEOUTS_SENT)).isEqualTo(// ensure that timeouts were processed
    2);
}
Also used : PreparedVertex(com.radixdlt.hotstuff.bft.PreparedVertex) DeterministicTest(com.radixdlt.harness.deterministic.DeterministicTest) Provides(com.google.inject.Provides) BFTValidatorSet(com.radixdlt.hotstuff.bft.BFTValidatorSet) ProvidesIntoSet(com.google.inject.multibindings.ProvidesIntoSet) AbstractModule(com.google.inject.AbstractModule) EventProcessor(com.radixdlt.environment.EventProcessor) ProcessOnDispatch(com.radixdlt.environment.ProcessOnDispatch) HashMap(java.util.HashMap) Map(java.util.Map) ProposerElection(com.radixdlt.hotstuff.liveness.ProposerElection) Test(org.junit.Test) DeterministicTest(com.radixdlt.harness.deterministic.DeterministicTest)

Example 3 with DeterministicTest

use of com.radixdlt.harness.deterministic.DeterministicTest in project radixdlt by radixdlt.

the class QuorumWithoutALeaderWithTimeoutsTest method run.

private void run(int numNodes, long numViews) {
    final DeterministicTest test = DeterministicTest.builder().numNodes(numNodes).messageSelector(MessageSelector.randomSelector(random)).messageMutator(dropAllNonTimeoutVotes()).buildWithoutEpochs().runUntil(DeterministicTest.hasReachedView(View.of(numViews)));
    for (int nodeIndex = 0; nodeIndex < numNodes; ++nodeIndex) {
        final SystemCounters counters = test.getSystemCounters(nodeIndex);
        final long numberOfIndirectParents = counters.get(CounterType.BFT_VERTEX_STORE_INDIRECT_PARENTS);
        final long totalNumberOfTimeouts = counters.get(CounterType.BFT_PACEMAKER_TIMEOUTS_SENT);
        final long totalNumberOfTimeoutQuorums = counters.get(CounterType.BFT_TIMEOUT_QUORUMS);
        final long totalNumberOfVoteQuorums = counters.get(CounterType.BFT_VOTE_QUORUMS);
        // no TCs
        assertThat(totalNumberOfTimeoutQuorums).isEqualTo(0);
        // no indirect parents
        assertThat(numberOfIndirectParents).isEqualTo(0);
        // a timeout for each view
        assertThat(totalNumberOfTimeouts).isEqualTo(numViews - 1);
        assertThat(totalNumberOfVoteQuorums).isBetween(numViews - 2, // quorum count matches views
        numViews);
    }
}
Also used : DeterministicTest(com.radixdlt.harness.deterministic.DeterministicTest) SystemCounters(com.radixdlt.counters.SystemCounters)

Example 4 with DeterministicTest

use of com.radixdlt.harness.deterministic.DeterministicTest in project radixdlt by radixdlt.

the class RandomChannelOrderResponsiveTest method run.

private void run(int numNodes, long viewsToRun) {
    assertEquals(0, viewsToRun % numNodes);
    final Random random = new Random(12345);
    DeterministicTest test = DeterministicTest.builder().numNodes(numNodes).messageSelector(MessageSelector.randomSelector(random)).messageMutator(MessageMutator.dropTimeouts()).buildWithoutEpochs().runUntil(DeterministicTest.hasReachedView(View.of(viewsToRun)));
    List<Long> proposalsMade = IntStream.range(0, numNodes).mapToObj(test::getSystemCounters).map(counters -> counters.get(CounterType.BFT_PACEMAKER_PROPOSALS_SENT)).collect(ImmutableList.toImmutableList());
    final long numViews = viewsToRun / numNodes;
    assertThat(proposalsMade).hasSize(numNodes).areAtLeast(numNodes - 1, new Condition<>(l -> l == numViews, "has as many proposals as views")).areAtMost(1, new Condition<>(l -> l == numViews - 1, "has one less proposal"));
}
Also used : IntStream(java.util.stream.IntStream) Random(java.util.Random) Test(org.junit.Test) DeterministicTest(com.radixdlt.harness.deterministic.DeterministicTest) List(java.util.List) View(com.radixdlt.hotstuff.bft.View) ImmutableList(com.google.common.collect.ImmutableList) MessageSelector(com.radixdlt.environment.deterministic.network.MessageSelector) Condition(org.assertj.core.api.Condition) Assertions(org.assertj.core.api.Assertions) MessageMutator(com.radixdlt.environment.deterministic.network.MessageMutator) CounterType(com.radixdlt.counters.SystemCounters.CounterType) Assert.assertEquals(org.junit.Assert.assertEquals) Condition(org.assertj.core.api.Condition) Random(java.util.Random) DeterministicTest(com.radixdlt.harness.deterministic.DeterministicTest)

Example 5 with DeterministicTest

use of com.radixdlt.harness.deterministic.DeterministicTest in project radixdlt by radixdlt.

the class MovingWindowValidatorsTest method run.

private void run(int numNodes, int windowSize, long maxEpoch, View highView) {
    DeterministicTest bftTest = DeterministicTest.builder().numNodes(numNodes).messageMutator(mutator()).messageSelector(firstSelector()).epochNodeIndexesMapping(windowedEpochToNodesMapper(windowSize, numNodes)).buildWithEpochs(highView).runUntil(DeterministicTest.hasReachedEpochView(EpochView.of(maxEpoch, highView)));
    LinkedList<SystemCounters> testCounters = systemCounters(bftTest);
    assertThat(testCounters).extracting(sc -> sc.get(CounterType.BFT_VERTEX_STORE_INDIRECT_PARENTS)).containsOnly(0L);
    assertThat(testCounters).extracting(sc -> sc.get(CounterType.BFT_PACEMAKER_TIMEOUTS_SENT)).containsOnly(0L);
    long maxCount = maxProcessedFor(numNodes, windowSize, maxEpoch, highView.number());
    assertThat(testCounters).extracting(sc -> sc.get(CounterType.BFT_COMMITTED_VERTICES)).allMatch(between(maxCount - maxEpoch, maxCount));
}
Also used : IntStream(java.util.stream.IntStream) ControlledMessage(com.radixdlt.environment.deterministic.network.ControlledMessage) EpochView(com.radixdlt.hotstuff.epoch.EpochView) SystemCounters(com.radixdlt.counters.SystemCounters) LongFunction(java.util.function.LongFunction) ScheduledLocalTimeout(com.radixdlt.hotstuff.liveness.ScheduledLocalTimeout) Predicate(java.util.function.Predicate) Assertions.assertThat(org.assertj.core.api.Assertions.assertThat) Test(org.junit.Test) Collectors(java.util.stream.Collectors) DeterministicTest(com.radixdlt.harness.deterministic.DeterministicTest) Epoched(com.radixdlt.hotstuff.epoch.Epoched) View(com.radixdlt.hotstuff.bft.View) MessageSelector(com.radixdlt.environment.deterministic.network.MessageSelector) MessageMutator(com.radixdlt.environment.deterministic.network.MessageMutator) ChannelId(com.radixdlt.environment.deterministic.network.ChannelId) LinkedList(java.util.LinkedList) CounterType(com.radixdlt.counters.SystemCounters.CounterType) DeterministicTest(com.radixdlt.harness.deterministic.DeterministicTest) SystemCounters(com.radixdlt.counters.SystemCounters)

Aggregations

DeterministicTest (com.radixdlt.harness.deterministic.DeterministicTest)6 Test (org.junit.Test)4 SystemCounters (com.radixdlt.counters.SystemCounters)3 CounterType (com.radixdlt.counters.SystemCounters.CounterType)2 MessageMutator (com.radixdlt.environment.deterministic.network.MessageMutator)2 MessageSelector (com.radixdlt.environment.deterministic.network.MessageSelector)2 View (com.radixdlt.hotstuff.bft.View)2 IntStream (java.util.stream.IntStream)2 ImmutableList (com.google.common.collect.ImmutableList)1 AbstractModule (com.google.inject.AbstractModule)1 Provides (com.google.inject.Provides)1 ProvidesIntoSet (com.google.inject.multibindings.ProvidesIntoSet)1 EventProcessor (com.radixdlt.environment.EventProcessor)1 ProcessOnDispatch (com.radixdlt.environment.ProcessOnDispatch)1 ChannelId (com.radixdlt.environment.deterministic.network.ChannelId)1 ControlledMessage (com.radixdlt.environment.deterministic.network.ControlledMessage)1 BFTValidatorSet (com.radixdlt.hotstuff.bft.BFTValidatorSet)1 PreparedVertex (com.radixdlt.hotstuff.bft.PreparedVertex)1 EpochView (com.radixdlt.hotstuff.epoch.EpochView)1 Epoched (com.radixdlt.hotstuff.epoch.Epoched)1