Index: net/spdy/spdy_session_unittest.cc |
diff --git a/net/spdy/spdy_session_unittest.cc b/net/spdy/spdy_session_unittest.cc |
index 34b4270b244eef94a2fc5c40fbc408d22bbfb260..7115e54e5f413632390fe0b5f06a944f6b12261d 100644 |
--- a/net/spdy/spdy_session_unittest.cc |
+++ b/net/spdy/spdy_session_unittest.cc |
@@ -1278,6 +1278,7 @@ TEST_F(SpdySessionTest, UnstallRacesWithStreamCreation) { |
} |
TEST_F(SpdySessionTest, DeleteExpiredPushStreams) { |
+ base::HistogramTester histogram_tester; |
session_deps_.host_resolver->set_synchronous_mode(true); |
session_deps_.time_func = TheNearFuture; |
@@ -1350,6 +1351,106 @@ TEST_F(SpdySessionTest, DeleteExpiredPushStreams) { |
data.Resume(); |
base::RunLoop().RunUntilIdle(); |
EXPECT_FALSE(session_); |
+ histogram_tester.ExpectBucketCount("Net.SpdySession.PushedBytes", 6, 1); |
+ histogram_tester.ExpectBucketCount("Net.SpdySession.PushedAndUnclaimedBytes", |
+ 6, 1); |
+} |
+ |
+TEST_F(SpdySessionTest, MetricsCollectionOnPushStreams) { |
+ base::HistogramTester histogram_tester; |
+ session_deps_.host_resolver->set_synchronous_mode(true); |
+ session_deps_.time_func = TheNearFuture; |
+ |
+ SpdySerializedFrame req( |
+ spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM, true)); |
+ SpdySerializedFrame rst( |
+ spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM)); |
+ MockWrite writes[] = {CreateMockWrite(req, 0), CreateMockWrite(rst, 5)}; |
+ |
+ SpdySerializedFrame push_a(spdy_util_.ConstructSpdyPush( |
+ nullptr, 0, 2, 1, "https://www.example.org/a.dat")); |
+ SpdySerializedFrame push_a_body(spdy_util_.ConstructSpdyDataFrame(2, false)); |
+ // In ascii "0" < "a". We use it to verify that we properly handle std::map |
+ // iterators inside. See http://crbug.com/443490 |
+ SpdySerializedFrame push_b(spdy_util_.ConstructSpdyPush( |
+ nullptr, 0, 4, 1, "https://www.example.org/0.dat")); |
+ SpdySerializedFrame push_c(spdy_util_.ConstructSpdyPush( |
+ nullptr, 0, 6, 1, "https://www.example.org/1.dat")); |
+ SpdySerializedFrame push_c_body(spdy_util_.ConstructSpdyDataFrame(6, false)); |
+ |
+ MockRead reads[] = { |
+ CreateMockRead(push_a, 1), |
+ CreateMockRead(push_a_body, 2), |
+ MockRead(ASYNC, ERR_IO_PENDING, 3), |
+ CreateMockRead(push_b, 4), |
+ MockRead(ASYNC, ERR_IO_PENDING, 6), |
+ CreateMockRead(push_c, 7), |
+ CreateMockRead(push_c_body, 8), |
+ MockRead(ASYNC, ERR_IO_PENDING, 9), |
+ MockRead(ASYNC, 0, 10) // EOF |
+ }; |
+ |
+ SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes)); |
+ session_deps_.socket_factory->AddSocketDataProvider(&data); |
+ |
+ AddSSLSocketData(); |
+ |
+ CreateNetworkSession(); |
+ CreateSecureSpdySession(); |
+ |
+ // Process the principal request, and the first push stream request & body. |
+ base::WeakPtr<SpdyStream> spdy_stream = |
+ CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_, |
+ test_url_, MEDIUM, NetLogWithSource()); |
+ test::StreamDelegateDoNothing delegate(spdy_stream); |
+ spdy_stream->SetDelegate(&delegate); |
+ |
+ SpdyHeaderBlock headers(spdy_util_.ConstructGetHeaderBlock(kDefaultUrl)); |
+ spdy_stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND); |
+ |
+ base::RunLoop().RunUntilIdle(); |
+ |
+ // Verify that there is one unclaimed push stream. |
+ EXPECT_EQ(1u, session_->num_unclaimed_pushed_streams()); |
+ EXPECT_EQ(1u, session_->count_unclaimed_pushed_streams_for_url( |
+ GURL("https://www.example.org/a.dat"))); |
+ |
+ // Unclaimed push body consumed bytes from the session window. |
+ EXPECT_EQ(kDefaultInitialWindowSize - kUploadDataSize, |
+ session_->session_recv_window_size_); |
+ EXPECT_EQ(0, session_->session_unacked_recv_window_bytes_); |
+ |
+ // Shift time to expire the push stream. Read the second HEADERS, |
+ // and verify a RST_STREAM was written. |
+ g_time_delta = base::TimeDelta::FromSeconds(300); |
+ data.Resume(); |
+ base::RunLoop().RunUntilIdle(); |
+ |
+ // Verify that the second pushed stream evicted the first pushed stream. |
+ EXPECT_EQ(1u, session_->num_unclaimed_pushed_streams()); |
+ EXPECT_EQ(1u, session_->count_unclaimed_pushed_streams_for_url( |
+ GURL("https://www.example.org/0.dat"))); |
+ |
+ // Verify that the session window reclaimed the evicted stream body. |
+ EXPECT_EQ(kDefaultInitialWindowSize, session_->session_recv_window_size_); |
+ EXPECT_EQ(kUploadDataSize, session_->session_unacked_recv_window_bytes_); |
+ |
+ // Read the third PUSH, this will not be expired when the test tear down. |
+ data.Resume(); |
+ base::RunLoop().RunUntilIdle(); |
+ |
+ EXPECT_EQ(2u, session_->num_unclaimed_pushed_streams()); |
+ EXPECT_EQ(1u, session_->count_unclaimed_pushed_streams_for_url( |
+ GURL("https://www.example.org/1.dat"))); |
+ |
+ // Read and process EOF. |
+ EXPECT_TRUE(session_); |
+ data.Resume(); |
+ base::RunLoop().RunUntilIdle(); |
+ EXPECT_FALSE(session_); |
+ histogram_tester.ExpectBucketCount("Net.SpdySession.PushedBytes", 12, 1); |
+ histogram_tester.ExpectBucketCount("Net.SpdySession.PushedAndUnclaimedBytes", |
+ 6, 1); |
} |
TEST_F(SpdySessionTest, FailedPing) { |
@@ -1750,8 +1851,8 @@ TEST_F(SpdySessionTest, SynCompressionHistograms) { |
base::RunLoop().RunUntilIdle(); |
// Regression test of compression performance under the request fixture. |
- histogram_tester.ExpectBucketCount( |
- "Net.SpdySynStreamCompressionPercentage", 81, 1); |
+ histogram_tester.ExpectBucketCount("Net.SpdySynStreamCompressionPercentage", |
+ 81, 1); |
// Read and process EOF. |
EXPECT_TRUE(session_); |