Search in sources :

Example 6 with SIZE_OF_INT

use of org.agrona.BitUtil.SIZE_OF_INT in project Aeron by real-logic.

the class ExclusivePublicationTest method shouldOfferTwoBuffersFromIndependentExclusivePublications.

@ParameterizedTest
@MethodSource("channels")
@InterruptAfter(10)
void shouldOfferTwoBuffersFromIndependentExclusivePublications(final String channel) {
    try (Subscription subscription = aeron.addSubscription(channel, STREAM_ID);
        ExclusivePublication publicationOne = aeron.addExclusivePublication(channel, STREAM_ID);
        ExclusivePublication publicationTwo = aeron.addExclusivePublication(channel, STREAM_ID)) {
        final int expectedNumberOfFragments = 778;
        int totalFragmentsRead = 0;
        final MutableInteger messageCount = new MutableInteger();
        final FragmentHandler fragmentHandler = (buffer, offset, length, header) -> {
            assertEquals(MESSAGE_LENGTH + SIZE_OF_INT, length);
            final int publisherId = buffer.getInt(offset);
            if (1 == publisherId) {
                assertEquals(Byte.MIN_VALUE, buffer.getByte(offset + SIZE_OF_INT));
            } else if (2 == publisherId) {
                assertEquals(Byte.MAX_VALUE, buffer.getByte(offset + SIZE_OF_INT));
            } else {
                fail("unknown publisherId=" + publisherId);
            }
            messageCount.value++;
        };
        Tests.awaitConnections(subscription, 2);
        final UnsafeBuffer pubOneHeader = new UnsafeBuffer(new byte[SIZE_OF_INT]);
        pubOneHeader.putInt(0, 1);
        final UnsafeBuffer pubOnePayload = new UnsafeBuffer(new byte[MESSAGE_LENGTH]);
        pubOnePayload.setMemory(0, MESSAGE_LENGTH, Byte.MIN_VALUE);
        final UnsafeBuffer pubTwoHeader = new UnsafeBuffer(new byte[SIZE_OF_INT]);
        pubTwoHeader.putInt(0, 2);
        final UnsafeBuffer pubTwoPayload = new UnsafeBuffer(new byte[MESSAGE_LENGTH]);
        pubTwoPayload.setMemory(0, MESSAGE_LENGTH, Byte.MAX_VALUE);
        for (int i = 0; i < expectedNumberOfFragments; i += 2) {
            while (publicationOne.offer(pubOneHeader, 0, SIZE_OF_INT, pubOnePayload, 0, MESSAGE_LENGTH) < 0L) {
                Tests.yield();
                totalFragmentsRead += pollFragments(subscription, fragmentHandler);
            }
            while (publicationTwo.offer(pubTwoHeader, 0, SIZE_OF_INT, pubTwoPayload, 0, MESSAGE_LENGTH) < 0L) {
                Tests.yield();
                totalFragmentsRead += pollFragments(subscription, fragmentHandler);
            }
            totalFragmentsRead += pollFragments(subscription, fragmentHandler);
        }
        do {
            totalFragmentsRead += pollFragments(subscription, fragmentHandler);
        } while (totalFragmentsRead < expectedNumberOfFragments);
        assertEquals(expectedNumberOfFragments, messageCount.value);
    }
}
Also used : SystemTestWatcher(io.aeron.test.SystemTestWatcher) Tests(io.aeron.test.Tests) UnsafeBuffer(org.agrona.concurrent.UnsafeBuffer) RawBlockHandler(io.aeron.logbuffer.RawBlockHandler) SIZE_OF_INT(org.agrona.BitUtil.SIZE_OF_INT) ExtendWith(org.junit.jupiter.api.extension.ExtendWith) RegisterExtension(org.junit.jupiter.api.extension.RegisterExtension) CLOSED(io.aeron.Publication.CLOSED) Arrays.asList(java.util.Arrays.asList) TestMediaDriver(io.aeron.test.driver.TestMediaDriver) MutableInteger(org.agrona.collections.MutableInteger) CloseHelper(org.agrona.CloseHelper) ExecutorService(java.util.concurrent.ExecutorService) MethodSource(org.junit.jupiter.params.provider.MethodSource) FrameDescriptor(io.aeron.logbuffer.FrameDescriptor) MediaDriver(io.aeron.driver.MediaDriver) InterruptingTestCallback(io.aeron.test.InterruptingTestCallback) BACK_PRESSURED(io.aeron.Publication.BACK_PRESSURED) Executors(java.util.concurrent.Executors) Test(org.junit.jupiter.api.Test) InterruptAfter(io.aeron.test.InterruptAfter) CountDownLatch(java.util.concurrent.CountDownLatch) YieldingIdleStrategy(org.agrona.concurrent.YieldingIdleStrategy) AfterEach(org.junit.jupiter.api.AfterEach) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) List(java.util.List) LITTLE_ENDIAN(java.nio.ByteOrder.LITTLE_ENDIAN) ThreadingMode(io.aeron.driver.ThreadingMode) Assertions(org.junit.jupiter.api.Assertions) DataHeaderFlyweight(io.aeron.protocol.DataHeaderFlyweight) FragmentHandler(io.aeron.logbuffer.FragmentHandler) FragmentHandler(io.aeron.logbuffer.FragmentHandler) MutableInteger(org.agrona.collections.MutableInteger) UnsafeBuffer(org.agrona.concurrent.UnsafeBuffer) InterruptAfter(io.aeron.test.InterruptAfter) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) MethodSource(org.junit.jupiter.params.provider.MethodSource)

