Fixed problem with sending broadcasts
(while adding some tests)
This commit is contained in:
parent
af3e63f592
commit
e4a69f42b0
@ -26,6 +26,7 @@ import ch.dissem.bitmessage.entity.valueobject.InventoryVector;
|
|||||||
import ch.dissem.bitmessage.entity.valueobject.Label;
|
import ch.dissem.bitmessage.entity.valueobject.Label;
|
||||||
import ch.dissem.bitmessage.entity.valueobject.PrivateKey;
|
import ch.dissem.bitmessage.entity.valueobject.PrivateKey;
|
||||||
import ch.dissem.bitmessage.exception.DecryptionFailedException;
|
import ch.dissem.bitmessage.exception.DecryptionFailedException;
|
||||||
|
import ch.dissem.bitmessage.factory.Factory;
|
||||||
import ch.dissem.bitmessage.ports.*;
|
import ch.dissem.bitmessage.ports.*;
|
||||||
import ch.dissem.bitmessage.utils.Property;
|
import ch.dissem.bitmessage.utils.Property;
|
||||||
import ch.dissem.bitmessage.utils.TTL;
|
import ch.dissem.bitmessage.utils.TTL;
|
||||||
@ -168,7 +169,7 @@ public class BitmessageContext {
|
|||||||
ctx.send(
|
ctx.send(
|
||||||
msg.getFrom(),
|
msg.getFrom(),
|
||||||
to,
|
to,
|
||||||
new Msg(msg),
|
wrapInObjectPayload(msg),
|
||||||
TTL.msg()
|
TTL.msg()
|
||||||
);
|
);
|
||||||
msg.setStatus(SENT);
|
msg.setStatus(SENT);
|
||||||
@ -179,6 +180,17 @@ public class BitmessageContext {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ObjectPayload wrapInObjectPayload(Plaintext msg) {
|
||||||
|
switch (msg.getType()) {
|
||||||
|
case MSG:
|
||||||
|
return new Msg(msg);
|
||||||
|
case BROADCAST:
|
||||||
|
return Factory.getBroadcast(msg);
|
||||||
|
default:
|
||||||
|
throw new RuntimeException("Unknown message type " + msg.getType());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void startup() {
|
public void startup() {
|
||||||
ctx.getNetworkHandler().start(networkListener);
|
ctx.getNetworkHandler().start(networkListener);
|
||||||
}
|
}
|
||||||
|
@ -196,7 +196,8 @@ public class Factory {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ObjectPayload getBroadcast(BitmessageAddress sendingAddress, Plaintext plaintext) {
|
public static ObjectPayload getBroadcast(Plaintext plaintext) {
|
||||||
|
BitmessageAddress sendingAddress = plaintext.getFrom();
|
||||||
if (sendingAddress.getVersion() < 4) {
|
if (sendingAddress.getVersion() < 4) {
|
||||||
return new V4Broadcast(sendingAddress, plaintext);
|
return new V4Broadcast(sendingAddress, plaintext);
|
||||||
} else {
|
} else {
|
||||||
|
@ -0,0 +1,164 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2016 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;
|
||||||
|
|
||||||
|
import ch.dissem.bitmessage.cryptography.bc.BouncyCryptography;
|
||||||
|
import ch.dissem.bitmessage.entity.BitmessageAddress;
|
||||||
|
import ch.dissem.bitmessage.entity.ObjectMessage;
|
||||||
|
import ch.dissem.bitmessage.entity.Plaintext;
|
||||||
|
import ch.dissem.bitmessage.entity.payload.ObjectType;
|
||||||
|
import ch.dissem.bitmessage.entity.payload.Pubkey;
|
||||||
|
import ch.dissem.bitmessage.ports.*;
|
||||||
|
import ch.dissem.bitmessage.utils.MessageMatchers;
|
||||||
|
import ch.dissem.bitmessage.utils.Singleton;
|
||||||
|
import ch.dissem.bitmessage.utils.TestUtils;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static ch.dissem.bitmessage.entity.payload.ObjectType.*;
|
||||||
|
import static ch.dissem.bitmessage.utils.MessageMatchers.object;
|
||||||
|
import static org.hamcrest.CoreMatchers.is;
|
||||||
|
import static org.hamcrest.CoreMatchers.notNullValue;
|
||||||
|
import static org.junit.Assert.assertThat;
|
||||||
|
import static org.mockito.Matchers.any;
|
||||||
|
import static org.mockito.Mockito.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Christian Basler
|
||||||
|
*/
|
||||||
|
public class BitmessageContextTest {
|
||||||
|
private BitmessageContext ctx;
|
||||||
|
private BitmessageContext.Listener listener;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() throws Exception {
|
||||||
|
Field field = Singleton.class.getDeclaredField("cryptography");
|
||||||
|
field.setAccessible(true);
|
||||||
|
field.set(null, null);
|
||||||
|
|
||||||
|
listener = mock(BitmessageContext.Listener.class);
|
||||||
|
ctx = new BitmessageContext.Builder()
|
||||||
|
.addressRepo(mock(AddressRepository.class))
|
||||||
|
.cryptography(new BouncyCryptography())
|
||||||
|
.inventory(mock(Inventory.class))
|
||||||
|
.listener(listener)
|
||||||
|
.messageCallback(mock(MessageCallback.class))
|
||||||
|
.messageRepo(mock(MessageRepository.class))
|
||||||
|
.networkHandler(mock(NetworkHandler.class))
|
||||||
|
.nodeRegistry(mock(NodeRegistry.class))
|
||||||
|
.powRepo(mock(ProofOfWorkRepository.class))
|
||||||
|
.proofOfWorkEngine(mock(ProofOfWorkEngine.class))
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void ensureContactIsSavedAndPubkeyRequested() {
|
||||||
|
BitmessageAddress contact = new BitmessageAddress("BM-opWQhvk9xtMFvQA2Kvetedpk8LkbraWHT");
|
||||||
|
ctx.addContact(contact);
|
||||||
|
|
||||||
|
verify(ctx.addresses(), times(2)).save(contact);
|
||||||
|
verify(ctx.internals().getProofOfWorkEngine())
|
||||||
|
.calculateNonce(any(byte[].class), any(byte[].class), any(ProofOfWorkEngine.Callback.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void ensurePubkeyIsNotRequestedIfItExists() throws Exception {
|
||||||
|
ObjectMessage object = TestUtils.loadObjectMessage(2, "V2Pubkey.payload");
|
||||||
|
Pubkey pubkey = (Pubkey) object.getPayload();
|
||||||
|
BitmessageAddress contact = new BitmessageAddress("BM-opWQhvk9xtMFvQA2Kvetedpk8LkbraWHT");
|
||||||
|
contact.setPubkey(pubkey);
|
||||||
|
|
||||||
|
ctx.addContact(contact);
|
||||||
|
|
||||||
|
verify(ctx.addresses(), times(1)).save(contact);
|
||||||
|
verify(ctx.internals().getProofOfWorkEngine(), never())
|
||||||
|
.calculateNonce(any(byte[].class), any(byte[].class), any(ProofOfWorkEngine.Callback.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void ensureSubscriptionIsAddedAndExistingBroadcastsRetrieved() throws Exception {
|
||||||
|
BitmessageAddress address = new BitmessageAddress("BM-2D9Vc5rFxxR5vTi53T9gkLfemViHRMVLQZ");
|
||||||
|
|
||||||
|
List<ObjectMessage> objects = new LinkedList<>();
|
||||||
|
objects.add(TestUtils.loadObjectMessage(4, "V4Broadcast.payload"));
|
||||||
|
objects.add(TestUtils.loadObjectMessage(5, "V5Broadcast.payload"));
|
||||||
|
when(ctx.internals().getInventory().getObjects(eq(address.getStream()), anyLong(), any(ObjectType.class)))
|
||||||
|
.thenReturn(objects);
|
||||||
|
|
||||||
|
ctx.addSubscribtion(address);
|
||||||
|
|
||||||
|
verify(ctx.addresses(), times(1)).save(address);
|
||||||
|
assertThat(address.isSubscribed(), is(true));
|
||||||
|
verify(ctx.internals().getInventory()).getObjects(eq(address.getStream()), anyLong(), any(ObjectType.class));
|
||||||
|
verify(listener).receive(any(Plaintext.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void ensureIdentityIsCreated() {
|
||||||
|
assertThat(ctx.createIdentity(false), notNullValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void ensureMessageIsSent() throws Exception {
|
||||||
|
ctx.send(TestUtils.loadIdentity("BM-2cSqjfJ8xK6UUn5Rw3RpdGQ9RsDkBhWnS8"), TestUtils.loadContact(),
|
||||||
|
"Subject", "Message");
|
||||||
|
verify(ctx.internals().getProofOfWorkRepository(), timeout(10000).atLeastOnce())
|
||||||
|
.putObject(object(MSG), eq(1000L), eq(1000L));
|
||||||
|
verify(ctx.messages(), timeout(10000).atLeastOnce()).save(MessageMatchers.plaintext(Plaintext.Type.MSG));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void ensurePubkeyIsRequestedIfItIsMissing() throws Exception {
|
||||||
|
ctx.send(TestUtils.loadIdentity("BM-2cSqjfJ8xK6UUn5Rw3RpdGQ9RsDkBhWnS8"),
|
||||||
|
new BitmessageAddress("BM-opWQhvk9xtMFvQA2Kvetedpk8LkbraWHT"),
|
||||||
|
"Subject", "Message");
|
||||||
|
verify(ctx.internals().getProofOfWorkRepository(), timeout(10000).atLeastOnce())
|
||||||
|
.putObject(object(GET_PUBKEY), eq(1000L), eq(1000L));
|
||||||
|
verify(ctx.messages(), timeout(10000).atLeastOnce()).save(MessageMatchers.plaintext(Plaintext.Type.MSG));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = IllegalArgumentException.class)
|
||||||
|
public void ensureSenderMustBeIdentity() {
|
||||||
|
ctx.send(new BitmessageAddress("BM-opWQhvk9xtMFvQA2Kvetedpk8LkbraWHT"),
|
||||||
|
new BitmessageAddress("BM-opWQhvk9xtMFvQA2Kvetedpk8LkbraWHT"),
|
||||||
|
"Subject", "Message");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void ensureBroadcastIsSent() throws Exception {
|
||||||
|
ctx.broadcast(TestUtils.loadIdentity("BM-2cSqjfJ8xK6UUn5Rw3RpdGQ9RsDkBhWnS8"),
|
||||||
|
"Subject", "Message");
|
||||||
|
verify(ctx.internals().getProofOfWorkRepository(), timeout(10000).atLeastOnce())
|
||||||
|
.putObject(object(BROADCAST), eq(1000L), eq(1000L));
|
||||||
|
verify(ctx.internals().getProofOfWorkEngine())
|
||||||
|
.calculateNonce(any(byte[].class), any(byte[].class), any(ProofOfWorkEngine.Callback.class));
|
||||||
|
verify(ctx.messages(), timeout(10000).atLeastOnce()).save(MessageMatchers.plaintext(Plaintext.Type.BROADCAST));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = IllegalArgumentException.class)
|
||||||
|
public void ensureSenderWithoutPrivateKeyThrowsException() {
|
||||||
|
Plaintext msg = new Plaintext.Builder(Plaintext.Type.BROADCAST)
|
||||||
|
.from(new BitmessageAddress("BM-2cSqjfJ8xK6UUn5Rw3RpdGQ9RsDkBhWnS8"))
|
||||||
|
.message("Subject", "Message")
|
||||||
|
.build();
|
||||||
|
ctx.send(msg);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2016 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.utils;
|
||||||
|
|
||||||
|
import ch.dissem.bitmessage.entity.ObjectMessage;
|
||||||
|
import ch.dissem.bitmessage.entity.Plaintext;
|
||||||
|
import ch.dissem.bitmessage.entity.payload.ObjectType;
|
||||||
|
import org.hamcrest.BaseMatcher;
|
||||||
|
import org.hamcrest.Description;
|
||||||
|
import org.hamcrest.Matcher;
|
||||||
|
import org.mockito.Matchers;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Christian Basler
|
||||||
|
*/
|
||||||
|
public class MessageMatchers {
|
||||||
|
public static Plaintext plaintext(final Plaintext.Type type) {
|
||||||
|
return Matchers.argThat(new BaseMatcher<Plaintext>() {
|
||||||
|
@Override
|
||||||
|
public boolean matches(Object item) {
|
||||||
|
return item instanceof Plaintext && ((Plaintext) item).getType() == type;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void describeTo(Description description) {
|
||||||
|
description.appendText("type should be ").appendValue(type);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ObjectMessage object(final ObjectType type) {
|
||||||
|
return Matchers.argThat(new BaseMatcher<ObjectMessage>() {
|
||||||
|
@Override
|
||||||
|
public boolean matches(Object item) {
|
||||||
|
return item instanceof ObjectMessage && ((ObjectMessage) item).getPayload().getType() == type;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void describeTo(Description description) {
|
||||||
|
description.appendText("payload type should be ").appendValue(type);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -6,9 +6,7 @@ import ch.dissem.bitmessage.entity.Plaintext;
|
|||||||
import ch.dissem.bitmessage.networking.DefaultNetworkHandler;
|
import ch.dissem.bitmessage.networking.DefaultNetworkHandler;
|
||||||
import ch.dissem.bitmessage.repository.*;
|
import ch.dissem.bitmessage.repository.*;
|
||||||
import ch.dissem.bitmessage.utils.TTL;
|
import ch.dissem.bitmessage.utils.TTL;
|
||||||
import org.junit.AfterClass;
|
import org.junit.*;
|
||||||
import org.junit.BeforeClass;
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
@ -21,16 +19,16 @@ import static org.junit.Assert.assertThat;
|
|||||||
* @author Christian Basler
|
* @author Christian Basler
|
||||||
*/
|
*/
|
||||||
public class SystemTest {
|
public class SystemTest {
|
||||||
static BitmessageContext alice;
|
private BitmessageContext alice;
|
||||||
static TestListener aliceListener = new TestListener();
|
private TestListener aliceListener = new TestListener();
|
||||||
static BitmessageAddress aliceIdentity;
|
private BitmessageAddress aliceIdentity;
|
||||||
|
|
||||||
static BitmessageContext bob;
|
private BitmessageContext bob;
|
||||||
static TestListener bobListener = new TestListener();
|
private TestListener bobListener = new TestListener();
|
||||||
static BitmessageAddress bobIdentity;
|
private BitmessageAddress bobIdentity;
|
||||||
|
|
||||||
@BeforeClass
|
@Before
|
||||||
public static void setUp() {
|
public void setUp() {
|
||||||
TTL.msg(5 * MINUTE);
|
TTL.msg(5 * MINUTE);
|
||||||
TTL.getpubkey(5 * MINUTE);
|
TTL.getpubkey(5 * MINUTE);
|
||||||
TTL.pubkey(5 * MINUTE);
|
TTL.pubkey(5 * MINUTE);
|
||||||
@ -65,20 +63,32 @@ public class SystemTest {
|
|||||||
bobIdentity = bob.createIdentity(false);
|
bobIdentity = bob.createIdentity(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterClass
|
@After
|
||||||
public static void tearDown() {
|
public void tearDown() {
|
||||||
alice.shutdown();
|
alice.shutdown();
|
||||||
bob.shutdown();
|
bob.shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void ensureAliceCanSendMessageToBob() throws Exception {
|
public void ensureAliceCanSendMessageToBob() throws Exception {
|
||||||
bobListener.reset();
|
|
||||||
String originalMessage = UUID.randomUUID().toString();
|
String originalMessage = UUID.randomUUID().toString();
|
||||||
alice.send(aliceIdentity, new BitmessageAddress(bobIdentity.getAddress()), "Subject", originalMessage);
|
alice.send(aliceIdentity, new BitmessageAddress(bobIdentity.getAddress()), "Subject", originalMessage);
|
||||||
|
|
||||||
Plaintext plaintext = bobListener.get(15, TimeUnit.MINUTES);
|
Plaintext plaintext = bobListener.get(15, TimeUnit.MINUTES);
|
||||||
|
|
||||||
|
assertThat(plaintext.getType(), equalTo(Plaintext.Type.MSG));
|
||||||
|
assertThat(plaintext.getText(), equalTo(originalMessage));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void ensureBobCanReceiveBroadcastFromAlice() throws Exception {
|
||||||
|
String originalMessage = UUID.randomUUID().toString();
|
||||||
|
bob.addSubscribtion(new BitmessageAddress(aliceIdentity.getAddress()));
|
||||||
|
alice.broadcast(aliceIdentity, "Subject", originalMessage);
|
||||||
|
|
||||||
|
Plaintext plaintext = bobListener.get(15, TimeUnit.MINUTES);
|
||||||
|
|
||||||
|
assertThat(plaintext.getType(), equalTo(Plaintext.Type.BROADCAST));
|
||||||
assertThat(plaintext.getText(), equalTo(originalMessage));
|
assertThat(plaintext.getText(), equalTo(originalMessage));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user