aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSorin Basca <sorinbasca@google.com>2021-06-24 06:14:00 +0000
committerSorin Basca <sorinbasca@google.com>2021-07-15 12:59:04 +0000
commita40903c6d4b947e0c4503e0ed753746f2ae5d41a (patch)
tree4330bb6c8c6565259615ca1f6b2b1aed5cf75e14
parent381a66cc396e4402ff2cb3415a6ef116e1413c3f (diff)
downloadokhttp-a40903c6d4b947e0c4503e0ed753746f2ae5d41a.tar.gz
Making the OkHttp internal framed tests more stable
The Spdy3ConnectionTest experienced some flakyness and inspecting it things could be improved. First of all the MockSpdyPeer.play() function was returning before the peer task executes, allowing room for race conditions. This has been fixed with the use of a CountDownLatch, so play() now waits for the task to start handling HTTP requests. Another potential problem is that tests would share the instance of MockSpdyPeer and rely on tearDown to clear any data, or resources. Tests have been updated to have their own instance of the class which gets auto-closed on test end. A last issue found is one where a listener would first provide an HTTP response before marking that the callback was received. This could cause a race condition as the main thread may start handling the response and checking if the callback was indeed received. It got fixed by first marking the callback and then providing the response. (cherry picked from commit 4291869755a4daebb5ec558e1b51f8d6080bb956) Bug: 191097565 Test: atest CtsLibcoreOkHttpTestCases --iterations 300 Test: atest CtsLibcoreOkHttpTestCases:com.squareup.okhttp.internal.framed.Spdy3ConnectionTest --iterations 300 Test: atest CtsLibcoreOkHttpTestCases:com.squareup.okhttp.internal.framed.Http2ConnectionTest --iterations 300 Merged-In: I88954f470d67299ff3c865a951e1ad91c7c8d1dd Change-Id: I88954f470d67299ff3c865a951e1ad91c7c8d1dd
-rw-r--r--okhttp-tests/src/test/java/com/squareup/okhttp/internal/framed/Http2ConnectionTest.java703
-rw-r--r--okhttp-tests/src/test/java/com/squareup/okhttp/internal/framed/MockSpdyPeer.java9
-rw-r--r--okhttp-tests/src/test/java/com/squareup/okhttp/internal/framed/Spdy3ConnectionTest.java2229
3 files changed, 1525 insertions, 1416 deletions
diff --git a/okhttp-tests/src/test/java/com/squareup/okhttp/internal/framed/Http2ConnectionTest.java b/okhttp-tests/src/test/java/com/squareup/okhttp/internal/framed/Http2ConnectionTest.java
index 1e00b4b..607b0b5 100644
--- a/okhttp-tests/src/test/java/com/squareup/okhttp/internal/framed/Http2ConnectionTest.java
+++ b/okhttp-tests/src/test/java/com/squareup/okhttp/internal/framed/Http2ConnectionTest.java
@@ -49,91 +49,92 @@ import static org.junit.Assert.fail;
public final class Http2ConnectionTest {
private static final Variant HTTP_2 = new Http2();
- private final MockSpdyPeer peer = new MockSpdyPeer();
-
- @After public void tearDown() throws Exception {
- peer.close();
- }
@Test public void serverPingsClientHttp2() throws Exception {
- peer.setVariantAndClient(HTTP_2, false);
-
- // write the mocking script
- peer.sendFrame().ping(false, 2, 3);
- peer.acceptFrame(); // PING
- peer.play();
-
- // play it back
- connection(peer, HTTP_2);
-
- // verify the peer received what was expected
- MockSpdyPeer.InFrame ping = peer.takeFrame();
- assertEquals(TYPE_PING, ping.type);
- assertEquals(0, ping.streamId);
- assertEquals(2, ping.payload1);
- assertEquals(3, ping.payload2);
- assertTrue(ping.ack);
+ try (MockSpdyPeer peer = new MockSpdyPeer()) {
+ peer.setVariantAndClient(HTTP_2, false);
+
+ // write the mocking script
+ peer.sendFrame().ping(false, 2, 3);
+ peer.acceptFrame(); // PING
+ peer.play();
+
+ // play it back
+ connection(peer, HTTP_2);
+
+ // verify the peer received what was expected
+ MockSpdyPeer.InFrame ping = peer.takeFrame();
+ assertEquals(TYPE_PING, ping.type);
+ assertEquals(0, ping.streamId);
+ assertEquals(2, ping.payload1);
+ assertEquals(3, ping.payload2);
+ assertTrue(ping.ack);
+ }
}
@Test public void clientPingsServerHttp2() throws Exception {
- peer.setVariantAndClient(HTTP_2, false);
-
- // write the mocking script
- peer.acceptFrame(); // PING
- peer.sendFrame().ping(true, 1, 5);
- peer.play();
-
- // play it back
- FramedConnection connection = connection(peer, HTTP_2);
- Ping ping = connection.ping();
- assertTrue(ping.roundTripTime() > 0);
- assertTrue(ping.roundTripTime() < TimeUnit.SECONDS.toNanos(1));
-
- // verify the peer received what was expected
- MockSpdyPeer.InFrame pingFrame = peer.takeFrame();
- assertEquals(0, pingFrame.streamId);
- assertEquals(1, pingFrame.payload1);
- assertEquals(0x4f4b6f6b, pingFrame.payload2); // connection.ping() sets this.
- assertFalse(pingFrame.ack);
+ try (MockSpdyPeer peer = new MockSpdyPeer()) {
+ peer.setVariantAndClient(HTTP_2, false);
+
+ // write the mocking script
+ peer.acceptFrame(); // PING
+ peer.sendFrame().ping(true, 1, 5);
+ peer.play();
+
+ // play it back
+ FramedConnection connection = connection(peer, HTTP_2);
+ Ping ping = connection.ping();
+ assertTrue(ping.roundTripTime() > 0);
+ assertTrue(ping.roundTripTime() < TimeUnit.SECONDS.toNanos(1));
+
+ // verify the peer received what was expected
+ MockSpdyPeer.InFrame pingFrame = peer.takeFrame();
+ assertEquals(0, pingFrame.streamId);
+ assertEquals(1, pingFrame.payload1);
+ assertEquals(0x4f4b6f6b, pingFrame.payload2); // connection.ping() sets this.
+ assertFalse(pingFrame.ack);
+ }
}
@Test public void peerHttp2ServerLowersInitialWindowSize() throws Exception {
- peer.setVariantAndClient(HTTP_2, false);
-
- Settings initial = new Settings();
- initial.set(Settings.INITIAL_WINDOW_SIZE, PERSIST_VALUE, 1684);
- Settings shouldntImpactConnection = new Settings();
- shouldntImpactConnection.set(Settings.INITIAL_WINDOW_SIZE, PERSIST_VALUE, 3368);
-
- peer.sendFrame().settings(initial);
- peer.acceptFrame(); // ACK
- peer.sendFrame().settings(shouldntImpactConnection);
- peer.acceptFrame(); // ACK 2
- peer.acceptFrame(); // HEADERS
- peer.play();
-
- FramedConnection connection = connection(peer, HTTP_2);
-
- // Default is 64KiB - 1.
- assertEquals(65535, connection.peerSettings.getInitialWindowSize(-1));
-
- // Verify the peer received the ACK.
- MockSpdyPeer.InFrame ackFrame = peer.takeFrame();
- assertEquals(TYPE_SETTINGS, ackFrame.type);
- assertEquals(0, ackFrame.streamId);
- assertTrue(ackFrame.ack);
- ackFrame = peer.takeFrame();
- assertEquals(TYPE_SETTINGS, ackFrame.type);
- assertEquals(0, ackFrame.streamId);
- assertTrue(ackFrame.ack);
-
- // This stream was created *after* the connection settings were adjusted.
- FramedStream stream = connection.newStream(headerEntries("a", "android"), false, true);
-
- assertEquals(3368, connection.peerSettings.getInitialWindowSize(DEFAULT_INITIAL_WINDOW_SIZE));
- assertEquals(1684, connection.bytesLeftInWriteWindow); // initial wasn't affected.
- // New Stream is has the most recent initial window size.
- assertEquals(3368, stream.bytesLeftInWriteWindow);
+ try (MockSpdyPeer peer = new MockSpdyPeer()) {
+ peer.setVariantAndClient(HTTP_2, false);
+
+ Settings initial = new Settings();
+ initial.set(Settings.INITIAL_WINDOW_SIZE, PERSIST_VALUE, 1684);
+ Settings shouldntImpactConnection = new Settings();
+ shouldntImpactConnection.set(Settings.INITIAL_WINDOW_SIZE, PERSIST_VALUE, 3368);
+
+ peer.sendFrame().settings(initial);
+ peer.acceptFrame(); // ACK
+ peer.sendFrame().settings(shouldntImpactConnection);
+ peer.acceptFrame(); // ACK 2
+ peer.acceptFrame(); // HEADERS
+ peer.play();
+
+ FramedConnection connection = connection(peer, HTTP_2);
+
+ // Default is 64KiB - 1.
+ assertEquals(65535, connection.peerSettings.getInitialWindowSize(-1));
+
+ // Verify the peer received the ACK.
+ MockSpdyPeer.InFrame ackFrame = peer.takeFrame();
+ assertEquals(TYPE_SETTINGS, ackFrame.type);
+ assertEquals(0, ackFrame.streamId);
+ assertTrue(ackFrame.ack);
+ ackFrame = peer.takeFrame();
+ assertEquals(TYPE_SETTINGS, ackFrame.type);
+ assertEquals(0, ackFrame.streamId);
+ assertTrue(ackFrame.ack);
+
+ // This stream was created *after* the connection settings were adjusted.
+ FramedStream stream = connection.newStream(headerEntries("a", "android"), false, true);
+
+ assertEquals(3368, connection.peerSettings.getInitialWindowSize(DEFAULT_INITIAL_WINDOW_SIZE));
+ assertEquals(1684, connection.bytesLeftInWriteWindow); // initial wasn't affected.
+ // New Stream is has the most recent initial window size.
+ assertEquals(3368, stream.bytesLeftInWriteWindow);
+ }
}
@Test public void peerHttp2ServerZerosCompressionTable() throws Exception {
@@ -174,101 +175,105 @@ public final class Http2ConnectionTest {
}
@Test public void receiveGoAwayHttp2() throws Exception {
- peer.setVariantAndClient(HTTP_2, false);
-
- // write the mocking script
- peer.acceptFrame(); // SYN_STREAM 3
- peer.acceptFrame(); // SYN_STREAM 5
- peer.sendFrame().goAway(3, PROTOCOL_ERROR, Util.EMPTY_BYTE_ARRAY);
- peer.acceptFrame(); // PING
- peer.sendFrame().ping(true, 1, 0);
- peer.acceptFrame(); // DATA STREAM 3
- peer.play();
-
- // play it back
- FramedConnection connection = connection(peer, HTTP_2);
- FramedStream stream1 = connection.newStream(headerEntries("a", "android"), true, true);
- FramedStream stream2 = connection.newStream(headerEntries("b", "banana"), true, true);
- connection.ping().roundTripTime(); // Ensure the GO_AWAY that resets stream2 has been received.
- BufferedSink sink1 = Okio.buffer(stream1.getSink());
- BufferedSink sink2 = Okio.buffer(stream2.getSink());
- sink1.writeUtf8("abc");
- try {
- sink2.writeUtf8("abc");
- sink2.flush();
- fail();
- } catch (IOException expected) {
- assertEquals("stream was reset: REFUSED_STREAM", expected.getMessage());
- }
- sink1.writeUtf8("def");
- sink1.close();
- try {
- connection.newStream(headerEntries("c", "cola"), true, true);
- fail();
- } catch (IOException expected) {
- assertEquals("shutdown", expected.getMessage());
+ try (MockSpdyPeer peer = new MockSpdyPeer()) {
+ peer.setVariantAndClient(HTTP_2, false);
+
+ // write the mocking script
+ peer.acceptFrame(); // SYN_STREAM 3
+ peer.acceptFrame(); // SYN_STREAM 5
+ peer.sendFrame().goAway(3, PROTOCOL_ERROR, Util.EMPTY_BYTE_ARRAY);
+ peer.acceptFrame(); // PING
+ peer.sendFrame().ping(true, 1, 0);
+ peer.acceptFrame(); // DATA STREAM 3
+ peer.play();
+
+ // play it back
+ FramedConnection connection = connection(peer, HTTP_2);
+ FramedStream stream1 = connection.newStream(headerEntries("a", "android"), true, true);
+ FramedStream stream2 = connection.newStream(headerEntries("b", "banana"), true, true);
+ connection.ping().roundTripTime(); // Ensure the GO_AWAY that resets stream2 has been received.
+ BufferedSink sink1 = Okio.buffer(stream1.getSink());
+ BufferedSink sink2 = Okio.buffer(stream2.getSink());
+ sink1.writeUtf8("abc");
+ try {
+ sink2.writeUtf8("abc");
+ sink2.flush();
+ fail();
+ } catch (IOException expected) {
+ assertEquals("stream was reset: REFUSED_STREAM", expected.getMessage());
+ }
+ sink1.writeUtf8("def");
+ sink1.close();
+ try {
+ connection.newStream(headerEntries("c", "cola"), true, true);
+ fail();
+ } catch (IOException expected) {
+ assertEquals("shutdown", expected.getMessage());
+ }
+ assertTrue(stream1.isOpen());
+ assertFalse(stream2.isOpen());
+ assertEquals(1, connection.openStreamCount());
+
+ // verify the peer received what was expected
+ MockSpdyPeer.InFrame synStream1 = peer.takeFrame();
+ assertEquals(TYPE_HEADERS, synStream1.type);
+ MockSpdyPeer.InFrame synStream2 = peer.takeFrame();
+ assertEquals(TYPE_HEADERS, synStream2.type);
+ MockSpdyPeer.InFrame ping = peer.takeFrame();
+ assertEquals(TYPE_PING, ping.type);
+ MockSpdyPeer.InFrame data1 = peer.takeFrame();
+ assertEquals(TYPE_DATA, data1.type);
+ assertEquals(3, data1.streamId);
+ assertTrue(Arrays.equals("abcdef".getBytes("UTF-8"), data1.data));
}
- assertTrue(stream1.isOpen());
- assertFalse(stream2.isOpen());
- assertEquals(1, connection.openStreamCount());
-
- // verify the peer received what was expected
- MockSpdyPeer.InFrame synStream1 = peer.takeFrame();
- assertEquals(TYPE_HEADERS, synStream1.type);
- MockSpdyPeer.InFrame synStream2 = peer.takeFrame();
- assertEquals(TYPE_HEADERS, synStream2.type);
- MockSpdyPeer.InFrame ping = peer.takeFrame();
- assertEquals(TYPE_PING, ping.type);
- MockSpdyPeer.InFrame data1 = peer.takeFrame();
- assertEquals(TYPE_DATA, data1.type);
- assertEquals(3, data1.streamId);
- assertTrue(Arrays.equals("abcdef".getBytes("UTF-8"), data1.data));
}
@Test public void readSendsWindowUpdateHttp2() throws Exception {
- peer.setVariantAndClient(HTTP_2, false);
-
- int windowSize = 100;
- int windowUpdateThreshold = 50;
-
- // Write the mocking script.
- peer.acceptFrame(); // SYN_STREAM
- peer.sendFrame().synReply(false, 3, headerEntries("a", "android"));
- for (int i = 0; i < 3; i++) {
- // Send frames of summing to size 50, which is windowUpdateThreshold.
- peer.sendFrame().data(false, 3, data(24), 24);
- peer.sendFrame().data(false, 3, data(25), 25);
- peer.sendFrame().data(false, 3, data(1), 1);
- peer.acceptFrame(); // connection WINDOW UPDATE
- peer.acceptFrame(); // stream WINDOW UPDATE
- }
- peer.sendFrame().data(true, 3, data(0), 0);
- peer.play();
-
- // Play it back.
- FramedConnection connection = connection(peer, HTTP_2);
- connection.okHttpSettings.set(Settings.INITIAL_WINDOW_SIZE, 0, windowSize);
- FramedStream stream = connection.newStream(headerEntries("b", "banana"), false, true);
- assertEquals(0, stream.unacknowledgedBytesRead);
- assertEquals(headerEntries("a", "android"), stream.getResponseHeaders());
- Source in = stream.getSource();
- Buffer buffer = new Buffer();
- buffer.writeAll(in);
- assertEquals(-1, in.read(buffer, 1));
- assertEquals(150, buffer.size());
-
- MockSpdyPeer.InFrame synStream = peer.takeFrame();
- assertEquals(TYPE_HEADERS, synStream.type);
- for (int i = 0; i < 3; i++) {
- List<Integer> windowUpdateStreamIds = new ArrayList<>(2);
- for (int j = 0; j < 2; j++) {
- MockSpdyPeer.InFrame windowUpdate = peer.takeFrame();
- assertEquals(TYPE_WINDOW_UPDATE, windowUpdate.type);
- windowUpdateStreamIds.add(windowUpdate.streamId);
- assertEquals(windowUpdateThreshold, windowUpdate.windowSizeIncrement);
+ try (MockSpdyPeer peer = new MockSpdyPeer()) {
+ peer.setVariantAndClient(HTTP_2, false);
+
+ int windowSize = 100;
+ int windowUpdateThreshold = 50;
+
+ // Write the mocking script.
+ peer.acceptFrame(); // SYN_STREAM
+ peer.sendFrame().synReply(false, 3, headerEntries("a", "android"));
+ for (int i = 0; i < 3; i++) {
+ // Send frames of summing to size 50, which is windowUpdateThreshold.
+ peer.sendFrame().data(false, 3, data(24), 24);
+ peer.sendFrame().data(false, 3, data(25), 25);
+ peer.sendFrame().data(false, 3, data(1), 1);
+ peer.acceptFrame(); // connection WINDOW UPDATE
+ peer.acceptFrame(); // stream WINDOW UPDATE
+ }
+ peer.sendFrame().data(true, 3, data(0), 0);
+ peer.play();
+
+ // Play it back.
+ FramedConnection connection = connection(peer, HTTP_2);
+ connection.okHttpSettings.set(Settings.INITIAL_WINDOW_SIZE, 0, windowSize);
+ FramedStream stream = connection.newStream(headerEntries("b", "banana"), false, true);
+ assertEquals(0, stream.unacknowledgedBytesRead);
+ assertEquals(headerEntries("a", "android"), stream.getResponseHeaders());
+ Source in = stream.getSource();
+ Buffer buffer = new Buffer();
+ buffer.writeAll(in);
+ assertEquals(-1, in.read(buffer, 1));
+ assertEquals(150, buffer.size());
+
+ MockSpdyPeer.InFrame synStream = peer.takeFrame();
+ assertEquals(TYPE_HEADERS, synStream.type);
+ for (int i = 0; i < 3; i++) {
+ List<Integer> windowUpdateStreamIds = new ArrayList<>(2);
+ for (int j = 0; j < 2; j++) {
+ MockSpdyPeer.InFrame windowUpdate = peer.takeFrame();
+ assertEquals(TYPE_WINDOW_UPDATE, windowUpdate.type);
+ windowUpdateStreamIds.add(windowUpdate.streamId);
+ assertEquals(windowUpdateThreshold, windowUpdate.windowSizeIncrement);
+ }
+ assertTrue(windowUpdateStreamIds.contains(0)); // connection
+ assertTrue(windowUpdateStreamIds.contains(3)); // stream
}
- assertTrue(windowUpdateStreamIds.contains(0)); // connection
- assertTrue(windowUpdateStreamIds.contains(3)); // stream
}
}
@@ -277,156 +282,168 @@ public final class Http2ConnectionTest {
}
@Test public void serverSendsEmptyDataClientDoesntSendWindowUpdateHttp2() throws Exception {
- peer.setVariantAndClient(HTTP_2, false);
-
- // Write the mocking script.
- peer.acceptFrame(); // SYN_STREAM
- peer.sendFrame().synReply(false, 3, headerEntries("a", "android"));
- peer.sendFrame().data(true, 3, data(0), 0);
- peer.play();
-
- // Play it back.
- FramedConnection connection = connection(peer, HTTP_2);
- FramedStream client = connection.newStream(headerEntries("b", "banana"), false, true);
- assertEquals(-1, client.getSource().read(new Buffer(), 1));
-
- // Verify the peer received what was expected.
- MockSpdyPeer.InFrame synStream = peer.takeFrame();
- assertEquals(TYPE_HEADERS, synStream.type);
- assertEquals(3, peer.frameCount());
+ try (MockSpdyPeer peer = new MockSpdyPeer()) {
+ peer.setVariantAndClient(HTTP_2, false);
+
+ // Write the mocking script.
+ peer.acceptFrame(); // SYN_STREAM
+ peer.sendFrame().synReply(false, 3, headerEntries("a", "android"));
+ peer.sendFrame().data(true, 3, data(0), 0);
+ peer.play();
+
+ // Play it back.
+ FramedConnection connection = connection(peer, HTTP_2);
+ FramedStream client = connection.newStream(headerEntries("b", "banana"), false, true);
+ assertEquals(-1, client.getSource().read(new Buffer(), 1));
+
+ // Verify the peer received what was expected.
+ MockSpdyPeer.InFrame synStream = peer.takeFrame();
+ assertEquals(TYPE_HEADERS, synStream.type);
+ assertEquals(3, peer.frameCount());
+ }
}
@Test public void clientSendsEmptyDataServerDoesntSendWindowUpdateHttp2() throws Exception {
- peer.setVariantAndClient(HTTP_2, false);
-
- // Write the mocking script.
- peer.acceptFrame(); // SYN_STREAM
- peer.acceptFrame(); // DATA
- peer.sendFrame().synReply(false, 3, headerEntries("a", "android"));
- peer.play();
-
- // Play it back.
- FramedConnection connection = connection(peer, HTTP_2);
- FramedStream client = connection.newStream(headerEntries("b", "banana"), true, true);
- BufferedSink out = Okio.buffer(client.getSink());
- out.write(Util.EMPTY_BYTE_ARRAY);
- out.flush();
- out.close();
-
- // Verify the peer received what was expected.
- assertEquals(TYPE_HEADERS, peer.takeFrame().type);
- assertEquals(TYPE_DATA, peer.takeFrame().type);
- assertEquals(3, peer.frameCount());
+ try (MockSpdyPeer peer = new MockSpdyPeer()) {
+ peer.setVariantAndClient(HTTP_2, false);
+
+ // Write the mocking script.
+ peer.acceptFrame(); // SYN_STREAM
+ peer.acceptFrame(); // DATA
+ peer.sendFrame().synReply(false, 3, headerEntries("a", "android"));
+ peer.play();
+
+ // Play it back.
+ FramedConnection connection = connection(peer, HTTP_2);
+ FramedStream client = connection.newStream(headerEntries("b", "banana"), true, true);
+ BufferedSink out = Okio.buffer(client.getSink());
+ out.write(Util.EMPTY_BYTE_ARRAY);
+ out.flush();
+ out.close();
+
+ // Verify the peer received what was expected.
+ assertEquals(TYPE_HEADERS, peer.takeFrame().type);
+ assertEquals(TYPE_DATA, peer.takeFrame().type);
+ assertEquals(3, peer.frameCount());
+ }
}
@Test public void maxFrameSizeHonored() throws Exception {
- peer.setVariantAndClient(HTTP_2, false);
-
- byte[] buff = new byte[peer.maxOutboundDataLength() + 1];
- Arrays.fill(buff, (byte) '*');
-
- // write the mocking script
- peer.acceptFrame(); // SYN_STREAM
- peer.sendFrame().synReply(false, 3, headerEntries("a", "android"));
- peer.acceptFrame(); // DATA
- peer.acceptFrame(); // DATA
- peer.play();
-
- // play it back
- FramedConnection connection = connection(peer, HTTP_2);
- FramedStream stream = connection.newStream(headerEntries("b", "banana"), true, true);
- BufferedSink out = Okio.buffer(stream.getSink());
- out.write(buff);
- out.flush();
- out.close();
-
- MockSpdyPeer.InFrame synStream = peer.takeFrame();
- assertEquals(TYPE_HEADERS, synStream.type);
- MockSpdyPeer.InFrame data = peer.takeFrame();
- assertEquals(peer.maxOutboundDataLength(), data.data.length);
- data = peer.takeFrame();
- assertEquals(1, data.data.length);
+ try (MockSpdyPeer peer = new MockSpdyPeer()) {
+ peer.setVariantAndClient(HTTP_2, false);
+
+ byte[] buff = new byte[peer.maxOutboundDataLength() + 1];
+ Arrays.fill(buff, (byte) '*');
+
+ // write the mocking script
+ peer.acceptFrame(); // SYN_STREAM
+ peer.sendFrame().synReply(false, 3, headerEntries("a", "android"));
+ peer.acceptFrame(); // DATA
+ peer.acceptFrame(); // DATA
+ peer.play();
+
+ // play it back
+ FramedConnection connection = connection(peer, HTTP_2);
+ FramedStream stream = connection.newStream(headerEntries("b", "banana"), true, true);
+ BufferedSink out = Okio.buffer(stream.getSink());
+ out.write(buff);
+ out.flush();
+ out.close();
+
+ MockSpdyPeer.InFrame synStream = peer.takeFrame();
+ assertEquals(TYPE_HEADERS, synStream.type);
+ MockSpdyPeer.InFrame data = peer.takeFrame();
+ assertEquals(peer.maxOutboundDataLength(), data.data.length);
+ data = peer.takeFrame();
+ assertEquals(1, data.data.length);
+ }
}
@Test public void pushPromiseStream() throws Exception {
- peer.setVariantAndClient(HTTP_2, false);
-
- // write the mocking script
- peer.acceptFrame(); // SYN_STREAM
- peer.sendFrame().synReply(false, 3, headerEntries("a", "android"));
- final List<Header> expectedRequestHeaders = Arrays.asList(
- new Header(Header.TARGET_METHOD, "GET"),
- new Header(Header.TARGET_SCHEME, "https"),
- new Header(Header.TARGET_AUTHORITY, "squareup.com"),
- new Header(Header.TARGET_PATH, "/cached")
- );
- peer.sendFrame().pushPromise(3, 2, expectedRequestHeaders);
- final List<Header> expectedResponseHeaders = Arrays.asList(
- new Header(Header.RESPONSE_STATUS, "200")
- );
- peer.sendFrame().synReply(true, 2, expectedResponseHeaders);
- peer.sendFrame().data(true, 3, data(0), 0);
- peer.play();
-
- RecordingPushObserver observer = new RecordingPushObserver();
-
- // play it back
- FramedConnection connection = connectionBuilder(peer, HTTP_2)
- .pushObserver(observer).build();
- FramedStream client = connection.newStream(headerEntries("b", "banana"), false, true);
- assertEquals(-1, client.getSource().read(new Buffer(), 1));
-
- // verify the peer received what was expected
- assertEquals(TYPE_HEADERS, peer.takeFrame().type);
-
- assertEquals(expectedRequestHeaders, observer.takeEvent());
- assertEquals(expectedResponseHeaders, observer.takeEvent());
+ try (MockSpdyPeer peer = new MockSpdyPeer()) {
+ peer.setVariantAndClient(HTTP_2, false);
+
+ // write the mocking script
+ peer.acceptFrame(); // SYN_STREAM
+ peer.sendFrame().synReply(false, 3, headerEntries("a", "android"));
+ final List<Header> expectedRequestHeaders = Arrays.asList(
+ new Header(Header.TARGET_METHOD, "GET"),
+ new Header(Header.TARGET_SCHEME, "https"),
+ new Header(Header.TARGET_AUTHORITY, "squareup.com"),
+ new Header(Header.TARGET_PATH, "/cached")
+ );
+ peer.sendFrame().pushPromise(3, 2, expectedRequestHeaders);
+ final List<Header> expectedResponseHeaders = Arrays.asList(
+ new Header(Header.RESPONSE_STATUS, "200")
+ );
+ peer.sendFrame().synReply(true, 2, expectedResponseHeaders);
+ peer.sendFrame().data(true, 3, data(0), 0);
+ peer.play();
+
+ RecordingPushObserver observer = new RecordingPushObserver();
+
+ // play it back
+ FramedConnection connection = connectionBuilder(peer, HTTP_2)
+ .pushObserver(observer).build();
+ FramedStream client = connection.newStream(headerEntries("b", "banana"), false, true);
+ assertEquals(-1, client.getSource().read(new Buffer(), 1));
+
+ // verify the peer received what was expected
+ assertEquals(TYPE_HEADERS, peer.takeFrame().type);
+
+ assertEquals(expectedRequestHeaders, observer.takeEvent());
+ assertEquals(expectedResponseHeaders, observer.takeEvent());
+ }
}
@Test public void doublePushPromise() throws Exception {
- peer.setVariantAndClient(HTTP_2, false);
-
- // write the mocking script
- peer.sendFrame().pushPromise(3, 2, headerEntries("a", "android"));
- peer.acceptFrame(); // SYN_REPLY
- peer.sendFrame().pushPromise(3, 2, headerEntries("b", "banana"));
- peer.acceptFrame(); // RST_STREAM
- peer.play();
-
- // play it back
- FramedConnection connection = connectionBuilder(peer, HTTP_2).build();
- connection.newStream(headerEntries("b", "banana"), false, true);
-
- // verify the peer received what was expected
- assertEquals(TYPE_HEADERS, peer.takeFrame().type);
- assertEquals(PROTOCOL_ERROR, peer.takeFrame().errorCode);
+ try (MockSpdyPeer peer = new MockSpdyPeer()) {
+ peer.setVariantAndClient(HTTP_2, false);
+
+ // write the mocking script
+ peer.sendFrame().pushPromise(3, 2, headerEntries("a", "android"));
+ peer.acceptFrame(); // SYN_REPLY
+ peer.sendFrame().pushPromise(3, 2, headerEntries("b", "banana"));
+ peer.acceptFrame(); // RST_STREAM
+ peer.play();
+
+ // play it back
+ FramedConnection connection = connectionBuilder(peer, HTTP_2).build();
+ connection.newStream(headerEntries("b", "banana"), false, true);
+
+ // verify the peer received what was expected
+ assertEquals(TYPE_HEADERS, peer.takeFrame().type);
+ assertEquals(PROTOCOL_ERROR, peer.takeFrame().errorCode);
+ }
}
@Test public void pushPromiseStreamsAutomaticallyCancel() throws Exception {
- peer.setVariantAndClient(HTTP_2, false);
-
- // write the mocking script
- peer.sendFrame().pushPromise(3, 2, Arrays.asList(
- new Header(Header.TARGET_METHOD, "GET"),
- new Header(Header.TARGET_SCHEME, "https"),
- new Header(Header.TARGET_AUTHORITY, "squareup.com"),
- new Header(Header.TARGET_PATH, "/cached")
- ));
- peer.sendFrame().synReply(true, 2, Arrays.asList(
- new Header(Header.RESPONSE_STATUS, "200")
- ));
- peer.acceptFrame(); // RST_STREAM
- peer.play();
-
- // play it back
- connectionBuilder(peer, HTTP_2)
- .pushObserver(PushObserver.CANCEL).build();
-
- // verify the peer received what was expected
- MockSpdyPeer.InFrame rstStream = peer.takeFrame();
- assertEquals(TYPE_RST_STREAM, rstStream.type);
- assertEquals(2, rstStream.streamId);
- assertEquals(CANCEL, rstStream.errorCode);
+ try (MockSpdyPeer peer = new MockSpdyPeer()) {
+ peer.setVariantAndClient(HTTP_2, false);
+
+ // write the mocking script
+ peer.sendFrame().pushPromise(3, 2, Arrays.asList(
+ new Header(Header.TARGET_METHOD, "GET"),
+ new Header(Header.TARGET_SCHEME, "https"),
+ new Header(Header.TARGET_AUTHORITY, "squareup.com"),
+ new Header(Header.TARGET_PATH, "/cached")
+ ));
+ peer.sendFrame().synReply(true, 2, Arrays.asList(
+ new Header(Header.RESPONSE_STATUS, "200")
+ ));
+ peer.acceptFrame(); // RST_STREAM
+ peer.play();
+
+ // play it back
+ connectionBuilder(peer, HTTP_2)
+ .pushObserver(PushObserver.CANCEL).build();
+
+ // verify the peer received what was expected
+ MockSpdyPeer.InFrame rstStream = peer.takeFrame();
+ assertEquals(TYPE_RST_STREAM, rstStream.type);
+ assertEquals(2, rstStream.streamId);
+ assertEquals(CANCEL, rstStream.errorCode);
+ }
}
/**
@@ -437,50 +454,54 @@ public final class Http2ConnectionTest {
* <p>See https://github.com/square/okhttp/issues/1651
*/
@Test public void socketExceptionWhileWritingHeaders() throws Exception {
- peer.setVariantAndClient(HTTP_2, false);
- peer.acceptFrame(); // SYN_STREAM.
- peer.play();
-
- String longString = repeat('a', Http2.INITIAL_MAX_FRAME_SIZE + 1);
- Socket socket = peer.openSocket();
- FramedConnection connection = new FramedConnection.Builder(true)
- .socket(socket)
- .pushObserver(IGNORE)
- .protocol(HTTP_2.getProtocol())
- .build();
- socket.shutdownOutput();
- try {
- connection.newStream(headerEntries("a", longString), false, true);
- fail();
- } catch (IOException expected) {
- }
- try {
- connection.newStream(headerEntries("b", longString), false, true);
- fail();
- } catch (IOException expected) {
+ try (MockSpdyPeer peer = new MockSpdyPeer()) {
+ peer.setVariantAndClient(HTTP_2, false);
+ peer.acceptFrame(); // SYN_STREAM.
+ peer.play();
+
+ String longString = repeat('a', Http2.INITIAL_MAX_FRAME_SIZE + 1);
+ Socket socket = peer.openSocket();
+ FramedConnection connection = new FramedConnection.Builder(true)
+ .socket(socket)
+ .pushObserver(IGNORE)
+ .protocol(HTTP_2.getProtocol())
+ .build();
+ socket.shutdownOutput();
+ try {
+ connection.newStream(headerEntries("a", longString), false, true);
+ fail();
+ } catch (IOException expected) {
+ }
+ try {
+ connection.newStream(headerEntries("b", longString), false, true);
+ fail();
+ } catch (IOException expected) {
+ }
}
}
private FramedConnection sendHttp2SettingsAndCheckForAck(boolean client, Settings settings)
throws IOException, InterruptedException {
- peer.setVariantAndClient(HTTP_2, client);
- peer.sendFrame().settings(settings);
- peer.acceptFrame(); // ACK
- peer.acceptFrame(); // PING
- peer.sendFrame().ping(true, 1, 0);
- peer.play();
-
- // play it back
- FramedConnection connection = connection(peer, HTTP_2);
-
- // verify the peer received the ACK
- MockSpdyPeer.InFrame ackFrame = peer.takeFrame();
- assertEquals(TYPE_SETTINGS, ackFrame.type);
- assertEquals(0, ackFrame.streamId);
- assertTrue(ackFrame.ack);
-
- connection.ping().roundTripTime(); // Ensure that settings have been applied before returning.
- return connection;
+ try (MockSpdyPeer peer = new MockSpdyPeer()) {
+ peer.setVariantAndClient(HTTP_2, client);
+ peer.sendFrame().settings(settings);
+ peer.acceptFrame(); // ACK
+ peer.acceptFrame(); // PING
+ peer.sendFrame().ping(true, 1, 0);
+ peer.play();
+
+ // play it back
+ FramedConnection connection = connection(peer, HTTP_2);
+
+ // verify the peer received the ACK
+ MockSpdyPeer.InFrame ackFrame = peer.takeFrame();
+ assertEquals(TYPE_SETTINGS, ackFrame.type);
+ assertEquals(0, ackFrame.streamId);
+ assertTrue(ackFrame.ack);
+
+ connection.ping().roundTripTime(); // Ensure that settings have been applied before returning.
+ return connection;
+ }
}
private FramedConnection connection(MockSpdyPeer peer, Variant variant) throws IOException {
diff --git a/okhttp-tests/src/test/java/com/squareup/okhttp/internal/framed/MockSpdyPeer.java b/okhttp-tests/src/test/java/com/squareup/okhttp/internal/framed/MockSpdyPeer.java
index f30d099..d402657 100644
--- a/okhttp-tests/src/test/java/com/squareup/okhttp/internal/framed/MockSpdyPeer.java
+++ b/okhttp-tests/src/test/java/com/squareup/okhttp/internal/framed/MockSpdyPeer.java
@@ -27,9 +27,11 @@ import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
import java.util.logging.Logger;
import okio.Buffer;
import okio.BufferedSource;
@@ -116,11 +118,13 @@ public final class MockSpdyPeer implements Closeable {
public void play() throws IOException {
if (serverSocket != null) throw new IllegalStateException();
+ final CountDownLatch startSignal = new CountDownLatch(1);
serverSocket = new ServerSocket(0);
serverSocket.setReuseAddress(true);
port = serverSocket.getLocalPort();
executor.execute(new Runnable() {
@Override public void run() {
+ startSignal.countDown();
try {
readAndWriteFrames();
} catch (IOException e) {
@@ -129,6 +133,11 @@ public final class MockSpdyPeer implements Closeable {
}
}
});
+ try {
+ startSignal.await(5L, TimeUnit.SECONDS);
+ } catch (InterruptedException e) {
+ // Do nothing
+ }
}
private void readAndWriteFrames() throws IOException {
diff --git a/okhttp-tests/src/test/java/com/squareup/okhttp/internal/framed/Spdy3ConnectionTest.java b/okhttp-tests/src/test/java/com/squareup/okhttp/internal/framed/Spdy3ConnectionTest.java
index 752e92b..38961ef 100644
--- a/okhttp-tests/src/test/java/com/squareup/okhttp/internal/framed/Spdy3ConnectionTest.java
+++ b/okhttp-tests/src/test/java/com/squareup/okhttp/internal/framed/Spdy3ConnectionTest.java
@@ -58,416 +58,441 @@ import static org.junit.Assert.fail;
public final class Spdy3ConnectionTest {
private static final Variant SPDY3 = new Spdy3();
- private final MockSpdyPeer peer = new MockSpdyPeer();
-
- @After public void tearDown() throws Exception {
- peer.close();
- }
@Test public void clientCreatesStreamAndServerReplies() throws Exception {
- // write the mocking script
- peer.acceptFrame(); // SYN_STREAM
- peer.sendFrame()
- .synReply(false, 1, headerEntries("a", "android"));
- peer.sendFrame().data(true, 1, new Buffer().writeUtf8("robot"), 5);
- peer.acceptFrame(); // DATA
- peer.play();
-
- // play it back
- FramedConnection connection = connection(peer, SPDY3);
- FramedStream stream = connection.newStream(headerEntries("b", "banana"), true, true);
- assertEquals(headerEntries("a", "android"), stream.getResponseHeaders());
- assertStreamData("robot", stream.getSource());
- BufferedSink out = Okio.buffer(stream.getSink());
- out.writeUtf8("c3po");
- out.close();
- assertEquals(0, connection.openStreamCount());
-
- // verify the peer received what was expected
- MockSpdyPeer.InFrame synStream = peer.takeFrame();
- assertEquals(TYPE_HEADERS, synStream.type);
- assertEquals(HeadersMode.SPDY_SYN_STREAM, synStream.headersMode);
- assertFalse(synStream.inFinished);
- assertFalse(synStream.outFinished);
- assertEquals(1, synStream.streamId);
- assertEquals(0, synStream.associatedStreamId);
- assertEquals(headerEntries("b", "banana"), synStream.headerBlock);
- MockSpdyPeer.InFrame requestData = peer.takeFrame();
- assertTrue(Arrays.equals("c3po".getBytes("UTF-8"), requestData.data));
+ try (MockSpdyPeer peer = new MockSpdyPeer()) {
+ // write the mocking script
+ peer.acceptFrame(); // SYN_STREAM
+ peer.sendFrame()
+ .synReply(false, 1, headerEntries("a", "android"));
+ peer.sendFrame().data(true, 1, new Buffer().writeUtf8("robot"), 5);
+ peer.acceptFrame(); // DATA
+ peer.play();
+
+ // play it back
+ FramedConnection connection = connection(peer, SPDY3);
+ FramedStream stream = connection.newStream(headerEntries("b", "banana"), true, true);
+ assertEquals(headerEntries("a", "android"), stream.getResponseHeaders());
+ assertStreamData("robot", stream.getSource());
+ BufferedSink out = Okio.buffer(stream.getSink());
+ out.writeUtf8("c3po");
+ out.close();
+ assertEquals(0, connection.openStreamCount());
+
+ // verify the peer received what was expected
+ MockSpdyPeer.InFrame synStream = peer.takeFrame();
+ assertEquals(TYPE_HEADERS, synStream.type);
+ assertEquals(HeadersMode.SPDY_SYN_STREAM, synStream.headersMode);
+ assertFalse(synStream.inFinished);
+ assertFalse(synStream.outFinished);
+ assertEquals(1, synStream.streamId);
+ assertEquals(0, synStream.associatedStreamId);
+ assertEquals(headerEntries("b", "banana"), synStream.headerBlock);
+ MockSpdyPeer.InFrame requestData = peer.takeFrame();
+ assertTrue(Arrays.equals("c3po".getBytes("UTF-8"), requestData.data));
+ }
}
@Test public void headersOnlyStreamIsClosedAfterReplyHeaders() throws Exception {
- peer.acceptFrame(); // SYN_STREAM
- peer.sendFrame().synReply(false, 1, headerEntries("b", "banana"));
- peer.acceptFrame(); // PING
- peer.sendFrame().ping(true, 1, 0);
- peer.play();
-
- FramedConnection connection = connection(peer, SPDY3);
- FramedStream stream = connection.newStream(headerEntries("a", "android"), false, false);
- assertEquals(1, connection.openStreamCount());
- assertEquals(headerEntries("b", "banana"), stream.getResponseHeaders());
- connection.ping().roundTripTime(); // Ensure that inFinished has been received.
- assertEquals(0, connection.openStreamCount());
+ try (MockSpdyPeer peer = new MockSpdyPeer()) {
+ peer.acceptFrame(); // SYN_STREAM
+ peer.sendFrame().synReply(false, 1, headerEntries("b", "banana"));
+ peer.acceptFrame(); // PING
+ peer.sendFrame().ping(true, 1, 0);
+ peer.play();
+
+ FramedConnection connection = connection(peer, SPDY3);
+ FramedStream stream = connection.newStream(headerEntries("a", "android"), false, false);
+ assertEquals(1, connection.openStreamCount());
+ assertEquals(headerEntries("b", "banana"), stream.getResponseHeaders());
+ connection.ping().roundTripTime(); // Ensure that inFinished has been received.
+ assertEquals(0, connection.openStreamCount());
+ }
}
@Test public void clientCreatesStreamAndServerRepliesWithFin() throws Exception {
- // write the mocking script
- peer.acceptFrame(); // SYN_STREAM
- peer.acceptFrame(); // PING
- peer.sendFrame().synReply(true, 1, headerEntries("a", "android"));
- peer.sendFrame().ping(true, 1, 0);
- peer.play();
-
- // play it back
- FramedConnection connection = connection(peer, SPDY3);
- connection.newStream(headerEntries("b", "banana"), false, true);
- assertEquals(1, connection.openStreamCount());
- connection.ping().roundTripTime(); // Ensure that the SYN_REPLY has been received.
- assertEquals(0, connection.openStreamCount());
-
- // verify the peer received what was expected
- MockSpdyPeer.InFrame synStream = peer.takeFrame();
- assertEquals(TYPE_HEADERS, synStream.type);
- assertEquals(HeadersMode.SPDY_SYN_STREAM, synStream.headersMode);
- MockSpdyPeer.InFrame ping = peer.takeFrame();
- assertEquals(TYPE_PING, ping.type);
+ try (MockSpdyPeer peer = new MockSpdyPeer()) {
+ // write the mocking script
+ peer.acceptFrame(); // SYN_STREAM
+ peer.acceptFrame(); // PING
+ peer.sendFrame().synReply(true, 1, headerEntries("a", "android"));
+ peer.sendFrame().ping(true, 1, 0);
+ peer.play();
+
+ // play it back
+ FramedConnection connection = connection(peer, SPDY3);
+ connection.newStream(headerEntries("b", "banana"), false, true);
+ assertEquals(1, connection.openStreamCount());
+ connection.ping().roundTripTime(); // Ensure that the SYN_REPLY has been received.
+ assertEquals(0, connection.openStreamCount());
+
+ // verify the peer received what was expected
+ MockSpdyPeer.InFrame synStream = peer.takeFrame();
+ assertEquals(TYPE_HEADERS, synStream.type);
+ assertEquals(HeadersMode.SPDY_SYN_STREAM, synStream.headersMode);
+ MockSpdyPeer.InFrame ping = peer.takeFrame();
+ assertEquals(TYPE_PING, ping.type);
+ }
}
@Test public void serverCreatesStreamAndClientReplies() throws Exception {
- final List<Header> pushHeaders = headerEntries(
- ":scheme", "https",
- ":host", "localhost:8888",
- ":method", "GET",
- ":path", "/index.html",
- ":status", "200",
- ":version", "HTTP/1.1",
- "content-type", "text/html");
- // write the mocking script
- peer.sendFrame().synStream(false, false, 2, 0, pushHeaders);
- peer.acceptFrame(); // SYN_REPLY
- peer.play();
-
- // play it back
- final AtomicInteger receiveCount = new AtomicInteger();
- FramedConnection.Listener handler = new FramedConnection.Listener() {
- @Override public void onStream(FramedStream stream) throws IOException {
- receiveCount.incrementAndGet();
- assertEquals(pushHeaders, stream.getRequestHeaders());
- assertEquals(null, stream.getErrorCode());
- stream.reply(headerEntries("b", "banana"), true);
- }
- };
- new FramedConnection.Builder(true)
- .socket(peer.openSocket())
- .listener(handler)
- .build();
-
- // verify the peer received what was expected
- MockSpdyPeer.InFrame reply = peer.takeFrame();
- assertEquals(TYPE_HEADERS, reply.type);
- assertEquals(HeadersMode.SPDY_REPLY, reply.headersMode);
- assertFalse(reply.inFinished);
- assertEquals(2, reply.streamId);
- assertEquals(headerEntries("b", "banana"), reply.headerBlock);
- assertEquals(1, receiveCount.get());
+ try (MockSpdyPeer peer = new MockSpdyPeer()) {
+ final List<Header> pushHeaders = headerEntries(
+ ":scheme", "https",
+ ":host", "localhost:8888",
+ ":method", "GET",
+ ":path", "/index.html",
+ ":status", "200",
+ ":version", "HTTP/1.1",
+ "content-type", "text/html");
+ // write the mocking script
+ peer.sendFrame().synStream(false, false, 2, 0, pushHeaders);
+ peer.acceptFrame(); // SYN_REPLY
+ peer.play();
+
+ // play it back
+ final AtomicInteger receiveCount = new AtomicInteger();
+ FramedConnection.Listener handler = new FramedConnection.Listener() {
+ @Override public void onStream(FramedStream stream) throws IOException {
+ receiveCount.incrementAndGet();
+ assertEquals(pushHeaders, stream.getRequestHeaders());
+ assertEquals(null, stream.getErrorCode());
+ stream.reply(headerEntries("b", "banana"), true);
+ }
+ };
+ new FramedConnection.Builder(true)
+ .socket(peer.openSocket())
+ .listener(handler)
+ .build();
+
+ // verify the peer received what was expected
+ MockSpdyPeer.InFrame reply = peer.takeFrame();
+ assertEquals(TYPE_HEADERS, reply.type);
+ assertEquals(HeadersMode.SPDY_REPLY, reply.headersMode);
+ assertFalse(reply.inFinished);
+ assertEquals(2, reply.streamId);
+ assertEquals(headerEntries("b", "banana"), reply.headerBlock);
+ assertEquals(1, receiveCount.get());
+ }
}
@Test public void replyWithNoData() throws Exception {
- // write the mocking script
- peer.sendFrame().synStream(false, false, 2, 0, headerEntries("a", "android"));
- peer.acceptFrame(); // SYN_REPLY
- peer.play();
-
- // play it back
- final AtomicInteger receiveCount = new AtomicInteger();
- FramedConnection.Listener listener = new FramedConnection.Listener() {
- @Override public void onStream(FramedStream stream) throws IOException {
- stream.reply(headerEntries("b", "banana"), false);
- receiveCount.incrementAndGet();
- }
- };
+ try (MockSpdyPeer peer = new MockSpdyPeer()) {
+ // write the mocking script
+ peer.sendFrame().synStream(false, false, 2, 0, headerEntries("a", "android"));
+ peer.acceptFrame(); // SYN_REPLY
+ peer.play();
+
+ // play it back
+ final AtomicInteger receiveCount = new AtomicInteger();
+ FramedConnection.Listener listener = new FramedConnection.Listener() {
+ @Override public void onStream(FramedStream stream) throws IOException {
+ receiveCount.incrementAndGet();
+ stream.reply(headerEntries("b", "banana"), false);
+ }
+ };
- connectionBuilder(peer, SPDY3).listener(listener).build();
+ connectionBuilder(peer, SPDY3).listener(listener).build();
- // verify the peer received what was expected
- MockSpdyPeer.InFrame reply = peer.takeFrame();
- assertEquals(TYPE_HEADERS, reply.type);
- assertTrue(reply.inFinished);
- assertEquals(headerEntries("b", "banana"), reply.headerBlock);
- assertEquals(1, receiveCount.get());
- assertEquals(HeadersMode.SPDY_REPLY, reply.headersMode);
+ // verify the peer received what was expected
+ MockSpdyPeer.InFrame reply = peer.takeFrame();
+ assertEquals(TYPE_HEADERS, reply.type);
+ assertTrue(reply.inFinished);
+ assertEquals(headerEntries("b", "banana"), reply.headerBlock);
+ assertEquals(1, receiveCount.get());
+ assertEquals(HeadersMode.SPDY_REPLY, reply.headersMode);
+ }
}
@Test public void serverPingsClient() throws Exception {
- // write the mocking script
- peer.sendFrame().ping(false, 2, 0);
- peer.acceptFrame(); // PING
- peer.play();
-
- // play it back
- connection(peer, SPDY3);
-
- // verify the peer received what was expected
- MockSpdyPeer.InFrame ping = peer.takeFrame();
- assertEquals(0, ping.streamId);
- assertEquals(2, ping.payload1);
- assertEquals(0, ping.payload2); // ignored in spdy!
- assertTrue(ping.ack);
+ try (MockSpdyPeer peer = new MockSpdyPeer()) {
+ // write the mocking script
+ peer.sendFrame().ping(false, 2, 0);
+ peer.acceptFrame(); // PING
+ peer.play();
+
+ // play it back
+ connection(peer, SPDY3);
+
+ // verify the peer received what was expected
+ MockSpdyPeer.InFrame ping = peer.takeFrame();
+ assertEquals(0, ping.streamId);
+ assertEquals(2, ping.payload1);
+ assertEquals(0, ping.payload2); // ignored in spdy!
+ assertTrue(ping.ack);
+ }
}
@Test public void clientPingsServer() throws Exception {
- // write the mocking script
- peer.acceptFrame(); // PING
- peer.sendFrame().ping(true, 1, 5); // payload2 ignored in spdy!
- peer.play();
-
- // play it back
- FramedConnection connection = connection(peer, SPDY3);
- Ping ping = connection.ping();
- assertTrue(ping.roundTripTime() > 0);
- assertTrue(ping.roundTripTime() < TimeUnit.SECONDS.toNanos(1));
-
- // verify the peer received what was expected
- MockSpdyPeer.InFrame pingFrame = peer.takeFrame();
- assertEquals(TYPE_PING, pingFrame.type);
- assertEquals(1, pingFrame.payload1);
- assertEquals(0, pingFrame.payload2);
- assertFalse(pingFrame.ack);
+ try (MockSpdyPeer peer = new MockSpdyPeer()) {
+ // write the mocking script
+ peer.acceptFrame(); // PING
+ peer.sendFrame().ping(true, 1, 5); // payload2 ignored in spdy!
+ peer.play();
+
+ // play it back
+ FramedConnection connection = connection(peer, SPDY3);
+ Ping ping = connection.ping();
+ assertTrue(ping.roundTripTime() > 0);
+ assertTrue(ping.roundTripTime() < TimeUnit.SECONDS.toNanos(1));
+
+ // verify the peer received what was expected
+ MockSpdyPeer.InFrame pingFrame = peer.takeFrame();
+ assertEquals(TYPE_PING, pingFrame.type);
+ assertEquals(1, pingFrame.payload1);
+ assertEquals(0, pingFrame.payload2);
+ assertFalse(pingFrame.ack);
+ }
}
@Test public void unexpectedPingIsNotReturned() throws Exception {
- // write the mocking script
- peer.sendFrame().ping(false, 2, 0);
- peer.acceptFrame(); // PING
- peer.sendFrame().ping(true, 3, 0); // This ping will not be returned.
- peer.sendFrame().ping(false, 4, 0);
- peer.acceptFrame(); // PING
- peer.play();
-
- // play it back
- connection(peer, SPDY3);
-
- // verify the peer received what was expected
- MockSpdyPeer.InFrame ping2 = peer.takeFrame();
- assertEquals(2, ping2.payload1);
- MockSpdyPeer.InFrame ping4 = peer.takeFrame();
- assertEquals(4, ping4.payload1);
+ try (MockSpdyPeer peer = new MockSpdyPeer()) {
+ // write the mocking script
+ peer.sendFrame().ping(false, 2, 0);
+ peer.acceptFrame(); // PING
+ peer.sendFrame().ping(true, 3, 0); // This ping will not be returned.
+ peer.sendFrame().ping(false, 4, 0);
+ peer.acceptFrame(); // PING
+ peer.play();
+
+ // play it back
+ connection(peer, SPDY3);
+
+ // verify the peer received what was expected
+ MockSpdyPeer.InFrame ping2 = peer.takeFrame();
+ assertEquals(2, ping2.payload1);
+ MockSpdyPeer.InFrame ping4 = peer.takeFrame();
+ assertEquals(4, ping4.payload1);
+ }
}
@Test public void serverSendsSettingsToClient() throws Exception {
- // write the mocking script
- final Settings settings = new Settings();
- settings.set(Settings.MAX_CONCURRENT_STREAMS, PERSIST_VALUE, 10);
- peer.sendFrame().settings(settings);
- peer.sendFrame().ping(false, 2, 0);
- peer.acceptFrame(); // PING
- peer.play();
-
- // play it back
- final AtomicInteger maxConcurrentStreams = new AtomicInteger();
- FramedConnection.Listener listener = new FramedConnection.Listener() {
- @Override public void onStream(FramedStream stream) throws IOException {
- throw new AssertionError();
- }
- @Override public void onSettings(FramedConnection connection) {
- maxConcurrentStreams.set(connection.maxConcurrentStreams());
+ try (MockSpdyPeer peer = new MockSpdyPeer()) {
+ // write the mocking script
+ final Settings settings = new Settings();
+ settings.set(Settings.MAX_CONCURRENT_STREAMS, PERSIST_VALUE, 10);
+ peer.sendFrame().settings(settings);
+ peer.sendFrame().ping(false, 2, 0);
+ peer.acceptFrame(); // PING
+ peer.play();
+
+ // play it back
+ final AtomicInteger maxConcurrentStreams = new AtomicInteger();
+ FramedConnection.Listener listener = new FramedConnection.Listener() {
+ @Override public void onStream(FramedStream stream) throws IOException {
+ throw new AssertionError();
+ }
+ @Override public void onSettings(FramedConnection connection) {
+ maxConcurrentStreams.set(connection.maxConcurrentStreams());
+ }
+ };
+ FramedConnection connection = connectionBuilder(peer, SPDY3)
+ .listener(listener)
+ .build();
+
+ peer.takeFrame(); // Guarantees that the peer Settings frame has been processed.
+ synchronized (connection) {
+ assertEquals(10, connection.peerSettings.getMaxConcurrentStreams(-1));
}
- };
- FramedConnection connection = connectionBuilder(peer, SPDY3)
- .listener(listener)
- .build();
-
- peer.takeFrame(); // Guarantees that the peer Settings frame has been processed.
- synchronized (connection) {
- assertEquals(10, connection.peerSettings.getMaxConcurrentStreams(-1));
+ assertEquals(10, maxConcurrentStreams.get());
}
- assertEquals(10, maxConcurrentStreams.get());
}
@Test public void multipleSettingsFramesAreMerged() throws Exception {
- // write the mocking script
- Settings settings1 = new Settings();
- settings1.set(Settings.UPLOAD_BANDWIDTH, PERSIST_VALUE, 100);
- settings1.set(Settings.DOWNLOAD_BANDWIDTH, PERSIST_VALUE, 200);
- settings1.set(Settings.DOWNLOAD_RETRANS_RATE, 0, 300);
- peer.sendFrame().settings(settings1);
- Settings settings2 = new Settings();
- settings2.set(Settings.DOWNLOAD_BANDWIDTH, 0, 400);
- settings2.set(Settings.DOWNLOAD_RETRANS_RATE, PERSIST_VALUE, 500);
- settings2.set(Settings.MAX_CONCURRENT_STREAMS, PERSIST_VALUE, 600);
- peer.sendFrame().settings(settings2);
- peer.sendFrame().ping(false, 2, 0);
- peer.acceptFrame();
- peer.play();
-
- // play it back
- FramedConnection connection = connection(peer, SPDY3);
-
- peer.takeFrame(); // Guarantees that the Settings frame has been processed.
- synchronized (connection) {
- assertEquals(100, connection.peerSettings.getUploadBandwidth(-1));
- assertEquals(PERSIST_VALUE, connection.peerSettings.flags(Settings.UPLOAD_BANDWIDTH));
- assertEquals(400, connection.peerSettings.getDownloadBandwidth(-1));
- assertEquals(0, connection.peerSettings.flags(Settings.DOWNLOAD_BANDWIDTH));
- assertEquals(500, connection.peerSettings.getDownloadRetransRate(-1));
- assertEquals(PERSIST_VALUE, connection.peerSettings.flags(Settings.DOWNLOAD_RETRANS_RATE));
- assertEquals(600, connection.peerSettings.getMaxConcurrentStreams(-1));
- assertEquals(PERSIST_VALUE, connection.peerSettings.flags(Settings.MAX_CONCURRENT_STREAMS));
+ try (MockSpdyPeer peer = new MockSpdyPeer()) {
+ // write the mocking script
+ Settings settings1 = new Settings();
+ settings1.set(Settings.UPLOAD_BANDWIDTH, PERSIST_VALUE, 100);
+ settings1.set(Settings.DOWNLOAD_BANDWIDTH, PERSIST_VALUE, 200);
+ settings1.set(Settings.DOWNLOAD_RETRANS_RATE, 0, 300);
+ peer.sendFrame().settings(settings1);
+ Settings settings2 = new Settings();
+ settings2.set(Settings.DOWNLOAD_BANDWIDTH, 0, 400);
+ settings2.set(Settings.DOWNLOAD_RETRANS_RATE, PERSIST_VALUE, 500);
+ settings2.set(Settings.MAX_CONCURRENT_STREAMS, PERSIST_VALUE, 600);
+ peer.sendFrame().settings(settings2);
+ peer.sendFrame().ping(false, 2, 0);
+ peer.acceptFrame();
+ peer.play();
+
+ // play it back
+ FramedConnection connection = connection(peer, SPDY3);
+
+ peer.takeFrame(); // Guarantees that the Settings frame has been processed.
+ synchronized (connection) {
+ assertEquals(100, connection.peerSettings.getUploadBandwidth(-1));
+ assertEquals(PERSIST_VALUE, connection.peerSettings.flags(Settings.UPLOAD_BANDWIDTH));
+ assertEquals(400, connection.peerSettings.getDownloadBandwidth(-1));
+ assertEquals(0, connection.peerSettings.flags(Settings.DOWNLOAD_BANDWIDTH));
+ assertEquals(500, connection.peerSettings.getDownloadRetransRate(-1));
+ assertEquals(PERSIST_VALUE, connection.peerSettings.flags(Settings.DOWNLOAD_RETRANS_RATE));
+ assertEquals(600, connection.peerSettings.getMaxConcurrentStreams(-1));
+ assertEquals(PERSIST_VALUE, connection.peerSettings.flags(Settings.MAX_CONCURRENT_STREAMS));
+ }
}
}
@Test public void clearSettingsBeforeMerge() throws Exception {
- // write the mocking script
- Settings settings1 = new Settings();
- settings1.set(Settings.UPLOAD_BANDWIDTH, PERSIST_VALUE, 100);
- settings1.set(Settings.DOWNLOAD_BANDWIDTH, PERSIST_VALUE, 200);
- settings1.set(Settings.DOWNLOAD_RETRANS_RATE, 0, 300);
- peer.sendFrame().settings(settings1);
- peer.sendFrame().ping(false, 2, 0);
- peer.acceptFrame();
- peer.play();
-
- // play it back
- FramedConnection connection = connection(peer, SPDY3);
-
- peer.takeFrame(); // Guarantees that the Settings frame has been processed.
-
- // fake a settings frame with clear flag set.
- Settings settings2 = new Settings();
- settings2.set(Settings.MAX_CONCURRENT_STREAMS, PERSIST_VALUE, 600);
- connection.readerRunnable.settings(true, settings2);
-
- synchronized (connection) {
- assertEquals(-1, connection.peerSettings.getUploadBandwidth(-1));
- assertEquals(-1, connection.peerSettings.getDownloadBandwidth(-1));
- assertEquals(-1, connection.peerSettings.getDownloadRetransRate(-1));
- assertEquals(600, connection.peerSettings.getMaxConcurrentStreams(-1));
+ try (MockSpdyPeer peer = new MockSpdyPeer()) {
+ // write the mocking script
+ Settings settings1 = new Settings();
+ settings1.set(Settings.UPLOAD_BANDWIDTH, PERSIST_VALUE, 100);
+ settings1.set(Settings.DOWNLOAD_BANDWIDTH, PERSIST_VALUE, 200);
+ settings1.set(Settings.DOWNLOAD_RETRANS_RATE, 0, 300);
+ peer.sendFrame().settings(settings1);
+ peer.sendFrame().ping(false, 2, 0);
+ peer.acceptFrame();
+ peer.play();
+
+ // play it back
+ FramedConnection connection = connection(peer, SPDY3);
+
+ peer.takeFrame(); // Guarantees that the Settings frame has been processed.
+
+ // fake a settings frame with clear flag set.
+ Settings settings2 = new Settings();
+ settings2.set(Settings.MAX_CONCURRENT_STREAMS, PERSIST_VALUE, 600);
+ connection.readerRunnable.settings(true, settings2);
+
+ synchronized (connection) {
+ assertEquals(-1, connection.peerSettings.getUploadBandwidth(-1));
+ assertEquals(-1, connection.peerSettings.getDownloadBandwidth(-1));
+ assertEquals(-1, connection.peerSettings.getDownloadRetransRate(-1));
+ assertEquals(600, connection.peerSettings.getMaxConcurrentStreams(-1));
+ }
}
}
@Test public void bogusDataFrameDoesNotDisruptConnection() throws Exception {
- // write the mocking script
- peer.sendFrame().data(true, 41, new Buffer().writeUtf8("bogus"), 5);
- peer.acceptFrame(); // RST_STREAM
- peer.sendFrame().ping(false, 2, 0);
- peer.acceptFrame(); // PING
- peer.play();
-
- // play it back
- connection(peer, SPDY3);
-
- // verify the peer received what was expected
- MockSpdyPeer.InFrame rstStream = peer.takeFrame();
- assertEquals(TYPE_RST_STREAM, rstStream.type);
- assertEquals(41, rstStream.streamId);
- assertEquals(INVALID_STREAM, rstStream.errorCode);
- MockSpdyPeer.InFrame ping = peer.takeFrame();
- assertEquals(2, ping.payload1);
+ try (MockSpdyPeer peer = new MockSpdyPeer()) {
+ // write the mocking script
+ peer.sendFrame().data(true, 41, new Buffer().writeUtf8("bogus"), 5);
+ peer.acceptFrame(); // RST_STREAM
+ peer.sendFrame().ping(false, 2, 0);
+ peer.acceptFrame(); // PING
+ peer.play();
+
+ // play it back
+ connection(peer, SPDY3);
+
+ // verify the peer received what was expected
+ MockSpdyPeer.InFrame rstStream = peer.takeFrame();
+ assertEquals(TYPE_RST_STREAM, rstStream.type);
+ assertEquals(41, rstStream.streamId);
+ assertEquals(INVALID_STREAM, rstStream.errorCode);
+ MockSpdyPeer.InFrame ping = peer.takeFrame();
+ assertEquals(2, ping.payload1);
+ }
}
@Test public void bogusReplyFrameDoesNotDisruptConnection() throws Exception {
- // write the mocking script
- peer.sendFrame().synReply(false, 41, headerEntries("a", "android"));
- peer.acceptFrame(); // RST_STREAM
- peer.sendFrame().ping(false, 2, 0);
- peer.acceptFrame(); // PING
- peer.play();
-
- // play it back
- connection(peer, SPDY3);
-
- // verify the peer received what was expected
- MockSpdyPeer.InFrame rstStream = peer.takeFrame();
- assertEquals(TYPE_RST_STREAM, rstStream.type);
- assertEquals(41, rstStream.streamId);
- assertEquals(INVALID_STREAM, rstStream.errorCode);
- MockSpdyPeer.InFrame ping = peer.takeFrame();
- assertEquals(2, ping.payload1);
+ try (MockSpdyPeer peer = new MockSpdyPeer()) {
+ // write the mocking script
+ peer.sendFrame().synReply(false, 41, headerEntries("a", "android"));
+ peer.acceptFrame(); // RST_STREAM
+ peer.sendFrame().ping(false, 2, 0);
+ peer.acceptFrame(); // PING
+ peer.play();
+
+ // play it back
+ connection(peer, SPDY3);
+
+ // verify the peer received what was expected
+ MockSpdyPeer.InFrame rstStream = peer.takeFrame();
+ assertEquals(TYPE_RST_STREAM, rstStream.type);
+ assertEquals(41, rstStream.streamId);
+ assertEquals(INVALID_STREAM, rstStream.errorCode);
+ MockSpdyPeer.InFrame ping = peer.takeFrame();
+ assertEquals(2, ping.payload1);
+ }
}
@Test public void clientClosesClientOutputStream() throws Exception {
- // write the mocking script
- peer.acceptFrame(); // SYN_STREAM
- peer.sendFrame().synReply(false, 1, headerEntries("b", "banana"));
- peer.acceptFrame(); // TYPE_DATA
- peer.acceptFrame(); // TYPE_DATA with FLAG_FIN
- peer.acceptFrame(); // PING
- peer.sendFrame().ping(true, 1, 0);
- peer.play();
-
- // play it back
- FramedConnection connection = connection(peer, SPDY3);
- FramedStream stream = connection.newStream(headerEntries("a", "android"), true, false);
- BufferedSink out = Okio.buffer(stream.getSink());
- out.writeUtf8("square");
- out.flush();
- assertEquals(1, connection.openStreamCount());
- out.close();
- try {
- out.writeUtf8("round");
- fail();
- } catch (Exception expected) {
- assertEquals("closed", expected.getMessage());
+ try (MockSpdyPeer peer = new MockSpdyPeer()) {
+ // write the mocking script
+ peer.acceptFrame(); // SYN_STREAM
+ peer.sendFrame().synReply(false, 1, headerEntries("b", "banana"));
+ peer.acceptFrame(); // TYPE_DATA
+ peer.acceptFrame(); // TYPE_DATA with FLAG_FIN
+ peer.acceptFrame(); // PING
+ peer.sendFrame().ping(true, 1, 0);
+ peer.play();
+
+ // play it back
+ FramedConnection connection = connection(peer, SPDY3);
+ FramedStream stream = connection.newStream(headerEntries("a", "android"), true, false);
+ BufferedSink out = Okio.buffer(stream.getSink());
+ out.writeUtf8("square");
+ out.flush();
+ assertEquals(1, connection.openStreamCount());
+ out.close();
+ try {
+ out.writeUtf8("round");
+ fail();
+ } catch (Exception expected) {
+ assertEquals("closed", expected.getMessage());
+ }
+ connection.ping().roundTripTime(); // Ensure that the SYN_REPLY has been received.
+ assertEquals(0, connection.openStreamCount());
+
+ // verify the peer received what was expected
+ MockSpdyPeer.InFrame synStream = peer.takeFrame();
+ assertEquals(TYPE_HEADERS, synStream.type);
+ assertEquals(HeadersMode.SPDY_SYN_STREAM, synStream.headersMode);
+ assertFalse(synStream.inFinished);
+ assertTrue(synStream.outFinished);
+ MockSpdyPeer.InFrame data = peer.takeFrame();
+ assertEquals(TYPE_DATA, data.type);
+ assertFalse(data.inFinished);
+ assertTrue(Arrays.equals("square".getBytes("UTF-8"), data.data));
+ MockSpdyPeer.InFrame fin = peer.takeFrame();
+ assertEquals(TYPE_DATA, fin.type);
+ assertTrue(fin.inFinished);
+ MockSpdyPeer.InFrame ping = peer.takeFrame();
+ assertEquals(TYPE_PING, ping.type);
+ assertEquals(1, ping.payload1);
}
- connection.ping().roundTripTime(); // Ensure that the SYN_REPLY has been received.
- assertEquals(0, connection.openStreamCount());
-
- // verify the peer received what was expected
- MockSpdyPeer.InFrame synStream = peer.takeFrame();
- assertEquals(TYPE_HEADERS, synStream.type);
- assertEquals(HeadersMode.SPDY_SYN_STREAM, synStream.headersMode);
- assertFalse(synStream.inFinished);
- assertTrue(synStream.outFinished);
- MockSpdyPeer.InFrame data = peer.takeFrame();
- assertEquals(TYPE_DATA, data.type);
- assertFalse(data.inFinished);
- assertTrue(Arrays.equals("square".getBytes("UTF-8"), data.data));
- MockSpdyPeer.InFrame fin = peer.takeFrame();
- assertEquals(TYPE_DATA, fin.type);
- assertTrue(fin.inFinished);
- MockSpdyPeer.InFrame ping = peer.takeFrame();
- assertEquals(TYPE_PING, ping.type);
- assertEquals(1, ping.payload1);
}
@Test public void serverClosesClientOutputStream() throws Exception {
- // write the mocking script
- peer.acceptFrame(); // SYN_STREAM
- peer.sendFrame().rstStream(1, CANCEL);
- peer.acceptFrame(); // PING
- peer.sendFrame().ping(true, 1, 0);
- peer.play();
-
- // play it back
- FramedConnection connection = connection(peer, SPDY3);
- FramedStream stream = connection.newStream(headerEntries("a", "android"), true, true);
- BufferedSink out = Okio.buffer(stream.getSink());
- connection.ping().roundTripTime(); // Ensure that the RST_CANCEL has been received.
- try {
- out.writeUtf8("square");
- out.flush();
- fail();
- } catch (IOException expected) {
- assertEquals("stream was reset: CANCEL", expected.getMessage());
- }
- try {
- out.close();
- fail();
- } catch (IOException expected) {
- // Close throws because buffered data wasn't flushed.
+ try (MockSpdyPeer peer = new MockSpdyPeer()) {
+ // write the mocking script
+ peer.acceptFrame(); // SYN_STREAM
+ peer.sendFrame().rstStream(1, CANCEL);
+ peer.acceptFrame(); // PING
+ peer.sendFrame().ping(true, 1, 0);
+ peer.play();
+
+ // play it back
+ FramedConnection connection = connection(peer, SPDY3);
+ FramedStream stream = connection.newStream(headerEntries("a", "android"), true, true);
+ BufferedSink out = Okio.buffer(stream.getSink());
+ connection.ping().roundTripTime(); // Ensure that the RST_CANCEL has been received.
+ try {
+ out.writeUtf8("square");
+ out.flush();
+ fail();
+ } catch (IOException expected) {
+ assertEquals("stream was reset: CANCEL", expected.getMessage());
+ }
+ try {
+ out.close();
+ fail();
+ } catch (IOException expected) {
+ // Close throws because buffered data wasn't flushed.
+ }
+ assertEquals(0, connection.openStreamCount());
+
+ // verify the peer received what was expected
+ MockSpdyPeer.InFrame synStream = peer.takeFrame();
+ assertEquals(TYPE_HEADERS, synStream.type);
+ assertEquals(HeadersMode.SPDY_SYN_STREAM, synStream.headersMode);
+ assertFalse(synStream.inFinished);
+ assertFalse(synStream.outFinished);
+ MockSpdyPeer.InFrame ping = peer.takeFrame();
+ assertEquals(TYPE_PING, ping.type);
+ assertEquals(1, ping.payload1);
}
- assertEquals(0, connection.openStreamCount());
-
- // verify the peer received what was expected
- MockSpdyPeer.InFrame synStream = peer.takeFrame();
- assertEquals(TYPE_HEADERS, synStream.type);
- assertEquals(HeadersMode.SPDY_SYN_STREAM, synStream.headersMode);
- assertFalse(synStream.inFinished);
- assertFalse(synStream.outFinished);
- MockSpdyPeer.InFrame ping = peer.takeFrame();
- assertEquals(TYPE_PING, ping.type);
- assertEquals(1, ping.payload1);
}
/**
@@ -475,41 +500,43 @@ public final class Spdy3ConnectionTest {
* output stream.
*/
@Test public void clientClosesClientInputStream() throws Exception {
- // write the mocking script
- peer.acceptFrame(); // SYN_STREAM
- peer.acceptFrame(); // RST_STREAM
- peer.play();
-
- // play it back
- FramedConnection connection = connection(peer, SPDY3);
- FramedStream stream = connection.newStream(headerEntries("a", "android"), false, true);
- Source in = stream.getSource();
- BufferedSink out = Okio.buffer(stream.getSink());
- in.close();
- try {
- in.read(new Buffer(), 1);
- fail();
- } catch (IOException expected) {
- assertEquals("stream closed", expected.getMessage());
- }
- try {
- out.writeUtf8("a");
- out.flush();
- fail();
- } catch (IOException expected) {
- assertEquals("stream finished", expected.getMessage());
+ try (MockSpdyPeer peer = new MockSpdyPeer()) {
+ // write the mocking script
+ peer.acceptFrame(); // SYN_STREAM
+ peer.acceptFrame(); // RST_STREAM
+ peer.play();
+
+ // play it back
+ FramedConnection connection = connection(peer, SPDY3);
+ FramedStream stream = connection.newStream(headerEntries("a", "android"), false, true);
+ Source in = stream.getSource();
+ BufferedSink out = Okio.buffer(stream.getSink());
+ in.close();
+ try {
+ in.read(new Buffer(), 1);
+ fail();
+ } catch (IOException expected) {
+ assertEquals("stream closed", expected.getMessage());
+ }
+ try {
+ out.writeUtf8("a");
+ out.flush();
+ fail();
+ } catch (IOException expected) {
+ assertEquals("stream finished", expected.getMessage());
+ }
+ assertEquals(0, connection.openStreamCount());
+
+ // verify the peer received what was expected
+ MockSpdyPeer.InFrame synStream = peer.takeFrame();
+ assertEquals(TYPE_HEADERS, synStream.type);
+ assertEquals(HeadersMode.SPDY_SYN_STREAM, synStream.headersMode);
+ assertTrue(synStream.inFinished);
+ assertFalse(synStream.outFinished);
+ MockSpdyPeer.InFrame rstStream = peer.takeFrame();
+ assertEquals(TYPE_RST_STREAM, rstStream.type);
+ assertEquals(CANCEL, rstStream.errorCode);
}
- assertEquals(0, connection.openStreamCount());
-
- // verify the peer received what was expected
- MockSpdyPeer.InFrame synStream = peer.takeFrame();
- assertEquals(TYPE_HEADERS, synStream.type);
- assertEquals(HeadersMode.SPDY_SYN_STREAM, synStream.headersMode);
- assertTrue(synStream.inFinished);
- assertFalse(synStream.outFinished);
- MockSpdyPeer.InFrame rstStream = peer.takeFrame();
- assertEquals(TYPE_RST_STREAM, rstStream.type);
- assertEquals(CANCEL, rstStream.errorCode);
}
/**
@@ -517,635 +544,675 @@ public final class Spdy3ConnectionTest {
* the output stream.
*/
@Test public void clientClosesClientInputStreamIfOutputStreamIsClosed() throws Exception {
- // write the mocking script
- peer.acceptFrame(); // SYN_STREAM
- peer.acceptFrame(); // DATA
- peer.acceptFrame(); // DATA with FLAG_FIN
- peer.acceptFrame(); // RST_STREAM
- peer.play();
-
- // play it back
- FramedConnection connection = connection(peer, SPDY3);
- FramedStream stream = connection.newStream(headerEntries("a", "android"), true, true);
- Source source = stream.getSource();
- BufferedSink out = Okio.buffer(stream.getSink());
- source.close();
- try {
- source.read(new Buffer(), 1);
- fail();
- } catch (IOException expected) {
- assertEquals("stream closed", expected.getMessage());
+ try (MockSpdyPeer peer = new MockSpdyPeer()) {
+ // write the mocking script
+ peer.acceptFrame(); // SYN_STREAM
+ peer.acceptFrame(); // DATA
+ peer.acceptFrame(); // DATA with FLAG_FIN
+ peer.acceptFrame(); // RST_STREAM
+ peer.play();
+
+ // play it back
+ FramedConnection connection = connection(peer, SPDY3);
+ FramedStream stream = connection.newStream(headerEntries("a", "android"), true, true);
+ Source source = stream.getSource();
+ BufferedSink out = Okio.buffer(stream.getSink());
+ source.close();
+ try {
+ source.read(new Buffer(), 1);
+ fail();
+ } catch (IOException expected) {
+ assertEquals("stream closed", expected.getMessage());
+ }
+ out.writeUtf8("square");
+ out.flush();
+ out.close();
+ assertEquals(0, connection.openStreamCount());
+
+ // verify the peer received what was expected
+ MockSpdyPeer.InFrame synStream = peer.takeFrame();
+ assertEquals(TYPE_HEADERS, synStream.type);
+ assertEquals(HeadersMode.SPDY_SYN_STREAM, synStream.headersMode);
+ assertFalse(synStream.inFinished);
+ assertFalse(synStream.outFinished);
+ MockSpdyPeer.InFrame data = peer.takeFrame();
+ assertEquals(TYPE_DATA, data.type);
+ assertTrue(Arrays.equals("square".getBytes("UTF-8"), data.data));
+ MockSpdyPeer.InFrame fin = peer.takeFrame();
+ assertEquals(TYPE_DATA, fin.type);
+ assertTrue(fin.inFinished);
+ assertFalse(fin.outFinished);
+ MockSpdyPeer.InFrame rstStream = peer.takeFrame();
+ assertEquals(TYPE_RST_STREAM, rstStream.type);
+ assertEquals(CANCEL, rstStream.errorCode);
}
- out.writeUtf8("square");
- out.flush();
- out.close();
- assertEquals(0, connection.openStreamCount());
-
- // verify the peer received what was expected
- MockSpdyPeer.InFrame synStream = peer.takeFrame();
- assertEquals(TYPE_HEADERS, synStream.type);
- assertEquals(HeadersMode.SPDY_SYN_STREAM, synStream.headersMode);
- assertFalse(synStream.inFinished);
- assertFalse(synStream.outFinished);
- MockSpdyPeer.InFrame data = peer.takeFrame();
- assertEquals(TYPE_DATA, data.type);
- assertTrue(Arrays.equals("square".getBytes("UTF-8"), data.data));
- MockSpdyPeer.InFrame fin = peer.takeFrame();
- assertEquals(TYPE_DATA, fin.type);
- assertTrue(fin.inFinished);
- assertFalse(fin.outFinished);
- MockSpdyPeer.InFrame rstStream = peer.takeFrame();
- assertEquals(TYPE_RST_STREAM, rstStream.type);
- assertEquals(CANCEL, rstStream.errorCode);
}
@Test public void serverClosesClientInputStream() throws Exception {
- // write the mocking script
- peer.acceptFrame(); // SYN_STREAM
- peer.sendFrame().synReply(false, 1, headerEntries("b", "banana"));
- peer.sendFrame().data(true, 1, new Buffer().writeUtf8("square"), 6);
- peer.acceptFrame(); // PING
- peer.sendFrame().ping(true, 1, 0);
- peer.play();
-
- // play it back
- FramedConnection connection = connection(peer, SPDY3);
- FramedStream stream = connection.newStream(headerEntries("a", "android"), false, true);
- Source source = stream.getSource();
- assertStreamData("square", source);
- connection.ping().roundTripTime(); // Ensure that inFinished has been received.
- assertEquals(0, connection.openStreamCount());
-
- // verify the peer received what was expected
- MockSpdyPeer.InFrame synStream = peer.takeFrame();
- assertEquals(TYPE_HEADERS, synStream.type);
- assertEquals(HeadersMode.SPDY_SYN_STREAM, synStream.headersMode);
- assertTrue(synStream.inFinished);
- assertFalse(synStream.outFinished);
+ try (MockSpdyPeer peer = new MockSpdyPeer()) {
+ // write the mocking script
+ peer.acceptFrame(); // SYN_STREAM
+ peer.sendFrame().synReply(false, 1, headerEntries("b", "banana"));
+ peer.sendFrame().data(true, 1, new Buffer().writeUtf8("square"), 6);
+ peer.acceptFrame(); // PING
+ peer.sendFrame().ping(true, 1, 0);
+ peer.play();
+
+ // play it back
+ FramedConnection connection = connection(peer, SPDY3);
+ FramedStream stream = connection.newStream(headerEntries("a", "android"), false, true);
+ Source source = stream.getSource();
+ assertStreamData("square", source);
+ connection.ping().roundTripTime(); // Ensure that inFinished has been received.
+ assertEquals(0, connection.openStreamCount());
+
+ // verify the peer received what was expected
+ MockSpdyPeer.InFrame synStream = peer.takeFrame();
+ assertEquals(TYPE_HEADERS, synStream.type);
+ assertEquals(HeadersMode.SPDY_SYN_STREAM, synStream.headersMode);
+ assertTrue(synStream.inFinished);
+ assertFalse(synStream.outFinished);
+ }
}
@Test public void remoteDoubleSynReply() throws Exception {
- // write the mocking script
- peer.acceptFrame(); // SYN_STREAM
- peer.sendFrame().synReply(false, 1, headerEntries("a", "android"));
- peer.acceptFrame(); // PING
- peer.sendFrame().synReply(false, 1, headerEntries("b", "banana"));
- peer.sendFrame().ping(true, 1, 0);
- peer.acceptFrame(); // RST_STREAM
- peer.play();
-
- // play it back
- FramedConnection connection = connection(peer, SPDY3);
- FramedStream stream = connection.newStream(headerEntries("c", "cola"), true, true);
- assertEquals(headerEntries("a", "android"), stream.getResponseHeaders());
- connection.ping().roundTripTime(); // Ensure that the 2nd SYN REPLY has been received.
- try {
- stream.getSource().read(new Buffer(), 1);
- fail();
- } catch (IOException expected) {
- assertEquals("stream was reset: STREAM_IN_USE", expected.getMessage());
- }
+ try (MockSpdyPeer peer = new MockSpdyPeer()) {
+ // write the mocking script
+ peer.acceptFrame(); // SYN_STREAM
+ peer.sendFrame().synReply(false, 1, headerEntries("a", "android"));
+ peer.acceptFrame(); // PING
+ peer.sendFrame().synReply(false, 1, headerEntries("b", "banana"));
+ peer.sendFrame().ping(true, 1, 0);
+ peer.acceptFrame(); // RST_STREAM
+ peer.play();
+
+ // play it back
+ FramedConnection connection = connection(peer, SPDY3);
+ FramedStream stream = connection.newStream(headerEntries("c", "cola"), true, true);
+ assertEquals(headerEntries("a", "android"), stream.getResponseHeaders());
+ connection.ping().roundTripTime(); // Ensure that the 2nd SYN REPLY has been received.
+ try {
+ stream.getSource().read(new Buffer(), 1);
+ fail();
+ } catch (IOException expected) {
+ assertEquals("stream was reset: STREAM_IN_USE", expected.getMessage());
+ }
- // verify the peer received what was expected
- MockSpdyPeer.InFrame synStream = peer.takeFrame();
- assertEquals(TYPE_HEADERS, synStream.type);
- assertEquals(HeadersMode.SPDY_SYN_STREAM, synStream.headersMode);
- MockSpdyPeer.InFrame ping = peer.takeFrame();
- assertEquals(TYPE_PING, ping.type);
- MockSpdyPeer.InFrame rstStream = peer.takeFrame();
- assertEquals(TYPE_RST_STREAM, rstStream.type);
- assertEquals(1, rstStream.streamId);
- assertEquals(STREAM_IN_USE, rstStream.errorCode);
+ // verify the peer received what was expected
+ MockSpdyPeer.InFrame synStream = peer.takeFrame();
+ assertEquals(TYPE_HEADERS, synStream.type);
+ assertEquals(HeadersMode.SPDY_SYN_STREAM, synStream.headersMode);
+ MockSpdyPeer.InFrame ping = peer.takeFrame();
+ assertEquals(TYPE_PING, ping.type);
+ MockSpdyPeer.InFrame rstStream = peer.takeFrame();
+ assertEquals(TYPE_RST_STREAM, rstStream.type);
+ assertEquals(1, rstStream.streamId);
+ assertEquals(STREAM_IN_USE, rstStream.errorCode);
+ }
}
@Test public void remoteDoubleSynStream() throws Exception {
- // write the mocking script
- peer.sendFrame().synStream(false, false, 2, 0, headerEntries("a", "android"));
- peer.acceptFrame(); // SYN_REPLY
- peer.sendFrame().synStream(false, false, 2, 0, headerEntries("b", "banana"));
- peer.acceptFrame(); // RST_STREAM
- peer.play();
-
- // play it back
- final AtomicInteger receiveCount = new AtomicInteger();
- FramedConnection.Listener listener = new FramedConnection.Listener() {
- @Override public void onStream(FramedStream stream) throws IOException {
- receiveCount.incrementAndGet();
- assertEquals(headerEntries("a", "android"), stream.getRequestHeaders());
- assertEquals(null, stream.getErrorCode());
- stream.reply(headerEntries("c", "cola"), true);
- }
- };
- new FramedConnection.Builder(true)
- .socket(peer.openSocket())
- .listener(listener)
- .build();
-
- // verify the peer received what was expected
- MockSpdyPeer.InFrame reply = peer.takeFrame();
- assertEquals(TYPE_HEADERS, reply.type);
- assertEquals(HeadersMode.SPDY_REPLY, reply.headersMode);
- MockSpdyPeer.InFrame rstStream = peer.takeFrame();
- assertEquals(TYPE_RST_STREAM, rstStream.type);
- assertEquals(2, rstStream.streamId);
- assertEquals(PROTOCOL_ERROR, rstStream.errorCode);
- assertEquals(1, receiveCount.intValue());
+ try (MockSpdyPeer peer = new MockSpdyPeer()) {
+ // write the mocking script
+ peer.sendFrame().synStream(false, false, 2, 0, headerEntries("a", "android"));
+ peer.acceptFrame(); // SYN_REPLY
+ peer.sendFrame().synStream(false, false, 2, 0, headerEntries("b", "banana"));
+ peer.acceptFrame(); // RST_STREAM
+ peer.play();
+
+ // play it back
+ final AtomicInteger receiveCount = new AtomicInteger();
+ FramedConnection.Listener listener = new FramedConnection.Listener() {
+ @Override public void onStream(FramedStream stream) throws IOException {
+ receiveCount.incrementAndGet();
+ assertEquals(headerEntries("a", "android"), stream.getRequestHeaders());
+ assertEquals(null, stream.getErrorCode());
+ stream.reply(headerEntries("c", "cola"), true);
+ }
+ };
+ new FramedConnection.Builder(true)
+ .socket(peer.openSocket())
+ .listener(listener)
+ .build();
+
+ // verify the peer received what was expected
+ MockSpdyPeer.InFrame reply = peer.takeFrame();
+ assertEquals(TYPE_HEADERS, reply.type);
+ assertEquals(HeadersMode.SPDY_REPLY, reply.headersMode);
+ MockSpdyPeer.InFrame rstStream = peer.takeFrame();
+ assertEquals(TYPE_RST_STREAM, rstStream.type);
+ assertEquals(2, rstStream.streamId);
+ assertEquals(PROTOCOL_ERROR, rstStream.errorCode);
+ assertEquals(1, receiveCount.intValue());
+ }
}
@Test public void remoteSendsDataAfterInFinished() throws Exception {
- // write the mocking script
- peer.acceptFrame(); // SYN_STREAM
- peer.sendFrame().synReply(false, 1, headerEntries("a", "android"));
- peer.sendFrame().data(true, 1, new Buffer().writeUtf8("robot"), 5);
- peer.sendFrame().data(true, 1, new Buffer().writeUtf8("c3po"), 4); // Ignored.
- peer.sendFrame().ping(false, 2, 0); // Ping just to make sure the stream was fastforwarded.
- peer.acceptFrame(); // PING
- peer.play();
-
- // play it back
- FramedConnection connection = connection(peer, SPDY3);
- FramedStream stream = connection.newStream(headerEntries("b", "banana"), true, true);
- assertEquals(headerEntries("a", "android"), stream.getResponseHeaders());
- assertStreamData("robot", stream.getSource());
-
- // verify the peer received what was expected
- MockSpdyPeer.InFrame synStream = peer.takeFrame();
- assertEquals(TYPE_HEADERS, synStream.type);
- assertEquals(HeadersMode.SPDY_SYN_STREAM, synStream.headersMode);
- MockSpdyPeer.InFrame ping = peer.takeFrame();
- assertEquals(TYPE_PING, ping.type);
- assertEquals(2, ping.payload1);
+ try (MockSpdyPeer peer = new MockSpdyPeer()) {
+ // write the mocking script
+ peer.acceptFrame(); // SYN_STREAM
+ peer.sendFrame().synReply(false, 1, headerEntries("a", "android"));
+ peer.sendFrame().data(true, 1, new Buffer().writeUtf8("robot"), 5);
+ peer.sendFrame().data(true, 1, new Buffer().writeUtf8("c3po"), 4); // Ignored.
+ peer.sendFrame().ping(false, 2, 0); // Ping just to make sure the stream was fastforwarded.
+ peer.acceptFrame(); // PING
+ peer.play();
+
+ // play it back
+ FramedConnection connection = connection(peer, SPDY3);
+ FramedStream stream = connection.newStream(headerEntries("b", "banana"), true, true);
+ assertEquals(headerEntries("a", "android"), stream.getResponseHeaders());
+ assertStreamData("robot", stream.getSource());
+
+ // verify the peer received what was expected
+ MockSpdyPeer.InFrame synStream = peer.takeFrame();
+ assertEquals(TYPE_HEADERS, synStream.type);
+ assertEquals(HeadersMode.SPDY_SYN_STREAM, synStream.headersMode);
+ MockSpdyPeer.InFrame ping = peer.takeFrame();
+ assertEquals(TYPE_PING, ping.type);
+ assertEquals(2, ping.payload1);
+ }
}
@Test public void clientDoesNotLimitFlowControl() throws Exception {
- int dataLength = 64 * 1024 + 1;
- // write the mocking script
- peer.acceptFrame(); // SYN_STREAM
- peer.sendFrame().synReply(false, 1, headerEntries("b", "banana"));
- peer.sendFrame().data(false, 1, new Buffer().write(new byte[dataLength]), dataLength);
- peer.sendFrame().ping(false, 2, 0); // Ping just to make sure the stream was fastforwarded.
- peer.acceptFrame(); // PING
- peer.play();
-
- // play it back
- FramedConnection connection = connection(peer, SPDY3);
- FramedStream stream = connection.newStream(headerEntries("a", "android"), true, true);
- assertEquals(headerEntries("b", "banana"), stream.getResponseHeaders());
-
- // verify the peer received what was expected
- MockSpdyPeer.InFrame synStream = peer.takeFrame();
- assertEquals(TYPE_HEADERS, synStream.type);
- assertEquals(HeadersMode.SPDY_SYN_STREAM, synStream.headersMode);
- MockSpdyPeer.InFrame ping = peer.takeFrame();
- assertEquals(TYPE_PING, ping.type);
- assertEquals(2, ping.payload1);
+ try (MockSpdyPeer peer = new MockSpdyPeer()) {
+ int dataLength = 64 * 1024 + 1;
+ // write the mocking script
+ peer.acceptFrame(); // SYN_STREAM
+ peer.sendFrame().synReply(false, 1, headerEntries("b", "banana"));
+ peer.sendFrame().data(false, 1, new Buffer().write(new byte[dataLength]), dataLength);
+ peer.sendFrame().ping(false, 2, 0); // Ping just to make sure the stream was fastforwarded.
+ peer.acceptFrame(); // PING
+ peer.play();
+
+ // play it back
+ FramedConnection connection = connection(peer, SPDY3);
+ FramedStream stream = connection.newStream(headerEntries("a", "android"), true, true);
+ assertEquals(headerEntries("b", "banana"), stream.getResponseHeaders());
+
+ // verify the peer received what was expected
+ MockSpdyPeer.InFrame synStream = peer.takeFrame();
+ assertEquals(TYPE_HEADERS, synStream.type);
+ assertEquals(HeadersMode.SPDY_SYN_STREAM, synStream.headersMode);
+ MockSpdyPeer.InFrame ping = peer.takeFrame();
+ assertEquals(TYPE_PING, ping.type);
+ assertEquals(2, ping.payload1);
+ }
}
@Test public void remoteSendsRefusedStreamBeforeReplyHeaders() throws Exception {
- // write the mocking script
- peer.acceptFrame(); // SYN_STREAM
- peer.sendFrame().rstStream(1, REFUSED_STREAM);
- peer.sendFrame().ping(false, 2, 0);
- peer.acceptFrame(); // PING
- peer.play();
-
- // play it back
- FramedConnection connection = connection(peer, SPDY3);
- FramedStream stream = connection.newStream(headerEntries("a", "android"), true, true);
- try {
- stream.getResponseHeaders();
- fail();
- } catch (IOException expected) {
- assertEquals("stream was reset: REFUSED_STREAM", expected.getMessage());
+ try (MockSpdyPeer peer = new MockSpdyPeer()) {
+ // write the mocking script
+ peer.acceptFrame(); // SYN_STREAM
+ peer.sendFrame().rstStream(1, REFUSED_STREAM);
+ peer.sendFrame().ping(false, 2, 0);
+ peer.acceptFrame(); // PING
+ peer.play();
+
+ // play it back
+ FramedConnection connection = connection(peer, SPDY3);
+ FramedStream stream = connection.newStream(headerEntries("a", "android"), true, true);
+ try {
+ stream.getResponseHeaders();
+ fail();
+ } catch (IOException expected) {
+ assertEquals("stream was reset: REFUSED_STREAM", expected.getMessage());
+ }
+ assertEquals(0, connection.openStreamCount());
+
+ // verify the peer received what was expected
+ MockSpdyPeer.InFrame synStream = peer.takeFrame();
+ assertEquals(TYPE_HEADERS, synStream.type);
+ assertEquals(HeadersMode.SPDY_SYN_STREAM, synStream.headersMode);
+ MockSpdyPeer.InFrame ping = peer.takeFrame();
+ assertEquals(TYPE_PING, ping.type);
+ assertEquals(2, ping.payload1);
}
- assertEquals(0, connection.openStreamCount());
-
- // verify the peer received what was expected
- MockSpdyPeer.InFrame synStream = peer.takeFrame();
- assertEquals(TYPE_HEADERS, synStream.type);
- assertEquals(HeadersMode.SPDY_SYN_STREAM, synStream.headersMode);
- MockSpdyPeer.InFrame ping = peer.takeFrame();
- assertEquals(TYPE_PING, ping.type);
- assertEquals(2, ping.payload1);
}
@Test public void receiveGoAway() throws Exception {
- peer.setVariantAndClient(SPDY3, false);
-
- // write the mocking script
- peer.acceptFrame(); // SYN_STREAM 1
- peer.acceptFrame(); // SYN_STREAM 3
- peer.acceptFrame(); // PING.
- peer.sendFrame().goAway(1, PROTOCOL_ERROR, Util.EMPTY_BYTE_ARRAY);
- peer.sendFrame().ping(true, 1, 0);
- peer.acceptFrame(); // DATA STREAM 1
- peer.play();
-
- // play it back
- FramedConnection connection = connection(peer, SPDY3);
- FramedStream stream1 = connection.newStream(headerEntries("a", "android"), true, true);
- FramedStream stream2 = connection.newStream(headerEntries("b", "banana"), true, true);
- connection.ping().roundTripTime(); // Ensure the GO_AWAY that resets stream2 has been received.
- BufferedSink sink1 = Okio.buffer(stream1.getSink());
- BufferedSink sink2 = Okio.buffer(stream2.getSink());
- sink1.writeUtf8("abc");
- try {
- sink2.writeUtf8("abc");
- sink2.flush();
- fail();
- } catch (IOException expected) {
- assertEquals("stream was reset: REFUSED_STREAM", expected.getMessage());
- }
- sink1.writeUtf8("def");
- sink1.close();
- try {
- connection.newStream(headerEntries("c", "cola"), true, true);
- fail();
- } catch (IOException expected) {
- assertEquals("shutdown", expected.getMessage());
+ try (MockSpdyPeer peer = new MockSpdyPeer()) {
+ peer.setVariantAndClient(SPDY3, false);
+
+ // write the mocking script
+ peer.acceptFrame(); // SYN_STREAM 1
+ peer.acceptFrame(); // SYN_STREAM 3
+ peer.acceptFrame(); // PING.
+ peer.sendFrame().goAway(1, PROTOCOL_ERROR, Util.EMPTY_BYTE_ARRAY);
+ peer.sendFrame().ping(true, 1, 0);
+ peer.acceptFrame(); // DATA STREAM 1
+ peer.play();
+
+ // play it back
+ FramedConnection connection = connection(peer, SPDY3);
+ FramedStream stream1 = connection.newStream(headerEntries("a", "android"), true, true);
+ FramedStream stream2 = connection.newStream(headerEntries("b", "banana"), true, true);
+ connection.ping().roundTripTime(); // Ensure the GO_AWAY that resets stream2 has been received.
+ BufferedSink sink1 = Okio.buffer(stream1.getSink());
+ BufferedSink sink2 = Okio.buffer(stream2.getSink());
+ sink1.writeUtf8("abc");
+ try {
+ sink2.writeUtf8("abc");
+ sink2.flush();
+ fail();
+ } catch (IOException expected) {
+ assertEquals("stream was reset: REFUSED_STREAM", expected.getMessage());
+ }
+ sink1.writeUtf8("def");
+ sink1.close();
+ try {
+ connection.newStream(headerEntries("c", "cola"), true, true);
+ fail();
+ } catch (IOException expected) {
+ assertEquals("shutdown", expected.getMessage());
+ }
+ assertTrue(stream1.isOpen());
+ assertFalse(stream2.isOpen());
+ assertEquals(1, connection.openStreamCount());
+
+ // verify the peer received what was expected
+ MockSpdyPeer.InFrame synStream1 = peer.takeFrame();
+ assertEquals(TYPE_HEADERS, synStream1.type);
+ MockSpdyPeer.InFrame synStream2 = peer.takeFrame();
+ assertEquals(TYPE_HEADERS, synStream2.type);
+ MockSpdyPeer.InFrame ping = peer.takeFrame();
+ assertEquals(TYPE_PING, ping.type);
+ MockSpdyPeer.InFrame data1 = peer.takeFrame();
+ assertEquals(TYPE_DATA, data1.type);
+ assertEquals(1, data1.streamId);
+ assertTrue(Arrays.equals("abcdef".getBytes("UTF-8"), data1.data));
}
- assertTrue(stream1.isOpen());
- assertFalse(stream2.isOpen());
- assertEquals(1, connection.openStreamCount());
-
- // verify the peer received what was expected
- MockSpdyPeer.InFrame synStream1 = peer.takeFrame();
- assertEquals(TYPE_HEADERS, synStream1.type);
- MockSpdyPeer.InFrame synStream2 = peer.takeFrame();
- assertEquals(TYPE_HEADERS, synStream2.type);
- MockSpdyPeer.InFrame ping = peer.takeFrame();
- assertEquals(TYPE_PING, ping.type);
- MockSpdyPeer.InFrame data1 = peer.takeFrame();
- assertEquals(TYPE_DATA, data1.type);
- assertEquals(1, data1.streamId);
- assertTrue(Arrays.equals("abcdef".getBytes("UTF-8"), data1.data));
}
@Test public void sendGoAway() throws Exception {
- // write the mocking script
- peer.acceptFrame(); // SYN_STREAM 1
- peer.acceptFrame(); // GOAWAY
- peer.acceptFrame(); // PING
- peer.sendFrame().synStream(false, false, 2, 0, headerEntries("b", "b")); // Should be ignored!
- peer.sendFrame().ping(true, 1, 0);
- peer.play();
-
- // play it back
- FramedConnection connection = connection(peer, SPDY3);
- connection.newStream(headerEntries("a", "android"), true, true);
- Ping ping = connection.ping();
- connection.shutdown(PROTOCOL_ERROR);
- assertEquals(1, connection.openStreamCount());
- ping.roundTripTime(); // Prevent the peer from exiting prematurely.
-
- // verify the peer received what was expected
- MockSpdyPeer.InFrame synStream1 = peer.takeFrame();
- assertEquals(TYPE_HEADERS, synStream1.type);
- MockSpdyPeer.InFrame pingFrame = peer.takeFrame();
- assertEquals(TYPE_PING, pingFrame.type);
- MockSpdyPeer.InFrame goaway = peer.takeFrame();
- assertEquals(TYPE_GOAWAY, goaway.type);
- assertEquals(0, goaway.streamId);
- assertEquals(PROTOCOL_ERROR, goaway.errorCode);
+ try (MockSpdyPeer peer = new MockSpdyPeer()) {
+ // write the mocking script
+ peer.acceptFrame(); // SYN_STREAM 1
+ peer.acceptFrame(); // GOAWAY
+ peer.acceptFrame(); // PING
+ peer.sendFrame().synStream(false, false, 2, 0, headerEntries("b", "b")); // Should be ignored!
+ peer.sendFrame().ping(true, 1, 0);
+ peer.play();
+
+ // play it back
+ FramedConnection connection = connection(peer, SPDY3);
+ connection.newStream(headerEntries("a", "android"), true, true);
+ Ping ping = connection.ping();
+ connection.shutdown(PROTOCOL_ERROR);
+ assertEquals(1, connection.openStreamCount());
+ ping.roundTripTime(); // Prevent the peer from exiting prematurely.
+
+ // verify the peer received what was expected
+ MockSpdyPeer.InFrame synStream1 = peer.takeFrame();
+ assertEquals(TYPE_HEADERS, synStream1.type);
+ MockSpdyPeer.InFrame pingFrame = peer.takeFrame();
+ assertEquals(TYPE_PING, pingFrame.type);
+ MockSpdyPeer.InFrame goaway = peer.takeFrame();
+ assertEquals(TYPE_GOAWAY, goaway.type);
+ assertEquals(0, goaway.streamId);
+ assertEquals(PROTOCOL_ERROR, goaway.errorCode);
+ }
}
@Test public void noPingsAfterShutdown() throws Exception {
- // write the mocking script
- peer.acceptFrame(); // GOAWAY
- peer.play();
-
- // play it back
- FramedConnection connection = connection(peer, SPDY3);
- connection.shutdown(INTERNAL_ERROR);
- try {
- connection.ping();
- fail();
- } catch (IOException expected) {
- assertEquals("shutdown", expected.getMessage());
- }
+ try (MockSpdyPeer peer = new MockSpdyPeer()) {
+ // write the mocking script
+ peer.acceptFrame(); // GOAWAY
+ peer.play();
+
+ // play it back
+ FramedConnection connection = connection(peer, SPDY3);
+ connection.shutdown(INTERNAL_ERROR);
+ try {
+ connection.ping();
+ fail();
+ } catch (IOException expected) {
+ assertEquals("shutdown", expected.getMessage());
+ }
- // verify the peer received what was expected
- MockSpdyPeer.InFrame goaway = peer.takeFrame();
- assertEquals(TYPE_GOAWAY, goaway.type);
- assertEquals(INTERNAL_ERROR, goaway.errorCode);
+ // verify the peer received what was expected
+ MockSpdyPeer.InFrame goaway = peer.takeFrame();
+ assertEquals(TYPE_GOAWAY, goaway.type);
+ assertEquals(INTERNAL_ERROR, goaway.errorCode);
+ }
}
@Test public void close() throws Exception {
- // write the mocking script
- peer.acceptFrame(); // SYN_STREAM
- peer.acceptFrame(); // GOAWAY
- peer.acceptFrame(); // RST_STREAM
- peer.play();
-
- // play it back
- FramedConnection connection = connection(peer, SPDY3);
- FramedStream stream = connection.newStream(headerEntries("a", "android"), true, true);
- assertEquals(1, connection.openStreamCount());
- connection.close();
- assertEquals(0, connection.openStreamCount());
- try {
- connection.newStream(headerEntries("b", "banana"), true, true);
- fail();
- } catch (IOException expected) {
- assertEquals("shutdown", expected.getMessage());
- }
- BufferedSink sink = Okio.buffer(stream.getSink());
- try {
- sink.writeByte(0);
- sink.flush();
- fail();
- } catch (IOException expected) {
- assertEquals("stream was reset: CANCEL", expected.getMessage());
- }
- try {
- stream.getSource().read(new Buffer(), 1);
- fail();
- } catch (IOException expected) {
- assertEquals("stream was reset: CANCEL", expected.getMessage());
- }
+ try (MockSpdyPeer peer = new MockSpdyPeer()) {
+ // write the mocking script
+ peer.acceptFrame(); // SYN_STREAM
+ peer.acceptFrame(); // GOAWAY
+ peer.acceptFrame(); // RST_STREAM
+ peer.play();
+
+ // play it back
+ FramedConnection connection = connection(peer, SPDY3);
+ FramedStream stream = connection.newStream(headerEntries("a", "android"), true, true);
+ assertEquals(1, connection.openStreamCount());
+ connection.close();
+ assertEquals(0, connection.openStreamCount());
+ try {
+ connection.newStream(headerEntries("b", "banana"), true, true);
+ fail();
+ } catch (IOException expected) {
+ assertEquals("shutdown", expected.getMessage());
+ }
+ BufferedSink sink = Okio.buffer(stream.getSink());
+ try {
+ sink.writeByte(0);
+ sink.flush();
+ fail();
+ } catch (IOException expected) {
+ assertEquals("stream was reset: CANCEL", expected.getMessage());
+ }
+ try {
+ stream.getSource().read(new Buffer(), 1);
+ fail();
+ } catch (IOException expected) {
+ assertEquals("stream was reset: CANCEL", expected.getMessage());
+ }
- // verify the peer received what was expected
- MockSpdyPeer.InFrame synStream = peer.takeFrame();
- assertEquals(TYPE_HEADERS, synStream.type);
- assertEquals(HeadersMode.SPDY_SYN_STREAM, synStream.headersMode);
- MockSpdyPeer.InFrame goaway = peer.takeFrame();
- assertEquals(TYPE_GOAWAY, goaway.type);
- MockSpdyPeer.InFrame rstStream = peer.takeFrame();
- assertEquals(TYPE_RST_STREAM, rstStream.type);
- assertEquals(1, rstStream.streamId);
+ // verify the peer received what was expected
+ MockSpdyPeer.InFrame synStream = peer.takeFrame();
+ assertEquals(TYPE_HEADERS, synStream.type);
+ assertEquals(HeadersMode.SPDY_SYN_STREAM, synStream.headersMode);
+ MockSpdyPeer.InFrame goaway = peer.takeFrame();
+ assertEquals(TYPE_GOAWAY, goaway.type);
+ MockSpdyPeer.InFrame rstStream = peer.takeFrame();
+ assertEquals(TYPE_RST_STREAM, rstStream.type);
+ assertEquals(1, rstStream.streamId);
+ }
}
@Test public void closeCancelsPings() throws Exception {
- // write the mocking script
- peer.acceptFrame(); // PING
- peer.acceptFrame(); // GOAWAY
- peer.play();
-
- // play it back
- FramedConnection connection = connection(peer, SPDY3);
- Ping ping = connection.ping();
- connection.close();
- assertEquals(-1, ping.roundTripTime());
+ try (MockSpdyPeer peer = new MockSpdyPeer()) {
+ // write the mocking script
+ peer.acceptFrame(); // PING
+ peer.acceptFrame(); // GOAWAY
+ peer.play();
+
+ // play it back
+ FramedConnection connection = connection(peer, SPDY3);
+ Ping ping = connection.ping();
+ connection.close();
+ assertEquals(-1, ping.roundTripTime());
+ }
}
@Test public void getResponseHeadersTimesOut() throws Exception {
- // write the mocking script
- peer.acceptFrame(); // SYN_STREAM
- peer.acceptFrame(); // RST_STREAM
- peer.play();
-
- // play it back
- FramedConnection connection = connection(peer, SPDY3);
- FramedStream stream = connection.newStream(headerEntries("b", "banana"), true, true);
- stream.readTimeout().timeout(500, TimeUnit.MILLISECONDS);
- long startNanos = System.nanoTime();
- try {
- stream.getResponseHeaders();
- fail();
- } catch (InterruptedIOException expected) {
+ try (MockSpdyPeer peer = new MockSpdyPeer()) {
+ // write the mocking script
+ peer.acceptFrame(); // SYN_STREAM
+ peer.acceptFrame(); // RST_STREAM
+ peer.play();
+
+ // play it back
+ FramedConnection connection = connection(peer, SPDY3);
+ FramedStream stream = connection.newStream(headerEntries("b", "banana"), true, true);
+ stream.readTimeout().timeout(500, TimeUnit.MILLISECONDS);
+ long startNanos = System.nanoTime();
+ try {
+ stream.getResponseHeaders();
+ fail();
+ } catch (InterruptedIOException expected) {
+ }
+ long elapsedNanos = System.nanoTime() - startNanos;
+ awaitWatchdogIdle();
+ assertEquals(500d, TimeUnit.NANOSECONDS.toMillis(elapsedNanos), 200d /* 200ms delta */);
+ assertEquals(0, connection.openStreamCount());
+
+ // verify the peer received what was expected
+ assertEquals(TYPE_HEADERS, peer.takeFrame().type);
+ assertEquals(TYPE_RST_STREAM, peer.takeFrame().type);
}
- long elapsedNanos = System.nanoTime() - startNanos;
- awaitWatchdogIdle();
- assertEquals(500d, TimeUnit.NANOSECONDS.toMillis(elapsedNanos), 200d /* 200ms delta */);
- assertEquals(0, connection.openStreamCount());
-
- // verify the peer received what was expected
- assertEquals(TYPE_HEADERS, peer.takeFrame().type);
- assertEquals(TYPE_RST_STREAM, peer.takeFrame().type);
}
@Test public void readTimesOut() throws Exception {
- // write the mocking script
- peer.acceptFrame(); // SYN_STREAM
- peer.sendFrame().synReply(false, 1, headerEntries("a", "android"));
- peer.acceptFrame(); // RST_STREAM
- peer.play();
-
- // play it back
- FramedConnection connection = connection(peer, SPDY3);
- FramedStream stream = connection.newStream(headerEntries("b", "banana"), true, true);
- stream.readTimeout().timeout(500, TimeUnit.MILLISECONDS);
- Source source = stream.getSource();
- long startNanos = System.nanoTime();
- try {
- source.read(new Buffer(), 1);
- fail();
- } catch (InterruptedIOException expected) {
+ try (MockSpdyPeer peer = new MockSpdyPeer()) {
+ // write the mocking script
+ peer.acceptFrame(); // SYN_STREAM
+ peer.sendFrame().synReply(false, 1, headerEntries("a", "android"));
+ peer.acceptFrame(); // RST_STREAM
+ peer.play();
+
+ // play it back
+ FramedConnection connection = connection(peer, SPDY3);
+ FramedStream stream = connection.newStream(headerEntries("b", "banana"), true, true);
+ stream.readTimeout().timeout(500, TimeUnit.MILLISECONDS);
+ Source source = stream.getSource();
+ long startNanos = System.nanoTime();
+ try {
+ source.read(new Buffer(), 1);
+ fail();
+ } catch (InterruptedIOException expected) {
+ }
+ long elapsedNanos = System.nanoTime() - startNanos;
+ awaitWatchdogIdle();
+ assertEquals(500d, TimeUnit.NANOSECONDS.toMillis(elapsedNanos), 200d /* 200ms delta */);
+ assertEquals(0, connection.openStreamCount());
+
+ // verify the peer received what was expected
+ assertEquals(TYPE_HEADERS, peer.takeFrame().type);
+ assertEquals(TYPE_RST_STREAM, peer.takeFrame().type);
}
- long elapsedNanos = System.nanoTime() - startNanos;
- awaitWatchdogIdle();
- assertEquals(500d, TimeUnit.NANOSECONDS.toMillis(elapsedNanos), 200d /* 200ms delta */);
- assertEquals(0, connection.openStreamCount());
-
- // verify the peer received what was expected
- assertEquals(TYPE_HEADERS, peer.takeFrame().type);
- assertEquals(TYPE_RST_STREAM, peer.takeFrame().type);
}
@Test public void writeTimesOutAwaitingStreamWindow() throws Exception {
- // Set the peer's receive window to 5 bytes!
- Settings peerSettings = new Settings().set(Settings.INITIAL_WINDOW_SIZE, PERSIST_VALUE, 5);
-
- // write the mocking script
- peer.sendFrame().settings(peerSettings);
- peer.acceptFrame(); // PING
- peer.sendFrame().ping(true, 1, 0);
- peer.acceptFrame(); // SYN_STREAM
- peer.sendFrame().synReply(false, 1, headerEntries("a", "android"));
- peer.acceptFrame(); // DATA
- peer.acceptFrame(); // RST_STREAM
- peer.play();
-
- // play it back
- FramedConnection connection = connection(peer, SPDY3);
- connection.ping().roundTripTime(); // Make sure settings have been received.
- FramedStream stream = connection.newStream(headerEntries("b", "banana"), true, true);
- Sink sink = stream.getSink();
- sink.write(new Buffer().writeUtf8("abcde"), 5);
- stream.writeTimeout().timeout(500, TimeUnit.MILLISECONDS);
- long startNanos = System.nanoTime();
- sink.write(new Buffer().writeUtf8("f"), 1);
- try {
- sink.flush(); // This will time out waiting on the write window.
- fail();
- } catch (InterruptedIOException expected) {
+ try (MockSpdyPeer peer = new MockSpdyPeer()) {
+ // Set the peer's receive window to 5 bytes!
+ Settings peerSettings = new Settings().set(Settings.INITIAL_WINDOW_SIZE, PERSIST_VALUE, 5);
+
+ // write the mocking script
+ peer.sendFrame().settings(peerSettings);
+ peer.acceptFrame(); // PING
+ peer.sendFrame().ping(true, 1, 0);
+ peer.acceptFrame(); // SYN_STREAM
+ peer.sendFrame().synReply(false, 1, headerEntries("a", "android"));
+ peer.acceptFrame(); // DATA
+ peer.acceptFrame(); // RST_STREAM
+ peer.play();
+
+ // play it back
+ FramedConnection connection = connection(peer, SPDY3);
+ connection.ping().roundTripTime(); // Make sure settings have been received.
+ FramedStream stream = connection.newStream(headerEntries("b", "banana"), true, true);
+ Sink sink = stream.getSink();
+ sink.write(new Buffer().writeUtf8("abcde"), 5);
+ stream.writeTimeout().timeout(500, TimeUnit.MILLISECONDS);
+ long startNanos = System.nanoTime();
+ sink.write(new Buffer().writeUtf8("f"), 1);
+ try {
+ sink.flush(); // This will time out waiting on the write window.
+ fail();
+ } catch (InterruptedIOException expected) {
+ }
+ long elapsedNanos = System.nanoTime() - startNanos;
+ awaitWatchdogIdle();
+ assertEquals(500d, TimeUnit.NANOSECONDS.toMillis(elapsedNanos), 200d /* 200ms delta */);
+ assertEquals(0, connection.openStreamCount());
+
+ // verify the peer received what was expected
+ assertEquals(TYPE_PING, peer.takeFrame().type);
+ assertEquals(TYPE_HEADERS, peer.takeFrame().type);
+ assertEquals(TYPE_DATA, peer.takeFrame().type);
+ assertEquals(TYPE_RST_STREAM, peer.takeFrame().type);
}
- long elapsedNanos = System.nanoTime() - startNanos;
- awaitWatchdogIdle();
- assertEquals(500d, TimeUnit.NANOSECONDS.toMillis(elapsedNanos), 200d /* 200ms delta */);
- assertEquals(0, connection.openStreamCount());
-
- // verify the peer received what was expected
- assertEquals(TYPE_PING, peer.takeFrame().type);
- assertEquals(TYPE_HEADERS, peer.takeFrame().type);
- assertEquals(TYPE_DATA, peer.takeFrame().type);
- assertEquals(TYPE_RST_STREAM, peer.takeFrame().type);
}
@Test public void writeTimesOutAwaitingConnectionWindow() throws Exception {
- // Set the peer's receive window to 5 bytes. Give the stream 5 bytes back, so only the
- // connection-level window is applicable.
- Settings peerSettings = new Settings().set(Settings.INITIAL_WINDOW_SIZE, PERSIST_VALUE, 5);
-
- // write the mocking script
- peer.sendFrame().settings(peerSettings);
- peer.acceptFrame(); // SYN_STREAM
- peer.sendFrame().synReply(false, 1, headerEntries("a", "android"));
- peer.sendFrame().windowUpdate(1, 5);
- peer.acceptFrame(); // PING
- peer.sendFrame().ping(true, 1, 0);
- peer.acceptFrame(); // DATA
- peer.acceptFrame(); // RST_STREAM
- peer.play();
-
- // play it back
- FramedConnection connection = connection(peer, SPDY3);
- FramedStream stream = connection.newStream(headerEntries("b", "banana"), true, true);
- connection.ping().roundTripTime(); // Make sure the window update has been received.
- Sink sink = stream.getSink();
- stream.writeTimeout().timeout(500, TimeUnit.MILLISECONDS);
- sink.write(new Buffer().writeUtf8("abcdef"), 6);
- long startNanos = System.nanoTime();
- try {
- sink.flush(); // This will time out waiting on the write window.
- fail();
- } catch (InterruptedIOException expected) {
+ try (MockSpdyPeer peer = new MockSpdyPeer()) {
+ // Set the peer's receive window to 5 bytes. Give the stream 5 bytes back, so only the
+ // connection-level window is applicable.
+ Settings peerSettings = new Settings().set(Settings.INITIAL_WINDOW_SIZE, PERSIST_VALUE, 5);
+
+ // write the mocking script
+ peer.sendFrame().settings(peerSettings);
+ peer.acceptFrame(); // SYN_STREAM
+ peer.sendFrame().synReply(false, 1, headerEntries("a", "android"));
+ peer.sendFrame().windowUpdate(1, 5);
+ peer.acceptFrame(); // PING
+ peer.sendFrame().ping(true, 1, 0);
+ peer.acceptFrame(); // DATA
+ peer.acceptFrame(); // RST_STREAM
+ peer.play();
+
+ // play it back
+ FramedConnection connection = connection(peer, SPDY3);
+ FramedStream stream = connection.newStream(headerEntries("b", "banana"), true, true);
+ connection.ping().roundTripTime(); // Make sure the window update has been received.
+ Sink sink = stream.getSink();
+ stream.writeTimeout().timeout(500, TimeUnit.MILLISECONDS);
+ sink.write(new Buffer().writeUtf8("abcdef"), 6);
+ long startNanos = System.nanoTime();
+ try {
+ sink.flush(); // This will time out waiting on the write window.
+ fail();
+ } catch (InterruptedIOException expected) {
+ }
+ long elapsedNanos = System.nanoTime() - startNanos;
+ awaitWatchdogIdle();
+ assertEquals(500d, TimeUnit.NANOSECONDS.toMillis(elapsedNanos), 200d /* 200ms delta */);
+ assertEquals(0, connection.openStreamCount());
+
+ // verify the peer received what was expected
+ assertEquals(TYPE_HEADERS, peer.takeFrame().type);
+ assertEquals(TYPE_PING, peer.takeFrame().type);
+ assertEquals(TYPE_DATA, peer.takeFrame().type);
+ assertEquals(TYPE_RST_STREAM, peer.takeFrame().type);
}
- long elapsedNanos = System.nanoTime() - startNanos;
- awaitWatchdogIdle();
- assertEquals(500d, TimeUnit.NANOSECONDS.toMillis(elapsedNanos), 200d /* 200ms delta */);
- assertEquals(0, connection.openStreamCount());
-
- // verify the peer received what was expected
- assertEquals(TYPE_HEADERS, peer.takeFrame().type);
- assertEquals(TYPE_PING, peer.takeFrame().type);
- assertEquals(TYPE_DATA, peer.takeFrame().type);
- assertEquals(TYPE_RST_STREAM, peer.takeFrame().type);
}
@Test public void outgoingWritesAreBatched() throws Exception {
- // write the mocking script
- peer.acceptFrame(); // SYN_STREAM
- peer.sendFrame().synReply(false, 1, headerEntries("a", "android"));
- peer.acceptFrame(); // DATA
- peer.play();
-
- // play it back
- FramedConnection connection = connection(peer, SPDY3);
- FramedStream stream = connection.newStream(headerEntries("b", "banana"), true, true);
-
- // two outgoing writes
- Sink sink = stream.getSink();
- sink.write(new Buffer().writeUtf8("abcde"), 5);
- sink.write(new Buffer().writeUtf8("fghij"), 5);
- sink.close();
-
- // verify the peer received one incoming frame
- assertEquals(TYPE_HEADERS, peer.takeFrame().type);
- MockSpdyPeer.InFrame data = peer.takeFrame();
- assertEquals(TYPE_DATA, data.type);
- assertTrue(Arrays.equals("abcdefghij".getBytes("UTF-8"), data.data));
- assertTrue(data.inFinished);
+ try (MockSpdyPeer peer = new MockSpdyPeer()) {
+ // write the mocking script
+ peer.acceptFrame(); // SYN_STREAM
+ peer.sendFrame().synReply(false, 1, headerEntries("a", "android"));
+ peer.acceptFrame(); // DATA
+ peer.play();
+
+ // play it back
+ FramedConnection connection = connection(peer, SPDY3);
+ FramedStream stream = connection.newStream(headerEntries("b", "banana"), true, true);
+
+ // two outgoing writes
+ Sink sink = stream.getSink();
+ sink.write(new Buffer().writeUtf8("abcde"), 5);
+ sink.write(new Buffer().writeUtf8("fghij"), 5);
+ sink.close();
+
+ // verify the peer received one incoming frame
+ assertEquals(TYPE_HEADERS, peer.takeFrame().type);
+ MockSpdyPeer.InFrame data = peer.takeFrame();
+ assertEquals(TYPE_DATA, data.type);
+ assertTrue(Arrays.equals("abcdefghij".getBytes("UTF-8"), data.data));
+ assertTrue(data.inFinished);
+ }
}
@Test public void headers() throws Exception {
- // write the mocking script
- peer.acceptFrame(); // SYN_STREAM
- peer.acceptFrame(); // PING
- peer.sendFrame().synReply(false, 1, headerEntries("a", "android"));
- peer.sendFrame().headers(1, headerEntries("c", "c3po"));
- peer.sendFrame().ping(true, 1, 0);
- peer.play();
-
- // play it back
- FramedConnection connection = connection(peer, SPDY3);
- FramedStream stream = connection.newStream(headerEntries("b", "banana"), true, true);
- connection.ping().roundTripTime(); // Ensure that the HEADERS has been received.
- assertEquals(headerEntries("a", "android", "c", "c3po"), stream.getResponseHeaders());
-
- // verify the peer received what was expected
- MockSpdyPeer.InFrame synStream = peer.takeFrame();
- assertEquals(TYPE_HEADERS, synStream.type);
- assertEquals(HeadersMode.SPDY_SYN_STREAM, synStream.headersMode);
- MockSpdyPeer.InFrame ping = peer.takeFrame();
- assertEquals(TYPE_PING, ping.type);
+ try (MockSpdyPeer peer = new MockSpdyPeer()) {
+ // write the mocking script
+ peer.acceptFrame(); // SYN_STREAM
+ peer.acceptFrame(); // PING
+ peer.sendFrame().synReply(false, 1, headerEntries("a", "android"));
+ peer.sendFrame().headers(1, headerEntries("c", "c3po"));
+ peer.sendFrame().ping(true, 1, 0);
+ peer.play();
+
+ // play it back
+ FramedConnection connection = connection(peer, SPDY3);
+ FramedStream stream = connection.newStream(headerEntries("b", "banana"), true, true);
+ connection.ping().roundTripTime(); // Ensure that the HEADERS has been received.
+ assertEquals(headerEntries("a", "android", "c", "c3po"), stream.getResponseHeaders());
+
+ // verify the peer received what was expected
+ MockSpdyPeer.InFrame synStream = peer.takeFrame();
+ assertEquals(TYPE_HEADERS, synStream.type);
+ assertEquals(HeadersMode.SPDY_SYN_STREAM, synStream.headersMode);
+ MockSpdyPeer.InFrame ping = peer.takeFrame();
+ assertEquals(TYPE_PING, ping.type);
+ }
}
@Test public void headersBeforeReply() throws Exception {
- // write the mocking script
- peer.acceptFrame(); // SYN_STREAM
- peer.acceptFrame(); // PING
- peer.sendFrame().headers(1, headerEntries("c", "c3po"));
- peer.acceptFrame(); // RST_STREAM
- peer.sendFrame().ping(true, 1, 0);
- peer.play();
-
- // play it back
- FramedConnection connection = connection(peer, SPDY3);
- FramedStream stream = connection.newStream(headerEntries("b", "banana"), true, true);
- connection.ping().roundTripTime(); // Ensure that the HEADERS has been received.
- try {
- stream.getResponseHeaders();
- fail();
- } catch (IOException expected) {
- assertEquals("stream was reset: PROTOCOL_ERROR", expected.getMessage());
- }
+ try (MockSpdyPeer peer = new MockSpdyPeer()) {
+ // write the mocking script
+ peer.acceptFrame(); // SYN_STREAM
+ peer.acceptFrame(); // PING
+ peer.sendFrame().headers(1, headerEntries("c", "c3po"));
+ peer.acceptFrame(); // RST_STREAM
+ peer.sendFrame().ping(true, 1, 0);
+ peer.play();
+
+ // play it back
+ FramedConnection connection = connection(peer, SPDY3);
+ FramedStream stream = connection.newStream(headerEntries("b", "banana"), true, true);
+ connection.ping().roundTripTime(); // Ensure that the HEADERS has been received.
+ try {
+ stream.getResponseHeaders();
+ fail();
+ } catch (IOException expected) {
+ assertEquals("stream was reset: PROTOCOL_ERROR", expected.getMessage());
+ }
- // verify the peer received what was expected
- MockSpdyPeer.InFrame synStream = peer.takeFrame();
- assertEquals(TYPE_HEADERS, synStream.type);
- assertEquals(HeadersMode.SPDY_SYN_STREAM, synStream.headersMode);
- MockSpdyPeer.InFrame ping = peer.takeFrame();
- assertEquals(TYPE_PING, ping.type);
- MockSpdyPeer.InFrame rstStream = peer.takeFrame();
- assertEquals(TYPE_RST_STREAM, rstStream.type);
- assertEquals(PROTOCOL_ERROR, rstStream.errorCode);
+ // verify the peer received what was expected
+ MockSpdyPeer.InFrame synStream = peer.takeFrame();
+ assertEquals(TYPE_HEADERS, synStream.type);
+ assertEquals(HeadersMode.SPDY_SYN_STREAM, synStream.headersMode);
+ MockSpdyPeer.InFrame ping = peer.takeFrame();
+ assertEquals(TYPE_PING, ping.type);
+ MockSpdyPeer.InFrame rstStream = peer.takeFrame();
+ assertEquals(TYPE_RST_STREAM, rstStream.type);
+ assertEquals(PROTOCOL_ERROR, rstStream.errorCode);
+ }
}
@Test public void readSendsWindowUpdate() throws Exception {
- peer.setVariantAndClient(SPDY3, false);
-
- int windowSize = 100;
- int windowUpdateThreshold = 50;
-
- // Write the mocking script.
- peer.acceptFrame(); // SYN_STREAM
- peer.sendFrame().synReply(false, 1, headerEntries("a", "android"));
- for (int i = 0; i < 3; i++) {
- // Send frames of summing to size 50, which is windowUpdateThreshold.
- peer.sendFrame().data(false, 1, data(24), 24);
- peer.sendFrame().data(false, 1, data(25), 25);
- peer.sendFrame().data(false, 1, data(1), 1);
- peer.acceptFrame(); // connection WINDOW UPDATE
- peer.acceptFrame(); // stream WINDOW UPDATE
- }
- peer.sendFrame().data(true, 1, data(0), 0);
- peer.play();
-
- // Play it back.
- FramedConnection connection = connection(peer, SPDY3);
- connection.okHttpSettings.set(Settings.INITIAL_WINDOW_SIZE, 0, windowSize);
- FramedStream stream = connection.newStream(headerEntries("b", "banana"), false, true);
- assertEquals(0, stream.unacknowledgedBytesRead);
- assertEquals(headerEntries("a", "android"), stream.getResponseHeaders());
- Source in = stream.getSource();
- Buffer buffer = new Buffer();
- buffer.writeAll(in);
- assertEquals(-1, in.read(buffer, 1));
- assertEquals(150, buffer.size());
-
- MockSpdyPeer.InFrame synStream = peer.takeFrame();
- assertEquals(TYPE_HEADERS, synStream.type);
- for (int i = 0; i < 3; i++) {
- List<Integer> windowUpdateStreamIds = new ArrayList<>(2);
- for (int j = 0; j < 2; j++) {
- MockSpdyPeer.InFrame windowUpdate = peer.takeFrame();
- assertEquals(TYPE_WINDOW_UPDATE, windowUpdate.type);
- windowUpdateStreamIds.add(windowUpdate.streamId);
- assertEquals(windowUpdateThreshold, windowUpdate.windowSizeIncrement);
+ try (MockSpdyPeer peer = new MockSpdyPeer()) {
+ peer.setVariantAndClient(SPDY3, false);
+
+ int windowSize = 100;
+ int windowUpdateThreshold = 50;
+
+ // Write the mocking script.
+ peer.acceptFrame(); // SYN_STREAM
+ peer.sendFrame().synReply(false, 1, headerEntries("a", "android"));
+ for (int i = 0; i < 3; i++) {
+ // Send frames of summing to size 50, which is windowUpdateThreshold.
+ peer.sendFrame().data(false, 1, data(24), 24);
+ peer.sendFrame().data(false, 1, data(25), 25);
+ peer.sendFrame().data(false, 1, data(1), 1);
+ peer.acceptFrame(); // connection WINDOW UPDATE
+ peer.acceptFrame(); // stream WINDOW UPDATE
+ }
+ peer.sendFrame().data(true, 1, data(0), 0);
+ peer.play();
+
+ // Play it back.
+ FramedConnection connection = connection(peer, SPDY3);
+ connection.okHttpSettings.set(Settings.INITIAL_WINDOW_SIZE, 0, windowSize);
+ FramedStream stream = connection.newStream(headerEntries("b", "banana"), false, true);
+ assertEquals(0, stream.unacknowledgedBytesRead);
+ assertEquals(headerEntries("a", "android"), stream.getResponseHeaders());
+ Source in = stream.getSource();
+ Buffer buffer = new Buffer();
+ buffer.writeAll(in);
+ assertEquals(-1, in.read(buffer, 1));
+ assertEquals(150, buffer.size());
+
+ MockSpdyPeer.InFrame synStream = peer.takeFrame();
+ assertEquals(TYPE_HEADERS, synStream.type);
+ for (int i = 0; i < 3; i++) {
+ List<Integer> windowUpdateStreamIds = new ArrayList<>(2);
+ for (int j = 0; j < 2; j++) {
+ MockSpdyPeer.InFrame windowUpdate = peer.takeFrame();
+ assertEquals(TYPE_WINDOW_UPDATE, windowUpdate.type);
+ windowUpdateStreamIds.add(windowUpdate.streamId);
+ assertEquals(windowUpdateThreshold, windowUpdate.windowSizeIncrement);
+ }
+ assertTrue(windowUpdateStreamIds.contains(0)); // connection
+ assertTrue(windowUpdateStreamIds.contains(1)); // stream
}
- assertTrue(windowUpdateStreamIds.contains(0)); // connection
- assertTrue(windowUpdateStreamIds.contains(1)); // stream
}
}
@@ -1154,107 +1221,115 @@ public final class Spdy3ConnectionTest {
}
@Test public void serverSendsEmptyDataClientDoesntSendWindowUpdate() throws Exception {
- peer.setVariantAndClient(SPDY3, false);
-
- // Write the mocking script.
- peer.acceptFrame(); // SYN_STREAM
- peer.sendFrame().synReply(false, 1, headerEntries("a", "android"));
- peer.sendFrame().data(true, 1, data(0), 0);
- peer.play();
-
- // Play it back.
- FramedConnection connection = connection(peer, SPDY3);
- FramedStream client = connection.newStream(headerEntries("b", "banana"), false, true);
- assertEquals(-1, client.getSource().read(new Buffer(), 1));
-
- // Verify the peer received what was expected.
- MockSpdyPeer.InFrame synStream = peer.takeFrame();
- assertEquals(TYPE_HEADERS, synStream.type);
- assertEquals(3, peer.frameCount());
+ try (MockSpdyPeer peer = new MockSpdyPeer()) {
+ peer.setVariantAndClient(SPDY3, false);
+
+ // Write the mocking script.
+ peer.acceptFrame(); // SYN_STREAM
+ peer.sendFrame().synReply(false, 1, headerEntries("a", "android"));
+ peer.sendFrame().data(true, 1, data(0), 0);
+ peer.play();
+
+ // Play it back.
+ FramedConnection connection = connection(peer, SPDY3);
+ FramedStream client = connection.newStream(headerEntries("b", "banana"), false, true);
+ assertEquals(-1, client.getSource().read(new Buffer(), 1));
+
+ // Verify the peer received what was expected.
+ MockSpdyPeer.InFrame synStream = peer.takeFrame();
+ assertEquals(TYPE_HEADERS, synStream.type);
+ assertEquals(3, peer.frameCount());
+ }
}
@Test public void clientSendsEmptyDataServerDoesntSendWindowUpdate() throws Exception {
- peer.setVariantAndClient(SPDY3, false);
-
- // Write the mocking script.
- peer.acceptFrame(); // SYN_STREAM
- peer.acceptFrame(); // DATA
- peer.sendFrame().synReply(false, 1, headerEntries("a", "android"));
- peer.play();
-
- // Play it back.
- FramedConnection connection = connection(peer, SPDY3);
- FramedStream client = connection.newStream(headerEntries("b", "banana"), true, true);
- BufferedSink out = Okio.buffer(client.getSink());
- out.write(Util.EMPTY_BYTE_ARRAY);
- out.flush();
- out.close();
-
- // Verify the peer received what was expected.
- assertEquals(TYPE_HEADERS, peer.takeFrame().type);
- assertEquals(TYPE_DATA, peer.takeFrame().type);
- assertEquals(3, peer.frameCount());
+ try (MockSpdyPeer peer = new MockSpdyPeer()) {
+ peer.setVariantAndClient(SPDY3, false);
+
+ // Write the mocking script.
+ peer.acceptFrame(); // SYN_STREAM
+ peer.acceptFrame(); // DATA
+ peer.sendFrame().synReply(false, 1, headerEntries("a", "android"));
+ peer.play();
+
+ // Play it back.
+ FramedConnection connection = connection(peer, SPDY3);
+ FramedStream client = connection.newStream(headerEntries("b", "banana"), true, true);
+ BufferedSink out = Okio.buffer(client.getSink());
+ out.write(Util.EMPTY_BYTE_ARRAY);
+ out.flush();
+ out.close();
+
+ // Verify the peer received what was expected.
+ assertEquals(TYPE_HEADERS, peer.takeFrame().type);
+ assertEquals(TYPE_DATA, peer.takeFrame().type);
+ assertEquals(3, peer.frameCount());
+ }
}
@Test public void testTruncatedDataFrame() throws Exception {
- // write the mocking script
- peer.acceptFrame(); // SYN_STREAM
- peer.sendFrame().synReply(false, 1, headerEntries("a", "android"));
- peer.sendFrame().data(false, 1, data(1024), 1024);
- peer.truncateLastFrame(8 + 100);
- peer.play();
-
- // play it back
- FramedConnection connection = connection(peer, SPDY3);
- FramedStream stream = connection.newStream(headerEntries("b", "banana"), true, true);
- assertEquals(headerEntries("a", "android"), stream.getResponseHeaders());
- Source in = stream.getSource();
- try {
- Okio.buffer(in).readByteString(101);
- fail();
- } catch (IOException expected) {
- assertEquals("stream was reset: PROTOCOL_ERROR", expected.getMessage());
+ try (MockSpdyPeer peer = new MockSpdyPeer()) {
+ // write the mocking script
+ peer.acceptFrame(); // SYN_STREAM
+ peer.sendFrame().synReply(false, 1, headerEntries("a", "android"));
+ peer.sendFrame().data(false, 1, data(1024), 1024);
+ peer.truncateLastFrame(8 + 100);
+ peer.play();
+
+ // play it back
+ FramedConnection connection = connection(peer, SPDY3);
+ FramedStream stream = connection.newStream(headerEntries("b", "banana"), true, true);
+ assertEquals(headerEntries("a", "android"), stream.getResponseHeaders());
+ Source in = stream.getSource();
+ try {
+ Okio.buffer(in).readByteString(101);
+ fail();
+ } catch (IOException expected) {
+ assertEquals("stream was reset: PROTOCOL_ERROR", expected.getMessage());
+ }
}
}
@Test public void blockedStreamDoesntStarveNewStream() throws Exception {
- int framesThatFillWindow = roundUp(DEFAULT_INITIAL_WINDOW_SIZE, peer.maxOutboundDataLength());
+ try (MockSpdyPeer peer = new MockSpdyPeer()) {
+ int framesThatFillWindow = roundUp(DEFAULT_INITIAL_WINDOW_SIZE, peer.maxOutboundDataLength());
- // Write the mocking script. This accepts more data frames than necessary!
- peer.acceptFrame(); // SYN_STREAM on stream 1
- for (int i = 0; i < framesThatFillWindow; i++) {
- peer.acceptFrame(); // DATA on stream 1
+ // Write the mocking script. This accepts more data frames than necessary!
+ peer.acceptFrame(); // SYN_STREAM on stream 1
+ for (int i = 0; i < framesThatFillWindow; i++) {
+ peer.acceptFrame(); // DATA on stream 1
+ }
+ peer.acceptFrame(); // SYN_STREAM on stream 2
+ peer.acceptFrame(); // DATA on stream 2
+ peer.play();
+
+ // Play it back.
+ FramedConnection connection = connection(peer, SPDY3);
+ FramedStream stream1 = connection.newStream(headerEntries("a", "apple"), true, true);
+ BufferedSink out1 = Okio.buffer(stream1.getSink());
+ out1.write(new byte[DEFAULT_INITIAL_WINDOW_SIZE]);
+ out1.flush();
+
+ // Check that we've filled the window for both the stream and also the connection.
+ assertEquals(0, connection.bytesLeftInWriteWindow);
+ assertEquals(0, connection.getStream(1).bytesLeftInWriteWindow);
+
+ // receiving a window update on the the connection will unblock new streams.
+ connection.readerRunnable.windowUpdate(0, 3);
+
+ assertEquals(3, connection.bytesLeftInWriteWindow);
+ assertEquals(0, connection.getStream(1).bytesLeftInWriteWindow);
+
+ // Another stream should be able to send data even though 1 is blocked.
+ FramedStream stream2 = connection.newStream(headerEntries("b", "banana"), true, true);
+ BufferedSink out2 = Okio.buffer(stream2.getSink());
+ out2.writeUtf8("foo");
+ out2.flush();
+
+ assertEquals(0, connection.bytesLeftInWriteWindow);
+ assertEquals(0, connection.getStream(1).bytesLeftInWriteWindow);
+ assertEquals(DEFAULT_INITIAL_WINDOW_SIZE - 3, connection.getStream(3).bytesLeftInWriteWindow);
}
- peer.acceptFrame(); // SYN_STREAM on stream 2
- peer.acceptFrame(); // DATA on stream 2
- peer.play();
-
- // Play it back.
- FramedConnection connection = connection(peer, SPDY3);
- FramedStream stream1 = connection.newStream(headerEntries("a", "apple"), true, true);
- BufferedSink out1 = Okio.buffer(stream1.getSink());
- out1.write(new byte[DEFAULT_INITIAL_WINDOW_SIZE]);
- out1.flush();
-
- // Check that we've filled the window for both the stream and also the connection.
- assertEquals(0, connection.bytesLeftInWriteWindow);
- assertEquals(0, connection.getStream(1).bytesLeftInWriteWindow);
-
- // receiving a window update on the the connection will unblock new streams.
- connection.readerRunnable.windowUpdate(0, 3);
-
- assertEquals(3, connection.bytesLeftInWriteWindow);
- assertEquals(0, connection.getStream(1).bytesLeftInWriteWindow);
-
- // Another stream should be able to send data even though 1 is blocked.
- FramedStream stream2 = connection.newStream(headerEntries("b", "banana"), true, true);
- BufferedSink out2 = Okio.buffer(stream2.getSink());
- out2.writeUtf8("foo");
- out2.flush();
-
- assertEquals(0, connection.bytesLeftInWriteWindow);
- assertEquals(0, connection.getStream(1).bytesLeftInWriteWindow);
- assertEquals(DEFAULT_INITIAL_WINDOW_SIZE - 3, connection.getStream(3).bytesLeftInWriteWindow);
}
/** https://github.com/square/okhttp/issues/333 */
@@ -1310,43 +1385,47 @@ public final class Spdy3ConnectionTest {
}
private void headerBlockHasTrailingCompressedBytes(String frame, int length) throws IOException {
- // write the mocking script
- peer.acceptFrame(); // SYN_STREAM
- byte[] trailingCompressedBytes = ByteString.decodeBase64(frame).toByteArray();
- trailingCompressedBytes[11] = 1; // Set SPDY/3 stream ID to 3.
- peer.sendFrame(trailingCompressedBytes);
- peer.sendFrame().data(true, 1, new Buffer().writeUtf8("robot"), 5);
- peer.acceptFrame(); // DATA
- peer.play();
-
- // play it back
- FramedConnection connection = connection(peer, SPDY3);
- FramedStream stream = connection.newStream(headerEntries("b", "banana"), true, true);
- assertEquals("a", stream.getResponseHeaders().get(0).name.utf8());
- assertEquals(length, stream.getResponseHeaders().get(0).value.size());
- assertStreamData("robot", stream.getSource());
+ try (MockSpdyPeer peer = new MockSpdyPeer()) {
+ // write the mocking script
+ peer.acceptFrame(); // SYN_STREAM
+ byte[] trailingCompressedBytes = ByteString.decodeBase64(frame).toByteArray();
+ trailingCompressedBytes[11] = 1; // Set SPDY/3 stream ID to 3.
+ peer.sendFrame(trailingCompressedBytes);
+ peer.sendFrame().data(true, 1, new Buffer().writeUtf8("robot"), 5);
+ peer.acceptFrame(); // DATA
+ peer.play();
+
+ // play it back
+ FramedConnection connection = connection(peer, SPDY3);
+ FramedStream stream = connection.newStream(headerEntries("b", "banana"), true, true);
+ assertEquals("a", stream.getResponseHeaders().get(0).name.utf8());
+ assertEquals(length, stream.getResponseHeaders().get(0).value.size());
+ assertStreamData("robot", stream.getSource());
+ }
}
@Test public void socketExceptionWhileWritingHeaders() throws Exception {
- peer.acceptFrame(); // SYN_STREAM.
- peer.play();
-
- String longString = ByteString.of(randomBytes(2048)).base64();
- Socket socket = peer.openSocket();
- FramedConnection connection = new FramedConnection.Builder(true)
- .socket(socket)
- .protocol(SPDY3.getProtocol())
- .build();
- socket.shutdownOutput();
- try {
- connection.newStream(headerEntries("a", longString), false, true);
- fail();
- } catch (IOException expected) {
- }
- try {
- connection.newStream(headerEntries("b", longString), false, true);
- fail();
- } catch (IOException expected) {
+ try (MockSpdyPeer peer = new MockSpdyPeer()) {
+ peer.acceptFrame(); // SYN_STREAM.
+ peer.play();
+
+ String longString = ByteString.of(randomBytes(2048)).base64();
+ Socket socket = peer.openSocket();
+ FramedConnection connection = new FramedConnection.Builder(true)
+ .socket(socket)
+ .protocol(SPDY3.getProtocol())
+ .build();
+ socket.shutdownOutput();
+ try {
+ connection.newStream(headerEntries("a", longString), false, true);
+ fail();
+ } catch (IOException expected) {
+ }
+ try {
+ connection.newStream(headerEntries("b", longString), false, true);
+ fail();
+ } catch (IOException expected) {
+ }
}
}