Example 7 with SIZE_OF_INT

use of org.agrona.BitUtil.SIZE_OF_INT in project Aeron by real-logic.

the class ClusterTest method shouldAllowChangingTermBufferLengthAndMtuAfterRecordingLogIsTruncatedToTheLatestSnapshot.

@SuppressWarnings("MethodLength")
@Test
@InterruptAfter(30)
public void shouldAllowChangingTermBufferLengthAndMtuAfterRecordingLogIsTruncatedToTheLatestSnapshot() {
    final int originalTermLength = 256 * 1024;
    final int originalMtu = 1408;
    final int newTermLength = 2 * 1024 * 1024;
    final int newMtu = 8992;
    final CRC32 crc32 = new CRC32();
    cluster = aCluster().withStaticNodes(3).withLogChannel("aeron:udp?term-length=" + originalTermLength + "|mtu=" + originalMtu).withIngressChannel("aeron:udp?term-length=" + originalTermLength + "|mtu=" + originalMtu).withEgressChannel("aeron:udp?endpoint=localhost:0|term-length=" + originalTermLength + "|mtu=" + originalMtu).withServiceSupplier((i) -> new TestNode.TestService[] { new TestNode.TestService(), new TestNode.ChecksumService() }).start();
    systemTestWatcher.cluster(cluster);
    final TestNode leader = cluster.awaitLeader();
    for (int i = 0; i < 3; i++) {
        assertEquals(2, cluster.node(i).services().length);
    }
    cluster.connectClient();
    final int firstBatch = 9;
    int messageLength = computeMaxMessageLength(originalTermLength) - AeronCluster.SESSION_HEADER_LENGTH;
    int payloadLength = messageLength - SIZE_OF_INT;
    cluster.msgBuffer().setMemory(0, payloadLength, (byte) 'x');
    crc32.reset();
    crc32.update(cluster.msgBuffer().byteArray(), 0, payloadLength);
    int msgChecksum = (int) crc32.getValue();
    cluster.msgBuffer().putInt(payloadLength, msgChecksum, LITTLE_ENDIAN);
    long checksum = 0;
    for (int i = 0; i < firstBatch; i++) {
        cluster.pollUntilMessageSent(messageLength);
        checksum = Hashing.hash(checksum ^ msgChecksum);
    }
    cluster.awaitResponseMessageCount(firstBatch);
    cluster.takeSnapshot(leader);
    cluster.awaitSnapshotCount(1);
    cluster.msgBuffer().setMemory(0, payloadLength, (byte) 'y');
    crc32.reset();
    crc32.update(cluster.msgBuffer().byteArray(), 0, payloadLength);
    msgChecksum = (int) crc32.getValue();
    cluster.msgBuffer().putInt(payloadLength, msgChecksum, LITTLE_ENDIAN);
    final int secondBatch = 11;
    for (int i = 0; i < secondBatch; i++) {
        cluster.pollUntilMessageSent(messageLength);
    }
    cluster.awaitResponseMessageCount(firstBatch + secondBatch);
    cluster.stopAllNodes();
    // seed all recording logs from the latest snapshot
    for (int i = 0; i < 3; i++) {
        ClusterTool.seedRecordingLogFromSnapshot(cluster.node(i).consensusModule().context().clusterDir());
    }
    cluster.logChannel("aeron:udp?term-length=" + newTermLength + "|mtu=" + newMtu);
    cluster.ingressChannel("aeron:udp?term-length=" + newTermLength + "|mtu=" + newMtu);
    cluster.egressChannel("aeron:udp?endpoint=localhost:0|term-length=" + newTermLength + "|mtu=" + newMtu);
    cluster.restartAllNodes(false);
    cluster.awaitLeader();
    assertEquals(2, cluster.followers().size());
    for (int i = 0; i < 3; i++) {
        assertEquals(2, cluster.node(i).services().length);
    }
    cluster.awaitSnapshotsLoaded();
    cluster.reconnectClient();
    messageLength = computeMaxMessageLength(newTermLength) - AeronCluster.SESSION_HEADER_LENGTH;
    payloadLength = messageLength - SIZE_OF_INT;
    cluster.msgBuffer().setMemory(0, payloadLength, (byte) 'z');
    crc32.reset();
    crc32.update(cluster.msgBuffer().byteArray(), 0, payloadLength);
    msgChecksum = (int) crc32.getValue();
    cluster.msgBuffer().putInt(payloadLength, msgChecksum, LITTLE_ENDIAN);
    final int thirdBatch = 5;
    for (int i = 0; i < thirdBatch; i++) {
        cluster.pollUntilMessageSent(messageLength);
        checksum = Hashing.hash(checksum ^ msgChecksum);
    }
    cluster.awaitResponseMessageCount(firstBatch + secondBatch + thirdBatch);
    final int finalMessageCount = firstBatch + thirdBatch;
    final long finalChecksum = checksum;
    final Predicate<TestNode> finalServiceState = node -> {
        final TestNode.TestService[] services = node.services();
        return finalMessageCount == services[0].messageCount() && finalChecksum == ((TestNode.ChecksumService) services[1]).checksum();
    };
    for (int i = 0; i < 3; i++) {
        final TestNode node = cluster.node(i);
        cluster.awaitServiceState(node, finalServiceState);
    }
}
Also used : UNKNOWN_HOST_FILTER(io.aeron.test.SystemTestWatcher.UNKNOWN_HOST_FILTER) ClusterTests(io.aeron.test.cluster.ClusterTests) AeronCluster(io.aeron.cluster.client.AeronCluster) ControlledEgressListener(io.aeron.cluster.client.ControlledEgressListener) io.aeron.test(io.aeron.test) NANOSECONDS(java.util.concurrent.TimeUnit.NANOSECONDS) io.aeron.cluster.codecs(io.aeron.cluster.codecs) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) SIZE_OF_INT(org.agrona.BitUtil.SIZE_OF_INT) FrameDescriptor.computeMaxMessageLength(io.aeron.logbuffer.FrameDescriptor.computeMaxMessageLength) ExtendWith(org.junit.jupiter.api.extension.ExtendWith) RegisterExtension(org.junit.jupiter.api.extension.RegisterExtension) AeronArchive(io.aeron.archive.client.AeronArchive) AuthorisationService(io.aeron.security.AuthorisationService) FOLLOWER(io.aeron.cluster.service.Cluster.Role.FOLLOWER) Publication(io.aeron.Publication) MutableInteger(org.agrona.collections.MutableInteger) EventLogExtension(io.aeron.log.EventLogExtension) MutableBoolean(org.agrona.collections.MutableBoolean) Aeron(io.aeron.Aeron) Tests.awaitAvailableWindow(io.aeron.test.Tests.awaitAvailableWindow) ControlledFragmentHandler(io.aeron.logbuffer.ControlledFragmentHandler) TestNode(io.aeron.test.cluster.TestNode) Predicate(java.util.function.Predicate) Test(org.junit.jupiter.api.Test) TimeUnit(java.util.concurrent.TimeUnit) EgressListener(io.aeron.cluster.client.EgressListener) List(java.util.List) Header(io.aeron.logbuffer.Header) Hashing(org.agrona.collections.Hashing) LITTLE_ENDIAN(java.nio.ByteOrder.LITTLE_ENDIAN) LEADER(io.aeron.cluster.service.Cluster.Role.LEADER) Assertions(org.junit.jupiter.api.Assertions) CRC32(java.util.zip.CRC32) TestCluster(io.aeron.test.cluster.TestCluster) MICROSECONDS(java.util.concurrent.TimeUnit.MICROSECONDS) DirectBuffer(org.agrona.DirectBuffer) CRC32(java.util.zip.CRC32) TestNode(io.aeron.test.cluster.TestNode) Test(org.junit.jupiter.api.Test)

