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

Side by Side Diff: net/spdy/spdy_session_spdy3_unittest.cc

Issue 12207122: SPDY - Added unit tests for use after free of SpdySession (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 7 years, 10 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/spdy/spdy_session.h" 5 #include "net/spdy/spdy_session.h"
6 6
7 #include "base/location.h" 7 #include "base/location.h"
8 #include "base/memory/scoped_ptr.h" 8 #include "base/memory/scoped_ptr.h"
9 #include "base/memory/scoped_vector.h" 9 #include "base/memory/scoped_vector.h"
10 #include "base/pending_task.h" 10 #include "base/pending_task.h"
(...skipping 1918 matching lines...) Expand 10 before | Expand all | Expand 10 after
1929 data.RunFor(6); 1929 data.RunFor(6);
1930 1930
1931 // Verify task observer's executed_count is 1, which indicates DoRead has 1931 // Verify task observer's executed_count is 1, which indicates DoRead has
1932 // posted only one task and thus yielded though there is data available for it 1932 // posted only one task and thus yielded though there is data available for it
1933 // to read. 1933 // to read.
1934 EXPECT_EQ(1u, observer.executed_count()); 1934 EXPECT_EQ(1u, observer.executed_count());
1935 EXPECT_TRUE(data.at_write_eof()); 1935 EXPECT_TRUE(data.at_write_eof());
1936 EXPECT_TRUE(data.at_read_eof()); 1936 EXPECT_TRUE(data.at_read_eof());
1937 } 1937 }
1938 1938
1939 // Test that SpdySession::DoRead yields while reading the data. This test makes 1939 // Test that SpdySession::DoRead() tests interactions of yielding + async,
1940 // 4 reads of kMaxReadBytes / 4 (-spdy_data_frame_size), one read of 1940 // by doing the following MockReads.
1941 // kMaxReadBytes (-spdy_data_frame_size), and some reads of kMaxReadBytes + 8k 1941 //
1942 // (-spdy_data_frame_size), bytes of data available on the socket for reading. 1942 // MockRead of SYNCHRONOUS 8K, SYNCHRONOUS 8K, SYNCHRONOUS 8K, SYNCHRONOUS 2K
1943 // It then verifies that DoRead has yielded even though there is data available 1943 // ASYNC 6K, SYNCHRONOUS 8K, SYNCHRONOUS 8K, SYNCHRONOUS 8K, SYNCHRONOUS 2K.
1944 // for it to read (i.e, socket()->Read didn't return ERR_IO_PENDING during 1944 //
1945 // socket reads). Also verifies that SpdySession reads only 1945 // The above reads 26K synchronously. Since that is less that 32K, we will
1946 // SpdySession::kReadBufferSize data from the underlying transport. 1946 // attempt to read again. However, that DoRead() will return ERR_IO_PENDING
1947 // TODO(rtennti): Make this test work after fixes to DeterministicSocketData. 1947 // (because of async read), so DoRead() will yield. When we come back, DoRead()
1948 TEST_F(SpdySessionSpdy3Test, DISABLED_TestYieldingDuringLargeReadData) { 1948 // will read the results from the async read, and rest of the data
1949 // synchronously.
1950 TEST_F(SpdySessionSpdy3Test, TestYieldingDuringAsyncReadData) {
1949 MockConnect connect_data(SYNCHRONOUS, OK); 1951 MockConnect connect_data(SYNCHRONOUS, OK);
1950 BufferedSpdyFramer framer(3, false); 1952 BufferedSpdyFramer framer(3, false);
1951 1953
1952 scoped_ptr<SpdyFrame> req1(ConstructSpdyGet(NULL, 0, false, 1, MEDIUM)); 1954 scoped_ptr<SpdyFrame> req1(ConstructSpdyGet(NULL, 0, false, 1, MEDIUM));
1953 MockWrite writes[] = { 1955 MockWrite writes[] = {
1954 CreateMockWrite(*req1, 0), 1956 CreateMockWrite(*req1, 0),
1955 }; 1957 };
1956 1958
1957 // Build buffer of size kMaxReadBytes / 4 (-spdy_data_frame_size). 1959 // Build buffer of size kMaxReadBytes / 4 (-spdy_data_frame_size).
1958 ASSERT_EQ(32 * 1024, kMaxReadBytes); 1960 ASSERT_EQ(32 * 1024, kMaxReadBytes);
1959 TestDataStream test_stream; 1961 TestDataStream test_stream;
1960 const int kSmallPayloadSize = kMaxReadBytes / 4 - SpdyDataFrame::size(); 1962 const int kEightKPayloadSize = kMaxReadBytes / 4 - SpdyDataFrame::size();
1961 scoped_refptr<net::IOBuffer> small_payload( 1963 scoped_refptr<net::IOBuffer> eightk_payload(
1962 new net::IOBuffer(kSmallPayloadSize)); 1964 new net::IOBuffer(kEightKPayloadSize));
1963 char* small_payload_data = small_payload->data(); 1965 char* eightk_payload_data = eightk_payload->data();
1964 test_stream.GetBytes(small_payload_data, kSmallPayloadSize); 1966 test_stream.GetBytes(eightk_payload_data, kEightKPayloadSize);
1965 1967
1966 // Build buffer of size kMaxReadBytes - (-spdy_data_frame_size). 1968 // Build buffer of 6k size.
1967 TestDataStream test_stream1; 1969 TestDataStream test_stream1;
1968 const int kMaxReadBytesPayloadSize = kMaxReadBytes - SpdyDataFrame::size(); 1970 const int kSixKPayloadSize = kEightKPayloadSize - 2 * 1024;
1969 scoped_refptr<net::IOBuffer> max_bytes_payload( 1971 scoped_refptr<net::IOBuffer> sixk_bytes_payload(
1970 new net::IOBuffer(kMaxReadBytesPayloadSize)); 1972 new net::IOBuffer(kSixKPayloadSize));
1971 char* max_bytes_payload_data = max_bytes_payload->data(); 1973 char* sixk_bytes_payload_data = sixk_bytes_payload->data();
1972 test_stream1.GetBytes(max_bytes_payload_data, kMaxReadBytesPayloadSize); 1974 test_stream1.GetBytes(sixk_bytes_payload_data, kSixKPayloadSize);
1973 1975
1974 // Build buffer of size kMaxReadBytes + kSmallPayloadSize 1976 // Build buffer of 2k size.
1975 // (-spdy_data_frame_size).
1976 TestDataStream test_stream2; 1977 TestDataStream test_stream2;
1977 const int kLargePayloadSize = 1978 const int kTwoKPayloadSize = kEightKPayloadSize - 6 * 1024;
1978 kMaxReadBytes + kSmallPayloadSize - SpdyDataFrame::size(); 1979 scoped_refptr<net::IOBuffer> twok_payload(
1979 scoped_refptr<net::IOBuffer> large_payload( 1980 new net::IOBuffer(kTwoKPayloadSize));
1980 new net::IOBuffer(kLargePayloadSize)); 1981 char* twok_payload_data = twok_payload->data();
1981 char* large_payload_data = large_payload->data(); 1982 test_stream2.GetBytes(twok_payload_data, kTwoKPayloadSize);
1982 test_stream2.GetBytes(large_payload_data, kLargePayloadSize);
1983 1983
1984 scoped_ptr<SpdyFrame> small_data_frame(framer.CreateDataFrame( 1984 scoped_ptr<SpdyFrame> eightk_data_frame(framer.CreateDataFrame(
1985 1, small_payload_data, kSmallPayloadSize, DATA_FLAG_NONE)); 1985 1, eightk_payload_data, kEightKPayloadSize, DATA_FLAG_NONE));
1986 scoped_ptr<SpdyFrame> max_bytes_data_frame(framer.CreateDataFrame( 1986 scoped_ptr<SpdyFrame> sixk_bytes_data_frame(framer.CreateDataFrame(
1987 1, max_bytes_payload_data, kMaxReadBytesPayloadSize, DATA_FLAG_NONE)); 1987 1, sixk_bytes_payload_data, kSixKPayloadSize, DATA_FLAG_NONE));
1988 scoped_ptr<SpdyFrame> large_data_frame(framer.CreateDataFrame( 1988 scoped_ptr<SpdyFrame> twok_data_frame(framer.CreateDataFrame(
1989 1, large_payload_data, kLargePayloadSize, DATA_FLAG_NONE)); 1989 1, twok_payload_data, kTwoKPayloadSize, DATA_FLAG_NONE));
1990 scoped_ptr<SpdyFrame> finish_data_frame(framer.CreateDataFrame( 1990 scoped_ptr<SpdyFrame> finish_data_frame(framer.CreateDataFrame(
1991 1, "h", 1, DATA_FLAG_FIN)); 1991 1, "h", 1, DATA_FLAG_FIN));
1992 1992
1993 scoped_ptr<SpdyFrame> resp1(ConstructSpdyGetSynReply(NULL, 0, 1)); 1993 scoped_ptr<SpdyFrame> resp1(ConstructSpdyGetSynReply(NULL, 0, 1));
1994 1994
1995 MockRead reads[] = { 1995 MockRead reads[] = {
1996 CreateMockRead(*resp1, 1), 1996 CreateMockRead(*resp1, 1),
1997 CreateMockRead(*small_data_frame, 2), 1997 CreateMockRead(*eightk_data_frame, 2),
1998 CreateMockRead(*small_data_frame, 3, SYNCHRONOUS), 1998 CreateMockRead(*eightk_data_frame, 3, SYNCHRONOUS),
1999 CreateMockRead(*small_data_frame, 4, SYNCHRONOUS), 1999 CreateMockRead(*eightk_data_frame, 4, SYNCHRONOUS),
2000 CreateMockRead(*small_data_frame, 5, SYNCHRONOUS), 2000 CreateMockRead(*twok_data_frame, 5, SYNCHRONOUS),
2001 CreateMockRead(*max_bytes_data_frame, 6), 2001 CreateMockRead(*sixk_bytes_data_frame, 6, ASYNC),
2002 CreateMockRead(*large_data_frame, 7, SYNCHRONOUS), 2002 CreateMockRead(*eightk_data_frame, 7, SYNCHRONOUS),
2003 CreateMockRead(*finish_data_frame, 8, SYNCHRONOUS), 2003 CreateMockRead(*eightk_data_frame, 8, SYNCHRONOUS),
2004 MockRead(ASYNC, 0, 9) // EOF 2004 CreateMockRead(*eightk_data_frame, 9, SYNCHRONOUS),
2005 CreateMockRead(*twok_data_frame, 10, SYNCHRONOUS),
2006 CreateMockRead(*finish_data_frame, 11, SYNCHRONOUS),
2007 MockRead(ASYNC, 0, 12) // EOF
2005 }; 2008 };
2006 2009
2007 // Create SpdySession and SpdyStream and send the request. 2010 // Create SpdySession and SpdyStream and send the request.
2008 DeterministicSocketData data(reads, arraysize(reads), 2011 DeterministicSocketData data(reads, arraysize(reads),
2009 writes, arraysize(writes)); 2012 writes, arraysize(writes));
2010 data.set_connect_data(connect_data); 2013 data.set_connect_data(connect_data);
2011 session_deps_.host_resolver->set_synchronous_mode(true); 2014 session_deps_.host_resolver->set_synchronous_mode(true);
2012 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 2015 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
2013 2016
2014 SSLSocketDataProvider ssl(SYNCHRONOUS, OK); 2017 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
(...skipping 14 matching lines...) Expand all
2029 (*headers)[":method"] = "GET"; 2032 (*headers)[":method"] = "GET";
2030 (*headers)[":scheme"] = url1.scheme(); 2033 (*headers)[":scheme"] = url1.scheme();
2031 (*headers)[":host"] = url1.host(); 2034 (*headers)[":host"] = url1.host();
2032 (*headers)[":path"] = url1.path(); 2035 (*headers)[":path"] = url1.path();
2033 (*headers)[":version"] = "HTTP/1.1"; 2036 (*headers)[":version"] = "HTTP/1.1";
2034 2037
2035 spdy_stream1->set_spdy_headers(headers.Pass()); 2038 spdy_stream1->set_spdy_headers(headers.Pass());
2036 EXPECT_TRUE(spdy_stream1->HasUrl()); 2039 EXPECT_TRUE(spdy_stream1->HasUrl());
2037 spdy_stream1->SendRequest(false); 2040 spdy_stream1->SendRequest(false);
2038 2041
2039 // Set up the TaskObserver to verify SpdySession::DoRead posts a task. 2042 // Set up the TaskObserver to monitor SpdySession::DoRead posting of tasks.
2040 SpdySessionTestTaskObserver observer("spdy_session.cc", "DoRead"); 2043 SpdySessionTestTaskObserver observer("spdy_session.cc", "DoRead");
2041 2044
2042 // Run until 1st read. 2045 // Run until 1st read.
2043 EXPECT_EQ(0u, spdy_stream1->stream_id()); 2046 EXPECT_EQ(0u, spdy_stream1->stream_id());
2044 data.RunFor(2); 2047 data.RunFor(2);
2045 EXPECT_EQ(1u, spdy_stream1->stream_id()); 2048 EXPECT_EQ(1u, spdy_stream1->stream_id());
2046 EXPECT_EQ(0u, observer.executed_count()); 2049 EXPECT_EQ(0u, observer.executed_count());
2047 2050
2048 // Read all the data and verify SpdySession::DoRead has posted a task. 2051 // Read all the data and verify SpdySession::DoRead has posted a task.
2049 data.RunFor(10); 2052 data.RunFor(12);
2050 2053
2051 // Verify task observer's executed_count is 1, which indicates DoRead has 2054 // Verify task observer's executed_count is 1, which indicates DoRead has
2052 // posted only one task and thus yielded though there is data available for 2055 // posted only one task and thus yielded though there is data available for
2053 // it to read. 2056 // it to read.
2054 EXPECT_EQ(1u, observer.executed_count()); 2057 EXPECT_EQ(1u, observer.executed_count());
2055 EXPECT_TRUE(data.at_write_eof()); 2058 EXPECT_TRUE(data.at_write_eof());
2056 EXPECT_TRUE(data.at_read_eof()); 2059 EXPECT_TRUE(data.at_read_eof());
2057 } 2060 }
2058 2061
2062 // Send a GoAway frame when SpdySession is in DoLoop. If scoped_refptr to
2063 // <SpdySession> is deleted from SpdySession::DoLoop(), we get a crash because
2064 // GoAway could delete the SpdySession from the SpdySessionPool and the last
2065 // reference to SpdySession.
2066 TEST_F(SpdySessionSpdy3Test, GoAwayWhileInDoLoop) {
2067 MockConnect connect_data(SYNCHRONOUS, OK);
2068 BufferedSpdyFramer framer(3, false);
2069
2070 scoped_ptr<SpdyFrame> req1(ConstructSpdyGet(NULL, 0, false, 1, MEDIUM));
2071 MockWrite writes[] = {
2072 CreateMockWrite(*req1, 0),
2073 };
2074
2075 scoped_ptr<SpdyFrame> resp1(ConstructSpdyGetSynReply(NULL, 0, 1));
2076 scoped_ptr<SpdyFrame> body1(ConstructSpdyBodyFrame(1, true));
2077 scoped_ptr<SpdyFrame> goaway(ConstructSpdyGoAway());
2078
2079 MockRead reads[] = {
2080 CreateMockRead(*resp1, 1),
2081 CreateMockRead(*body1, 2),
2082 CreateMockRead(*goaway, 3),
2083 MockRead(ASYNC, 0, 4) // EOF
2084 };
2085
2086 // Create SpdySession and SpdyStream and send the request.
2087 DeterministicSocketData data(reads, arraysize(reads),
2088 writes, arraysize(writes));
2089 data.set_connect_data(connect_data);
2090 session_deps_.host_resolver->set_synchronous_mode(true);
2091 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
2092
2093 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
2094 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
2095
2096 CreateDeterministicNetworkSession();
2097
2098 scoped_refptr<SpdySession> session = CreateInitializedSession();
2099
2100 scoped_refptr<SpdyStream> spdy_stream1;
2101 TestCompletionCallback callback1;
2102 GURL url1("http://www.google.com");
2103 EXPECT_EQ(OK, session->CreateStream(url1, MEDIUM, &spdy_stream1,
2104 BoundNetLog(), callback1.callback()));
2105 EXPECT_EQ(0u, spdy_stream1->stream_id());
2106
2107 scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock);
2108 (*headers)[":method"] = "GET";
2109 (*headers)[":scheme"] = url1.scheme();
2110 (*headers)[":host"] = url1.host();
2111 (*headers)[":path"] = url1.path();
2112 (*headers)[":version"] = "HTTP/1.1";
2113
2114 spdy_stream1->set_spdy_headers(headers.Pass());
2115 EXPECT_TRUE(spdy_stream1->HasUrl());
2116 spdy_stream1->SendRequest(false);
2117
2118 // Run until 1st read.
2119 EXPECT_EQ(0u, spdy_stream1->stream_id());
2120 data.RunFor(1);
2121 EXPECT_EQ(1u, spdy_stream1->stream_id());
2122
2123 // Drop the reference to the session.
2124 session = NULL;
2125
2126 // Run until GoAway.
2127 data.RunFor(2);
2128
2129 // Drop the reference to the stream which deletes its reference to the
2130 // SpdySession. Only references to SpdySession are held by DoLoop and
2131 // SpdySessionPool. If DoLoop doesn't hold the reference, we get a crash if
2132 // SpdySession is deleted from the SpdySessionPool.
2133 spdy_stream1 = NULL;
2134
2135 data.RunFor(2);
2136 EXPECT_TRUE(data.at_write_eof());
2137 EXPECT_TRUE(data.at_read_eof());
2138 }
2139
2059 } // namespace net 2140 } // namespace net
OLDNEW
« net/spdy/spdy_session_spdy2_unittest.cc ('K') | « net/spdy/spdy_session_spdy2_unittest.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698