OLD | NEW |
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/memory/scoped_ptr.h" |
| 8 #include "base/memory/scoped_vector.h" |
| 9 #include "base/string_util.h" |
7 #include "net/base/cert_test_util.h" | 10 #include "net/base/cert_test_util.h" |
8 #include "net/base/host_cache.h" | 11 #include "net/base/host_cache.h" |
| 12 #include "net/base/io_buffer.h" |
9 #include "net/base/ip_endpoint.h" | 13 #include "net/base/ip_endpoint.h" |
10 #include "net/base/net_log_unittest.h" | 14 #include "net/base/net_log_unittest.h" |
11 #include "net/base/test_data_directory.h" | 15 #include "net/base/test_data_directory.h" |
| 16 #include "net/base/test_data_stream.h" |
12 #include "net/spdy/spdy_io_buffer.h" | 17 #include "net/spdy/spdy_io_buffer.h" |
13 #include "net/spdy/spdy_session_pool.h" | 18 #include "net/spdy/spdy_session_pool.h" |
14 #include "net/spdy/spdy_stream.h" | 19 #include "net/spdy/spdy_stream.h" |
15 #include "net/spdy/spdy_test_util_spdy3.h" | 20 #include "net/spdy/spdy_test_util_spdy3.h" |
16 #include "testing/platform_test.h" | 21 #include "testing/platform_test.h" |
17 | 22 |
18 using namespace net::test_spdy3; | 23 using namespace net::test_spdy3; |
19 | 24 |
20 namespace net { | 25 namespace net { |
21 | 26 |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
161 | 166 |
162 scoped_refptr<TransportSocketParams> transport_params_; | 167 scoped_refptr<TransportSocketParams> transport_params_; |
163 SpdySessionDependencies session_deps_; | 168 SpdySessionDependencies session_deps_; |
164 scoped_refptr<HttpNetworkSession> http_session_; | 169 scoped_refptr<HttpNetworkSession> http_session_; |
165 SpdySessionPool* spdy_session_pool_; | 170 SpdySessionPool* spdy_session_pool_; |
166 GURL test_url_; | 171 GURL test_url_; |
167 HostPortPair test_host_port_pair_; | 172 HostPortPair test_host_port_pair_; |
168 HostPortProxyPair pair_; | 173 HostPortProxyPair pair_; |
169 }; | 174 }; |
170 | 175 |
| 176 class SpdySessionTaskObserver : public MessageLoop::TaskObserver { |
| 177 public: |
| 178 explicit SpdySessionTaskObserver(const std::string& function_name) |
| 179 : function_name_(function_name), |
| 180 posted_(false) { |
| 181 MessageLoop::current()->AddTaskObserver(this); |
| 182 } |
| 183 |
| 184 virtual ~SpdySessionTaskObserver() { |
| 185 MessageLoop::current()->RemoveTaskObserver(this); |
| 186 } |
| 187 |
| 188 virtual void WillProcessTask(const base::PendingTask& pending_task) OVERRIDE { |
| 189 } |
| 190 |
| 191 virtual void DidProcessTask(const base::PendingTask& pending_task) OVERRIDE { |
| 192 if (!posted_) { |
| 193 posted_ = EndsWith(pending_task.posted_from.function_name(), |
| 194 function_name_, true); |
| 195 } |
| 196 } |
| 197 |
| 198 bool posted() const { return posted_; } |
| 199 |
| 200 private: |
| 201 std::string function_name_; |
| 202 bool posted_; |
| 203 }; |
| 204 |
171 // Test the SpdyIOBuffer class. | 205 // Test the SpdyIOBuffer class. |
172 TEST_F(SpdySessionSpdy3Test, SpdyIOBuffer) { | 206 TEST_F(SpdySessionSpdy3Test, SpdyIOBuffer) { |
173 std::priority_queue<SpdyIOBuffer> queue_; | 207 std::priority_queue<SpdyIOBuffer> queue_; |
174 const size_t kQueueSize = 100; | 208 const size_t kQueueSize = 100; |
175 | 209 |
176 // Insert items with random priority and increasing buffer size. | 210 // Insert items with random priority and increasing buffer size. |
177 for (size_t index = 0; index < kQueueSize; ++index) { | 211 for (size_t index = 0; index < kQueueSize; ++index) { |
178 queue_.push(SpdyIOBuffer( | 212 queue_.push(SpdyIOBuffer( |
179 new IOBufferWithSize(index + 1), | 213 new IOBufferWithSize(index + 1), |
180 index + 1, | 214 index + 1, |
(...skipping 1560 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1741 | 1775 |
1742 scoped_refptr<SpdyStream> spdy_stream2; | 1776 scoped_refptr<SpdyStream> spdy_stream2; |
1743 EXPECT_EQ(OK, session->CreateStream(test_url_, MEDIUM, &spdy_stream2, | 1777 EXPECT_EQ(OK, session->CreateStream(test_url_, MEDIUM, &spdy_stream2, |
1744 BoundNetLog(), callback1.callback())); | 1778 BoundNetLog(), callback1.callback())); |
1745 | 1779 |
1746 EXPECT_EQ(spdy_stream2->send_window_size(), window_size); | 1780 EXPECT_EQ(spdy_stream2->send_window_size(), window_size); |
1747 spdy_stream2->Cancel(); | 1781 spdy_stream2->Cancel(); |
1748 spdy_stream2 = NULL; | 1782 spdy_stream2 = NULL; |
1749 } | 1783 } |
1750 | 1784 |
| 1785 TEST_F(SpdySessionSpdy3Test, SyncRead) { |
| 1786 MockConnect connect_data(SYNCHRONOUS, OK); |
| 1787 BufferedSpdyFramer framer(3, false); |
| 1788 |
| 1789 scoped_ptr<SpdyFrame> req1(ConstructSpdyGet(NULL, 0, false, 1, MEDIUM)); |
| 1790 MockWrite writes[] = { |
| 1791 CreateMockWrite(*req1, 0), |
| 1792 }; |
| 1793 |
| 1794 const int kPayloadSize = 1600; |
| 1795 TestDataStream test_stream; |
| 1796 scoped_refptr<net::IOBuffer> payload(new net::IOBuffer(kPayloadSize)); |
| 1797 char* payload_data = payload->data(); |
| 1798 test_stream.GetBytes(payload_data, kPayloadSize); |
| 1799 |
| 1800 scoped_ptr<SpdyFrame> data_frame1( |
| 1801 framer.CreateDataFrame(1, payload_data, kPayloadSize, DATA_FLAG_NONE)); |
| 1802 scoped_ptr<SpdyFrame> data_frame( |
| 1803 framer.CreateDataFrame(1, payload_data, kPayloadSize, DATA_FLAG_FIN)); |
| 1804 |
| 1805 scoped_ptr<SpdyFrame> resp1(ConstructSpdyGetSynReply(NULL, 0, 1)); |
| 1806 |
| 1807 size_t num_reads = 6; |
| 1808 scoped_array<MockRead> reads(new MockRead[num_reads]); |
| 1809 size_t i = 0; |
| 1810 reads[i] = CreateMockRead(*resp1, 1); |
| 1811 i = 1; |
| 1812 reads[i] = CreateMockRead(*data_frame1, 2); |
| 1813 for (i = 2; i < num_reads - 2; ++i) |
| 1814 reads[i] = CreateMockRead(*data_frame1, i + 1, SYNCHRONOUS); |
| 1815 reads[i] = CreateMockRead(*data_frame, i + 1, SYNCHRONOUS); |
| 1816 ++i; |
| 1817 reads[i] = MockRead(ASYNC, 0, i + 1); // EOF |
| 1818 |
| 1819 DeterministicSocketData data(reads.get(), num_reads, |
| 1820 writes, arraysize(writes)); |
| 1821 data.set_connect_data(connect_data); |
| 1822 session_deps_.host_resolver->set_synchronous_mode(true); |
| 1823 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); |
| 1824 |
| 1825 SSLSocketDataProvider ssl(SYNCHRONOUS, OK); |
| 1826 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl); |
| 1827 |
| 1828 CreateDeterministicNetworkSession(); |
| 1829 |
| 1830 scoped_refptr<SpdySession> session = CreateInitializedSession(); |
| 1831 |
| 1832 scoped_refptr<SpdyStream> spdy_stream1; |
| 1833 TestCompletionCallback callback1; |
| 1834 GURL url1("http://www.google.com"); |
| 1835 EXPECT_EQ(OK, session->CreateStream(url1, MEDIUM, &spdy_stream1, |
| 1836 BoundNetLog(), callback1.callback())); |
| 1837 EXPECT_EQ(0u, spdy_stream1->stream_id()); |
| 1838 |
| 1839 scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock); |
| 1840 (*headers)[":method"] = "GET"; |
| 1841 (*headers)[":scheme"] = url1.scheme(); |
| 1842 (*headers)[":host"] = url1.host(); |
| 1843 (*headers)[":path"] = url1.path(); |
| 1844 (*headers)[":version"] = "HTTP/1.1"; |
| 1845 |
| 1846 spdy_stream1->set_spdy_headers(headers.Pass()); |
| 1847 EXPECT_TRUE(spdy_stream1->HasUrl()); |
| 1848 spdy_stream1->SendRequest(false); |
| 1849 |
| 1850 SpdySessionTaskObserver observer("DoRead"); |
| 1851 |
| 1852 // Run until 1st read. |
| 1853 EXPECT_EQ(0u, spdy_stream1->stream_id()); |
| 1854 data.RunFor(2); |
| 1855 EXPECT_EQ(1u, spdy_stream1->stream_id()); |
| 1856 EXPECT_FALSE(observer.posted()); |
| 1857 |
| 1858 // Do 4 reads. |
| 1859 data.RunFor(4); |
| 1860 EXPECT_FALSE(observer.posted()); |
| 1861 EXPECT_TRUE(data.at_write_eof()); |
| 1862 EXPECT_TRUE(data.at_read_eof()); |
| 1863 } |
| 1864 |
| 1865 TEST_F(SpdySessionSpdy3Test, ASyncRead) { |
| 1866 MockConnect connect_data(SYNCHRONOUS, OK); |
| 1867 BufferedSpdyFramer framer(3, false); |
| 1868 |
| 1869 scoped_ptr<SpdyFrame> req1(ConstructSpdyGet(NULL, 0, false, 1, MEDIUM)); |
| 1870 MockWrite writes[] = { |
| 1871 CreateMockWrite(*req1, 0), |
| 1872 }; |
| 1873 |
| 1874 // Build buffers of size 8k. |
| 1875 ASSERT_EQ(32 * 1024, kMaxReadBytes); |
| 1876 const int kPayloadSize = (kMaxReadBytes / 4) - SpdyDataFrame::size(); |
| 1877 TestDataStream test_stream; |
| 1878 scoped_refptr<net::IOBuffer> payload(new net::IOBuffer(kPayloadSize)); |
| 1879 char* payload_data = payload->data(); |
| 1880 test_stream.GetBytes(payload_data, kPayloadSize); |
| 1881 |
| 1882 scoped_ptr<SpdyFrame> data_frame1( |
| 1883 framer.CreateDataFrame(1, payload_data, kPayloadSize, DATA_FLAG_NONE)); |
| 1884 scoped_ptr<SpdyFrame> data_frame( |
| 1885 framer.CreateDataFrame(1, payload_data, kPayloadSize, DATA_FLAG_FIN)); |
| 1886 |
| 1887 scoped_ptr<SpdyFrame> resp1(ConstructSpdyGetSynReply(NULL, 0, 1)); |
| 1888 |
| 1889 // Send twice as many bytes as kMaxReadBytes. |
| 1890 size_t num_reads = 2 + (2 * kMaxReadBytes / kPayloadSize); |
| 1891 scoped_array<MockRead> reads(new MockRead[num_reads]); |
| 1892 size_t i = 0; |
| 1893 reads[i] = CreateMockRead(*resp1, 1); |
| 1894 i = 1; |
| 1895 reads[i] = CreateMockRead(*data_frame1, i + 1); |
| 1896 for (i = 2; i < num_reads - 2; ++i) |
| 1897 reads[i] = CreateMockRead(*data_frame1, i + 1, SYNCHRONOUS); |
| 1898 reads[i] = CreateMockRead(*data_frame, i + 1, SYNCHRONOUS); |
| 1899 ++i; |
| 1900 reads[i] = MockRead(ASYNC, 0, i + 1); // EOF |
| 1901 |
| 1902 DeterministicSocketData data(reads.get(), num_reads, |
| 1903 writes, arraysize(writes)); |
| 1904 data.set_connect_data(connect_data); |
| 1905 session_deps_.host_resolver->set_synchronous_mode(true); |
| 1906 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); |
| 1907 |
| 1908 SSLSocketDataProvider ssl(SYNCHRONOUS, OK); |
| 1909 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl); |
| 1910 |
| 1911 CreateDeterministicNetworkSession(); |
| 1912 |
| 1913 scoped_refptr<SpdySession> session = CreateInitializedSession(); |
| 1914 |
| 1915 scoped_refptr<SpdyStream> spdy_stream1; |
| 1916 TestCompletionCallback callback1; |
| 1917 GURL url1("http://www.google.com"); |
| 1918 EXPECT_EQ(OK, session->CreateStream(url1, MEDIUM, &spdy_stream1, |
| 1919 BoundNetLog(), callback1.callback())); |
| 1920 EXPECT_EQ(0u, spdy_stream1->stream_id()); |
| 1921 |
| 1922 scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock); |
| 1923 (*headers)[":method"] = "GET"; |
| 1924 (*headers)[":scheme"] = url1.scheme(); |
| 1925 (*headers)[":host"] = url1.host(); |
| 1926 (*headers)[":path"] = url1.path(); |
| 1927 (*headers)[":version"] = "HTTP/1.1"; |
| 1928 |
| 1929 spdy_stream1->set_spdy_headers(headers.Pass()); |
| 1930 EXPECT_TRUE(spdy_stream1->HasUrl()); |
| 1931 spdy_stream1->SendRequest(false); |
| 1932 |
| 1933 SpdySessionTaskObserver observer("DoRead"); |
| 1934 |
| 1935 // Run until 1st read. |
| 1936 EXPECT_EQ(0u, spdy_stream1->stream_id()); |
| 1937 data.RunFor(2); |
| 1938 EXPECT_EQ(1u, spdy_stream1->stream_id()); |
| 1939 EXPECT_FALSE(observer.posted()); |
| 1940 |
| 1941 // Do 8 reads. |
| 1942 data.RunFor(8); |
| 1943 EXPECT_TRUE(observer.posted()); |
| 1944 EXPECT_TRUE(data.at_write_eof()); |
| 1945 EXPECT_TRUE(data.at_read_eof()); |
| 1946 } |
| 1947 |
1751 } // namespace net | 1948 } // namespace net |
OLD | NEW |