Example 8 with SIZE_OF_INT

use of org.agrona.BitUtil.SIZE_OF_INT in project Aeron by real-logic.

the class ClusterNodeRestartTest method launchService.

private void launchService(final AtomicLong msgCounter) {
    final ClusteredService service = new StubClusteredService() {

        private int nextCorrelationId = 0;

        private int counterValue = 0;

        public void onStart(final Cluster cluster, final Image snapshotImage) {
            super.onStart(cluster, snapshotImage);
            if (null != snapshotImage) {
                final FragmentHandler fragmentHandler = (buffer, offset, length, header) -> {
                    nextCorrelationId = buffer.getInt(offset);
                    offset += SIZE_OF_INT;
                    counterValue = buffer.getInt(offset);
                    offset += SIZE_OF_INT;
                    serviceState.set(buffer.getStringAscii(offset));
                };
                while (true) {
                    final int fragments = snapshotImage.poll(fragmentHandler, 1);
                    if (fragments == 1 || snapshotImage.isEndOfStream()) {
                        break;
                    }
                    idleStrategy.idle();
                }
            }
        }

        public void onSessionMessage(final ClientSession session, final long timestamp, final DirectBuffer buffer, final int offset, final int length, final Header header) {
            final int sentValue = buffer.getInt(offset + MESSAGE_VALUE_OFFSET);
            assertEquals(counterValue, sentValue);
            counterValue++;
            serviceState.set(Integer.toString(counterValue));
            msgCounter.getAndIncrement();
            if (TIMER_MESSAGE_LENGTH == length) {
                final long correlationId = serviceCorrelationId(nextCorrelationId++);
                final long deadlineMs = timestamp + buffer.getLong(offset + TIMER_MESSAGE_DELAY_OFFSET);
                while (!cluster.scheduleTimer(correlationId, deadlineMs)) {
                    idleStrategy.idle();
                }
            }
        }

        public void onTakeSnapshot(final ExclusivePublication snapshotPublication) {
            final ExpandableArrayBuffer buffer = new ExpandableArrayBuffer();
            int length = 0;
            buffer.putInt(length, nextCorrelationId);
            length += SIZE_OF_INT;
            buffer.putInt(length, counterValue);
            length += SIZE_OF_INT;
            length += buffer.putStringAscii(length, Integer.toString(counterValue));
            snapshotPublication.offer(buffer, 0, length);
        }
    };
    container = ClusteredServiceContainer.launch(new ClusteredServiceContainer.Context().clusteredService(service).terminationHook(ClusterTests.NOOP_TERMINATION_HOOK).errorHandler(ClusterTests.errorHandler(0)));
}
Also used : ClusterTests(io.aeron.test.cluster.ClusterTests) AeronCluster(io.aeron.cluster.client.AeronCluster) BeforeEach(org.junit.jupiter.api.BeforeEach) StubClusteredService(io.aeron.test.cluster.StubClusteredService) AtomicCounter(org.agrona.concurrent.status.AtomicCounter) ClusteredServiceContainer(io.aeron.cluster.service.ClusteredServiceContainer) io.aeron.test(io.aeron.test) CountersReader(org.agrona.concurrent.status.CountersReader) CLUSTER_MEMBERS(io.aeron.cluster.ClusterTestConstants.CLUSTER_MEMBERS) ClusteredService(io.aeron.cluster.service.ClusteredService) SIZE_OF_INT(org.agrona.BitUtil.SIZE_OF_INT) AtomicReference(java.util.concurrent.atomic.AtomicReference) ExtendWith(org.junit.jupiter.api.extension.ExtendWith) SIZE_OF_LONG(org.agrona.BitUtil.SIZE_OF_LONG) Publication(io.aeron.Publication) ArchiveThreadingMode(io.aeron.archive.ArchiveThreadingMode) CloseHelper(org.agrona.CloseHelper) ExclusivePublication(io.aeron.ExclusivePublication) PrintStream(java.io.PrintStream) MediaDriver(io.aeron.driver.MediaDriver) Image(io.aeron.Image) Archive(io.aeron.archive.Archive) ExpandableArrayBuffer(org.agrona.ExpandableArrayBuffer) File(java.io.File) Mockito.verify(org.mockito.Mockito.verify) Test(org.junit.jupiter.api.Test) TimeUnit(java.util.concurrent.TimeUnit) CountDownLatch(java.util.concurrent.CountDownLatch) AtomicLong(java.util.concurrent.atomic.AtomicLong) Cluster(io.aeron.cluster.service.Cluster) AfterEach(org.junit.jupiter.api.AfterEach) Header(io.aeron.logbuffer.Header) ClientSession(io.aeron.cluster.service.ClientSession) ThreadingMode(io.aeron.driver.ThreadingMode) Assertions(org.junit.jupiter.api.Assertions) INGRESS_ENDPOINTS(io.aeron.cluster.ClusterTestConstants.INGRESS_ENDPOINTS) FragmentHandler(io.aeron.logbuffer.FragmentHandler) DirectBuffer(org.agrona.DirectBuffer) Mockito.mock(org.mockito.Mockito.mock) AeronCluster(io.aeron.cluster.client.AeronCluster) Cluster(io.aeron.cluster.service.Cluster) StubClusteredService(io.aeron.test.cluster.StubClusteredService) ClusteredService(io.aeron.cluster.service.ClusteredService) ExclusivePublication(io.aeron.ExclusivePublication) Image(io.aeron.Image) ExpandableArrayBuffer(org.agrona.ExpandableArrayBuffer) DirectBuffer(org.agrona.DirectBuffer) Header(io.aeron.logbuffer.Header) FragmentHandler(io.aeron.logbuffer.FragmentHandler) ClientSession(io.aeron.cluster.service.ClientSession) StubClusteredService(io.aeron.test.cluster.StubClusteredService) ClusteredServiceContainer(io.aeron.cluster.service.ClusteredServiceContainer)

