From 96b3d88ece31a64e0395b48db27b68576a76c26f Mon Sep 17 00:00:00 2001
From: akwizgran <michael@briarproject.org>
Date: Mon, 24 Sep 2012 14:38:28 +0100
Subject: [PATCH] Fixes and refactoring for tests.

---
 test/build.xml                                |   8 +-
 .../KeyAgreementTest.java}                    |  19 +-
 test/net/sf/briar/db/H2DatabaseTest.java      |  22 +--
 test/net/sf/briar/db/TestGroup.java           |   2 +-
 test/net/sf/briar/db/TestGroupFactory.java    |  20 +++
 test/net/sf/briar/protocol/AckReaderTest.java |   2 +
 .../sf/briar/protocol/BatchReaderTest.java    |   2 +
 test/net/sf/briar/protocol/ConsumersTest.java |  61 +++++--
 .../sf/briar/protocol/OfferReaderTest.java    |   2 +
 ...Test.java => ProtocolIntegrationTest.java} |   4 +-
 .../protocol/ProtocolWriterImplTest.java      |   2 +
 .../sf/briar/protocol/RequestReaderTest.java  |   2 +
 .../protocol/UnverifiedBatchImplTest.java     |   2 +
 ...va => SimplexProtocolIntegrationTest.java} |  11 +-
 .../briar/transport/ConnectionWriterTest.java |  95 ----------
 .../briar/transport/FrameReadWriteTest.java   | 103 -----------
 .../IncomingEncryptionLayerTest.java          |   2 +
 .../OutgoingEncryptionLayerTest.java          |   2 +
 .../transport/TransportIntegrationTest.java   | 169 ++++++++++++++++++
 19 files changed, 270 insertions(+), 260 deletions(-)
 rename test/net/sf/briar/{plugins/InvitationStarterImplTest.java => crypto/KeyAgreementTest.java} (61%)
 create mode 100644 test/net/sf/briar/db/TestGroupFactory.java
 rename test/net/sf/briar/protocol/{ProtocolReadWriteTest.java => ProtocolIntegrationTest.java} (97%)
 rename test/net/sf/briar/protocol/simplex/{SimplexConnectionReadWriteTest.java => SimplexProtocolIntegrationTest.java} (95%)
 delete mode 100644 test/net/sf/briar/transport/ConnectionWriterTest.java
 delete mode 100644 test/net/sf/briar/transport/FrameReadWriteTest.java
 create mode 100644 test/net/sf/briar/transport/TransportIntegrationTest.java

diff --git a/test/build.xml b/test/build.xml
index b006dad312..3b86a959e8 100644
--- a/test/build.xml
+++ b/test/build.xml
@@ -18,6 +18,7 @@
 			<test name='net.sf.briar.ProtocolIntegrationTest'/>
 			<test name='net.sf.briar.crypto.CounterModeTest'/>
 			<test name='net.sf.briar.crypto.ErasableKeyTest'/>
+			<test name='net.sf.briar.crypto.KeyAgreementTest'/>
 			<test name='net.sf.briar.crypto.KeyDerivationTest'/>
 			<test name='net.sf.briar.crypto.KeyRotatorImplTest'/>
 			<test name='net.sf.briar.db.BasicH2Test'/>
@@ -38,22 +39,21 @@
 			<test name='net.sf.briar.protocol.ConstantsTest'/>
 			<test name='net.sf.briar.protocol.ConsumersTest'/>
 			<test name='net.sf.briar.protocol.OfferReaderTest'/>
-			<test name='net.sf.briar.protocol.ProtocolReadWriteTest'/>
+			<test name='net.sf.briar.protocol.ProtocolIntegrationTest'/>
 			<test name='net.sf.briar.protocol.ProtocolWriterImplTest'/>
 			<test name='net.sf.briar.protocol.RequestReaderTest'/>
 			<test name='net.sf.briar.protocol.UnverifiedBatchImplTest'/>
 			<test name='net.sf.briar.protocol.simplex.OutgoingSimplexConnectionTest'/>
-			<test name='net.sf.briar.protocol.simplex.SimplexConnectionReadWriteTest'/>
+			<test name='net.sf.briar.protocol.simplex.SimplexProtocolIntegrationTest'/>
 			<test name='net.sf.briar.serial.ReaderImplTest'/>
 			<test name='net.sf.briar.serial.WriterImplTest'/>
 			<test name='net.sf.briar.transport.ConnectionReaderImplTest'/>
 			<test name='net.sf.briar.transport.ConnectionRegistryImplTest'/>
 			<test name='net.sf.briar.transport.ConnectionWindowImplTest'/>
 			<test name='net.sf.briar.transport.ConnectionWriterImplTest'/>
-			<test name='net.sf.briar.transport.ConnectionWriterTest'/>
-			<test name='net.sf.briar.transport.FrameReadWriteTest'/>
 			<test name='net.sf.briar.transport.IncomingEncryptionLayerTest'/>
 			<test name='net.sf.briar.transport.OutgoingEncryptionLayerTest'/>
