Skip to content

Commit

Permalink
Merge pull request #2272 from rsksmart/improving-sonar-coverage
Browse files Browse the repository at this point in the history
Adding some tests for SnapshotProcessor class
  • Loading branch information
Vovchyk authored Mar 20, 2024
2 parents 2c4ac29 + cecbfea commit 36e5af6
Show file tree
Hide file tree
Showing 2 changed files with 239 additions and 0 deletions.
221 changes: 221 additions & 0 deletions rskj-core/src/test/java/co/rsk/net/SnapshotProcessorTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@
/*
* This file is part of RskJ
* Copyright (C) 2024 RSK Labs Ltd.
* (derived from ethereumJ library, Copyright (c) 2016 <ether.camp>)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package co.rsk.net;

import co.rsk.core.BlockDifficulty;
import co.rsk.net.messages.*;
import co.rsk.net.sync.PeersInformation;
import co.rsk.net.sync.SnapSyncState;
import co.rsk.test.builders.BlockChainBuilder;
import co.rsk.trie.TrieStore;
import org.ethereum.core.Block;
import org.ethereum.core.Blockchain;
import org.ethereum.core.TransactionPool;
import org.ethereum.db.BlockStore;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import static org.mockito.Mockito.*;

class SnapshotProcessorTest {

Check notice

Code scanning / CodeQL

Unused classes and interfaces Note test

Unused class: SnapshotProcessorTest is not referenced within this codebase. If not used as an external API it should be removed.
public static final int TEST_CHUNK_SIZE = 200;
private BlockChainBuilder blockChainBuilder;
private Blockchain blockchain;
private TransactionPool transactionPool;
private BlockStore blockStore;
private TrieStore trieStore;
private Peer peer;
private PeersInformation peersInformation = mock(PeersInformation.class);
private SnapSyncState snapSyncState = mock(SnapSyncState.class);

private SnapshotProcessor underTest;
@BeforeEach
void setUp() throws UnknownHostException {
peer = mockedPeer();
when(peersInformation.getBestPeerCandidates()).thenReturn(Arrays.asList(peer));
}

@Test
void givenStartSyncingIsCalled_thenSnapStatusStartToBeRequestedFromPeer() {
//given
initializeBlockchainWithAmountOfBlocks(10);
underTest = new SnapshotProcessor(
blockchain,
trieStore,
peersInformation,
blockStore,
transactionPool,
TEST_CHUNK_SIZE,
false);
//when
underTest.startSyncing(peersInformation, snapSyncState);
//then
verify(peer).sendMessage(any(SnapStatusRequestMessage.class));
}

@Test
void givenSnapStatusResponseCalled_thenSnapChunkRequestsAreMade() {
//given
List<Block> blocks = new ArrayList<>();
List<BlockDifficulty> difficulties = new ArrayList<>();
initializeBlockchainWithAmountOfBlocks(10);
underTest = new SnapshotProcessor(
blockchain,
trieStore,
peersInformation,
blockStore,
transactionPool,
TEST_CHUNK_SIZE,
false);

for (int blockNumber = 0; blockNumber < blockchain.getSize(); blockNumber ++){

Check failure

Code scanning / CodeQL

Comparison of narrow type with wide type in loop condition High test

Comparison between
expression
of type int and
expression
of wider type long.
Block currentBlock = blockchain.getBlockByNumber(blockNumber);
blocks.add(currentBlock);
difficulties.add(blockStore.getTotalDifficultyForHash(currentBlock.getHash().getBytes()));
}

SnapStatusResponseMessage snapStatusResponseMessage = new SnapStatusResponseMessage(blocks, difficulties, 100000L);
underTest.startSyncing(peersInformation, snapSyncState);

//when
underTest.processSnapStatusResponse(peer, snapStatusResponseMessage);

//then
verify(peer, atLeast(3)).sendMessage(any()); // 1 for SnapStatusRequestMessage, 1 for SnapBlocksRequestMessage and 1 for SnapStateChunkRequestMessage
verify(peersInformation, times(2)).getBestPeerCandidates();
}

@Test
void givenSnapStatusRequestReceived_thenSnapStatusResponseIsSent() {
//given
initializeBlockchainWithAmountOfBlocks(5010);
underTest = new SnapshotProcessor(
blockchain,
trieStore,
peersInformation,
blockStore,
transactionPool,
TEST_CHUNK_SIZE,
false);
//when
underTest.processSnapStatusRequest(peer);

//then
verify(peer, atLeast(1)).sendMessage(any(SnapStatusResponseMessage.class));
}

@Test
void givenSnapBlockRequestReceived_thenSnapBlocksResponseMessageIsSent() {
//given
initializeBlockchainWithAmountOfBlocks(5010);
underTest = new SnapshotProcessor(
blockchain,
trieStore,
peersInformation,
blockStore,
transactionPool,
TEST_CHUNK_SIZE,
false);
SnapBlocksRequestMessage snapBlocksRequestMessage = new SnapBlocksRequestMessage(460);
//when
underTest.processSnapBlocksRequest(peer, snapBlocksRequestMessage);

//then
verify(peer, atLeast(1)).sendMessage(any(SnapBlocksResponseMessage.class));
}

@Test
void givenSnapBlocksResponseReceived_thenSnapBlocksRequestMessageIsSent() {
//given
List<Block> blocks = new ArrayList<>();
List<BlockDifficulty> difficulties = new ArrayList<>();
initializeBlockchainWithAmountOfBlocks(10);
underTest = new SnapshotProcessor(
blockchain,
trieStore,
peersInformation,
blockStore,
transactionPool,
200,
false);

for (int blockNumber = 0; blockNumber < blockchain.getSize(); blockNumber ++){

Check failure

Code scanning / CodeQL

Comparison of narrow type with wide type in loop condition High test

Comparison between
expression
of type int and
expression
of wider type long.
Block currentBlock = blockchain.getBlockByNumber(blockNumber);
blocks.add(currentBlock);
difficulties.add(blockStore.getTotalDifficultyForHash(currentBlock.getHash().getBytes()));
}

SnapStatusResponseMessage snapStatusResponseMessage = new SnapStatusResponseMessage(blocks, difficulties, 100000L);
underTest.startSyncing(peersInformation, snapSyncState);
underTest.processSnapStatusResponse(peer, snapStatusResponseMessage);

SnapBlocksResponseMessage snapBlocksResponseMessage = new SnapBlocksResponseMessage(blocks, difficulties);
//when
underTest.processSnapBlocksResponse(peer, snapBlocksResponseMessage);

//then
verify(peer, atLeast(2)).sendMessage(any(SnapBlocksRequestMessage.class));
}

@Test
void givenSnapStateChunkRequest_thenSnapStateChunkResponseMessageIsSent() {
//given
initializeBlockchainWithAmountOfBlocks(1000);
underTest = new SnapshotProcessor(
blockchain,
trieStore,
peersInformation,
blockStore,
transactionPool,
TEST_CHUNK_SIZE,
false);

SnapStateChunkRequestMessage snapStateChunkRequestMessage = new SnapStateChunkRequestMessage(1L, 1L,1, TEST_CHUNK_SIZE);

//when
underTest.processStateChunkRequest(peer, snapStateChunkRequestMessage);

//then
verify(peer, timeout(5000).atLeast(1)).sendMessage(any(SnapStateChunkResponseMessage.class)); // We have to wait because this method does the job insides thread
}

private void initializeBlockchainWithAmountOfBlocks(int numberOfBlocks) {
blockChainBuilder = new BlockChainBuilder();
blockchain = blockChainBuilder.ofSize(numberOfBlocks);
transactionPool = blockChainBuilder.getTransactionPool();
blockStore = blockChainBuilder.getBlockStore();
trieStore = blockChainBuilder.getTrieStore();
}

private Peer mockedPeer() throws UnknownHostException {
Peer mockedPeer = mock(Peer.class);
NodeID nodeID = mock(NodeID.class);
when(mockedPeer.getPeerNodeID()).thenReturn(nodeID);
when(mockedPeer.getAddress()).thenReturn(InetAddress.getByName("127.0.0.1"));
when(peersInformation.getBestPeerCandidates()).thenReturn(Arrays.asList(peer));
return mockedPeer;
}

}
Original file line number Diff line number Diff line change
@@ -1,3 +1,21 @@
/*
* This file is part of RskJ
* Copyright (C) 2024 RSK Labs Ltd.
* (derived from ethereumJ library, Copyright (c) 2016 <ether.camp>)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package co.rsk.trie;

import org.ethereum.datasource.HashMapDB;
Expand Down

0 comments on commit 36e5af6

Please sign in to comment.