Added synchronization code and unit test.
Synchronisation fails if the trusted host has no new messages - this needs to be fixed (but shouldn't be an issue for real world applications)
This commit is contained in:
@ -1,64 +0,0 @@
|
||||
/*
|
||||
* Copyright 2015 Christian Basler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package ch.dissem.bitmessage.networking;
|
||||
|
||||
import ch.dissem.bitmessage.entity.NetworkMessage;
|
||||
import ch.dissem.bitmessage.entity.Version;
|
||||
import ch.dissem.bitmessage.entity.valueobject.NetworkAddress;
|
||||
import ch.dissem.bitmessage.utils.UnixTime;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* FIXME: there really should be sensible tests for the network handler
|
||||
*/
|
||||
public class DefaultNetworkHandlerTest {
|
||||
private NetworkAddress localhost = new NetworkAddress.Builder().ipv4(127, 0, 0, 1).port(8444).build();
|
||||
|
||||
// void start(MessageListener listener);
|
||||
// void stop();
|
||||
// void offer(InventoryVector iv);
|
||||
// Property getNetworkStatus();
|
||||
|
||||
@Ignore
|
||||
@Test(expected = InterruptedException.class)
|
||||
public void testSendMessage() throws Exception {
|
||||
final Thread baseThread = Thread.currentThread();
|
||||
DefaultNetworkHandler net = new DefaultNetworkHandler();
|
||||
// net.setListener(localhost, new NetworkHandler.MessageListener() {
|
||||
// @Override
|
||||
// public void receive(ObjectPayload payload) {
|
||||
// System.out.println(payload);
|
||||
// baseThread.interrupt();
|
||||
// }
|
||||
// });
|
||||
NetworkMessage ver = new NetworkMessage(
|
||||
new Version.Builder()
|
||||
.version(3)
|
||||
.services(1)
|
||||
.timestamp(UnixTime.now())
|
||||
.addrFrom(localhost)
|
||||
.addrRecv(localhost)
|
||||
.nonce(-1)
|
||||
.userAgent("Test")
|
||||
.streams(1, 2)
|
||||
.build()
|
||||
);
|
||||
// net.send(localhost, ver);
|
||||
Thread.sleep(20000);
|
||||
}
|
||||
}
|
@ -0,0 +1,147 @@
|
||||
/*
|
||||
* Copyright 2015 Christian Basler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package ch.dissem.bitmessage.networking;
|
||||
|
||||
import ch.dissem.bitmessage.BitmessageContext;
|
||||
import ch.dissem.bitmessage.entity.valueobject.NetworkAddress;
|
||||
import ch.dissem.bitmessage.ports.AddressRepository;
|
||||
import ch.dissem.bitmessage.ports.MessageRepository;
|
||||
import ch.dissem.bitmessage.ports.NetworkHandler;
|
||||
import ch.dissem.bitmessage.security.bc.BouncySecurity;
|
||||
import ch.dissem.bitmessage.utils.Property;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import java.net.InetAddress;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* FIXME: there really should be sensible tests for the network handler
|
||||
*/
|
||||
public class NetworkHandlerTest {
|
||||
private static NetworkAddress localhost = new NetworkAddress.Builder().ipv4(127, 0, 0, 1).port(6001).build();
|
||||
|
||||
private static TestInventory peerInventory;
|
||||
private static TestInventory nodeInventory;
|
||||
|
||||
private static BitmessageContext node;
|
||||
private static NetworkHandler networkHandler;
|
||||
|
||||
@BeforeClass
|
||||
public static void setUp() {
|
||||
peerInventory = new TestInventory();
|
||||
BitmessageContext peer = new BitmessageContext.Builder()
|
||||
.addressRepo(Mockito.mock(AddressRepository.class))
|
||||
.inventory(peerInventory)
|
||||
.messageRepo(Mockito.mock(MessageRepository.class))
|
||||
.port(6001)
|
||||
.nodeRegistry(new TestNodeRegistry())
|
||||
.networkHandler(new DefaultNetworkHandler())
|
||||
.security(new BouncySecurity())
|
||||
.build();
|
||||
peer.startup(Mockito.mock(BitmessageContext.Listener.class));
|
||||
|
||||
nodeInventory = new TestInventory();
|
||||
networkHandler = new DefaultNetworkHandler();
|
||||
node = new BitmessageContext.Builder()
|
||||
.addressRepo(Mockito.mock(AddressRepository.class))
|
||||
.inventory(nodeInventory)
|
||||
.messageRepo(Mockito.mock(MessageRepository.class))
|
||||
.port(6002)
|
||||
.nodeRegistry(new TestNodeRegistry(localhost))
|
||||
.networkHandler(networkHandler)
|
||||
.security(new BouncySecurity())
|
||||
.build();
|
||||
}
|
||||
|
||||
@Test(timeout = 20_000)
|
||||
public void ensureNodesAreConnecting() {
|
||||
try {
|
||||
node.startup(Mockito.mock(BitmessageContext.Listener.class));
|
||||
Property status;
|
||||
do {
|
||||
Thread.yield();
|
||||
status = node.status().getProperty("network").getProperty("connections").getProperty("stream 0");
|
||||
} while (status == null);
|
||||
assertEquals(1, status.getProperty("outgoing").getValue());
|
||||
} finally {
|
||||
shutdown(node);
|
||||
}
|
||||
}
|
||||
|
||||
@Test(timeout = 5_000)
|
||||
public void ensureObjectsAreSynchronizedIfBothHaveObjects() throws Exception {
|
||||
peerInventory.init(
|
||||
"V4Pubkey.payload",
|
||||
"V5Broadcast.payload"
|
||||
);
|
||||
|
||||
nodeInventory.init(
|
||||
"V1Msg.payload"
|
||||
);
|
||||
|
||||
Thread t = networkHandler.synchronize(InetAddress.getLocalHost(), 6001,
|
||||
mock(NetworkHandler.MessageListener.class),
|
||||
10);
|
||||
t.join();
|
||||
assertEquals(3, nodeInventory.getInventory().size());
|
||||
assertEquals(3, peerInventory.getInventory().size());
|
||||
}
|
||||
|
||||
@Test(timeout = 5_000)
|
||||
public void ensureObjectsAreSynchronizedIfOnlyPeerHasObjects() throws Exception {
|
||||
peerInventory.init(
|
||||
"V4Pubkey.payload",
|
||||
"V5Broadcast.payload"
|
||||
);
|
||||
|
||||
nodeInventory.init();
|
||||
|
||||
Thread t = networkHandler.synchronize(InetAddress.getLocalHost(), 6001,
|
||||
mock(NetworkHandler.MessageListener.class),
|
||||
10);
|
||||
t.join();
|
||||
assertEquals(2, nodeInventory.getInventory().size());
|
||||
assertEquals(2, peerInventory.getInventory().size());
|
||||
}
|
||||
|
||||
@Test(timeout = 5_000)
|
||||
public void ensureObjectsAreSynchronizedIfOnlyNodeHasObjects() throws Exception {
|
||||
peerInventory.init();
|
||||
|
||||
nodeInventory.init(
|
||||
"V1Msg.payload"
|
||||
);
|
||||
|
||||
Thread t = networkHandler.synchronize(InetAddress.getLocalHost(), 6001,
|
||||
mock(NetworkHandler.MessageListener.class),
|
||||
10);
|
||||
t.join();
|
||||
assertEquals(1, nodeInventory.getInventory().size());
|
||||
assertEquals(1, peerInventory.getInventory().size());
|
||||
}
|
||||
|
||||
private void shutdown(BitmessageContext node) {
|
||||
node.shutdown();
|
||||
do {
|
||||
Thread.yield();
|
||||
} while (node.isRunning());
|
||||
}
|
||||
}
|
@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright 2015 Christian Basler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package ch.dissem.bitmessage.networking;
|
||||
|
||||
import ch.dissem.bitmessage.entity.ObjectMessage;
|
||||
import ch.dissem.bitmessage.entity.payload.ObjectType;
|
||||
import ch.dissem.bitmessage.entity.valueobject.InventoryVector;
|
||||
import ch.dissem.bitmessage.ports.Inventory;
|
||||
import ch.dissem.bitmessage.utils.TestUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class TestInventory implements Inventory {
|
||||
private final Map<InventoryVector, ObjectMessage> inventory;
|
||||
|
||||
public TestInventory() {
|
||||
this.inventory = new HashMap<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<InventoryVector> getInventory(long... streams) {
|
||||
return new ArrayList<>(inventory.keySet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<InventoryVector> getMissing(List<InventoryVector> offer, long... streams) {
|
||||
return offer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectMessage getObject(InventoryVector vector) {
|
||||
return inventory.get(vector);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ObjectMessage> getObjects(long stream, long version, ObjectType... types) {
|
||||
return new ArrayList<>(inventory.values());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void storeObject(ObjectMessage object) {
|
||||
inventory.put(object.getInventoryVector(), object);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cleanup() {
|
||||
|
||||
}
|
||||
|
||||
public void init(String... resources) throws IOException {
|
||||
inventory.clear();
|
||||
for (String resource : resources) {
|
||||
int version = Integer.parseInt(resource.substring(1, 2));
|
||||
ObjectMessage obj = TestUtils.loadObjectMessage(version, resource);
|
||||
inventory.put(obj.getInventoryVector(), obj);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2015 Christian Basler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package ch.dissem.bitmessage.networking;
|
||||
|
||||
import ch.dissem.bitmessage.entity.valueobject.NetworkAddress;
|
||||
import ch.dissem.bitmessage.ports.NodeRegistry;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Empty {@link NodeRegistry} that doesn't do anything, but shouldn't break things either.
|
||||
*/
|
||||
class TestNodeRegistry implements NodeRegistry {
|
||||
private List<NetworkAddress> nodes;
|
||||
|
||||
public TestNodeRegistry(NetworkAddress... nodes) {
|
||||
this.nodes = Arrays.asList(nodes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<NetworkAddress> getKnownAddresses(int limit, long... streams) {
|
||||
return nodes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void offerAddresses(List<NetworkAddress> addresses) {
|
||||
// Ignore
|
||||
}
|
||||
}
|
BIN
networking/src/test/resources/V1Msg.payload
Normal file
BIN
networking/src/test/resources/V1Msg.payload
Normal file
Binary file not shown.
BIN
networking/src/test/resources/V4Pubkey.payload
Normal file
BIN
networking/src/test/resources/V4Pubkey.payload
Normal file
Binary file not shown.
BIN
networking/src/test/resources/V5Broadcast.payload
Normal file
BIN
networking/src/test/resources/V5Broadcast.payload
Normal file
Binary file not shown.
Reference in New Issue
Block a user