Chromium Code Reviews| 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_spdy2.h" | 20 #include "net/spdy/spdy_test_util_spdy2.h" |
| 16 #include "testing/platform_test.h" | 21 #include "testing/platform_test.h" |
| 17 | 22 |
| 18 using namespace net::test_spdy2; | 23 using namespace net::test_spdy2; |
| 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_; | |
|
Ryan Hamilton
2013/02/05 05:03:45
I think I might be inclined to make this a count i
ramant (doing other things)
2013/02/05 20:43:43
Done.
| |
| 203 }; | |
| 204 | |
| 171 // Test the SpdyIOBuffer class. | 205 // Test the SpdyIOBuffer class. |
| 172 TEST_F(SpdySessionSpdy2Test, SpdyIOBuffer) { | 206 TEST_F(SpdySessionSpdy2Test, 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 1434 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1615 EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), true, OK)); | 1649 EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), true, OK)); |
| 1616 | 1650 |
| 1617 EXPECT_FALSE(session->NeedsCredentials()); | 1651 EXPECT_FALSE(session->NeedsCredentials()); |
| 1618 | 1652 |
| 1619 // Flush the SpdySession::OnReadComplete() task. | 1653 // Flush the SpdySession::OnReadComplete() task. |
| 1620 MessageLoop::current()->RunUntilIdle(); | 1654 MessageLoop::current()->RunUntilIdle(); |
| 1621 | 1655 |
| 1622 spdy_session_pool_->Remove(session); | 1656 spdy_session_pool_->Remove(session); |
| 1623 } | 1657 } |
| 1624 | 1658 |
| 1659 TEST_F(SpdySessionSpdy2Test, SyncRead) { | |
| 1660 MockConnect connect_data(SYNCHRONOUS, OK); | |
| 1661 BufferedSpdyFramer framer(2, false); | |
| 1662 | |
| 1663 scoped_ptr<SpdyFrame> req1(ConstructSpdyGet(NULL, 0, false, 1, MEDIUM)); | |
| 1664 MockWrite writes[] = { | |
| 1665 CreateMockWrite(*req1, 0), | |
| 1666 }; | |
| 1667 | |
| 1668 const int kPayloadSize = 1600; | |
| 1669 TestDataStream test_stream; | |
| 1670 scoped_refptr<net::IOBuffer> payload(new net::IOBuffer(kPayloadSize)); | |
| 1671 char* payload_data = payload->data(); | |
| 1672 test_stream.GetBytes(payload_data, kPayloadSize); | |
| 1673 | |
| 1674 scoped_ptr<SpdyFrame> data_frame1( | |
| 1675 framer.CreateDataFrame(1, payload_data, kPayloadSize, DATA_FLAG_NONE)); | |
| 1676 scoped_ptr<SpdyFrame> data_frame( | |
| 1677 framer.CreateDataFrame(1, payload_data, kPayloadSize, DATA_FLAG_FIN)); | |
| 1678 | |
| 1679 scoped_ptr<SpdyFrame> resp1(ConstructSpdyGetSynReply(NULL, 0, 1)); | |
| 1680 | |
| 1681 size_t num_reads = 6; | |
| 1682 scoped_array<MockRead> reads(new MockRead[num_reads]); | |
| 1683 size_t i = 0; | |
| 1684 reads[i] = CreateMockRead(*resp1, 1); | |
| 1685 i = 1; | |
| 1686 reads[i] = CreateMockRead(*data_frame1, 2); | |
| 1687 for (i = 2; i < num_reads - 2; ++i) | |
| 1688 reads[i] = CreateMockRead(*data_frame1, i + 1, SYNCHRONOUS); | |
| 1689 reads[i] = CreateMockRead(*data_frame, i + 1, SYNCHRONOUS); | |
|
Ryan Hamilton
2013/02/05 05:03:45
Any reason not to define the reads array with the
ramant (doing other things)
2013/02/05 20:43:43
Done.
| |
| 1690 ++i; | |
| 1691 reads[i] = MockRead(ASYNC, 0, i + 1); // EOF | |
| 1692 | |
| 1693 DeterministicSocketData data(reads.get(), num_reads, | |
| 1694 writes, arraysize(writes)); | |
| 1695 data.set_connect_data(connect_data); | |
| 1696 session_deps_.host_resolver->set_synchronous_mode(true); | |
| 1697 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); | |
| 1698 | |
| 1699 SSLSocketDataProvider ssl(SYNCHRONOUS, OK); | |
| 1700 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl); | |
| 1701 | |
| 1702 CreateDeterministicNetworkSession(); | |
| 1703 | |
| 1704 scoped_refptr<SpdySession> session = CreateInitializedSession(); | |
| 1705 | |
| 1706 scoped_refptr<SpdyStream> spdy_stream1; | |
| 1707 TestCompletionCallback callback1; | |
| 1708 GURL url1("http://www.google.com"); | |
| 1709 EXPECT_EQ(OK, session->CreateStream(url1, MEDIUM, &spdy_stream1, | |
| 1710 BoundNetLog(), callback1.callback())); | |
| 1711 EXPECT_EQ(0u, spdy_stream1->stream_id()); | |
| 1712 | |
| 1713 scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock); | |
| 1714 (*headers)["method"] = "GET"; | |
| 1715 (*headers)["scheme"] = url1.scheme(); | |
| 1716 (*headers)["host"] = url1.host(); | |
| 1717 (*headers)["url"] = url1.path(); | |
| 1718 (*headers)["version"] = "HTTP/1.1"; | |
| 1719 | |
| 1720 spdy_stream1->set_spdy_headers(headers.Pass()); | |
| 1721 EXPECT_TRUE(spdy_stream1->HasUrl()); | |
| 1722 spdy_stream1->SendRequest(false); | |
| 1723 | |
| 1724 SpdySessionTaskObserver observer("DoRead"); | |
|
Ryan Hamilton
2013/02/05 05:03:45
Only "DoRead"? is there a way to check for the Sp
ramant (doing other things)
2013/02/05 20:43:43
Done.
| |
| 1725 | |
| 1726 // Run until 1st read. | |
| 1727 EXPECT_EQ(0u, spdy_stream1->stream_id()); | |
| 1728 data.RunFor(2); | |
| 1729 EXPECT_EQ(1u, spdy_stream1->stream_id()); | |
| 1730 EXPECT_FALSE(observer.posted()); | |
| 1731 | |
| 1732 // Do 4 reads. | |
| 1733 data.RunFor(4); | |
| 1734 EXPECT_FALSE(observer.posted()); | |
| 1735 EXPECT_TRUE(data.at_write_eof()); | |
| 1736 EXPECT_TRUE(data.at_read_eof()); | |
| 1737 } | |
| 1738 | |
| 1739 TEST_F(SpdySessionSpdy2Test, ASyncRead) { | |
| 1740 MockConnect connect_data(SYNCHRONOUS, OK); | |
| 1741 BufferedSpdyFramer framer(2, false); | |
| 1742 | |
| 1743 scoped_ptr<SpdyFrame> req1(ConstructSpdyGet(NULL, 0, false, 1, MEDIUM)); | |
| 1744 MockWrite writes[] = { | |
| 1745 CreateMockWrite(*req1, 0), | |
| 1746 }; | |
| 1747 | |
| 1748 // Build buffers of size 8k. | |
| 1749 ASSERT_EQ(32 * 1024, kMaxReadBytes); | |
| 1750 const int kPayloadSize = (kMaxReadBytes / 4) - SpdyDataFrame::size(); | |
| 1751 TestDataStream test_stream; | |
| 1752 scoped_refptr<net::IOBuffer> payload(new net::IOBuffer(kPayloadSize)); | |
| 1753 char* payload_data = payload->data(); | |
| 1754 test_stream.GetBytes(payload_data, kPayloadSize); | |
| 1755 | |
| 1756 scoped_ptr<SpdyFrame> data_frame1( | |
| 1757 framer.CreateDataFrame(1, payload_data, kPayloadSize, DATA_FLAG_NONE)); | |
| 1758 scoped_ptr<SpdyFrame> data_frame( | |
| 1759 framer.CreateDataFrame(1, payload_data, kPayloadSize, DATA_FLAG_FIN)); | |
| 1760 | |
| 1761 scoped_ptr<SpdyFrame> resp1(ConstructSpdyGetSynReply(NULL, 0, 1)); | |
| 1762 | |
| 1763 // Send twice as many bytes as kMaxReadBytes. | |
| 1764 size_t num_reads = 2 + (2 * kMaxReadBytes / kPayloadSize); | |
| 1765 scoped_array<MockRead> reads(new MockRead[num_reads]); | |
| 1766 size_t i = 0; | |
| 1767 reads[i] = CreateMockRead(*resp1, 1); | |
| 1768 i = 1; | |
| 1769 reads[i] = CreateMockRead(*data_frame1, i + 1); | |
| 1770 for (i = 2; i < num_reads - 2; ++i) | |
| 1771 reads[i] = CreateMockRead(*data_frame1, i + 1, SYNCHRONOUS); | |
| 1772 reads[i] = CreateMockRead(*data_frame, i + 1, SYNCHRONOUS); | |
| 1773 ++i; | |
| 1774 reads[i] = MockRead(ASYNC, 0, i + 1); // EOF | |
| 1775 | |
| 1776 DeterministicSocketData data(reads.get(), num_reads, | |
| 1777 writes, arraysize(writes)); | |
| 1778 data.set_connect_data(connect_data); | |
| 1779 session_deps_.host_resolver->set_synchronous_mode(true); | |
| 1780 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); | |
| 1781 | |
| 1782 SSLSocketDataProvider ssl(SYNCHRONOUS, OK); | |
| 1783 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl); | |
| 1784 | |
| 1785 CreateDeterministicNetworkSession(); | |
| 1786 | |
| 1787 scoped_refptr<SpdySession> session = CreateInitializedSession(); | |
| 1788 | |
| 1789 scoped_refptr<SpdyStream> spdy_stream1; | |
| 1790 TestCompletionCallback callback1; | |
| 1791 GURL url1("http://www.google.com"); | |
| 1792 EXPECT_EQ(OK, session->CreateStream(url1, MEDIUM, &spdy_stream1, | |
| 1793 BoundNetLog(), callback1.callback())); | |
| 1794 EXPECT_EQ(0u, spdy_stream1->stream_id()); | |
| 1795 | |
| 1796 scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock); | |
| 1797 (*headers)["method"] = "GET"; | |
| 1798 (*headers)["scheme"] = url1.scheme(); | |
| 1799 (*headers)["host"] = url1.host(); | |
| 1800 (*headers)["url"] = url1.path(); | |
| 1801 (*headers)["version"] = "HTTP/1.1"; | |
| 1802 | |
| 1803 spdy_stream1->set_spdy_headers(headers.Pass()); | |
| 1804 EXPECT_TRUE(spdy_stream1->HasUrl()); | |
| 1805 spdy_stream1->SendRequest(false); | |
| 1806 | |
| 1807 SpdySessionTaskObserver observer("DoRead"); | |
| 1808 | |
| 1809 // Run until 1st read. | |
| 1810 EXPECT_EQ(0u, spdy_stream1->stream_id()); | |
| 1811 data.RunFor(2); | |
| 1812 EXPECT_EQ(1u, spdy_stream1->stream_id()); | |
| 1813 EXPECT_FALSE(observer.posted()); | |
| 1814 | |
| 1815 // Do 8 reads. | |
| 1816 data.RunFor(8); | |
| 1817 EXPECT_TRUE(observer.posted()); | |
| 1818 EXPECT_TRUE(data.at_write_eof()); | |
| 1819 EXPECT_TRUE(data.at_read_eof()); | |
| 1820 } | |
| 1821 | |
| 1625 } // namespace net | 1822 } // namespace net |
| OLD | NEW |