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

Unified Diff: net/quic/chromium/quic_chromium_client_stream_test.cc

Issue 2409273002: QuicChromiumClientStream handle Read() after trailers are received but not yet delivered (Closed)
Patch Set: Created 4 years, 2 months 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/quic/chromium/quic_chromium_client_stream.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/quic/chromium/quic_chromium_client_stream_test.cc
diff --git a/net/quic/chromium/quic_chromium_client_stream_test.cc b/net/quic/chromium/quic_chromium_client_stream_test.cc
index 30587d05b42d2c82096f5a32ebc596153f8ce9f0..41e0ca5e535016f62910e950d781efdba22c24f5 100644
--- a/net/quic/chromium/quic_chromium_client_stream_test.cc
+++ b/net/quic/chromium/quic_chromium_client_stream_test.cc
@@ -365,6 +365,17 @@ TEST_P(QuicChromiumClientStreamTest, OnTrailers) {
.WillOnce(testing::InvokeWithoutArgs([&run_loop]() { run_loop.Quit(); }));
run_loop.Run();
+
+ // OnDataAvailable callback should follow trailers notification.
+ base::RunLoop run_loop3;
+ EXPECT_CALL(delegate_, OnDataAvailable())
+ .Times(1)
+ .WillOnce(testing::DoAll(
+ testing::Invoke(CreateFunctor(&QuicChromiumClientStreamTest::ReadData,
+ base::Unretained(this), StringPiece())),
+ testing::InvokeWithoutArgs([&run_loop3]() { run_loop3.Quit(); })));
+ run_loop3.Run();
+
// Make sure kFinalOffsetHeaderKey is gone from the delivered actual trailers.
trailers.erase(kFinalOffsetHeaderKey);
EXPECT_EQ(trailers, delegate_.headers_);
@@ -425,6 +436,16 @@ TEST_P(QuicChromiumClientStreamTest, MarkTrailersConsumedWhenNotifyDelegate) {
run_loop2.Run();
+ // OnDataAvailable callback should follow trailers notification.
+ base::RunLoop run_loop3;
+ EXPECT_CALL(delegate_, OnDataAvailable())
+ .Times(1)
+ .WillOnce(testing::DoAll(
+ testing::Invoke(CreateFunctor(&QuicChromiumClientStreamTest::ReadData,
+ base::Unretained(this), StringPiece())),
+ testing::InvokeWithoutArgs([&run_loop3]() { run_loop3.Quit(); })));
+ run_loop3.Run();
+
// Make sure the stream is properly closed since trailers and data are all
// consumed.
EXPECT_TRUE(stream_->IsDoneReading());
@@ -436,6 +457,84 @@ TEST_P(QuicChromiumClientStreamTest, MarkTrailersConsumedWhenNotifyDelegate) {
EXPECT_CALL(delegate_, OnClose());
}
+// Test that if Read() is called after response body is read and after trailers
+// are received but not yet delivered, Read() will return ERR_IO_PENDING instead
+// of 0 (EOF).
+TEST_P(QuicChromiumClientStreamTest, ReadAfterTrailersReceivedButNotDelivered) {
+ InitializeHeaders();
+ std::string uncompressed_headers =
+ SpdyUtils::SerializeUncompressedHeaders(headers_);
+ stream_->OnStreamHeaders(uncompressed_headers);
+ stream_->OnStreamHeadersComplete(false, uncompressed_headers.length());
+
+ EXPECT_CALL(delegate_,
+ OnHeadersAvailableMock(_, uncompressed_headers.length()));
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(headers_, delegate_.headers_);
+ EXPECT_TRUE(stream_->decompressed_headers().empty());
+
+ const char data[] = "hello world!";
+ stream_->OnStreamFrame(QuicStreamFrame(kTestStreamId, /*fin=*/false,
+ /*offset=*/0, data));
+
+ base::RunLoop run_loop;
+ EXPECT_CALL(delegate_, OnDataAvailable())
+ .Times(1)
+ .WillOnce(testing::DoAll(
+ testing::Invoke(CreateFunctor(
+ &QuicChromiumClientStreamTest::ReadData, base::Unretained(this),
+ StringPiece(data, arraysize(data) - 1))),
+ testing::Invoke([&run_loop]() { run_loop.Quit(); })));
+
+ // Wait for the read to complete.
+ run_loop.Run();
+
+ // Deliver trailers. Delegate notification is posted asynchronously.
+ SpdyHeaderBlock trailers;
+ trailers["bar"] = "foo";
+ trailers[kFinalOffsetHeaderKey] = base::IntToString(strlen(data));
+ std::string uncompressed_trailers =
+ SpdyUtils::SerializeUncompressedHeaders(trailers);
+
+ stream_->OnStreamHeaders(uncompressed_trailers);
+ stream_->OnStreamHeadersComplete(true, uncompressed_trailers.length());
+
+ // Read again, it return ERR_IO_PENDING.
+ scoped_refptr<IOBuffer> buffer(new IOBuffer(1));
+ EXPECT_THAT(stream_->Read(buffer.get(), 1), ERR_IO_PENDING);
+
+ // Trailers are not delivered
+ EXPECT_FALSE(stream_->IsDoneReading());
+
+ base::RunLoop run_loop2;
+ EXPECT_CALL(delegate_,
+ OnHeadersAvailableMock(_, uncompressed_trailers.length()))
+ .WillOnce(
+ testing::InvokeWithoutArgs([&run_loop2]() { run_loop2.Quit(); }));
+
+ run_loop2.Run();
+
+ base::RunLoop run_loop3;
+ // OnDataAvailable() should follow right after and Read() will return 0.
+ EXPECT_CALL(delegate_, OnDataAvailable())
+ .WillOnce(testing::DoAll(
+ testing::Invoke(CreateFunctor(&QuicChromiumClientStreamTest::ReadData,
+ base::Unretained(this), StringPiece())),
+ testing::Invoke([&run_loop3]() { run_loop3.Quit(); })));
+ run_loop3.Run();
+
+ // Make sure the stream is properly closed since trailers and data are all
+ // consumed.
+ EXPECT_TRUE(stream_->IsDoneReading());
+
+ // Make sure kFinalOffsetHeaderKey is gone from the delivered actual trailers.
+ trailers.erase(kFinalOffsetHeaderKey);
+ EXPECT_EQ(trailers, delegate_.headers_);
+
+ base::RunLoop().RunUntilIdle();
+ EXPECT_CALL(delegate_, OnClose());
+}
+
TEST_P(QuicChromiumClientStreamTest, WriteStreamData) {
EXPECT_CALL(delegate_, OnClose());
« no previous file with comments | « net/quic/chromium/quic_chromium_client_stream.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698