Fixed problem with sending broadcasts
(while adding some tests)
This commit is contained in:
		| @@ -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)); | ||||
|     } | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user