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.PrivateKey;
|
||||
import ch.dissem.bitmessage.exception.DecryptionFailedException;
|
||||
import ch.dissem.bitmessage.factory.Factory;
|
||||
import ch.dissem.bitmessage.ports.*;
|
||||
import ch.dissem.bitmessage.utils.Property;
|
||||
import ch.dissem.bitmessage.utils.TTL;
|
||||
@ -168,7 +169,7 @@ public class BitmessageContext {
|
||||
ctx.send(
|
||||
msg.getFrom(),
|
||||
to,
|
||||
new Msg(msg),
|
||||
wrapInObjectPayload(msg),
|
||||
TTL.msg()
|
||||
);
|
||||
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() {
|
||||
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) {
|
||||
return new V4Broadcast(sendingAddress, plaintext);
|
||||
} 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.repository.*;
|
||||
import ch.dissem.bitmessage.utils.TTL;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.*;
|
||||
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@ -21,16 +19,16 @@ import static org.junit.Assert.assertThat;
|
||||
* @author Christian Basler
|
||||
*/
|
||||
public class SystemTest {
|
||||
static BitmessageContext alice;
|
||||
static TestListener aliceListener = new TestListener();
|
||||
static BitmessageAddress aliceIdentity;
|
||||
private BitmessageContext alice;
|
||||
private TestListener aliceListener = new TestListener();
|
||||
private BitmessageAddress aliceIdentity;
|
||||
|
||||
static BitmessageContext bob;
|
||||
static TestListener bobListener = new TestListener();
|
||||
static BitmessageAddress bobIdentity;
|
||||
private BitmessageContext bob;
|
||||
private TestListener bobListener = new TestListener();
|
||||
private BitmessageAddress bobIdentity;
|
||||
|
||||
@BeforeClass
|
||||
public static void setUp() {
|
||||
@Before
|
||||
public void setUp() {
|
||||
TTL.msg(5 * MINUTE);
|
||||
TTL.getpubkey(5 * MINUTE);
|
||||
TTL.pubkey(5 * MINUTE);
|
||||
@ -65,20 +63,32 @@ public class SystemTest {
|
||||
bobIdentity = bob.createIdentity(false);
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void tearDown() {
|
||||
@After
|
||||
public void tearDown() {
|
||||
alice.shutdown();
|
||||
bob.shutdown();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ensureAliceCanSendMessageToBob() throws Exception {
|
||||
bobListener.reset();
|
||||
String originalMessage = UUID.randomUUID().toString();
|
||||
alice.send(aliceIdentity, new BitmessageAddress(bobIdentity.getAddress()), "Subject", originalMessage);
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user