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

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

Issue 11644088: SPDY - implement greedy approach to read all the data and process it (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
« no previous file with comments | « net/spdy/spdy_session.cc ('k') | net/spdy/spdy_session_spdy3_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/memory/scoped_ptr.h"
8 #include "base/memory/scoped_vector.h"
7 #include "net/base/cert_test_util.h" 9 #include "net/base/cert_test_util.h"
8 #include "net/base/host_cache.h" 10 #include "net/base/host_cache.h"
11 #include "net/base/io_buffer.h"
9 #include "net/base/ip_endpoint.h" 12 #include "net/base/ip_endpoint.h"
10 #include "net/base/net_log_unittest.h" 13 #include "net/base/net_log_unittest.h"
11 #include "net/base/test_data_directory.h" 14 #include "net/base/test_data_directory.h"
15 #include "net/base/test_data_stream.h"
12 #include "net/spdy/spdy_io_buffer.h" 16 #include "net/spdy/spdy_io_buffer.h"
13 #include "net/spdy/spdy_session_pool.h" 17 #include "net/spdy/spdy_session_pool.h"
18 #include "net/spdy/spdy_session_test_util.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
22 namespace { 27 namespace {
23 28
(...skipping 1591 matching lines...) Expand 10 before | Expand all | Expand 10 after
1615 EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), true, OK)); 1620 EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), true, OK));
1616 1621
1617 EXPECT_FALSE(session->NeedsCredentials()); 1622 EXPECT_FALSE(session->NeedsCredentials());
1618 1623
1619 // Flush the SpdySession::OnReadComplete() task. 1624 // Flush the SpdySession::OnReadComplete() task.
1620 MessageLoop::current()->RunUntilIdle(); 1625 MessageLoop::current()->RunUntilIdle();
1621 1626
1622 spdy_session_pool_->Remove(session); 1627 spdy_session_pool_->Remove(session);
1623 } 1628 }
1624 1629
1630 // Test that SpdySession::DoRead reads data from the socket without yielding.
1631 // This test makes 32k - 1 bytes of data available on the socket for reading. It
1632 // then verifies that it has read all the available data without yielding.
1633 TEST_F(SpdySessionSpdy2Test, ReadDataWithoutYielding) {
1634 MockConnect connect_data(SYNCHRONOUS, OK);
1635 BufferedSpdyFramer framer(2, false);
1636
1637 scoped_ptr<SpdyFrame> req1(ConstructSpdyGet(NULL, 0, false, 1, MEDIUM));
1638 MockWrite writes[] = {
1639 CreateMockWrite(*req1, 0),
1640 };
1641
1642 // Build buffer of size kMaxReadBytes / 4 (-spdy_data_frame_size).
1643 ASSERT_EQ(32 * 1024, kMaxReadBytes);
1644 const int kPayloadSize = kMaxReadBytes / 4 - SpdyDataFrame::size();
1645 TestDataStream test_stream;
1646 scoped_refptr<net::IOBuffer> payload(new net::IOBuffer(kPayloadSize));
1647 char* payload_data = payload->data();
1648 test_stream.GetBytes(payload_data, kPayloadSize);
1649
1650 scoped_ptr<SpdyFrame> partial_data_frame(
1651 framer.CreateDataFrame(1, payload_data, kPayloadSize, DATA_FLAG_NONE));
1652 scoped_ptr<SpdyFrame> finish_data_frame(
1653 framer.CreateDataFrame(1, payload_data, kPayloadSize - 1, DATA_FLAG_FIN));
1654
1655 scoped_ptr<SpdyFrame> resp1(ConstructSpdyGetSynReply(NULL, 0, 1));
1656
1657 // Write 1 byte less than kMaxReadBytes to check that DoRead reads up to 32k
1658 // bytes.
1659 MockRead reads[] = {
1660 CreateMockRead(*resp1, 1),
1661 CreateMockRead(*partial_data_frame, 2),
1662 CreateMockRead(*partial_data_frame, 3, SYNCHRONOUS),
1663 CreateMockRead(*partial_data_frame, 4, SYNCHRONOUS),
1664 CreateMockRead(*finish_data_frame, 5, SYNCHRONOUS),
1665 MockRead(ASYNC, 0, 6) // EOF
1666 };
1667
1668 // Create SpdySession and SpdyStream and send the request.
1669 DeterministicSocketData data(reads, arraysize(reads),
1670 writes, arraysize(writes));
1671 data.set_connect_data(connect_data);
1672 session_deps_.host_resolver->set_synchronous_mode(true);
1673 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
1674
1675 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
1676 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
1677
1678 CreateDeterministicNetworkSession();
1679
1680 scoped_refptr<SpdySession> session = CreateInitializedSession();
1681
1682 scoped_refptr<SpdyStream> spdy_stream1;
1683 TestCompletionCallback callback1;
1684 GURL url1("http://www.google.com");
1685 EXPECT_EQ(OK, session->CreateStream(url1, MEDIUM, &spdy_stream1,
1686 BoundNetLog(), callback1.callback()));
1687 EXPECT_EQ(0u, spdy_stream1->stream_id());
1688
1689 scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock);
1690 (*headers)["method"] = "GET";
1691 (*headers)["scheme"] = url1.scheme();
1692 (*headers)["host"] = url1.host();
1693 (*headers)["url"] = url1.path();
1694 (*headers)["version"] = "HTTP/1.1";
1695
1696 spdy_stream1->set_spdy_headers(headers.Pass());
1697 EXPECT_TRUE(spdy_stream1->HasUrl());
1698 spdy_stream1->SendRequest(false);
1699
1700 // Set up the TaskObserver to verify SpdySession::DoRead doesn't post a task.
1701 SpdySessionTestTaskObserver observer("spdy_session.cc", "DoRead");
1702
1703 // Run until 1st read.
1704 EXPECT_EQ(0u, spdy_stream1->stream_id());
1705 data.RunFor(2);
1706 EXPECT_EQ(1u, spdy_stream1->stream_id());
1707 EXPECT_EQ(0u, observer.executed_count());
1708
1709 // Read all the data and verify SpdySession::DoRead has not posted a task.
1710 data.RunFor(4);
1711
1712 // Verify task observer's executed_count is zero, which indicates DoRead read
1713 // all the available data.
1714 EXPECT_EQ(0u, observer.executed_count());
1715 EXPECT_TRUE(data.at_write_eof());
1716 EXPECT_TRUE(data.at_read_eof());
1717 }
1718
1719 // Test that SpdySession::DoRead yields while reading the data. This test makes
1720 // 32k + 1 bytes of data available on the socket for reading. It then verifies
1721 // that DoRead has yielded even though there is data available for it to read
1722 // (i.e, socket()->Read didn't return ERR_IO_PENDING during socket reads).
1723 TEST_F(SpdySessionSpdy2Test, TestYieldingDuringReadData) {
1724 MockConnect connect_data(SYNCHRONOUS, OK);
1725 BufferedSpdyFramer framer(2, false);
1726
1727 scoped_ptr<SpdyFrame> req1(ConstructSpdyGet(NULL, 0, false, 1, MEDIUM));
1728 MockWrite writes[] = {
1729 CreateMockWrite(*req1, 0),
1730 };
1731
1732 // Build buffer of size kMaxReadBytes / 4 (-spdy_data_frame_size).
1733 ASSERT_EQ(32 * 1024, kMaxReadBytes);
1734 const int kPayloadSize = kMaxReadBytes / 4 - SpdyDataFrame::size();
1735 TestDataStream test_stream;
1736 scoped_refptr<net::IOBuffer> payload(new net::IOBuffer(kPayloadSize));
1737 char* payload_data = payload->data();
1738 test_stream.GetBytes(payload_data, kPayloadSize);
1739
1740 scoped_ptr<SpdyFrame> partial_data_frame(
1741 framer.CreateDataFrame(1, payload_data, kPayloadSize, DATA_FLAG_NONE));
1742 scoped_ptr<SpdyFrame> finish_data_frame(
1743 framer.CreateDataFrame(1, "h", 1, DATA_FLAG_FIN));
1744
1745 scoped_ptr<SpdyFrame> resp1(ConstructSpdyGetSynReply(NULL, 0, 1));
1746
1747 // Write 1 byte more than kMaxReadBytes to check that DoRead yields.
1748 MockRead reads[] = {
1749 CreateMockRead(*resp1, 1),
1750 CreateMockRead(*partial_data_frame, 2),
1751 CreateMockRead(*partial_data_frame, 3, SYNCHRONOUS),
1752 CreateMockRead(*partial_data_frame, 4, SYNCHRONOUS),
1753 CreateMockRead(*partial_data_frame, 5, SYNCHRONOUS),
1754 CreateMockRead(*finish_data_frame, 6, SYNCHRONOUS),
1755 MockRead(ASYNC, 0, 7) // EOF
1756 };
1757
1758 // Create SpdySession and SpdyStream and send the request.
1759 DeterministicSocketData data(reads, arraysize(reads),
1760 writes, arraysize(writes));
1761 data.set_connect_data(connect_data);
1762 session_deps_.host_resolver->set_synchronous_mode(true);
1763 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
1764
1765 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
1766 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
1767
1768 CreateDeterministicNetworkSession();
1769
1770 scoped_refptr<SpdySession> session = CreateInitializedSession();
1771
1772 scoped_refptr<SpdyStream> spdy_stream1;
1773 TestCompletionCallback callback1;
1774 GURL url1("http://www.google.com");
1775 EXPECT_EQ(OK, session->CreateStream(url1, MEDIUM, &spdy_stream1,
1776 BoundNetLog(), callback1.callback()));
1777 EXPECT_EQ(0u, spdy_stream1->stream_id());
1778
1779 scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock);
1780 (*headers)["method"] = "GET";
1781 (*headers)["scheme"] = url1.scheme();
1782 (*headers)["host"] = url1.host();
1783 (*headers)["url"] = url1.path();
1784 (*headers)["version"] = "HTTP/1.1";
1785
1786 spdy_stream1->set_spdy_headers(headers.Pass());
1787 EXPECT_TRUE(spdy_stream1->HasUrl());
1788 spdy_stream1->SendRequest(false);
1789
1790 // Set up the TaskObserver to verify SpdySession::DoRead posts a task.
1791 SpdySessionTestTaskObserver observer("spdy_session.cc", "DoRead");
1792
1793 // Run until 1st read.
1794 EXPECT_EQ(0u, spdy_stream1->stream_id());
1795 data.RunFor(2);
1796 EXPECT_EQ(1u, spdy_stream1->stream_id());
1797 EXPECT_EQ(0u, observer.executed_count());
1798
1799 // Read all the data and verify SpdySession::DoRead has posted a task.
1800 data.RunFor(6);
1801
1802 // Verify task observer's executed_count is 1, which indicates DoRead has
1803 // posted only one task and thus yielded though there is data available for it
1804 // to read.
1805 EXPECT_EQ(1u, observer.executed_count());
1806 EXPECT_TRUE(data.at_write_eof());
1807 EXPECT_TRUE(data.at_read_eof());
1808 }
1809
1810 // Test that SpdySession::DoRead yields while reading the data. This test makes
1811 // 4 reads of kMaxReadBytes / 4 (-spdy_data_frame_size), one read of
1812 // kMaxReadBytes (-spdy_data_frame_size), and some reads of kMaxReadBytes + 8k
1813 // (-spdy_data_frame_size), bytes of data available on the socket for reading.
1814 // It then verifies that DoRead has yielded even though there is data available
1815 // for it to read (i.e, socket()->Read didn't return ERR_IO_PENDING during
1816 // socket reads). Also verifies that SpdySession reads only
1817 // SpdySession::kReadBufferSize data from the underlying transport.
1818 // TODO(rtennti): Make this test work after fixes to DeterministicSocketData.
1819 TEST_F(SpdySessionSpdy2Test, DISABLED_TestYieldingDuringLargeReadData) {
1820 MockConnect connect_data(SYNCHRONOUS, OK);
1821 BufferedSpdyFramer framer(2, false);
1822
1823 scoped_ptr<SpdyFrame> req1(ConstructSpdyGet(NULL, 0, false, 1, MEDIUM));
1824 MockWrite writes[] = {
1825 CreateMockWrite(*req1, 0),
1826 };
1827
1828 // Build buffer of size kMaxReadBytes / 4 (-spdy_data_frame_size).
1829 ASSERT_EQ(32 * 1024, kMaxReadBytes);
1830 TestDataStream test_stream;
1831 const int kSmallPayloadSize = kMaxReadBytes / 4 - SpdyDataFrame::size();
1832 scoped_refptr<net::IOBuffer> small_payload(
1833 new net::IOBuffer(kSmallPayloadSize));
1834 char* small_payload_data = small_payload->data();
1835 test_stream.GetBytes(small_payload_data, kSmallPayloadSize);
1836
1837 // Build buffer of size kMaxReadBytes - (-spdy_data_frame_size).
1838 TestDataStream test_stream1;
1839 const int kMaxReadBytesPayloadSize = kMaxReadBytes - SpdyDataFrame::size();
1840 scoped_refptr<net::IOBuffer> max_bytes_payload(
1841 new net::IOBuffer(kMaxReadBytesPayloadSize));
1842 char* max_bytes_payload_data = max_bytes_payload->data();
1843 test_stream1.GetBytes(max_bytes_payload_data, kMaxReadBytesPayloadSize);
1844
1845 // Build buffer of size kMaxReadBytes + kSmallPayloadSize
1846 // (-spdy_data_frame_size).
1847 TestDataStream test_stream2;
1848 const int kLargePayloadSize =
1849 kMaxReadBytes + kSmallPayloadSize - SpdyDataFrame::size();
1850 scoped_refptr<net::IOBuffer> large_payload(
1851 new net::IOBuffer(kLargePayloadSize));
1852 char* large_payload_data = large_payload->data();
1853 test_stream2.GetBytes(large_payload_data, kLargePayloadSize);
1854
1855 scoped_ptr<SpdyFrame> small_data_frame(framer.CreateDataFrame(
1856 1, small_payload_data, kSmallPayloadSize, DATA_FLAG_NONE));
1857 scoped_ptr<SpdyFrame> max_bytes_data_frame(framer.CreateDataFrame(
1858 1, max_bytes_payload_data, kMaxReadBytesPayloadSize, DATA_FLAG_NONE));
1859 scoped_ptr<SpdyFrame> large_data_frame(framer.CreateDataFrame(
1860 1, large_payload_data, kLargePayloadSize, DATA_FLAG_NONE));
1861 scoped_ptr<SpdyFrame> finish_data_frame(framer.CreateDataFrame(
1862 1, "h", 1, DATA_FLAG_FIN));
1863
1864 scoped_ptr<SpdyFrame> resp1(ConstructSpdyGetSynReply(NULL, 0, 1));
1865
1866 MockRead reads[] = {
1867 CreateMockRead(*resp1, 1),
1868 CreateMockRead(*small_data_frame, 2),
1869 CreateMockRead(*small_data_frame, 3, SYNCHRONOUS),
1870 CreateMockRead(*small_data_frame, 4, SYNCHRONOUS),
1871 CreateMockRead(*small_data_frame, 5, SYNCHRONOUS),
1872 CreateMockRead(*max_bytes_data_frame, 6),
1873 CreateMockRead(*large_data_frame, 7, SYNCHRONOUS),
1874 CreateMockRead(*finish_data_frame, 8, SYNCHRONOUS),
1875 MockRead(ASYNC, 0, 9) // EOF
1876 };
1877
1878 // Create SpdySession and SpdyStream and send the request.
1879 DeterministicSocketData data(reads, arraysize(reads),
1880 writes, arraysize(writes));
1881 data.set_connect_data(connect_data);
1882 session_deps_.host_resolver->set_synchronous_mode(true);
1883 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
1884
1885 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
1886 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
1887
1888 CreateDeterministicNetworkSession();
1889
1890 scoped_refptr<SpdySession> session = CreateInitializedSession();
1891
1892 scoped_refptr<SpdyStream> spdy_stream1;
1893 TestCompletionCallback callback1;
1894 GURL url1("http://www.google.com");
1895 EXPECT_EQ(OK, session->CreateStream(url1, MEDIUM, &spdy_stream1,
1896 BoundNetLog(), callback1.callback()));
1897 EXPECT_EQ(0u, spdy_stream1->stream_id());
1898
1899 scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock);
1900 (*headers)["method"] = "GET";
1901 (*headers)["scheme"] = url1.scheme();
1902 (*headers)["host"] = url1.host();
1903 (*headers)["url"] = url1.path();
1904 (*headers)["version"] = "HTTP/1.1";
1905
1906 spdy_stream1->set_spdy_headers(headers.Pass());
1907 EXPECT_TRUE(spdy_stream1->HasUrl());
1908 spdy_stream1->SendRequest(false);
1909
1910 // Set up the TaskObserver to verify SpdySession::DoRead posts a task.
1911 SpdySessionTestTaskObserver observer("spdy_session.cc", "DoRead");
1912
1913 // Run until 1st read.
1914 EXPECT_EQ(0u, spdy_stream1->stream_id());
1915 data.RunFor(2);
1916 EXPECT_EQ(1u, spdy_stream1->stream_id());
1917 EXPECT_EQ(0u, observer.executed_count());
1918
1919 // Read all the data and verify SpdySession::DoRead has posted a task.
1920 data.RunFor(10);
1921
1922 // Verify task observer's executed_count is 1, which indicates DoRead has
1923 // posted only one task and thus yielded though there is data available for
1924 // it to read.
1925 EXPECT_EQ(1u, observer.executed_count());
1926 EXPECT_TRUE(data.at_write_eof());
1927 EXPECT_TRUE(data.at_read_eof());
1928 }
1929
1625 } // namespace net 1930 } // namespace net
OLDNEW
« no previous file with comments | « net/spdy/spdy_session.cc ('k') | net/spdy/spdy_session_spdy3_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698