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

Unified Diff: net/spdy/bidirectional_stream_spdy_impl_unittest.cc

Issue 2462463002: Make net::BidirectionalStream handle RST_STREAM_NO_ERROR (Closed)
Patch Set: 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/bidirectional_stream_spdy_impl.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/spdy/bidirectional_stream_spdy_impl_unittest.cc
diff --git a/net/spdy/bidirectional_stream_spdy_impl_unittest.cc b/net/spdy/bidirectional_stream_spdy_impl_unittest.cc
index bee61f0a6f61274370fe9ec218a9fdcd53232d72..334782008d1d2f965a6db6beaa1351a17a11df2f 100644
--- a/net/spdy/bidirectional_stream_spdy_impl_unittest.cc
+++ b/net/spdy/bidirectional_stream_spdy_impl_unittest.cc
@@ -234,7 +234,7 @@ class TestDelegateBase : public BidirectionalStreamImpl::Delegate {
} // namespace
-class BidirectionalStreamSpdyImplTest : public testing::Test {
+class BidirectionalStreamSpdyImplTest : public testing::TestWithParam<bool> {
public:
BidirectionalStreamSpdyImplTest()
: default_url_(kDefaultUrl),
@@ -432,4 +432,91 @@ TEST_F(BidirectionalStreamSpdyImplTest, SendDataAfterStreamFailed) {
delegate->GetTotalReceivedBytes());
}
+INSTANTIATE_TEST_CASE_P(BidirectionalStreamSpdyImplTests,
+ BidirectionalStreamSpdyImplTest,
+ ::testing::Bool());
+
+// Tests that when received RST_STREAM with NO_ERROR, BidirectionalStream does
+// not crash when processing pending writes. See crbug.com/650438.
+TEST_P(BidirectionalStreamSpdyImplTest, RstWithNoErrorBeforeSendIsComplete) {
+ bool is_test_sendv = GetParam();
+ SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
+ kDefaultUrl, 1, kBodyDataSize * 3, LOW, nullptr, 0));
+ MockWrite writes[] = {CreateMockWrite(req, 0)};
+
+ SpdySerializedFrame resp(spdy_util_.ConstructSpdyPostReply(nullptr, 0));
+ SpdySerializedFrame rst(
+ spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_NO_ERROR));
+ MockRead reads[] = {CreateMockRead(resp, 1),
+ MockRead(ASYNC, ERR_IO_PENDING, 2), // Force a pause.
+ CreateMockRead(rst, 3), MockRead(ASYNC, 0, 4)};
+
+ InitSession(reads, arraysize(reads), writes, arraysize(writes));
+
+ BidirectionalStreamRequestInfo request_info;
+ request_info.method = "POST";
+ request_info.url = default_url_;
+ request_info.extra_headers.SetHeader(net::HttpRequestHeaders::kContentLength,
+ base::SizeTToString(kBodyDataSize * 3));
+
+ scoped_refptr<IOBuffer> read_buffer(new IOBuffer(kReadBufferSize));
+ std::unique_ptr<TestDelegateBase> delegate(
+ new TestDelegateBase(session_, read_buffer.get(), kReadBufferSize));
+ delegate->SetRunUntilCompletion(true);
+ delegate->Start(&request_info, net_log_.bound());
+ sequenced_data_->RunUntilPaused();
+ // Make a write pending before receiving RST_STREAM.
+ scoped_refptr<StringIOBuffer> write_buffer(
+ new StringIOBuffer(std::string(kBodyData, kBodyDataSize)));
+ delegate->SendData(write_buffer.get(), write_buffer->size(), false);
+ sequenced_data_->Resume();
+ base::RunLoop().RunUntilIdle();
+
+ // Make sure OnClose() without an error completes any pending write().
+ EXPECT_EQ(1, delegate->on_data_sent_count());
+ EXPECT_FALSE(delegate->on_failed_called());
+
+ if (is_test_sendv) {
+ std::vector<scoped_refptr<IOBuffer>> three_buffers = {
+ write_buffer.get(), write_buffer.get(), write_buffer.get()};
+ std::vector<int> three_lengths = {
+ write_buffer->size(), write_buffer->size(), write_buffer->size()};
+ delegate->SendvData(three_buffers, three_lengths, /*end_of_stream=*/true);
+ base::RunLoop().RunUntilIdle();
+ } else {
+ for (size_t j = 0; j < 3; j++) {
+ delegate->SendData(write_buffer.get(), write_buffer->size(),
+ /*end_of_stream=*/j == 2);
+ base::RunLoop().RunUntilIdle();
+ }
+ }
+ delegate->WaitUntilCompletion();
+ LoadTimingInfo load_timing_info;
+ EXPECT_TRUE(delegate->GetLoadTimingInfo(&load_timing_info));
+ TestLoadTimingNotReused(load_timing_info);
+
+ EXPECT_THAT(delegate->error(), IsError(OK));
+ EXPECT_EQ(1, delegate->on_data_read_count());
+ EXPECT_EQ(is_test_sendv ? 2 : 4, delegate->on_data_sent_count());
+ EXPECT_EQ(kProtoHTTP2, delegate->GetProtocol());
+ EXPECT_EQ(CountWriteBytes(writes, 1), delegate->GetTotalSentBytes());
+ // Should not count RST stream.
+ EXPECT_EQ(CountReadBytes(reads, arraysize(reads) - 2),
+ delegate->GetTotalReceivedBytes());
+
+ // Now call SendData again should produce an error because end of stream
+ // flag has been written.
+ if (is_test_sendv) {
+ std::vector<scoped_refptr<IOBuffer>> buffer = {write_buffer.get()};
+ std::vector<int> buffer_size = {write_buffer->size()};
+ delegate->SendvData(buffer, buffer_size, true);
+ } else {
+ delegate->SendData(write_buffer.get(), write_buffer->size(), true);
+ }
+ base::RunLoop().RunUntilIdle();
+ EXPECT_THAT(delegate->error(), IsError(ERR_UNEXPECTED));
+ EXPECT_TRUE(delegate->on_failed_called());
+ EXPECT_EQ(is_test_sendv ? 2 : 4, delegate->on_data_sent_count());
+}
+
} // namespace net
« no previous file with comments | « net/spdy/bidirectional_stream_spdy_impl.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698