Example 9 with SIZE_OF_INT

use of org.agrona.BitUtil.SIZE_OF_INT in project aeron by real-logic.

the class ClusterTimerTest method launchReschedulingService.

private void launchReschedulingService(final AtomicLong triggeredTimersCounter) {
    final ClusteredService service = new StubClusteredService() {

        private int timerId = 1;

        public void onTimerEvent(final long correlationId, final long timestamp) {
            triggeredTimersCounter.getAndIncrement();
            scheduleNext(serviceCorrelationId(timerId++), timestamp + INTERVAL_MS);
        }

        public void onStart(final Cluster cluster, final Image snapshotImage) {
            super.onStart(cluster, snapshotImage);
            this.cluster = cluster;
            if (null != snapshotImage) {
                final FragmentHandler fragmentHandler = (buffer, offset, length, header) -> timerId = buffer.getInt(offset);
                while (true) {
                    final int fragments = snapshotImage.poll(fragmentHandler, 1);
                    if (fragments == 1 || snapshotImage.isEndOfStream()) {
                        break;
                    }
                    idleStrategy.idle();
                }
            }
        }

        public void onTakeSnapshot(final ExclusivePublication snapshotPublication) {
            final ExpandableArrayBuffer buffer = new ExpandableArrayBuffer(SIZE_OF_INT);
            buffer.putInt(0, timerId);
            idleStrategy.reset();
            while (snapshotPublication.offer(buffer, 0, SIZE_OF_INT) < 0) {
                idleStrategy.idle();
            }
        }

        public void onNewLeadershipTermEvent(final long leadershipTermId, final long logPosition, final long timestamp, final long termBaseLogPosition, final int leaderMemberId, final int logSessionId, final TimeUnit timeUnit, final int appVersion) {
            scheduleNext(serviceCorrelationId(timerId++), timestamp + INTERVAL_MS);
        }

        private void scheduleNext(final long correlationId, final long deadlineMs) {
            idleStrategy.reset();
            while (!cluster.scheduleTimer(correlationId, deadlineMs)) {
                idleStrategy.idle();
            }
        }
    };
    container = ClusteredServiceContainer.launch(new ClusteredServiceContainer.Context().clusteredService(service).terminationHook(ClusterTests.NOOP_TERMINATION_HOOK).errorHandler(ClusterTests.errorHandler(0)));
}
Also used : ClusterTests(io.aeron.test.cluster.ClusterTests) AeronCluster(io.aeron.cluster.client.AeronCluster) Tests(io.aeron.test.Tests) BeforeEach(org.junit.jupiter.api.BeforeEach) StubClusteredService(io.aeron.test.cluster.StubClusteredService) AtomicCounter(org.agrona.concurrent.status.AtomicCounter) ClusteredServiceContainer(io.aeron.cluster.service.ClusteredServiceContainer) CountersReader(org.agrona.concurrent.status.CountersReader) CLUSTER_MEMBERS(io.aeron.cluster.ClusterTestConstants.CLUSTER_MEMBERS) ClusteredService(io.aeron.cluster.service.ClusteredService) SIZE_OF_INT(org.agrona.BitUtil.SIZE_OF_INT) ExtendWith(org.junit.jupiter.api.extension.ExtendWith) ArchiveThreadingMode(io.aeron.archive.ArchiveThreadingMode) CloseHelper(org.agrona.CloseHelper) ExclusivePublication(io.aeron.ExclusivePublication) MediaDriver(io.aeron.driver.MediaDriver) InterruptingTestCallback(io.aeron.test.InterruptingTestCallback) Image(io.aeron.Image) Archive(io.aeron.archive.Archive) ExpandableArrayBuffer(org.agrona.ExpandableArrayBuffer) Test(org.junit.jupiter.api.Test) TimeUnit(java.util.concurrent.TimeUnit) InterruptAfter(io.aeron.test.InterruptAfter) AtomicLong(java.util.concurrent.atomic.AtomicLong) Cluster(io.aeron.cluster.service.Cluster) AfterEach(org.junit.jupiter.api.AfterEach) ClientSession(io.aeron.cluster.service.ClientSession) ThreadingMode(io.aeron.driver.ThreadingMode) Assertions(org.junit.jupiter.api.Assertions) INGRESS_ENDPOINTS(io.aeron.cluster.ClusterTestConstants.INGRESS_ENDPOINTS) FragmentHandler(io.aeron.logbuffer.FragmentHandler) FragmentHandler(io.aeron.logbuffer.FragmentHandler) AeronCluster(io.aeron.cluster.client.AeronCluster) Cluster(io.aeron.cluster.service.Cluster) TimeUnit(java.util.concurrent.TimeUnit) StubClusteredService(io.aeron.test.cluster.StubClusteredService) ClusteredService(io.aeron.cluster.service.ClusteredService) ExclusivePublication(io.aeron.ExclusivePublication) StubClusteredService(io.aeron.test.cluster.StubClusteredService) Image(io.aeron.Image) ExpandableArrayBuffer(org.agrona.ExpandableArrayBuffer) ClusteredServiceContainer(io.aeron.cluster.service.ClusteredServiceContainer)

