Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(671)

Unified Diff: net/spdy/spdy_session_unittest.cc

Issue 2458793002: Server push cancellation: add PushPromiseHelper which reflects information on the push promise. (Closed)
Patch Set: sync and fix tests Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « net/spdy/spdy_session.cc ('k') | net/tools/quic/test_tools/push_promise_delegate.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/spdy/spdy_session_unittest.cc
diff --git a/net/spdy/spdy_session_unittest.cc b/net/spdy/spdy_session_unittest.cc
index e6dd43974fd7ac7c25d49582dc6e4e1c3cdb3664..b8472d759a31481a3b5ee33cf95bfd96ca1905a4 100644
--- a/net/spdy/spdy_session_unittest.cc
+++ b/net/spdy/spdy_session_unittest.cc
@@ -78,6 +78,28 @@ class MockRequireCTDelegate : public TransportSecurityState::RequireCTDelegate {
CTRequirementLevel(const std::string& host));
};
+class TestServerPushDelegate : public ServerPushDelegate {
+ public:
+ explicit TestServerPushDelegate() {}
+
+ void OnPush(std::unique_ptr<ServerPushHelper> push_helper) override {
+ push_helpers[push_helper->GetURL()] = std::move(push_helper);
+ }
+
+ bool CancelPush(GURL url) {
+ auto itr = push_helpers.find(url);
+ if (itr == push_helpers.end())
+ return false;
+
+ itr->second->Cancel();
+ push_helpers.erase(itr);
+ return true;
+ }
+
+ private:
+ std::map<GURL, std::unique_ptr<ServerPushHelper>> push_helpers;
+};
+
} // namespace
class SpdySessionTest : public PlatformTest {
@@ -208,6 +230,7 @@ class SpdySessionTest : public PlatformTest {
SpdySessionDependencies session_deps_;
std::unique_ptr<HttpNetworkSession> http_session_;
base::WeakPtr<SpdySession> session_;
+ TestServerPushDelegate test_push_delegate_;
SpdySessionPool* spdy_session_pool_;
const GURL test_url_;
const url::SchemeHostPort test_server_;
@@ -1277,6 +1300,92 @@ TEST_F(SpdySessionTest, UnstallRacesWithStreamCreation) {
EXPECT_THAT(callback2.WaitForResult(), IsOk());
}
+TEST_F(SpdySessionTest, CancelPushAfterSessionGoesAway) {
+ 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"));
+ 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), MockRead(ASYNC, 0, 7) // EOF
+ };
+
+ SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes));
+ session_deps_.socket_factory->AddSocketDataProvider(&data);
+
+ AddSSLSocketData();
+
+ CreateNetworkSession();
+ CreateSecureSpdySession();
+ session_->set_push_delegate(&test_push_delegate_);
+
+ // 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(301);
+ 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_);
+ EXPECT_TRUE(session_);
+
+ // Read and process EOF.
+ data.Resume();
+ base::RunLoop().RunUntilIdle();
+
+ // Cancel the first push after session goes away. Verify the test doesn't
+ // crash.
+ EXPECT_FALSE(session_);
+ EXPECT_TRUE(
+ test_push_delegate_.CancelPush(GURL("https://www.example.org/a.dat")));
+
+ histogram_tester.ExpectBucketCount("Net.SpdySession.PushedBytes", 6, 1);
+ histogram_tester.ExpectBucketCount("Net.SpdySession.PushedAndUnclaimedBytes",
+ 6, 1);
+}
+
TEST_F(SpdySessionTest, CancelPushAfterExpired) {
base::HistogramTester histogram_tester;
session_deps_.host_resolver->set_synchronous_mode(true);
@@ -1308,6 +1417,7 @@ TEST_F(SpdySessionTest, CancelPushAfterExpired) {
CreateNetworkSession();
CreateSecureSpdySession();
+ session_->set_push_delegate(&test_push_delegate_);
// Process the principal request, and the first push stream request & body.
base::WeakPtr<SpdyStream> spdy_stream =
@@ -1343,7 +1453,8 @@ TEST_F(SpdySessionTest, CancelPushAfterExpired) {
GURL("https://www.example.org/0.dat")));
// Cancel the first push after its expiration.
- session_->CancelPush(GURL("https://www.example.org/a.dat"));
+ EXPECT_TRUE(
+ test_push_delegate_.CancelPush(GURL("https://www.example.org/a.dat")));
EXPECT_EQ(1u, session_->num_unclaimed_pushed_streams());
EXPECT_TRUE(session_);
@@ -1356,6 +1467,7 @@ TEST_F(SpdySessionTest, CancelPushAfterExpired) {
data.Resume();
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(session_);
+
histogram_tester.ExpectBucketCount("Net.SpdySession.PushedBytes", 6, 1);
histogram_tester.ExpectBucketCount("Net.SpdySession.PushedAndUnclaimedBytes",
6, 1);
@@ -1392,6 +1504,7 @@ TEST_F(SpdySessionTest, CancelPushBeforeClaimed) {
CreateNetworkSession();
CreateSecureSpdySession();
+ session_->set_push_delegate(&test_push_delegate_);
// Process the principal request, and the first push stream request & body.
base::WeakPtr<SpdyStream> spdy_stream =
@@ -1432,7 +1545,7 @@ TEST_F(SpdySessionTest, CancelPushBeforeClaimed) {
EXPECT_TRUE(session_);
// Cancel the push before it's claimed.
- session_->CancelPush(pushed_url);
+ EXPECT_TRUE(test_push_delegate_.CancelPush(pushed_url));
EXPECT_EQ(0u, session_->num_unclaimed_pushed_streams());
EXPECT_EQ(0u, session_->count_unclaimed_pushed_streams_for_url(pushed_url));
« no previous file with comments | « net/spdy/spdy_session.cc ('k') | net/tools/quic/test_tools/push_promise_delegate.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698