Check periodically for retransmittable packets. Bug #46.

This commit is contained in:
akwizgran
2014-12-14 20:26:41 +00:00
parent 29a6596ee3
commit 388b36b6be
51 changed files with 351 additions and 331 deletions

View File

@@ -2,6 +2,7 @@ package org.briarproject.messaging;
import static org.briarproject.api.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
import static org.briarproject.api.messaging.MessagingConstants.GROUP_SALT_LENGTH;
import static org.briarproject.api.transport.TransportConstants.MAX_CLOCK_DIFFERENCE;
import static org.briarproject.api.transport.TransportConstants.MAX_FRAME_LENGTH;
import static org.briarproject.api.transport.TransportConstants.TAG_LENGTH;
@@ -32,7 +33,9 @@ import org.briarproject.api.messaging.Message;
import org.briarproject.api.messaging.MessageFactory;
import org.briarproject.api.messaging.MessageVerifier;
import org.briarproject.api.messaging.MessagingSession;
import org.briarproject.api.messaging.PacketReader;
import org.briarproject.api.messaging.PacketReaderFactory;
import org.briarproject.api.messaging.PacketWriter;
import org.briarproject.api.messaging.PacketWriterFactory;
import org.briarproject.api.transport.Endpoint;
import org.briarproject.api.transport.StreamContext;
@@ -56,8 +59,9 @@ import com.google.inject.Injector;
public class SimplexMessagingIntegrationTest extends BriarTestCase {
private static final long CLOCK_DIFFERENCE = 60 * 1000;
private static final long LATENCY = 60 * 1000;
private static final int MAX_LATENCY = 2 * 60 * 1000; // 2 minutes
private static final int ROTATION_PERIOD =
MAX_CLOCK_DIFFERENCE + MAX_LATENCY;
private final File testDir = TestUtils.getTestDirectory();
private final File aliceDir = new File(testDir, "alice");
@@ -73,8 +77,7 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase {
// Create matching secrets for Alice and Bob
initialSecret = new byte[32];
new Random().nextBytes(initialSecret);
long rotationPeriod = 2 * CLOCK_DIFFERENCE + LATENCY;
epoch = System.currentTimeMillis() - 2 * rotationPeriod;
epoch = System.currentTimeMillis() - 2 * ROTATION_PERIOD;
}
@Override
@@ -121,10 +124,10 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase {
db.addGroup(group);
db.setInboxGroup(contactId, group);
// Add the transport and the endpoint
db.addTransport(transportId, LATENCY);
db.addTransport(transportId, MAX_LATENCY);
Endpoint ep = new Endpoint(contactId, transportId, epoch, true);
db.addEndpoint(ep);
keyManager.endpointAdded(ep, LATENCY, initialSecret.clone());
keyManager.endpointAdded(ep, MAX_LATENCY, initialSecret.clone());
// Send Bob a message
String contentType = "text/plain";
long timestamp = System.currentTimeMillis();
@@ -145,10 +148,11 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase {
EventBus eventBus = alice.getInstance(EventBus.class);
PacketWriterFactory packetWriterFactory =
alice.getInstance(PacketWriterFactory.class);
MessagingSession session = new SimplexOutgoingSession(db,
new ImmediateExecutor(), eventBus, packetWriterFactory,
contactId, transportId, Long.MAX_VALUE,
PacketWriter packetWriter = packetWriterFactory.createPacketWriter(
streamWriter.getOutputStream());
MessagingSession session = new SimplexOutgoingSession(db,
new ImmediateExecutor(), eventBus, contactId, transportId,
MAX_LATENCY, packetWriter);
// Write whatever needs to be written
session.run();
streamWriter.getOutputStream().close();
@@ -182,10 +186,10 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase {
db.addGroup(group);
db.setInboxGroup(contactId, group);
// Add the transport and the endpoint
db.addTransport(transportId, LATENCY);
db.addTransport(transportId, MAX_LATENCY);
Endpoint ep = new Endpoint(contactId, transportId, epoch, false);
db.addEndpoint(ep);
keyManager.endpointAdded(ep, LATENCY, initialSecret.clone());
keyManager.endpointAdded(ep, MAX_LATENCY, initialSecret.clone());
// Set up an event listener
MessageListener listener = new MessageListener();
bob.getInstance(EventBus.class).addListener(listener);
@@ -208,10 +212,11 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase {
bob.getInstance(MessageVerifier.class);
PacketReaderFactory packetReaderFactory =
bob.getInstance(PacketReaderFactory.class);
PacketReader packetReader = packetReaderFactory.createPacketReader(
streamReader.getInputStream());
MessagingSession session = new IncomingSession(db,
new ImmediateExecutor(), new ImmediateExecutor(), eventBus,
messageVerifier, packetReaderFactory, contactId, transportId,
streamReader.getInputStream());
messageVerifier, contactId, transportId, packetReader);
// No messages should have been added yet
assertFalse(listener.messageAdded);
// Read whatever needs to be read

View File

@@ -1,72 +1,53 @@
package org.briarproject.messaging;
import java.io.ByteArrayOutputStream;
import java.util.Arrays;
import java.util.Random;
import java.util.concurrent.Executor;
import org.briarproject.BriarTestCase;
import org.briarproject.TestUtils;
import org.briarproject.api.ContactId;
import org.briarproject.api.TransportId;
import org.briarproject.api.UniqueId;
import org.briarproject.api.db.DatabaseComponent;
import org.briarproject.api.event.EventBus;
import org.briarproject.api.messaging.Ack;
import org.briarproject.api.messaging.MessageId;
import org.briarproject.api.messaging.PacketWriterFactory;
import org.briarproject.api.messaging.PacketWriter;
import org.briarproject.plugins.ImmediateExecutor;
import org.briarproject.serial.SerialModule;
import org.jmock.Expectations;
import org.jmock.Mockery;
import org.junit.Test;
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Module;
public class SimplexOutgoingSessionTest extends BriarTestCase {
// FIXME: This is an integration test, not a unit test
private static final int MAX_MESSAGES_PER_ACK = 10;
private final Mockery context;
private final DatabaseComponent db;
private final Executor dbExecutor;
private final EventBus eventBus;
private final PacketWriterFactory packetWriterFactory;
private final ContactId contactId;
private final TransportId transportId;
private final MessageId messageId;
private final byte[] secret;
private final int maxLatency;
private final PacketWriter packetWriter;
public SimplexOutgoingSessionTest() {
context = new Mockery();
db = context.mock(DatabaseComponent.class);
dbExecutor = new ImmediateExecutor();
Module testModule = new AbstractModule() {
@Override
public void configure() {
bind(PacketWriterFactory.class).to(
PacketWriterFactoryImpl.class);
}
};
Injector i = Guice.createInjector(testModule, new SerialModule());
eventBus = context.mock(EventBus.class);
packetWriterFactory = i.getInstance(PacketWriterFactory.class);
packetWriter = context.mock(PacketWriter.class);
contactId = new ContactId(234);
transportId = new TransportId("id");
messageId = new MessageId(TestUtils.getRandomId());
secret = new byte[32];
new Random().nextBytes(secret);
maxLatency = Integer.MAX_VALUE;
}
@Test
public void testNothingToSend() throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
final SimplexOutgoingSession session = new SimplexOutgoingSession(db,
dbExecutor, eventBus, packetWriterFactory, contactId,
transportId, Long.MAX_VALUE, out);
dbExecutor, eventBus, contactId, transportId, maxLatency,
packetWriter);
context.checking(new Expectations() {{
// Add listener
oneOf(eventBus).addListener(session);
@@ -74,46 +55,45 @@ public class SimplexOutgoingSessionTest extends BriarTestCase {
oneOf(db).generateTransportAcks(contactId);
will(returnValue(null));
// No transport updates to send
oneOf(db).generateTransportUpdates(with(contactId),
with(any(long.class)));
oneOf(db).generateTransportUpdates(contactId, maxLatency);
will(returnValue(null));
// No subscription ack to send
oneOf(db).generateSubscriptionAck(contactId);
will(returnValue(null));
// No subscription update to send
oneOf(db).generateSubscriptionUpdate(with(contactId),
with(any(long.class)));
oneOf(db).generateSubscriptionUpdate(contactId, maxLatency);
will(returnValue(null));
// No retention ack to send
oneOf(db).generateRetentionAck(contactId);
will(returnValue(null));
// No retention update to send
oneOf(db).generateRetentionUpdate(with(contactId),
with(any(long.class)));
oneOf(db).generateRetentionUpdate(contactId, maxLatency);
will(returnValue(null));
// No acks to send
oneOf(db).generateAck(with(contactId), with(any(int.class)));
oneOf(packetWriter).getMaxMessagesForAck(with(any(long.class)));
will(returnValue(MAX_MESSAGES_PER_ACK));
oneOf(db).generateAck(contactId, MAX_MESSAGES_PER_ACK);
will(returnValue(null));
// No messages to send
oneOf(db).generateBatch(with(contactId), with(any(int.class)),
with(any(long.class)));
with(maxLatency));
will(returnValue(null));
// Flush the output stream
oneOf(packetWriter).flush();
// Remove listener
oneOf(eventBus).removeListener(session);
}});
session.run();
// Nothing should have been written
assertEquals(0, out.size());
context.assertIsSatisfied();
}
@Test
public void testSomethingToSend() throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
final SimplexOutgoingSession session = new SimplexOutgoingSession(db,
dbExecutor, eventBus, packetWriterFactory, contactId,
transportId, Long.MAX_VALUE, out);
final Ack ack = new Ack(Arrays.asList(messageId));
final byte[] raw = new byte[1234];
final SimplexOutgoingSession session = new SimplexOutgoingSession(db,
dbExecutor, eventBus, contactId, transportId, maxLatency,
packetWriter);
context.checking(new Expectations() {{
// Add listener
oneOf(eventBus).addListener(session);
@@ -121,43 +101,46 @@ public class SimplexOutgoingSessionTest extends BriarTestCase {
oneOf(db).generateTransportAcks(contactId);
will(returnValue(null));
// No transport updates to send
oneOf(db).generateTransportUpdates(with(contactId),
with(any(long.class)));
oneOf(db).generateTransportUpdates(contactId, maxLatency);
will(returnValue(null));
// No subscription ack to send
oneOf(db).generateSubscriptionAck(contactId);
will(returnValue(null));
// No subscription update to send
oneOf(db).generateSubscriptionUpdate(with(contactId),
with(any(long.class)));
oneOf(db).generateSubscriptionUpdate(contactId, maxLatency);
will(returnValue(null));
// No retention ack to send
oneOf(db).generateRetentionAck(contactId);
will(returnValue(null));
// No retention update to send
oneOf(db).generateRetentionUpdate(with(contactId),
with(any(long.class)));
oneOf(db).generateRetentionUpdate(contactId, maxLatency);
will(returnValue(null));
// One ack to send
oneOf(db).generateAck(with(contactId), with(any(int.class)));
will(returnValue(new Ack(Arrays.asList(messageId))));
oneOf(packetWriter).getMaxMessagesForAck(with(any(long.class)));
will(returnValue(MAX_MESSAGES_PER_ACK));
oneOf(db).generateAck(contactId, MAX_MESSAGES_PER_ACK);
will(returnValue(ack));
oneOf(packetWriter).writeAck(ack);
// No more acks
oneOf(db).generateAck(with(contactId), with(any(int.class)));
oneOf(packetWriter).getMaxMessagesForAck(with(any(long.class)));
will(returnValue(MAX_MESSAGES_PER_ACK));
oneOf(db).generateAck(contactId, MAX_MESSAGES_PER_ACK);
will(returnValue(null));
// One message to send
oneOf(db).generateBatch(with(contactId), with(any(int.class)),
with(any(long.class)));
with(maxLatency));
will(returnValue(Arrays.asList(raw)));
oneOf(packetWriter).writeMessage(raw);
// No more messages
oneOf(db).generateBatch(with(contactId), with(any(int.class)),
with(any(long.class)));
with(maxLatency));
will(returnValue(null));
// Flush the output stream
oneOf(packetWriter).flush();
// Remove listener
oneOf(eventBus).removeListener(session);
}});
session.run();
// Something should have been written
assertTrue(out.size() > UniqueId.LENGTH + raw.length);
context.assertIsSatisfied();
}
}