Example 10 with SIZE_OF_INT

use of org.agrona.BitUtil.SIZE_OF_INT in project aeron by real-logic.

the class ClusterTest method shouldAllowChangingTermBufferLengthAndMtuAfterRecordingLogIsTruncatedToTheLatestSnapshot.

@SuppressWarnings("MethodLength")
@Test
@InterruptAfter(30)
public void shouldAllowChangingTermBufferLengthAndMtuAfterRecordingLogIsTruncatedToTheLatestSnapshot() {
    final int originalTermLength = 256 * 1024;
    final int originalMtu = 1408;
    final int newTermLength = 2 * 1024 * 1024;
    final int newMtu = 8992;
    final CRC32 crc32 = new CRC32();
    cluster = aCluster().withStaticNodes(3).withLogChannel("aeron:udp?term-length=" + originalTermLength + "|mtu=" + originalMtu).withIngressChannel("aeron:udp?term-length=" + originalTermLength + "|mtu=" + originalMtu).withEgressChannel("aeron:udp?endpoint=localhost:0|term-length=" + originalTermLength + "|mtu=" + originalMtu).withServiceSupplier((i) -> new TestNode.TestService[] { new TestNode.TestService(), new TestNode.ChecksumService() }).start();
    systemTestWatcher.cluster(cluster);
    final TestNode leader = cluster.awaitLeader();
    for (int i = 0; i < 3; i++) {
        assertEquals(2, cluster.node(i).services().length);
    }
    cluster.connectClient();
    final int firstBatch = 9;
    int messageLength = computeMaxMessageLength(originalTermLength) - AeronCluster.SESSION_HEADER_LENGTH;
    int payloadLength = messageLength - SIZE_OF_INT;
    cluster.msgBuffer().setMemory(0, payloadLength, (byte) 'x');
    crc32.reset();
    crc32.update(cluster.msgBuffer().byteArray(), 0, payloadLength);
    int msgChecksum = (int) crc32.getValue();
    cluster.msgBuffer().putInt(payloadLength, msgChecksum, LITTLE_ENDIAN);
    long checksum = 0;
    for (int i = 0; i < firstBatch; i++) {
        cluster.pollUntilMessageSent(messageLength);
        checksum = Hashing.hash(checksum ^ msgChecksum);
    }
    cluster.awaitResponseMessageCount(firstBatch);
    cluster.takeSnapshot(leader);
    cluster.awaitSnapshotCount(1);
    cluster.msgBuffer().setMemory(0, payloadLength, (byte) 'y');
    crc32.reset();
    crc32.update(cluster.msgBuffer().byteArray(), 0, payloadLength);
    msgChecksum = (int) crc32.getValue();
    cluster.msgBuffer().putInt(payloadLength, msgChecksum, LITTLE_ENDIAN);
    final int secondBatch = 11;
    for (int i = 0; i < secondBatch; i++) {
        cluster.pollUntilMessageSent(messageLength);
    }
    cluster.awaitResponseMessageCount(firstBatch + secondBatch);
    cluster.stopAllNodes();
    // seed all recording logs from the latest snapshot
    for (int i = 0; i < 3; i++) {
        ClusterTool.seedRecordingLogFromSnapshot(cluster.node(i).consensusModule().context().clusterDir());
    }
    cluster.logChannel("aeron:udp?term-length=" + newTermLength + "|mtu=" + newMtu);
    cluster.ingressChannel("aeron:udp?term-length=" + newTermLength + "|mtu=" + newMtu);
    cluster.egressChannel("aeron:udp?endpoint=localhost:0|term-length=" + newTermLength + "|mtu=" + newMtu);
    cluster.restartAllNodes(false);
    cluster.awaitLeader();
    assertEquals(2, cluster.followers().size());
    for (int i = 0; i < 3; i++) {
        assertEquals(2, cluster.node(i).services().length);
    }
    cluster.awaitSnapshotsLoaded();
    cluster.reconnectClient();
    messageLength = computeMaxMessageLength(newTermLength) - AeronCluster.SESSION_HEADER_LENGTH;
    payloadLength = messageLength - SIZE_OF_INT;
    cluster.msgBuffer().setMemory(0, payloadLength, (byte) 'z');
    crc32.reset();
    crc32.update(cluster.msgBuffer().byteArray(), 0, payloadLength);
    msgChecksum = (int) crc32.getValue();
    cluster.msgBuffer().putInt(payloadLength, msgChecksum, LITTLE_ENDIAN);
    final int thirdBatch = 5;
    for (int i = 0; i < thirdBatch; i++) {
        cluster.pollUntilMessageSent(messageLength);
        checksum = Hashing.hash(checksum ^ msgChecksum);
    }
    cluster.awaitResponseMessageCount(firstBatch + secondBatch + thirdBatch);
    final int finalMessageCount = firstBatch + thirdBatch;
    final long finalChecksum = checksum;
    final Predicate<TestNode> finalServiceState = node -> {
        final TestNode.TestService[] services = node.services();
        return finalMessageCount == services[0].messageCount() && finalChecksum == ((TestNode.ChecksumService) services[1]).checksum();
    };
    for (int i = 0; i < 3; i++) {
        final TestNode node = cluster.node(i);
        cluster.awaitServiceState(node, finalServiceState);
    }
}
Also used : UNKNOWN_HOST_FILTER(io.aeron.test.SystemTestWatcher.UNKNOWN_HOST_FILTER) ClusterTests(io.aeron.test.cluster.ClusterTests) AeronCluster(io.aeron.cluster.client.AeronCluster) ControlledEgressListener(io.aeron.cluster.client.ControlledEgressListener) io.aeron.test(io.aeron.test) NANOSECONDS(java.util.concurrent.TimeUnit.NANOSECONDS) io.aeron.cluster.codecs(io.aeron.cluster.codecs) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) SIZE_OF_INT(org.agrona.BitUtil.SIZE_OF_INT) FrameDescriptor.computeMaxMessageLength(io.aeron.logbuffer.FrameDescriptor.computeMaxMessageLength) ExtendWith(org.junit.jupiter.api.extension.ExtendWith) RegisterExtension(org.junit.jupiter.api.extension.RegisterExtension) AeronArchive(io.aeron.archive.client.AeronArchive) AuthorisationService(io.aeron.security.AuthorisationService) FOLLOWER(io.aeron.cluster.service.Cluster.Role.FOLLOWER) Publication(io.aeron.Publication) MutableInteger(org.agrona.collections.MutableInteger) EventLogExtension(io.aeron.log.EventLogExtension) MutableBoolean(org.agrona.collections.MutableBoolean) Aeron(io.aeron.Aeron) Tests.awaitAvailableWindow(io.aeron.test.Tests.awaitAvailableWindow) ControlledFragmentHandler(io.aeron.logbuffer.ControlledFragmentHandler) TestNode(io.aeron.test.cluster.TestNode) Predicate(java.util.function.Predicate) Test(org.junit.jupiter.api.Test) TimeUnit(java.util.concurrent.TimeUnit) EgressListener(io.aeron.cluster.client.EgressListener) List(java.util.List) Header(io.aeron.logbuffer.Header) Hashing(org.agrona.collections.Hashing) LITTLE_ENDIAN(java.nio.ByteOrder.LITTLE_ENDIAN) LEADER(io.aeron.cluster.service.Cluster.Role.LEADER) Assertions(org.junit.jupiter.api.Assertions) CRC32(java.util.zip.CRC32) TestCluster(io.aeron.test.cluster.TestCluster) MICROSECONDS(java.util.concurrent.TimeUnit.MICROSECONDS) DirectBuffer(org.agrona.DirectBuffer) CRC32(java.util.zip.CRC32) TestNode(io.aeron.test.cluster.TestNode) Test(org.junit.jupiter.api.Test)