+			<test name='net.sf.briar.transport.TransportIntegrationTest'/>
 			<test name='net.sf.briar.util.ByteUtilsTest'/>
 			<test name='net.sf.briar.util.FileUtilsTest'/>
 			<test name='net.sf.briar.util.StringUtilsTest'/>
diff --git a/test/net/sf/briar/plugins/InvitationStarterImplTest.java b/test/net/sf/briar/crypto/KeyAgreementTest.java
similarity index 61%
rename from test/net/sf/briar/plugins/InvitationStarterImplTest.java
rename to test/net/sf/briar/crypto/KeyAgreementTest.java
index b64c42b5d6..f1ba77f986 100644
--- a/test/net/sf/briar/plugins/InvitationStarterImplTest.java
+++ b/test/net/sf/briar/crypto/KeyAgreementTest.java
@@ -1,4 +1,4 @@
-package net.sf.briar.plugins;
+package net.sf.briar.crypto;
 
 import static org.junit.Assert.assertArrayEquals;
 
@@ -7,27 +7,14 @@ import java.security.PrivateKey;
 
 import net.sf.briar.BriarTestCase;
 import net.sf.briar.api.crypto.CryptoComponent;
-import net.sf.briar.crypto.CryptoModule;
 
 import org.junit.Test;
 
