From 4bdb8b1a34471707d1ec761edb860749b3d64337 Mon Sep 17 00:00:00 2001 From: Angel Soto Date: Wed, 7 Aug 2024 13:05:12 +0200 Subject: [PATCH] Fixing integration test and adding some basic unit tests --- .../java/co/rsk/net/SnapshotProcessor.java | 3 +- .../co/rsk/net/SnapshotProcessorTest.java | 36 +++++- .../co/rsk/net/sync/SnapSyncStateTest.java | 106 ++++++++++++++++-- 3 files changed, 129 insertions(+), 16 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/net/SnapshotProcessor.java b/rskj-core/src/main/java/co/rsk/net/SnapshotProcessor.java index 4ff11d8d9db..5da673128af 100644 --- a/rskj-core/src/main/java/co/rsk/net/SnapshotProcessor.java +++ b/rskj-core/src/main/java/co/rsk/net/SnapshotProcessor.java @@ -363,7 +363,8 @@ public void processStateChunkResponse(SnapSyncState state, Peer peer, SnapStateC } } - private void onStateChunkResponseError(Peer peer, SnapStateChunkResponseMessage responseMessage) { + @VisibleForTesting + void onStateChunkResponseError(Peer peer, SnapStateChunkResponseMessage responseMessage) { logger.error("Error while processing chunk response from {} of peer {}. Asking for chunk again.", responseMessage.getFrom(), peer.getPeerNodeID()); Peer alternativePeer = peersInformation.getBestSnapPeerCandidates().stream() .filter(listedPeer -> !listedPeer.getPeerNodeID().equals(peer.getPeerNodeID())) diff --git a/rskj-core/src/test/java/co/rsk/net/SnapshotProcessorTest.java b/rskj-core/src/test/java/co/rsk/net/SnapshotProcessorTest.java index 9e869d6a89b..0a6b126bb2d 100644 --- a/rskj-core/src/test/java/co/rsk/net/SnapshotProcessorTest.java +++ b/rskj-core/src/test/java/co/rsk/net/SnapshotProcessorTest.java @@ -29,6 +29,7 @@ import org.ethereum.core.Blockchain; import org.ethereum.core.TransactionPool; import org.ethereum.db.BlockStore; +import org.ethereum.util.RLP; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -104,7 +105,7 @@ void givenSnapStatusResponseCalled_thenSnapChunkRequestsAreMade() { TEST_CHUNK_SIZE, false); - for (long blockNumber = 0; blockNumber < blockchain.getSize(); blockNumber ++){ + for (long blockNumber = 0; blockNumber < blockchain.getSize(); blockNumber++) { Block currentBlock = blockchain.getBlockByNumber(blockNumber); blocks.add(currentBlock); difficulties.add(blockStore.getTotalDifficultyForHash(currentBlock.getHash().getBytes())); @@ -181,7 +182,7 @@ void givenSnapBlocksResponseReceived_thenSnapBlocksRequestMessageIsSent() { 200, false); - for (long blockNumber = 0; blockNumber < blockchain.getSize(); blockNumber ++){ + for (long blockNumber = 0; blockNumber < blockchain.getSize(); blockNumber++) { Block currentBlock = blockchain.getBlockByNumber(blockNumber); blocks.add(currentBlock); difficulties.add(blockStore.getTotalDifficultyForHash(currentBlock.getHash().getBytes())); @@ -216,7 +217,7 @@ void givenSnapStateChunkRequest_thenSnapStateChunkResponseMessageIsSent() { TEST_CHUNK_SIZE, false); - SnapStateChunkRequestMessage snapStateChunkRequestMessage = new SnapStateChunkRequestMessage(1L, 1L,1, TEST_CHUNK_SIZE); + SnapStateChunkRequestMessage snapStateChunkRequestMessage = new SnapStateChunkRequestMessage(1L, 1L, 1, TEST_CHUNK_SIZE); //when underTest.processStateChunkRequestInternal(peer, snapStateChunkRequestMessage); @@ -333,6 +334,35 @@ void processStateChunkRequestInternal(Peer sender, SnapStateChunkRequestMessage assertEquals(msg, jobArg.getValue().getMsg()); } + @Test + void givenErrorRLPData_thenOnStateChunkErrorIsCalled() { + underTest = new SnapshotProcessor( + blockchain, + trieStore, + peersInformation, + blockStore, + transactionPool, + TEST_CHUNK_SIZE, + false); + + PriorityQueue queue = new PriorityQueue<>( + Comparator.comparingLong(SnapStateChunkResponseMessage::getFrom)); + when(snapSyncState.getSnapStateChunkQueue()).thenReturn(queue); + when(snapSyncState.getChunkTaskQueue()).thenReturn(new LinkedList<>()); + SnapStateChunkResponseMessage responseMessage = mock(SnapStateChunkResponseMessage.class); + when(snapSyncState.getNextExpectedFrom()).thenReturn(1L); + when(responseMessage.getFrom()).thenReturn(1L); + when(responseMessage.getChunkOfTrieKeyValue()).thenReturn(RLP.encodedEmptyList()); + underTest = spy(underTest); + + underTest.processStateChunkResponse(snapSyncState, peer, responseMessage); + + verify(snapSyncState, times(1)).onNewChunk(); + verify(underTest, times(1)).onStateChunkResponseError(peer, responseMessage); + verify(peer, times(1)).sendMessage(any(SnapStateChunkRequestMessage.class)); + + } + private void initializeBlockchainWithAmountOfBlocks(int numberOfBlocks) { BlockChainBuilder blockChainBuilder = new BlockChainBuilder(); blockchain = blockChainBuilder.ofSize(numberOfBlocks); diff --git a/rskj-core/src/test/java/co/rsk/net/sync/SnapSyncStateTest.java b/rskj-core/src/test/java/co/rsk/net/sync/SnapSyncStateTest.java index 9b51929c4e5..8ce31717683 100644 --- a/rskj-core/src/test/java/co/rsk/net/sync/SnapSyncStateTest.java +++ b/rskj-core/src/test/java/co/rsk/net/sync/SnapSyncStateTest.java @@ -18,29 +18,35 @@ */ package co.rsk.net.sync; +import co.rsk.core.BlockDifficulty; import co.rsk.net.NodeID; import co.rsk.net.Peer; import co.rsk.net.SnapshotProcessor; import co.rsk.net.messages.SnapBlocksResponseMessage; import co.rsk.net.messages.SnapStateChunkResponseMessage; import co.rsk.net.messages.SnapStatusResponseMessage; +import org.apache.commons.lang3.tuple.Pair; +import org.ethereum.core.Block; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.ArgumentCaptor; +import java.math.BigInteger; import java.net.InetAddress; import java.net.UnknownHostException; import java.time.Duration; +import java.util.List; import java.util.Optional; +import java.util.PriorityQueue; +import java.util.Queue; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.greaterThan; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.*; class SnapSyncStateTest { @@ -56,8 +62,8 @@ class SnapSyncStateTest { private final SnapSyncState underTest = new SnapSyncState(syncEventsHandler, snapshotProcessor, syncConfiguration, listener); @BeforeEach - void setUp(){ - reset(syncEventsHandler,peersInformation, snapshotProcessor); + void setUp() { + reset(syncEventsHandler, peersInformation, snapshotProcessor); } @AfterEach @@ -66,7 +72,7 @@ void tearDown() { } @Test - void givenOnEnterWasCalledAndNotRunningYet_thenSyncingStartsWithTestObjectAsParameter(){ + void givenOnEnterWasCalledAndNotRunningYet_thenSyncingStartsWithTestObjectAsParameter() { //given-when underTest.onEnter(); //then @@ -74,7 +80,7 @@ void givenOnEnterWasCalledAndNotRunningYet_thenSyncingStartsWithTestObjectAsPara } @Test - void givenFinishWasCalledTwice_thenStopSyncingOnlyOnce(){ + void givenFinishWasCalledTwice_thenStopSyncingOnlyOnce() { //given-when underTest.setRunning(); underTest.finish(); @@ -84,7 +90,7 @@ void givenFinishWasCalledTwice_thenStopSyncingOnlyOnce(){ } @Test - void givenOnEnterWasCalledTwice_thenSyncingStartsOnlyOnce(){ + void givenOnEnterWasCalledTwice_thenSyncingStartsOnlyOnce() { //given-when underTest.onEnter(); underTest.onEnter(); @@ -93,7 +99,7 @@ void givenOnEnterWasCalledTwice_thenSyncingStartsOnlyOnce(){ } @Test - void givenOnMessageTimeOutCalled_thenSyncingStops(){ + void givenOnMessageTimeOutCalled_thenSyncingStops() { //given-when underTest.setRunning(); underTest.onMessageTimeOut(); @@ -102,7 +108,7 @@ void givenOnMessageTimeOutCalled_thenSyncingStops(){ } @Test - void givenNewChunk_thenTimerIsReset(){ + void givenNewChunk_thenTimerIsReset() { //given underTest.timeElapsed = Duration.ofMinutes(1); assertThat(underTest.timeElapsed, greaterThan(Duration.ZERO)); @@ -114,7 +120,7 @@ void givenNewChunk_thenTimerIsReset(){ } @Test - void givenTickIsCalledBeforeTimeout_thenTimerIsUpdated_andNoTimeoutHappens(){ + void givenTickIsCalledBeforeTimeout_thenTimerIsUpdated_andNoTimeoutHappens() { //given Duration elapsedTime = Duration.ofMillis(10); underTest.timeElapsed = Duration.ZERO; @@ -123,7 +129,7 @@ void givenTickIsCalledBeforeTimeout_thenTimerIsUpdated_andNoTimeoutHappens(){ //then assertThat(underTest.timeElapsed, equalTo(elapsedTime)); verify(syncEventsHandler, never()).stopSyncing(); - verify(syncEventsHandler, never()).onErrorSyncing(any(),any(),any(),any()); + verify(syncEventsHandler, never()).onErrorSyncing(any(), any(), any(), any()); } @Test @@ -145,7 +151,7 @@ void givenTickIsCalledAfterTimeout_thenTimerIsUpdated_andTimeoutHappens() throws } @Test - void givenFinishIsCalled_thenSyncEventHandlerStopsSync(){ + void givenFinishIsCalled_thenSyncEventHandlerStopsSync() { //given-when underTest.setRunning(); underTest.finish(); @@ -219,10 +225,86 @@ void givenOnSnapStateChunkIsCalled_thenJobIsAddedAndRun() throws InterruptedExce assertEquals(msg, jobArg.getValue().getMsg()); } + @Test + void testSetAndGetLastBlock() { + Block mockBlock = mock(Block.class); + underTest.setLastBlock(mockBlock); + assertEquals(mockBlock, underTest.getLastBlock()); + } + + @Test + void testSetAndGetStateChunkSize() { + BigInteger expectedSize = BigInteger.valueOf(100L); + underTest.setStateChunkSize(expectedSize); + assertEquals(expectedSize, underTest.getStateChunkSize()); + } + + @Test + void testSetAndGetStateSize() { + BigInteger expectedSize = BigInteger.valueOf(1000L); + underTest.setStateSize(expectedSize); + assertEquals(expectedSize, underTest.getStateSize()); + } + + @Test + void testGetChunkTaskQueue() { + Queue queue = underTest.getChunkTaskQueue(); + assertNotNull(queue); + } + + @Test + void testSetAndGetNextExpectedFrom() { + long expectedValue = 100L; + underTest.setNextExpectedFrom(expectedValue); + assertEquals(expectedValue, underTest.getNextExpectedFrom()); + } + private static void doCountDownOnQueueEmpty(SyncMessageHandler.Listener listener, CountDownLatch latch) { doAnswer(invocation -> { latch.countDown(); return null; }).when(listener).onQueueEmpty(); } + + @Test + void testGetSnapStateChunkQueue() { + PriorityQueue queue = underTest.getSnapStateChunkQueue(); + assertNotNull(queue); + } + + @Test + void testSetAndGetLastBlockDifficulty() { + BlockDifficulty mockBlockDifficulty = mock(BlockDifficulty.class); + underTest.setLastBlockDifficulty(mockBlockDifficulty); + assertEquals(mockBlockDifficulty, underTest.getLastBlockDifficulty()); + } + + @Test + void testSetAndGetRemoteRootHash() { + byte[] mockRootHash = new byte[]{1, 2, 3}; + underTest.setRemoteRootHash(mockRootHash); + assertArrayEquals(mockRootHash, underTest.getRemoteRootHash()); + } + + @Test + void testSetAndGetRemoteTrieSize() { + long expectedSize = 12345L; + underTest.setRemoteTrieSize(expectedSize); + assertEquals(expectedSize, underTest.getRemoteTrieSize()); + } + + @Test + void testConnectBlocks() { + BlockConnectorHelper blockConnectorHelper = mock(BlockConnectorHelper.class); + Pair mockBlockPair = mock(Pair.class); + underTest.addBlock(mockBlockPair); + ArgumentCaptor>> captor = ArgumentCaptor.forClass(List.class); + + underTest.connectBlocks(blockConnectorHelper); + + verify(blockConnectorHelper, times(1)).startConnecting(captor.capture()); + assertTrue(captor.getValue().contains(mockBlockPair)); + } + + }