Aggregations

SIZE_OF_INT (org.agrona.BitUtil.SIZE_OF_INT)12 Assertions (org.junit.jupiter.api.Assertions)12 Test (org.junit.jupiter.api.Test)12 ExtendWith (org.junit.jupiter.api.extension.ExtendWith)12 MediaDriver (io.aeron.driver.MediaDriver)10 ThreadingMode (io.aeron.driver.ThreadingMode)10 FragmentHandler (io.aeron.logbuffer.FragmentHandler)10 CloseHelper (org.agrona.CloseHelper)10 AfterEach (org.junit.jupiter.api.AfterEach)10 AeronCluster (io.aeron.cluster.client.AeronCluster)8 ClusterTests (io.aeron.test.cluster.ClusterTests)8 CountDownLatch (java.util.concurrent.CountDownLatch)8 TimeUnit (java.util.concurrent.TimeUnit)8 ExclusivePublication (io.aeron.ExclusivePublication)6 Image (io.aeron.Image)6 Publication (io.aeron.Publication)6 Archive (io.aeron.archive.Archive)6 ArchiveThreadingMode (io.aeron.archive.ArchiveThreadingMode)6 CLUSTER_MEMBERS (io.aeron.cluster.ClusterTestConstants.CLUSTER_MEMBERS)6 InterruptAfter (io.aeron.test.InterruptAfter)5