mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-18 21:59:54 +01:00
Unit tests for ConnectionWriterImpl.
This commit is contained in:
@@ -2,7 +2,6 @@ package net.sf.briar.transport;
|
|||||||
|
|
||||||
import static net.sf.briar.api.transport.TransportConstants.HEADER_LENGTH;
|
import static net.sf.briar.api.transport.TransportConstants.HEADER_LENGTH;
|
||||||
import static net.sf.briar.api.transport.TransportConstants.MAC_LENGTH;
|
import static net.sf.briar.api.transport.TransportConstants.MAC_LENGTH;
|
||||||
import static net.sf.briar.util.ByteUtils.MAX_32_BIT_UNSIGNED;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
@@ -22,7 +21,6 @@ class ConnectionWriterImpl extends OutputStream implements ConnectionWriter {
|
|||||||
private final int frameLength;
|
private final int frameLength;
|
||||||
|
|
||||||
private int length = 0;
|
private int length = 0;
|
||||||
private long frameNumber = 0L;
|
|
||||||
|
|
||||||
ConnectionWriterImpl(FrameWriter out, int frameLength) {
|
ConnectionWriterImpl(FrameWriter out, int frameLength) {
|
||||||
this.out = out;
|
this.out = out;
|
||||||
@@ -80,9 +78,7 @@ class ConnectionWriterImpl extends OutputStream implements ConnectionWriter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void writeFrame(boolean finalFrame) throws IOException {
|
private void writeFrame(boolean finalFrame) throws IOException {
|
||||||
if(frameNumber > MAX_32_BIT_UNSIGNED) throw new IllegalStateException();
|
|
||||||
out.writeFrame(frame, length, finalFrame);
|
out.writeFrame(frame, length, finalFrame);
|
||||||
length = 0;
|
length = 0;
|
||||||
frameNumber++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,6 +69,7 @@ class OutgoingEncryptionLayer implements FrameWriter {
|
|||||||
|
|
||||||
public void writeFrame(byte[] frame, int payloadLength, boolean finalFrame)
|
public void writeFrame(byte[] frame, int payloadLength, boolean finalFrame)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
|
if(frameNumber > MAX_32_BIT_UNSIGNED) throw new IllegalStateException();
|
||||||
// If the initiator's side of the connection is closed without writing
|
// If the initiator's side of the connection is closed without writing
|
||||||
// any data, don't write anything to the underlying transport
|
// any data, don't write anything to the underlying transport
|
||||||
if(writeTag && finalFrame && payloadLength == 0) return;
|
if(writeTag && finalFrame && payloadLength == 0) return;
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ public class ConnectionReaderImplTest extends BriarTestCase {
|
|||||||
assertEquals(0, c.read()); // Read another byte
|
assertEquals(0, c.read()); // Read another byte
|
||||||
assertEquals(-1, c.read()); // Skip the second empty frame, reach EOF
|
assertEquals(-1, c.read()); // Skip the second empty frame, reach EOF
|
||||||
assertEquals(-1, c.read()); // Still at EOF
|
assertEquals(-1, c.read()); // Still at EOF
|
||||||
|
context.assertIsSatisfied();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -57,6 +58,7 @@ public class ConnectionReaderImplTest extends BriarTestCase {
|
|||||||
assertEquals(-1, c.read(buf));
|
assertEquals(-1, c.read(buf));
|
||||||
// Still at EOF
|
// Still at EOF
|
||||||
assertEquals(-1, c.read(buf));
|
assertEquals(-1, c.read(buf));
|
||||||
|
context.assertIsSatisfied();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -77,6 +79,7 @@ public class ConnectionReaderImplTest extends BriarTestCase {
|
|||||||
assertEquals(MAX_PAYLOAD_LENGTH / 2, c.read(buf));
|
assertEquals(MAX_PAYLOAD_LENGTH / 2, c.read(buf));
|
||||||
// Reach EOF
|
// Reach EOF
|
||||||
assertEquals(-1, c.read(buf, 0, buf.length));
|
assertEquals(-1, c.read(buf, 0, buf.length));
|
||||||
|
context.assertIsSatisfied();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -99,5 +102,6 @@ public class ConnectionReaderImplTest extends BriarTestCase {
|
|||||||
MAX_PAYLOAD_LENGTH / 2));
|
MAX_PAYLOAD_LENGTH / 2));
|
||||||
// Reach EOF
|
// Reach EOF
|
||||||
assertEquals(-1, c.read(buf, 0, buf.length));
|
assertEquals(-1, c.read(buf, 0, buf.length));
|
||||||
|
context.assertIsSatisfied();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,123 @@
|
|||||||
package net.sf.briar.transport;
|
package net.sf.briar.transport;
|
||||||
|
|
||||||
import org.junit.Test;
|
import static net.sf.briar.api.transport.TransportConstants.HEADER_LENGTH;
|
||||||
|
import static net.sf.briar.api.transport.TransportConstants.MAC_LENGTH;
|
||||||
import net.sf.briar.BriarTestCase;
|
import net.sf.briar.BriarTestCase;
|
||||||
|
|
||||||
|
import org.jmock.Expectations;
|
||||||
|
import org.jmock.Mockery;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
public class ConnectionWriterImplTest extends BriarTestCase {
|
public class ConnectionWriterImplTest extends BriarTestCase {
|
||||||
|
|
||||||
// FIXME: This is an arbitrary change to test the synchronization view
|
private static final int FRAME_LENGTH = 1024;
|
||||||
|
private static final int MAX_PAYLOAD_LENGTH =
|
||||||
|
FRAME_LENGTH - HEADER_LENGTH - MAC_LENGTH;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNothing() {}
|
public void testCloseWithoutWritingWritesFinalFrame() throws Exception {
|
||||||
|
Mockery context = new Mockery();
|
||||||
|
final FrameWriter writer = context.mock(FrameWriter.class);
|
||||||
|
context.checking(new Expectations() {{
|
||||||
|
// Write an empty final frame
|
||||||
|
oneOf(writer).writeFrame(with(any(byte[].class)), with(0),
|
||||||
|
with(true));
|
||||||
|
// Flush the stream
|
||||||
|
oneOf(writer).flush();
|
||||||
|
}});
|
||||||
|
ConnectionWriterImpl c = new ConnectionWriterImpl(writer, FRAME_LENGTH);
|
||||||
|
c.close();
|
||||||
|
context.assertIsSatisfied();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFlushWithoutBufferedDataWritesFrame() throws Exception {
|
||||||
|
Mockery context = new Mockery();
|
||||||
|
final FrameWriter writer = context.mock(FrameWriter.class);
|
||||||
|
ConnectionWriterImpl c = new ConnectionWriterImpl(writer, FRAME_LENGTH);
|
||||||
|
context.checking(new Expectations() {{
|
||||||
|
// Flush the stream
|
||||||
|
oneOf(writer).flush();
|
||||||
|
}});
|
||||||
|
c.flush();
|
||||||
|
context.assertIsSatisfied();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFlushWithBufferedDataWritesFrameAndFlushes()
|
||||||
|
throws Exception {
|
||||||
|
Mockery context = new Mockery();
|
||||||
|
final FrameWriter writer = context.mock(FrameWriter.class);
|
||||||
|
ConnectionWriterImpl c = new ConnectionWriterImpl(writer, FRAME_LENGTH);
|
||||||
|
context.checking(new Expectations() {{
|
||||||
|
// Write a non-final frame with one payload byte
|
||||||
|
oneOf(writer).writeFrame(with(any(byte[].class)), with(1),
|
||||||
|
with(false));
|
||||||
|
// Flush the stream
|
||||||
|
oneOf(writer).flush();
|
||||||
|
}});
|
||||||
|
c.write(0);
|
||||||
|
c.flush();
|
||||||
|
context.assertIsSatisfied();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSingleByteWritesWriteFullFrame() throws Exception {
|
||||||
|
Mockery context = new Mockery();
|
||||||
|
final FrameWriter writer = context.mock(FrameWriter.class);
|
||||||
|
ConnectionWriterImpl c = new ConnectionWriterImpl(writer, FRAME_LENGTH);
|
||||||
|
context.checking(new Expectations() {{
|
||||||
|
// Write a full non-final frame
|
||||||
|
oneOf(writer).writeFrame(with(any(byte[].class)),
|
||||||
|
with(MAX_PAYLOAD_LENGTH), with(false));
|
||||||
|
}});
|
||||||
|
for(int i = 0; i < MAX_PAYLOAD_LENGTH; i++) {
|
||||||
|
c.write(0);
|
||||||
|
}
|
||||||
|
context.assertIsSatisfied();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMultiByteWritesWriteFullFrames() throws Exception {
|
||||||
|
Mockery context = new Mockery();
|
||||||
|
final FrameWriter writer = context.mock(FrameWriter.class);
|
||||||
|
ConnectionWriterImpl c = new ConnectionWriterImpl(writer, FRAME_LENGTH);
|
||||||
|
context.checking(new Expectations() {{
|
||||||
|
// Write two full non-final frames
|
||||||
|
exactly(2).of(writer).writeFrame(with(any(byte[].class)),
|
||||||
|
with(MAX_PAYLOAD_LENGTH), with(false));
|
||||||
|
}});
|
||||||
|
// Sanity check
|
||||||
|
assertEquals(0, MAX_PAYLOAD_LENGTH % 2);
|
||||||
|
// Write two full payloads using four multi-byte writes
|
||||||
|
byte[] b = new byte[MAX_PAYLOAD_LENGTH / 2];
|
||||||
|
c.write(b);
|
||||||
|
c.write(b);
|
||||||
|
c.write(b);
|
||||||
|
c.write(b);
|
||||||
|
context.assertIsSatisfied();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLargeMultiByteWriteWritesFullFrames() throws Exception {
|
||||||
|
Mockery context = new Mockery();
|
||||||
|
final FrameWriter writer = context.mock(FrameWriter.class);
|
||||||
|
ConnectionWriterImpl c = new ConnectionWriterImpl(writer, FRAME_LENGTH);
|
||||||
|
context.checking(new Expectations() {{
|
||||||
|
// Write two full non-final frames
|
||||||
|
exactly(2).of(writer).writeFrame(with(any(byte[].class)),
|
||||||
|
with(MAX_PAYLOAD_LENGTH), with(false));
|
||||||
|
// Write a final frame with a one-byte payload
|
||||||
|
oneOf(writer).writeFrame(with(any(byte[].class)), with(1),
|
||||||
|
with(true));
|
||||||
|
// Flush the stream
|
||||||
|
oneOf(writer).flush();
|
||||||
|
}});
|
||||||
|
// Write two full payloads using one large multi-byte write
|
||||||
|
byte[] b = new byte[MAX_PAYLOAD_LENGTH * 2 + 1];
|
||||||
|
c.write(b);
|
||||||
|
// There should be one byte left in the buffer
|
||||||
|
c.close();
|
||||||
|
context.assertIsSatisfied();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user