Massive refactoring to merge handling of simplex and duplex connections.

This commit is contained in:
akwizgran
2014-11-04 16:51:25 +00:00
parent b24f153704
commit 7b8181e309
67 changed files with 1981 additions and 2288 deletions

View File

@@ -46,8 +46,6 @@ import org.briarproject.api.messaging.TransportUpdate;
import org.briarproject.crypto.CryptoModule;
import org.briarproject.db.DatabaseModule;
import org.briarproject.event.EventModule;
import org.briarproject.messaging.duplex.DuplexMessagingModule;
import org.briarproject.messaging.simplex.SimplexMessagingModule;
import org.briarproject.serial.SerialModule;
import org.briarproject.transport.TransportModule;
import org.junit.Test;
@@ -67,8 +65,7 @@ public class ConstantsTest extends BriarTestCase {
Injector i = Guice.createInjector(new TestDatabaseModule(),
new TestLifecycleModule(), new TestSystemModule(),
new CryptoModule(), new DatabaseModule(), new EventModule(),
new MessagingModule(), new DuplexMessagingModule(),
new SimplexMessagingModule(), new SerialModule(),
new MessagingModule(), new SerialModule(),
new TransportModule());
crypto = i.getInstance(CryptoComponent.class);
groupFactory = i.getInstance(GroupFactory.class);

View File

@@ -1,4 +1,4 @@
package org.briarproject.messaging.simplex;
package org.briarproject.messaging;
import static org.briarproject.api.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
import static org.briarproject.api.messaging.MessagingConstants.GROUP_SALT_LENGTH;
@@ -30,9 +30,9 @@ import org.briarproject.api.messaging.GroupFactory;
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.PacketReaderFactory;
import org.briarproject.api.messaging.PacketWriterFactory;
import org.briarproject.api.transport.ConnectionRegistry;
import org.briarproject.api.transport.Endpoint;
import org.briarproject.api.transport.StreamContext;
import org.briarproject.api.transport.StreamReaderFactory;
@@ -41,8 +41,6 @@ import org.briarproject.api.transport.TagRecogniser;
import org.briarproject.crypto.CryptoModule;
import org.briarproject.db.DatabaseModule;
import org.briarproject.event.EventModule;
import org.briarproject.messaging.MessagingModule;
import org.briarproject.messaging.duplex.DuplexMessagingModule;
import org.briarproject.plugins.ImmediateExecutor;
import org.briarproject.serial.SerialModule;
import org.briarproject.transport.TransportModule;
@@ -88,8 +86,7 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase {
return Guice.createInjector(new TestDatabaseModule(dir),
new TestLifecycleModule(), new TestSystemModule(),
new CryptoModule(), new DatabaseModule(), new EventModule(),
new MessagingModule(), new DuplexMessagingModule(),
new SimplexMessagingModule(), new SerialModule(),
new MessagingModule(), new SerialModule(),
new TransportModule());
}
@@ -140,29 +137,26 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase {
Message message = messageFactory.createAnonymousMessage(null, group,
contentType, timestamp, body);
db.addLocalMessage(message);
// Create an outgoing simplex connection
// Create an outgoing messaging session
ByteArrayOutputStream out = new ByteArrayOutputStream();
ConnectionRegistry connRegistry =
alice.getInstance(ConnectionRegistry.class);
StreamWriterFactory connWriterFactory =
StreamWriterFactory streamWriterFactory =
alice.getInstance(StreamWriterFactory.class);
PacketWriterFactory packetWriterFactory =
alice.getInstance(PacketWriterFactory.class);
TestSimplexTransportWriter transport = new TestSimplexTransportWriter(
out, Long.MAX_VALUE, Long.MAX_VALUE);
TestTransportConnectionWriter transport =
new TestTransportConnectionWriter(out);
StreamContext ctx = km.getStreamContext(contactId, transportId);
assertNotNull(ctx);
OutgoingSimplexConnection simplex = new OutgoingSimplexConnection(db,
connRegistry, connWriterFactory, packetWriterFactory, ctx,
transport);
MessagingSession session = new SinglePassOutgoingSession(db,
new ImmediateExecutor(), streamWriterFactory,
packetWriterFactory, ctx, transport);
// Write whatever needs to be written
simplex.write();
assertTrue(transport.getDisposed());
assertFalse(transport.getException());
session.run();
transport.dispose(false);
// Clean up
km.stop();
db.close();
// Return the contents of the simplex connection
// Return the contents of the stream
return out.toByteArray();
}
@@ -204,28 +198,24 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase {
assertEquals(tag.length, read);
StreamContext ctx = rec.recogniseTag(transportId, tag);
assertNotNull(ctx);
// Create an incoming simplex connection
// Create an incoming messaging session
MessageVerifier messageVerifier =
bob.getInstance(MessageVerifier.class);
ConnectionRegistry connRegistry =
bob.getInstance(ConnectionRegistry.class);
StreamReaderFactory connWriterFactory =
StreamReaderFactory streamReaderFactory =
bob.getInstance(StreamReaderFactory.class);
PacketReaderFactory packetWriterFactory =
PacketReaderFactory packetReaderFactory =
bob.getInstance(PacketReaderFactory.class);
TestSimplexTransportReader transport =
new TestSimplexTransportReader(in);
IncomingSimplexConnection simplex = new IncomingSimplexConnection(
TestTransportConnectionReader transport =
new TestTransportConnectionReader(in);
MessagingSession session = new IncomingSession(db,
new ImmediateExecutor(), new ImmediateExecutor(),
messageVerifier, db, connRegistry, connWriterFactory,
packetWriterFactory, ctx, transport);
messageVerifier, streamReaderFactory, packetReaderFactory,
ctx, transport);
// No messages should have been added yet
assertFalse(listener.messageAdded);
// Read whatever needs to be read
simplex.read();
assertTrue(transport.getDisposed());
assertFalse(transport.getException());
assertTrue(transport.getRecognised());
session.run();
transport.dispose(false, true);
// The private message from Alice should have been added
assertTrue(listener.messageAdded);
// Clean up

View File

@@ -1,9 +1,7 @@
package org.briarproject.messaging.simplex;
package org.briarproject.messaging;
import static org.briarproject.api.messaging.MessagingConstants.MAX_PACKET_LENGTH;
import static org.briarproject.api.transport.TransportConstants.HEADER_LENGTH;
import static org.briarproject.api.transport.TransportConstants.MAC_LENGTH;
import static org.briarproject.api.transport.TransportConstants.MIN_STREAM_LENGTH;
import static org.briarproject.api.transport.TransportConstants.TAG_LENGTH;
import java.io.ByteArrayOutputStream;
@@ -23,14 +21,12 @@ import org.briarproject.api.db.DatabaseComponent;
import org.briarproject.api.db.DatabaseExecutor;
import org.briarproject.api.messaging.Ack;
import org.briarproject.api.messaging.MessageId;
import org.briarproject.api.messaging.MessagingSession;
import org.briarproject.api.messaging.PacketWriterFactory;
import org.briarproject.api.transport.ConnectionRegistry;
import org.briarproject.api.transport.StreamContext;
import org.briarproject.api.transport.StreamWriterFactory;
import org.briarproject.crypto.CryptoModule;
import org.briarproject.event.EventModule;
import org.briarproject.messaging.MessagingModule;
import org.briarproject.messaging.duplex.DuplexMessagingModule;
import org.briarproject.serial.SerialModule;
import org.briarproject.transport.TransportModule;
import org.jmock.Expectations;
@@ -42,39 +38,37 @@ import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Module;
public class OutgoingSimplexConnectionTest extends BriarTestCase {
public class SinglePassOutgoingSessionTest extends BriarTestCase {
// FIXME: This is an integration test, not a unit test
private final Mockery context;
private final DatabaseComponent db;
private final ConnectionRegistry connRegistry;
private final StreamWriterFactory connWriterFactory;
private final Executor dbExecutor;
private final StreamWriterFactory streamWriterFactory;
private final PacketWriterFactory packetWriterFactory;
private final ContactId contactId;
private final MessageId messageId;
private final TransportId transportId;
private final byte[] secret;
public OutgoingSimplexConnectionTest() {
public SinglePassOutgoingSessionTest() {
context = new Mockery();
db = context.mock(DatabaseComponent.class);
dbExecutor = Executors.newSingleThreadExecutor();
Module testModule = new AbstractModule() {
@Override
public void configure() {
bind(DatabaseComponent.class).toInstance(db);
bind(Executor.class).annotatedWith(
DatabaseExecutor.class).toInstance(
Executors.newCachedThreadPool());
DatabaseExecutor.class).toInstance(dbExecutor);
}
};
Injector i = Guice.createInjector(testModule,
new TestLifecycleModule(), new TestSystemModule(),
new CryptoModule(), new EventModule(), new MessagingModule(),
new DuplexMessagingModule(), new SimplexMessagingModule(),
new SerialModule(), new TransportModule());
connRegistry = i.getInstance(ConnectionRegistry.class);
connWriterFactory = i.getInstance(StreamWriterFactory.class);
streamWriterFactory = i.getInstance(StreamWriterFactory.class);
packetWriterFactory = i.getInstance(PacketWriterFactory.class);
contactId = new ContactId(234);
messageId = new MessageId(TestUtils.getRandomId());
@@ -83,34 +77,15 @@ public class OutgoingSimplexConnectionTest extends BriarTestCase {
new Random().nextBytes(secret);
}
@Test
public void testConnectionTooShort() throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
TestSimplexTransportWriter transport = new TestSimplexTransportWriter(
out, MAX_PACKET_LENGTH, Long.MAX_VALUE);
StreamContext ctx = new StreamContext(contactId, transportId,
secret, 0, true);
OutgoingSimplexConnection connection = new OutgoingSimplexConnection(db,
connRegistry, connWriterFactory, packetWriterFactory, ctx,
transport);
connection.write();
// Nothing should have been written
assertEquals(0, out.size());
// The transport should have been disposed with exception == true
assertTrue(transport.getDisposed());
assertTrue(transport.getException());
}
@Test
public void testNothingToSend() throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
TestSimplexTransportWriter transport = new TestSimplexTransportWriter(
out, MIN_STREAM_LENGTH, Long.MAX_VALUE);
TestTransportConnectionWriter writer =
new TestTransportConnectionWriter(out);
StreamContext ctx = new StreamContext(contactId, transportId,
secret, 0, true);
OutgoingSimplexConnection connection = new OutgoingSimplexConnection(db,
connRegistry, connWriterFactory, packetWriterFactory, ctx,
transport);
MessagingSession session = new SinglePassOutgoingSession(db, dbExecutor,
streamWriterFactory, packetWriterFactory, ctx, writer);
context.checking(new Expectations() {{
// No transport acks to send
oneOf(db).generateTransportAcks(contactId);
@@ -141,25 +116,22 @@ public class OutgoingSimplexConnectionTest extends BriarTestCase {
with(any(long.class)));
will(returnValue(null));
}});
connection.write();
session.run();
// Only the tag and an empty final frame should have been written
assertEquals(TAG_LENGTH + HEADER_LENGTH + MAC_LENGTH, out.size());
// The transport should have been disposed with exception == false
assertTrue(transport.getDisposed());
assertFalse(transport.getException());
context.assertIsSatisfied();
}
@Test
public void testSomethingToSend() throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
TestSimplexTransportWriter transport = new TestSimplexTransportWriter(
out, MIN_STREAM_LENGTH, Long.MAX_VALUE);
TestTransportConnectionWriter writer =
new TestTransportConnectionWriter(out);
StreamContext ctx = new StreamContext(contactId, transportId,
secret, 0, true);
OutgoingSimplexConnection connection = new OutgoingSimplexConnection(db,
connRegistry, connWriterFactory, packetWriterFactory, ctx,
transport);
MessagingSession session = new SinglePassOutgoingSession(db, dbExecutor,
streamWriterFactory, packetWriterFactory,
ctx, writer);
final byte[] raw = new byte[1234];
context.checking(new Expectations() {{
// No transport acks to send
@@ -198,13 +170,10 @@ public class OutgoingSimplexConnectionTest extends BriarTestCase {
with(any(long.class)));
will(returnValue(null));
}});
connection.write();
session.run();
// Something should have been written
int overhead = TAG_LENGTH + HEADER_LENGTH + MAC_LENGTH;
assertTrue(out.size() > overhead + UniqueId.LENGTH + raw.length);
// The transport should have been disposed with exception == false
assertTrue(transport.getDisposed());
assertFalse(transport.getException());
context.assertIsSatisfied();
}
}

View File

@@ -0,0 +1,35 @@
package org.briarproject.messaging;
import static org.briarproject.api.transport.TransportConstants.MAX_FRAME_LENGTH;
import java.io.InputStream;
import org.briarproject.api.plugins.TransportConnectionReader;
class TestTransportConnectionReader implements TransportConnectionReader {
private final InputStream in;
private boolean disposed = false;
TestTransportConnectionReader(InputStream in) {
this.in = in;
}
public int getMaxFrameLength() {
return MAX_FRAME_LENGTH;
}
public long getMaxLatency() {
return Long.MAX_VALUE;
}
public InputStream getInputStream() {
return in;
}
public void dispose(boolean exception, boolean recognised) {
assert !disposed;
disposed = true;
}
}

View File

@@ -0,0 +1,40 @@
package org.briarproject.messaging;
import static org.briarproject.api.transport.TransportConstants.MAX_FRAME_LENGTH;
import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import org.briarproject.api.plugins.TransportConnectionWriter;
class TestTransportConnectionWriter implements TransportConnectionWriter {
private final ByteArrayOutputStream out;
private boolean disposed = false;
TestTransportConnectionWriter(ByteArrayOutputStream out) {
this.out = out;
}
public long getCapacity() {
return Long.MAX_VALUE;
}
public int getMaxFrameLength() {
return MAX_FRAME_LENGTH;
}
public long getMaxLatency() {
return Long.MAX_VALUE;
}
public OutputStream getOutputStream() {
return out;
}
public void dispose(boolean exception) {
assert !disposed;
disposed = true;
}
}

View File

@@ -1,45 +0,0 @@
package org.briarproject.messaging.simplex;
import static org.briarproject.api.transport.TransportConstants.MAX_FRAME_LENGTH;
import java.io.InputStream;
import org.briarproject.api.plugins.simplex.SimplexTransportReader;
class TestSimplexTransportReader implements SimplexTransportReader {
private final InputStream in;
private boolean disposed = false, exception = false, recognised = false;
TestSimplexTransportReader(InputStream in) {
this.in = in;
}
public int getMaxFrameLength() {
return MAX_FRAME_LENGTH;
}
public InputStream getInputStream() {
return in;
}
public void dispose(boolean exception, boolean recognised) {
assert !disposed;
disposed = true;
this.exception = exception;
this.recognised = recognised;
}
boolean getDisposed() {
return disposed;
}
boolean getException() {
return exception;
}
boolean getRecognised() {
return recognised;
}
}

View File

@@ -1,53 +0,0 @@
package org.briarproject.messaging.simplex;
import static org.briarproject.api.transport.TransportConstants.MAX_FRAME_LENGTH;
import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import org.briarproject.api.plugins.simplex.SimplexTransportWriter;
class TestSimplexTransportWriter implements SimplexTransportWriter {
private final ByteArrayOutputStream out;
private final long capacity, maxLatency;
private boolean disposed = false, exception = false;
TestSimplexTransportWriter(ByteArrayOutputStream out, long capacity,
long maxLatency) {
this.out = out;
this.capacity = capacity;
this.maxLatency = maxLatency;
}
public long getCapacity() {
return capacity;
}
public int getMaxFrameLength() {
return MAX_FRAME_LENGTH;
}
public long getMaxLatency() {
return maxLatency;
}
public OutputStream getOutputStream() {
return out;
}
public void dispose(boolean exception) {
assert !disposed;
disposed = true;
this.exception = exception;
}
boolean getDisposed() {
return disposed;
}
boolean getException() {
return exception;
}
}