-import com.google.inject.Guice;
-import com.google.inject.Injector;
-
-public class InvitationStarterImplTest extends BriarTestCase {
-
-	// FIXME: This is actually a test of CryptoComponent
-
-	private final CryptoComponent crypto;
-
-	public InvitationStarterImplTest() {
-		super();
-		Injector i = Guice.createInjector(new CryptoModule());
-		crypto = i.getInstance(CryptoComponent.class);
-	}
+public class KeyAgreementTest extends BriarTestCase {
 
 	@Test
 	public void testKeyAgreement() {
+		CryptoComponent crypto = new CryptoComponentImpl();
 		KeyPair a = crypto.generateAgreementKeyPair();
 		byte[] aPub = a.getPublic().getEncoded();
 		PrivateKey aPriv = a.getPrivate();
diff --git a/test/net/sf/briar/db/H2DatabaseTest.java b/test/net/sf/briar/db/H2DatabaseTest.java
index 783487e262..8e98aed0ba 100644
--- a/test/net/sf/briar/db/H2DatabaseTest.java
+++ b/test/net/sf/briar/db/H2DatabaseTest.java
@@ -3,7 +3,6 @@ package net.sf.briar.db;
 import static org.junit.Assert.assertArrayEquals;
 
 import java.io.File;
-import java.io.IOException;
 import java.sql.Connection;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -1110,8 +1109,7 @@ public class H2DatabaseTest extends BriarTestCase {
 	}
 
 	@Test
-	public void testGetMessageIfSendableReturnsNullIfSeen()
-			throws Exception {
+	public void testGetMessageIfSendableReturnsNullIfSeen() throws Exception {
 		Database<Connection> db = open(false);
 		Connection txn = db.startTransaction();
 
@@ -1416,8 +1414,7 @@ public class H2DatabaseTest extends BriarTestCase {
 	}
 
 	@Test
-	public void testGetGroupMessageParentWithPrivateParent()
-			throws Exception {
+	public void testGetGroupMessageParentWithPrivateParent() throws Exception {
 		Database<Connection> db = open(false);
 		Connection txn = db.startTransaction();
 
@@ -1721,6 +1718,8 @@ public class H2DatabaseTest extends BriarTestCase {
 		db.close();
 	}
 
+	// FIXME: Test new methods
+
 	@Test
 	public void testExceptionHandling() throws Exception {
 		Database<Connection> db = open(false);
@@ -1755,17 +1754,4 @@ public class H2DatabaseTest extends BriarTestCase {
 			return passwordString.toCharArray();
 		}
 	}
-
-	private class TestGroupFactory implements GroupFactory {
-
-		public Group createGroup(String name, byte[] publicKey)
-				throws IOException {
-			GroupId id = new GroupId(TestUtils.getRandomId());
-			return new TestGroup(id, name, publicKey);
-		}
-
-		public Group createGroup(GroupId id, String name, byte[] publicKey) {
-			return new TestGroup(id, name, publicKey);
-		}
-	}
 }
diff --git a/test/net/sf/briar/db/TestGroup.java b/test/net/sf/briar/db/TestGroup.java
index 40617162e2..4e78e07880 100644
--- a/test/net/sf/briar/db/TestGroup.java
+++ b/test/net/sf/briar/db/TestGroup.java
@@ -3,7 +3,7 @@ package net.sf.briar.db;
 import net.sf.briar.api.protocol.Group;
 import net.sf.briar.api.protocol.GroupId;
 
-public class TestGroup implements Group {
+class TestGroup implements Group {
 
 	private final GroupId id;
 	private final String name;
diff --git a/test/net/sf/briar/db/TestGroupFactory.java b/test/net/sf/briar/db/TestGroupFactory.java
new file mode 100644
index 0000000000..89f29b92d1
--- /dev/null
+++ b/test/net/sf/briar/db/TestGroupFactory.java
@@ -0,0 +1,20 @@
+package net.sf.briar.db;
+
+import java.io.IOException;
+
+import net.sf.briar.TestUtils;
+import net.sf.briar.api.protocol.Group;
+import net.sf.briar.api.protocol.GroupFactory;
+import net.sf.briar.api.protocol.GroupId;
+
+class TestGroupFactory implements GroupFactory {
+
+	public Group createGroup(String name, byte[] publicKey) throws IOException {
+		GroupId id = new GroupId(TestUtils.getRandomId());
+		return new TestGroup(id, name, publicKey);
+	}
+
+	public Group createGroup(GroupId id, String name, byte[] publicKey) {
+		return new TestGroup(id, name, publicKey);
+	}
+}
\ No newline at end of file
diff --git a/test/net/sf/briar/protocol/AckReaderTest.java b/test/net/sf/briar/protocol/AckReaderTest.java
index 0220818d76..990cd05a1e 100644
--- a/test/net/sf/briar/protocol/AckReaderTest.java
+++ b/test/net/sf/briar/protocol/AckReaderTest.java
@@ -27,6 +27,8 @@ import com.google.inject.Injector;
 
 public class AckReaderTest extends BriarTestCase {
 
+	// FIXME: This is an integration test, not a unit test
+
 	private final SerialComponent serial;
 	private final ReaderFactory readerFactory;
 	private final WriterFactory writerFactory;
diff --git a/test/net/sf/briar/protocol/BatchReaderTest.java b/test/net/sf/briar/protocol/BatchReaderTest.java
index 9023f0f771..0d2e1ffe24 100644
--- a/test/net/sf/briar/protocol/BatchReaderTest.java
+++ b/test/net/sf/briar/protocol/BatchReaderTest.java
@@ -26,6 +26,8 @@ import com.google.inject.Injector;
 
 public class BatchReaderTest extends BriarTestCase {
 
+	// FIXME: This is an integration test, not a unit test
+
 	private final ReaderFactory readerFactory;
 	private final WriterFactory writerFactory;
 	private final Mockery context;
diff --git a/test/net/sf/briar/protocol/ConsumersTest.java b/test/net/sf/briar/protocol/ConsumersTest.java
index 095e792966..0bb89d6d29 100644
--- a/test/net/sf/briar/protocol/ConsumersTest.java
+++ b/test/net/sf/briar/protocol/ConsumersTest.java
@@ -2,39 +2,26 @@ package net.sf.briar.protocol;
 
 import static org.junit.Assert.assertArrayEquals;
 
+import java.security.GeneralSecurityException;
 import java.util.Random;
 
 import net.sf.briar.BriarTestCase;
 import net.sf.briar.api.FormatException;
-import net.sf.briar.api.crypto.CryptoComponent;
 import net.sf.briar.api.crypto.MessageDigest;
 import net.sf.briar.api.serial.CopyingConsumer;
 import net.sf.briar.api.serial.CountingConsumer;
 import net.sf.briar.api.serial.DigestingConsumer;
-import net.sf.briar.crypto.CryptoModule;
 
-import org.junit.Before;
 import org.junit.Test;
 
-import com.google.inject.Guice;
-import com.google.inject.Injector;
-
 public class ConsumersTest extends BriarTestCase {
 
-	private CryptoComponent crypto = null;
-
-	@Before
-	public void setUp() {
-		Injector i = Guice.createInjector(new CryptoModule());
-		crypto = i.getInstance(CryptoComponent.class);
-	}
-
 	@Test
 	public void testDigestingConsumer() throws Exception {
 		byte[] data = new byte[1234];
 		// Generate some random data and digest it
 		new Random().nextBytes(data);
-		MessageDigest messageDigest = crypto.getMessageDigest();
+		MessageDigest messageDigest = new TestMessageDigest();
 		messageDigest.update(data);
 		byte[] dig = messageDigest.digest();
 		// Check that feeding a DigestingConsumer generates the same digest
@@ -71,4 +58,48 @@ public class ConsumersTest extends BriarTestCase {
 		cc.write(data[data.length - 1]);
 		assertArrayEquals(data, cc.getCopy());
 	}
+
+	private static class TestMessageDigest implements MessageDigest {
+
+		private final java.security.MessageDigest delegate;
+
+		private TestMessageDigest() throws GeneralSecurityException {
+			delegate = java.security.MessageDigest.getInstance("SHA-256");
+		}
+
+		public byte[] digest() {
+			return delegate.digest();
+		}
+
+		public byte[] digest(byte[] input) {
+			return delegate.digest(input);
+		}
+
+		public int digest(byte[] buf, int offset, int len) {
+			byte[] digest = digest();
+			len = Math.min(len, digest.length);
+			System.arraycopy(digest, 0, buf, offset, len);
+			return len;
+		}
+
+		public int getDigestLength() {
+			return delegate.getDigestLength();
+		}
+
+		public void reset() {
+			delegate.reset();
+		}
+
+		public void update(byte input) {
+			delegate.update(input);
+		}
+
+		public void update(byte[] input) {
+			delegate.update(input);
+		}
+
+		public void update(byte[] input, int offset, int len) {
+			delegate.update(input, offset, len);
+		}		
+	}
 }
diff --git a/test/net/sf/briar/protocol/OfferReaderTest.java b/test/net/sf/briar/protocol/OfferReaderTest.java
index 0afb60804c..acc9b97b20 100644
--- a/test/net/sf/briar/protocol/OfferReaderTest.java
+++ b/test/net/sf/briar/protocol/OfferReaderTest.java
@@ -27,6 +27,8 @@ import com.google.inject.Injector;
 
 public class OfferReaderTest extends BriarTestCase {
 
+	// FIXME: This is an integration test, not a unit test
+
 	private final SerialComponent serial;
 	private final ReaderFactory readerFactory;
 	private final WriterFactory writerFactory;
diff --git a/test/net/sf/briar/protocol/ProtocolReadWriteTest.java b/test/net/sf/briar/protocol/ProtocolIntegrationTest.java
similarity index 97%
rename from test/net/sf/briar/protocol/ProtocolReadWriteTest.java
rename to test/net/sf/briar/protocol/ProtocolIntegrationTest.java
index 51c15ea205..4c939bc9c4 100644
--- a/test/net/sf/briar/protocol/ProtocolReadWriteTest.java
+++ b/test/net/sf/briar/protocol/ProtocolIntegrationTest.java
@@ -37,7 +37,7 @@ import org.junit.Test;
 import com.google.inject.Guice;
 import com.google.inject.Injector;
 
-public class ProtocolReadWriteTest extends BriarTestCase {
+public class ProtocolIntegrationTest extends BriarTestCase {
 
 	private final ProtocolReaderFactory readerFactory;
 	private final ProtocolWriterFactory writerFactory;
@@ -52,7 +52,7 @@ public class ProtocolReadWriteTest extends BriarTestCase {
 	private final Collection<Transport> transports;
 	private final long timestamp = System.currentTimeMillis();
 
-	public ProtocolReadWriteTest() throws Exception {
+	public ProtocolIntegrationTest() throws Exception {
 		super();
 		Injector i = Guice.createInjector(new CryptoModule(),
 				new ProtocolModule(), new SerialModule());
diff --git a/test/net/sf/briar/protocol/ProtocolWriterImplTest.java b/test/net/sf/briar/protocol/ProtocolWriterImplTest.java
index 35bdb40c87..4f2343b19a 100644
--- a/test/net/sf/briar/protocol/ProtocolWriterImplTest.java
+++ b/test/net/sf/briar/protocol/ProtocolWriterImplTest.java
@@ -21,6 +21,8 @@ import com.google.inject.Injector;
 
 public class ProtocolWriterImplTest extends BriarTestCase {
 
+	// FIXME: This is an integration test, not a unit test
+
 	private final PacketFactory packetFactory;
 	private final SerialComponent serial;
 	private final WriterFactory writerFactory;
diff --git a/test/net/sf/briar/protocol/RequestReaderTest.java b/test/net/sf/briar/protocol/RequestReaderTest.java
index fb45878d5e..1729d84bee 100644
--- a/test/net/sf/briar/protocol/RequestReaderTest.java
+++ b/test/net/sf/briar/protocol/RequestReaderTest.java
@@ -26,6 +26,8 @@ import com.google.inject.Injector;
 
 public class RequestReaderTest extends BriarTestCase {
 
+	// FIXME: This is an integration test, not a unit test
+
 	private final ReaderFactory readerFactory;
 	private final WriterFactory writerFactory;
 	private final PacketFactory packetFactory;
diff --git a/test/net/sf/briar/protocol/UnverifiedBatchImplTest.java b/test/net/sf/briar/protocol/UnverifiedBatchImplTest.java
index d2c3a5c5b7..dcf6f38a85 100644
--- a/test/net/sf/briar/protocol/UnverifiedBatchImplTest.java
+++ b/test/net/sf/briar/protocol/UnverifiedBatchImplTest.java
@@ -32,6 +32,8 @@ import com.google.inject.Injector;
 
 public class UnverifiedBatchImplTest extends BriarTestCase {
 
+	// FIXME: This is an integration test, not a unit test
+
 	private final CryptoComponent crypto;
 	private final byte[] raw, raw1;
 	private final String subject;
diff --git a/test/net/sf/briar/protocol/simplex/SimplexConnectionReadWriteTest.java b/test/net/sf/briar/protocol/simplex/SimplexProtocolIntegrationTest.java
similarity index 95%
rename from test/net/sf/briar/protocol/simplex/SimplexConnectionReadWriteTest.java
rename to test/net/sf/briar/protocol/simplex/SimplexProtocolIntegrationTest.java
index 7628ec6322..906da6bb26 100644
--- a/test/net/sf/briar/protocol/simplex/SimplexConnectionReadWriteTest.java
+++ b/test/net/sf/briar/protocol/simplex/SimplexProtocolIntegrationTest.java
@@ -46,9 +46,7 @@ import org.junit.Test;
 import com.google.inject.Guice;
 import com.google.inject.Injector;
 
-public class SimplexConnectionReadWriteTest extends BriarTestCase {
-
-	// FIXME: This is an integration test, not a unit test
+public class SimplexProtocolIntegrationTest extends BriarTestCase {
 
 	private final File testDir = TestUtils.getTestDirectory();
 	private final File aliceDir = new File(testDir, "alice");
@@ -58,7 +56,7 @@ public class SimplexConnectionReadWriteTest extends BriarTestCase {
 
 	private Injector alice, bob;
 
-	public SimplexConnectionReadWriteTest() throws Exception {
+	public SimplexProtocolIntegrationTest() throws Exception {
 		super();
 		transportId = new TransportId(TestUtils.getRandomId());
 		// Create matching secrets for Alice and Bob
@@ -164,14 +162,15 @@ public class SimplexConnectionReadWriteTest extends BriarTestCase {
 		ConnectionContext ctx = rec.acceptConnection(transportId, tag);
 		assertNotNull(ctx);
 		assertEquals(contactId, ctx.getContactId());
-		// Create an incoming batch connection
+		// Create an incoming simplex connection
 		ConnectionRegistry connRegistry =
 				bob.getInstance(ConnectionRegistry.class);
 		ConnectionReaderFactory connFactory =
 				bob.getInstance(ConnectionReaderFactory.class);
 		ProtocolReaderFactory protoFactory =
 				bob.getInstance(ProtocolReaderFactory.class);
-		TestSimplexTransportReader transport = new TestSimplexTransportReader(in);
+		TestSimplexTransportReader transport =
+				new TestSimplexTransportReader(in);
 		IncomingSimplexConnection simplex = new IncomingSimplexConnection(
 				new ImmediateExecutor(), new ImmediateExecutor(), db,
 				connRegistry, connFactory, protoFactory, ctx, transport);
diff --git a/test/net/sf/briar/transport/ConnectionWriterTest.java b/test/net/sf/briar/transport/ConnectionWriterTest.java
deleted file mode 100644
index cbfc46b44a..0000000000
--- a/test/net/sf/briar/transport/ConnectionWriterTest.java
+++ /dev/null
@@ -1,95 +0,0 @@
-package net.sf.briar.transport;
-
-import static net.sf.briar.api.protocol.ProtocolConstants.MAX_PACKET_LENGTH;
-import static net.sf.briar.api.transport.TransportConstants.MIN_CONNECTION_LENGTH;
-import static net.sf.briar.api.transport.TransportConstants.TAG_LENGTH;
-
-import java.io.ByteArrayOutputStream;
-import java.util.Random;
-
-import net.sf.briar.BriarTestCase;
-import net.sf.briar.TestDatabaseModule;
-import net.sf.briar.TestUtils;
-import net.sf.briar.api.ContactId;
-import net.sf.briar.api.protocol.TransportId;
-import net.sf.briar.api.transport.ConnectionContext;
-import net.sf.briar.api.transport.ConnectionWriter;
-import net.sf.briar.api.transport.ConnectionWriterFactory;
-import net.sf.briar.clock.ClockModule;
-import net.sf.briar.crypto.CryptoModule;
-import net.sf.briar.db.DatabaseModule;
-import net.sf.briar.lifecycle.LifecycleModule;
-import net.sf.briar.protocol.ProtocolModule;
-import net.sf.briar.protocol.duplex.DuplexProtocolModule;
-import net.sf.briar.protocol.simplex.SimplexProtocolModule;
-import net.sf.briar.serial.SerialModule;
-
-import org.junit.Test;
-
-import com.google.inject.Guice;
-import com.google.inject.Injector;
-
-public class ConnectionWriterTest extends BriarTestCase {
-
-	private final ConnectionWriterFactory connectionWriterFactory;
-	private final ContactId contactId;
-	private final TransportId transportId;
-	private final byte[] secret;
-
-	public ConnectionWriterTest() throws Exception {
-		super();
-		Injector i = Guice.createInjector(new ClockModule(), new CryptoModule(),
-				new DatabaseModule(), new LifecycleModule(),
-				new ProtocolModule(), new SerialModule(),
-				new TestDatabaseModule(), new SimplexProtocolModule(),
-				new TransportModule(), new DuplexProtocolModule());
-		connectionWriterFactory = i.getInstance(ConnectionWriterFactory.class);
-		contactId = new ContactId(234);
-		transportId = new TransportId(TestUtils.getRandomId());
-		secret = new byte[32];
-		new Random().nextBytes(secret);
-	}
-
-	@Test
-	public void testOverheadWithTag() throws Exception {
-		ByteArrayOutputStream out =
-				new ByteArrayOutputStream(MIN_CONNECTION_LENGTH);
-		byte[] tag = new byte[TAG_LENGTH];
-		ConnectionContext ctx = new ConnectionContext(contactId, transportId,
-				tag, secret, 0L, true);
-		ConnectionWriter w = connectionWriterFactory.createConnectionWriter(out,
-				MIN_CONNECTION_LENGTH, ctx, true);
-		// Check that the connection writer thinks there's room for a packet
-		long capacity = w.getRemainingCapacity();
-		assertTrue(capacity > MAX_PACKET_LENGTH);
-		assertTrue(capacity < MIN_CONNECTION_LENGTH);
-		// Check that there really is room for a packet
-		byte[] payload = new byte[MAX_PACKET_LENGTH];
-		w.getOutputStream().write(payload);
-		w.getOutputStream().close();
-		long used = out.size();
-		assertTrue(used > MAX_PACKET_LENGTH);
-		assertTrue(used <= MIN_CONNECTION_LENGTH);
-	}
-
-	@Test
-	public void testOverheadWithoutTag() throws Exception {
-		ByteArrayOutputStream out =
-				new ByteArrayOutputStream(MIN_CONNECTION_LENGTH);
-		ConnectionContext ctx = new ConnectionContext(contactId, transportId,
-				null, secret, 0L, true);
-		ConnectionWriter w = connectionWriterFactory.createConnectionWriter(out,
-				MIN_CONNECTION_LENGTH, ctx, false);
-		// Check that the connection writer thinks there's room for a packet
-		long capacity = w.getRemainingCapacity();
-		assertTrue(capacity > MAX_PACKET_LENGTH);
-		assertTrue(capacity < MIN_CONNECTION_LENGTH);
-		// Check that there really is room for a packet
-		byte[] payload = new byte[MAX_PACKET_LENGTH];
-		w.getOutputStream().write(payload);
-		w.getOutputStream().close();
-		long used = out.size();
-		assertTrue(used > MAX_PACKET_LENGTH);
-		assertTrue(used <= MIN_CONNECTION_LENGTH);
-	}
-}
diff --git a/test/net/sf/briar/transport/FrameReadWriteTest.java b/test/net/sf/briar/transport/FrameReadWriteTest.java
deleted file mode 100644
index 6443b973f1..0000000000
--- a/test/net/sf/briar/transport/FrameReadWriteTest.java
+++ /dev/null
@@ -1,103 +0,0 @@
-package net.sf.briar.transport;
-
-import static org.junit.Assert.assertArrayEquals;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.Random;
-
-import net.sf.briar.BriarTestCase;
-import net.sf.briar.api.crypto.AuthenticatedCipher;
-import net.sf.briar.api.crypto.CryptoComponent;
-import net.sf.briar.api.crypto.ErasableKey;
-import net.sf.briar.api.transport.ConnectionReader;
-import net.sf.briar.api.transport.ConnectionWriter;
-import net.sf.briar.crypto.CryptoModule;
-
-import org.junit.Test;
-
-import com.google.inject.Guice;
-import com.google.inject.Injector;
-
-public class FrameReadWriteTest extends BriarTestCase {
-
-	private final int FRAME_LENGTH = 2048;
-
-	private final CryptoComponent crypto;
-	private final AuthenticatedCipher frameCipher;
-	private final Random random;
-	private final byte[] outSecret;
-	private final ErasableKey frameKey;
-
-	public FrameReadWriteTest() {
-		super();
-		Injector i = Guice.createInjector(new CryptoModule());
-		crypto = i.getInstance(CryptoComponent.class);
-		frameCipher = crypto.getFrameCipher();
-		random = new Random();
-		// Since we're sending frames to ourselves, we only need outgoing keys
-		outSecret = new byte[32];
-		random.nextBytes(outSecret);
-		frameKey = crypto.deriveFrameKey(outSecret, 0L, true, true);
-	}
-
-	@Test
-	public void testInitiatorWriteAndRead() throws Exception {
-		testWriteAndRead(true);
-	}
-
-	@Test
-	public void testResponderWriteAndRead() throws Exception {
-		testWriteAndRead(false);
-	}
-
-	private void testWriteAndRead(boolean initiator) throws Exception {
-		// Generate two random frames
-		byte[] frame = new byte[1234];
-		random.nextBytes(frame);
-		byte[] frame1 = new byte[321];
-		random.nextBytes(frame1);
-		// Copy the frame key - the copy will be erased
-		ErasableKey frameCopy = frameKey.copy();
-		// Write the frames
-		ByteArrayOutputStream out = new ByteArrayOutputStream();
-		FrameWriter encryptionOut = new OutgoingEncryptionLayer(out,
-				Long.MAX_VALUE, frameCipher, frameCopy, FRAME_LENGTH);
-		ConnectionWriter writer = new ConnectionWriterImpl(encryptionOut,
-				FRAME_LENGTH);
-		OutputStream out1 = writer.getOutputStream();
-		out1.write(frame);
-		out1.flush();
-		out1.write(frame1);
-		out1.flush();
-		byte[] output = out.toByteArray();
-		assertEquals(FRAME_LENGTH * 2, output.length);
-		// Read the tag and the frames back
-		ByteArrayInputStream in = new ByteArrayInputStream(output);
-		FrameReader encryptionIn = new IncomingEncryptionLayer(in, frameCipher,
-				frameKey, FRAME_LENGTH);
-		ConnectionReader reader = new ConnectionReaderImpl(encryptionIn,
-				FRAME_LENGTH);
-		InputStream in1 = reader.getInputStream();
-		byte[] recovered = new byte[frame.length];
-		int offset = 0;
-		while(offset < recovered.length) {
-			int read = in1.read(recovered, offset, recovered.length - offset);
-			if(read == -1) break;
-			offset += read;
-		}
-		assertEquals(recovered.length, offset);
-		assertArrayEquals(frame, recovered);
-		byte[] recovered1 = new byte[frame1.length];
-		offset = 0;
-		while(offset < recovered1.length) {
-			int read = in1.read(recovered1, offset, recovered1.length - offset);
-			if(read == -1) break;
-			offset += read;
-		}
-		assertEquals(recovered1.length, offset);
-		assertArrayEquals(frame1, recovered1);
-	}
-}
diff --git a/test/net/sf/briar/transport/IncomingEncryptionLayerTest.java b/test/net/sf/briar/transport/IncomingEncryptionLayerTest.java
index 4eb9dc02ae..7638bea2c6 100644
--- a/test/net/sf/briar/transport/IncomingEncryptionLayerTest.java
+++ b/test/net/sf/briar/transport/IncomingEncryptionLayerTest.java
@@ -22,6 +22,8 @@ import com.google.inject.Injector;
 
 public class IncomingEncryptionLayerTest extends BriarTestCase {
 
+	// FIXME: This is an integration test, not a unit test
+
 	private static final int FRAME_LENGTH = 1024;
 	private static final int MAX_PAYLOAD_LENGTH =
 			FRAME_LENGTH - HEADER_LENGTH - MAC_LENGTH;
diff --git a/test/net/sf/briar/transport/OutgoingEncryptionLayerTest.java b/test/net/sf/briar/transport/OutgoingEncryptionLayerTest.java
index f4eba23486..475e5d9adb 100644
--- a/test/net/sf/briar/transport/OutgoingEncryptionLayerTest.java
+++ b/test/net/sf/briar/transport/OutgoingEncryptionLayerTest.java
@@ -22,6 +22,8 @@ import com.google.inject.Injector;
 
 public class OutgoingEncryptionLayerTest extends BriarTestCase {
 
+	// FIXME: This is an integration test, not a unit test
+
 	private static final int FRAME_LENGTH = 1024;
 	private static final int MAX_PAYLOAD_LENGTH =
 			FRAME_LENGTH - HEADER_LENGTH - MAC_LENGTH;
diff --git a/test/net/sf/briar/transport/TransportIntegrationTest.java b/test/net/sf/briar/transport/TransportIntegrationTest.java
new file mode 100644
index 0000000000..2c61124e0b
--- /dev/null
+++ b/test/net/sf/briar/transport/TransportIntegrationTest.java
@@ -0,0 +1,169 @@
+package net.sf.briar.transport;
+
+import static net.sf.briar.api.protocol.ProtocolConstants.MAX_PACKET_LENGTH;
+import static net.sf.briar.api.transport.TransportConstants.MIN_CONNECTION_LENGTH;
+import static net.sf.briar.api.transport.TransportConstants.TAG_LENGTH;
+import static org.junit.Assert.assertArrayEquals;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Random;
+
+import net.sf.briar.BriarTestCase;
+import net.sf.briar.TestUtils;
+import net.sf.briar.api.ContactId;
+import net.sf.briar.api.crypto.AuthenticatedCipher;
+import net.sf.briar.api.crypto.CryptoComponent;
+import net.sf.briar.api.crypto.ErasableKey;
+import net.sf.briar.api.protocol.TransportId;
+import net.sf.briar.api.transport.ConnectionContext;
+import net.sf.briar.api.transport.ConnectionReader;
+import net.sf.briar.api.transport.ConnectionWriter;
+import net.sf.briar.api.transport.ConnectionWriterFactory;
+import net.sf.briar.crypto.CryptoModule;
+
+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 TransportIntegrationTest extends BriarTestCase {
+
+	private final int FRAME_LENGTH = 2048;
+
+	private final CryptoComponent crypto;
+	private final ConnectionWriterFactory connectionWriterFactory;
+	private final ContactId contactId;
+	private final TransportId transportId;
+	private final AuthenticatedCipher frameCipher;
+	private final Random random;
+	private final byte[] secret;
+	private final ErasableKey frameKey;
+
+	public TransportIntegrationTest() {
+		super();
+		Module testModule = new AbstractModule() {
+			@Override
+			public void configure() {
+				bind(ConnectionWriterFactory.class).to(
+						ConnectionWriterFactoryImpl.class);
+			}
+		};
+		Injector i = Guice.createInjector(testModule, new CryptoModule());
+		crypto = i.getInstance(CryptoComponent.class);
+		connectionWriterFactory = i.getInstance(ConnectionWriterFactory.class);
+		contactId = new ContactId(234);
+		transportId = new TransportId(TestUtils.getRandomId());
+		frameCipher = crypto.getFrameCipher();
+		random = new Random();
+		// Since we're sending frames to ourselves, we only need outgoing keys
+		secret = new byte[32];
+		random.nextBytes(secret);
+		frameKey = crypto.deriveFrameKey(secret, 0L, true, true);
+	}
+
+	@Test
+	public void testInitiatorWriteAndRead() throws Exception {
+		testWriteAndRead(true);
+	}
+
+	@Test
+	public void testResponderWriteAndRead() throws Exception {
+		testWriteAndRead(false);
+	}
+
+	private void testWriteAndRead(boolean initiator) throws Exception {
+		// Generate two random frames
+		byte[] frame = new byte[1234];
+		random.nextBytes(frame);
+		byte[] frame1 = new byte[321];
+		random.nextBytes(frame1);
+		// Copy the frame key - the copy will be erased
+		ErasableKey frameCopy = frameKey.copy();
+		// Write the frames
+		ByteArrayOutputStream out = new ByteArrayOutputStream();
+		FrameWriter encryptionOut = new OutgoingEncryptionLayer(out,
+				Long.MAX_VALUE, frameCipher, frameCopy, FRAME_LENGTH);
+		ConnectionWriter writer = new ConnectionWriterImpl(encryptionOut,
+				FRAME_LENGTH);
+		OutputStream out1 = writer.getOutputStream();
+		out1.write(frame);
+		out1.flush();
+		out1.write(frame1);
+		out1.flush();
+		byte[] output = out.toByteArray();
+		assertEquals(FRAME_LENGTH * 2, output.length);
+		// Read the tag and the frames back
+		ByteArrayInputStream in = new ByteArrayInputStream(output);
+		FrameReader encryptionIn = new IncomingEncryptionLayer(in, frameCipher,
+				frameKey, FRAME_LENGTH);
+		ConnectionReader reader = new ConnectionReaderImpl(encryptionIn,
+				FRAME_LENGTH);
+		InputStream in1 = reader.getInputStream();
+		byte[] recovered = new byte[frame.length];
+		int offset = 0;
+		while(offset < recovered.length) {
+			int read = in1.read(recovered, offset, recovered.length - offset);
+			if(read == -1) break;
+			offset += read;
+		}
+		assertEquals(recovered.length, offset);
+		assertArrayEquals(frame, recovered);
+		byte[] recovered1 = new byte[frame1.length];
+		offset = 0;
+		while(offset < recovered1.length) {
+			int read = in1.read(recovered1, offset, recovered1.length - offset);
+			if(read == -1) break;
+			offset += read;
+		}
+		assertEquals(recovered1.length, offset);
+		assertArrayEquals(frame1, recovered1);
+	}
+
+	@Test
+	public void testOverheadWithTag() throws Exception {
+		ByteArrayOutputStream out =
+				new ByteArrayOutputStream(MIN_CONNECTION_LENGTH);
+		byte[] tag = new byte[TAG_LENGTH];
+		ConnectionContext ctx = new ConnectionContext(contactId, transportId,
+				tag, secret, 0L, true);
+		ConnectionWriter w = connectionWriterFactory.createConnectionWriter(out,
+				MIN_CONNECTION_LENGTH, ctx, true);
+		// Check that the connection writer thinks there's room for a packet
+		long capacity = w.getRemainingCapacity();
+		assertTrue(capacity > MAX_PACKET_LENGTH);
+		assertTrue(capacity < MIN_CONNECTION_LENGTH);
+		// Check that there really is room for a packet
+		byte[] payload = new byte[MAX_PACKET_LENGTH];
+		w.getOutputStream().write(payload);
+		w.getOutputStream().close();
+		long used = out.size();
+		assertTrue(used > MAX_PACKET_LENGTH);
+		assertTrue(used <= MIN_CONNECTION_LENGTH);
+	}
+
+	@Test
+	public void testOverheadWithoutTag() throws Exception {
+		ByteArrayOutputStream out =
+				new ByteArrayOutputStream(MIN_CONNECTION_LENGTH);
+		ConnectionContext ctx = new ConnectionContext(contactId, transportId,
+				null, secret, 0L, true);
+		ConnectionWriter w = connectionWriterFactory.createConnectionWriter(out,
+				MIN_CONNECTION_LENGTH, ctx, false);
+		// Check that the connection writer thinks there's room for a packet
+		long capacity = w.getRemainingCapacity();
+		assertTrue(capacity > MAX_PACKET_LENGTH);
+		assertTrue(capacity < MIN_CONNECTION_LENGTH);
+		// Check that there really is room for a packet
+		byte[] payload = new byte[MAX_PACKET_LENGTH];
+		w.getOutputStream().write(payload);
+		w.getOutputStream().close();
+		long used = out.size();
+		assertTrue(used > MAX_PACKET_LENGTH);
+		assertTrue(used <= MIN_CONNECTION_LENGTH);
+	}
+}
-- 
GitLab