mirror of
https://github.com/bitcoinj/bitcoinj.git
synced 2024-11-20 10:12:19 +01:00
Unit tests for Peer
This commit is contained in:
parent
381cda1ff2
commit
dc20212fdc
18
pom.xml
18
pom.xml
@ -249,6 +249,24 @@
|
||||
<type>jar</type>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.easymock</groupId>
|
||||
<artifactId>easymock</artifactId>
|
||||
<version>3.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cglib</groupId>
|
||||
<artifactId>cglib</artifactId>
|
||||
<version>2.2.2</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.objenesis</groupId>
|
||||
<artifactId>objenesis</artifactId>
|
||||
<version>1.2</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
|
@ -33,6 +33,14 @@ public class GetBlocksMessage extends Message {
|
||||
|
||||
public void parse() {
|
||||
}
|
||||
|
||||
public List<Sha256Hash> getLocator() {
|
||||
return locator;
|
||||
}
|
||||
|
||||
public Sha256Hash getStopHash() {
|
||||
return stopHash;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuffer b = new StringBuffer();
|
||||
|
@ -81,8 +81,8 @@ public class Peer {
|
||||
eventListeners.add(listener);
|
||||
}
|
||||
|
||||
public synchronized void removeEventListener(PeerEventListener listener) {
|
||||
eventListeners.remove(listener);
|
||||
public synchronized boolean removeEventListener(PeerEventListener listener) {
|
||||
return eventListeners.remove(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -105,6 +105,11 @@ public class Peer {
|
||||
}
|
||||
}
|
||||
|
||||
// For testing
|
||||
void setConnection(NetworkConnection conn) {
|
||||
this.conn = conn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs in the peers network loop and manages communication with the peer.
|
||||
*
|
||||
|
337
tests/com/google/bitcoin/core/PeerTest.java
Normal file
337
tests/com/google/bitcoin/core/PeerTest.java
Normal file
@ -0,0 +1,337 @@
|
||||
package com.google.bitcoin.core;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
import static org.easymock.EasyMock.*;
|
||||
|
||||
import org.easymock.Capture;
|
||||
import org.easymock.IAnswer;
|
||||
import org.easymock.IMocksControl;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
|
||||
import com.google.bitcoin.store.MemoryBlockStore;
|
||||
|
||||
public class PeerTest {
|
||||
|
||||
private Peer peer;
|
||||
private IMocksControl control;
|
||||
private NetworkConnection conn;
|
||||
private NetworkParameters unitTestParams;
|
||||
private MemoryBlockStore blockStore;
|
||||
private BlockChain blockChain;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
control = createStrictControl();
|
||||
control.checkOrder(true);
|
||||
unitTestParams = NetworkParameters.unitTests();
|
||||
blockStore = new MemoryBlockStore(unitTestParams);
|
||||
blockChain = new BlockChain(unitTestParams, new Wallet(unitTestParams), blockStore);
|
||||
PeerAddress address = new PeerAddress(InetAddress.getLocalHost());
|
||||
//peer = new Peer(unitTestParams, address , testNetChain );
|
||||
conn = createMockBuilder(NetworkConnection.class)
|
||||
.addMockedMethod("getVersionMessage")
|
||||
.addMockedMethod("readMessage")
|
||||
.addMockedMethod("writeMessage")
|
||||
.addMockedMethod("shutdown")
|
||||
.addMockedMethod("toString")
|
||||
.createMock(control);
|
||||
peer = new Peer(unitTestParams, address , blockChain);
|
||||
peer.setConnection(conn);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddEventListener() {
|
||||
PeerEventListener listener = new AbstractPeerEventListener();
|
||||
peer.addEventListener(listener);
|
||||
assertTrue(peer.removeEventListener(listener));
|
||||
assertFalse(peer.removeEventListener(listener));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRun_exception() throws Exception {
|
||||
expect(conn.readMessage()).andThrow(new IOException("done"));
|
||||
conn.shutdown();
|
||||
expectLastCall();
|
||||
|
||||
control.replay();
|
||||
|
||||
try {
|
||||
peer.run();
|
||||
fail("did not throw");
|
||||
} catch (PeerException e) {
|
||||
// expected
|
||||
assert(e.getCause() instanceof IOException);
|
||||
}
|
||||
|
||||
control.verify();
|
||||
|
||||
control.reset();
|
||||
expect(conn.readMessage()).andThrow(new ProtocolException("proto"));
|
||||
conn.shutdown();
|
||||
expectLastCall();
|
||||
|
||||
control.replay();
|
||||
|
||||
try {
|
||||
peer.run();
|
||||
fail("did not throw");
|
||||
} catch (PeerException e) {
|
||||
// expected
|
||||
assert(e.getCause() instanceof PeerException);
|
||||
}
|
||||
|
||||
control.verify();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRun_normal() throws Exception {
|
||||
expectPeerDisconnect();
|
||||
|
||||
control.replay();
|
||||
|
||||
peer.run();
|
||||
control.verify();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRun_unconnected_block() throws Exception {
|
||||
PeerEventListener listener = control.createMock(PeerEventListener.class);
|
||||
peer.addEventListener(listener);
|
||||
|
||||
Block b1 = TestUtils.createFakeBlock(unitTestParams, blockStore).block;
|
||||
blockChain.add(b1);
|
||||
|
||||
Block prev = TestUtils.makeSolvedTestBlock(unitTestParams, blockStore);
|
||||
final Block block = TestUtils.makeSolvedTestBlock(unitTestParams, prev);
|
||||
|
||||
expect(conn.readMessage()).andAnswer(new IAnswer<Message>() {
|
||||
public Message answer() throws Throwable {
|
||||
return block;
|
||||
}
|
||||
});
|
||||
Capture<GetBlocksMessage> message = new Capture<GetBlocksMessage>();
|
||||
|
||||
conn.writeMessage(capture(message));
|
||||
expectLastCall();
|
||||
|
||||
expectPeerDisconnect();
|
||||
|
||||
control.replay();
|
||||
|
||||
peer.run();
|
||||
control.verify();
|
||||
|
||||
List<Sha256Hash> expectedLocator = new ArrayList<Sha256Hash>();
|
||||
expectedLocator.add(b1.getHash());
|
||||
expectedLocator.add(unitTestParams.genesisBlock.getHash());
|
||||
|
||||
assertEquals(message.getValue().getLocator(), expectedLocator);
|
||||
assertEquals(message.getValue().getStopHash(), block.getHash());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRun_inv_tickle() throws Exception {
|
||||
PeerEventListener listener = control.createMock(PeerEventListener.class);
|
||||
peer.addEventListener(listener);
|
||||
|
||||
Block b1 = TestUtils.createFakeBlock(unitTestParams, blockStore).block;
|
||||
blockChain.add(b1);
|
||||
|
||||
Block prev = TestUtils.makeSolvedTestBlock(unitTestParams, blockStore);
|
||||
final Block block = TestUtils.makeSolvedTestBlock(unitTestParams, prev);
|
||||
|
||||
expect(conn.readMessage()).andAnswer(new IAnswer<Message>() {
|
||||
public Message answer() throws Throwable {
|
||||
return block;
|
||||
}
|
||||
});
|
||||
|
||||
conn.writeMessage(anyObject(Message.class));
|
||||
expectLastCall();
|
||||
|
||||
expect(conn.readMessage()).andAnswer(new IAnswer<Message>() {
|
||||
public Message answer() throws Throwable {
|
||||
InventoryMessage inv = new InventoryMessage(unitTestParams);
|
||||
InventoryItem item = new InventoryItem(InventoryItem.Type.Block, block.getHash());
|
||||
inv.addItem(item);
|
||||
return inv;
|
||||
}
|
||||
});
|
||||
|
||||
Capture<GetBlocksMessage> message = new Capture<GetBlocksMessage>();
|
||||
conn.writeMessage(capture(message));
|
||||
expectLastCall();
|
||||
|
||||
expectPeerDisconnect();
|
||||
|
||||
control.replay();
|
||||
|
||||
peer.run();
|
||||
control.verify();
|
||||
|
||||
List<Sha256Hash> expectedLocator = new ArrayList<Sha256Hash>();
|
||||
expectedLocator.add(b1.getHash());
|
||||
expectedLocator.add(unitTestParams.genesisBlock.getHash());
|
||||
|
||||
assertEquals(message.getValue().getLocator(), expectedLocator);
|
||||
assertEquals(message.getValue().getStopHash(), block.getHash());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRun_inv_block() throws Exception {
|
||||
PeerEventListener listener = control.createMock(PeerEventListener.class);
|
||||
peer.addEventListener(listener);
|
||||
|
||||
Block b1 = TestUtils.createFakeBlock(unitTestParams, blockStore).block;
|
||||
blockChain.add(b1);
|
||||
|
||||
Block prev = TestUtils.makeSolvedTestBlock(unitTestParams, blockStore);
|
||||
final Block b2 = TestUtils.makeSolvedTestBlock(unitTestParams, prev);
|
||||
final Block b3 = TestUtils.makeSolvedTestBlock(unitTestParams, b2);
|
||||
|
||||
expect(conn.readMessage()).andAnswer(new IAnswer<Message>() {
|
||||
public Message answer() throws Throwable {
|
||||
return b2;
|
||||
}
|
||||
});
|
||||
|
||||
conn.writeMessage(anyObject(Message.class));
|
||||
expectLastCall();
|
||||
|
||||
expect(conn.readMessage()).andAnswer(new IAnswer<Message>() {
|
||||
public Message answer() throws Throwable {
|
||||
InventoryMessage inv = new InventoryMessage(unitTestParams);
|
||||
InventoryItem item = new InventoryItem(InventoryItem.Type.Block, b3.getHash());
|
||||
inv.addItem(item);
|
||||
return inv;
|
||||
}
|
||||
});
|
||||
|
||||
Capture<GetDataMessage> message = new Capture<GetDataMessage>();
|
||||
conn.writeMessage(capture(message));
|
||||
expectLastCall();
|
||||
|
||||
expectPeerDisconnect();
|
||||
|
||||
control.replay();
|
||||
|
||||
peer.run();
|
||||
control.verify();
|
||||
|
||||
List<InventoryItem> items = message.getValue().getItems();
|
||||
assertEquals(1, items.size());
|
||||
assertEquals(b3.getHash(), items.get(0).hash);
|
||||
assertEquals(InventoryItem.Type.Block, items.get(0).type);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStartBlockChainDownload() throws Exception {
|
||||
PeerEventListener listener = control.createMock(PeerEventListener.class);
|
||||
peer.addEventListener(listener);
|
||||
|
||||
Block b1 = TestUtils.createFakeBlock(unitTestParams, blockStore).block;
|
||||
blockChain.add(b1);
|
||||
|
||||
expect(conn.getVersionMessage()).andStubReturn(new VersionMessage(unitTestParams, 100));
|
||||
|
||||
listener.onChainDownloadStarted(peer, 99);
|
||||
expectLastCall();
|
||||
|
||||
Capture<GetBlocksMessage> message = new Capture<GetBlocksMessage>();
|
||||
conn.writeMessage(capture(message));
|
||||
expectLastCall();
|
||||
|
||||
control.replay();
|
||||
|
||||
peer.startBlockChainDownload();
|
||||
control.verify();
|
||||
|
||||
List<Sha256Hash> expectedLocator = new ArrayList<Sha256Hash>();
|
||||
expectedLocator.add(b1.getHash());
|
||||
expectedLocator.add(unitTestParams.genesisBlock.getHash());
|
||||
|
||||
assertEquals(message.getValue().getLocator(), expectedLocator);
|
||||
assertEquals(message.getValue().getStopHash(), Sha256Hash.ZERO_HASH);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetBlock() throws Exception {
|
||||
PeerEventListener listener = control.createMock(PeerEventListener.class);
|
||||
peer.addEventListener(listener);
|
||||
|
||||
Block b1 = TestUtils.createFakeBlock(unitTestParams, blockStore).block;
|
||||
blockChain.add(b1);
|
||||
|
||||
Block prev = TestUtils.makeSolvedTestBlock(unitTestParams, blockStore);
|
||||
final Block b2 = TestUtils.makeSolvedTestBlock(unitTestParams, prev);
|
||||
|
||||
expect(conn.getVersionMessage()).andStubReturn(new VersionMessage(unitTestParams, 100));
|
||||
|
||||
Capture<GetDataMessage> message = new Capture<GetDataMessage>();
|
||||
conn.writeMessage(capture(message));
|
||||
expectLastCall();
|
||||
|
||||
expect(conn.readMessage()).andReturn(b2);
|
||||
|
||||
expectPeerDisconnect();
|
||||
|
||||
control.replay();
|
||||
|
||||
Future<Block> resultFuture = peer.getBlock(b2.getHash());
|
||||
peer.run();
|
||||
|
||||
assertEquals(b2.getHash(), resultFuture.get().getHash());
|
||||
|
||||
control.verify();
|
||||
|
||||
List<Sha256Hash> expectedLocator = new ArrayList<Sha256Hash>();
|
||||
expectedLocator.add(b1.getHash());
|
||||
expectedLocator.add(unitTestParams.genesisBlock.getHash());
|
||||
|
||||
List<InventoryItem> items = message.getValue().getItems();
|
||||
assertEquals(1, items.size());
|
||||
assertEquals(b2.getHash(), items.get(0).hash);
|
||||
assertEquals(InventoryItem.Type.Block, items.get(0).type);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRun_new_block() throws Exception {
|
||||
PeerEventListener listener = control.createMock(PeerEventListener.class);
|
||||
peer.addEventListener(listener);
|
||||
|
||||
expect(conn.readMessage()).andAnswer(new IAnswer<Message>() {
|
||||
public Message answer() throws Throwable {
|
||||
return TestUtils.makeSolvedTestBlock(unitTestParams, blockStore);
|
||||
}
|
||||
});
|
||||
expect(conn.getVersionMessage()).andReturn(new VersionMessage(unitTestParams, 100));
|
||||
listener.onBlocksDownloaded(eq(peer), anyObject(Block.class), eq(99));
|
||||
expectLastCall();
|
||||
expectPeerDisconnect();
|
||||
|
||||
control.replay();
|
||||
|
||||
peer.run();
|
||||
control.verify();
|
||||
}
|
||||
|
||||
private void expectPeerDisconnect() throws IOException, ProtocolException {
|
||||
expect(conn.readMessage()).andAnswer(new IAnswer<Message>() {
|
||||
public Message answer() throws Throwable {
|
||||
peer.disconnect();
|
||||
throw new IOException("done");
|
||||
}
|
||||
});
|
||||
conn.shutdown();
|
||||
expectLastCall().times(2);
|
||||
}
|
||||
}
|
@ -45,7 +45,7 @@ public class TestUtils {
|
||||
public static BlockPair createFakeBlock(NetworkParameters params, BlockStore blockStore,
|
||||
Transaction... transactions) {
|
||||
try {
|
||||
Block b = blockStore.getChainHead().getHeader().createNextBlock(new ECKey().toAddress(params));
|
||||
Block b = makeTestBlock(params, blockStore);
|
||||
// Coinbase tx was already added.
|
||||
for (Transaction tx : transactions)
|
||||
b.addTransaction(tx);
|
||||
@ -62,4 +62,23 @@ public class TestUtils {
|
||||
throw new RuntimeException(e); // Cannot happen.
|
||||
}
|
||||
}
|
||||
|
||||
public static Block makeTestBlock(NetworkParameters params,
|
||||
BlockStore blockStore) throws BlockStoreException {
|
||||
return blockStore.getChainHead().getHeader().createNextBlock(new ECKey().toAddress(params));
|
||||
}
|
||||
|
||||
public static Block makeSolvedTestBlock(NetworkParameters params,
|
||||
BlockStore blockStore) throws BlockStoreException {
|
||||
Block b = blockStore.getChainHead().getHeader().createNextBlock(new ECKey().toAddress(params));
|
||||
b.solve();
|
||||
return b;
|
||||
}
|
||||
|
||||
public static Block makeSolvedTestBlock(NetworkParameters params,
|
||||
Block prev) throws BlockStoreException {
|
||||
Block b = prev.createNextBlock(new ECKey().toAddress(params));
|
||||
b.solve();
|
||||
return b;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user