| Index: net/tools/quic/end_to_end_test.cc
|
| diff --git a/net/tools/quic/end_to_end_test.cc b/net/tools/quic/end_to_end_test.cc
|
| index 944105ec165dcf9387123c71b9c21284b68db0a1..1a97b9005f400099d2b37f6dc4e964063b6b6e21 100644
|
| --- a/net/tools/quic/end_to_end_test.cc
|
| +++ b/net/tools/quic/end_to_end_test.cc
|
| @@ -91,7 +91,8 @@ struct TestParams {
|
| bool use_fec,
|
| bool client_supports_stateless_rejects,
|
| bool server_uses_stateless_rejects_if_peer_supported,
|
| - QuicTag congestion_control_tag)
|
| + QuicTag congestion_control_tag,
|
| + bool auto_tune_flow_control_window)
|
| : client_supported_versions(client_supported_versions),
|
| server_supported_versions(server_supported_versions),
|
| negotiated_version(negotiated_version),
|
| @@ -99,7 +100,8 @@ struct TestParams {
|
| client_supports_stateless_rejects(client_supports_stateless_rejects),
|
| server_uses_stateless_rejects_if_peer_supported(
|
| server_uses_stateless_rejects_if_peer_supported),
|
| - congestion_control_tag(congestion_control_tag) {}
|
| + congestion_control_tag(congestion_control_tag),
|
| + auto_tune_flow_control_window(auto_tune_flow_control_window) {}
|
|
|
| friend ostream& operator<<(ostream& os, const TestParams& p) {
|
| os << "{ server_supported_versions: "
|
| @@ -113,7 +115,9 @@ struct TestParams {
|
| << p.server_uses_stateless_rejects_if_peer_supported;
|
| os << " use_fec: " << p.use_fec;
|
| os << " congestion_control_tag: "
|
| - << QuicUtils::TagToString(p.congestion_control_tag) << " }";
|
| + << QuicUtils::TagToString(p.congestion_control_tag);
|
| + os << " auto_tune_flow_control_window: " << p.auto_tune_flow_control_window
|
| + << " }";
|
| return os;
|
| }
|
|
|
| @@ -124,6 +128,7 @@ struct TestParams {
|
| bool client_supports_stateless_rejects;
|
| bool server_uses_stateless_rejects_if_peer_supported;
|
| QuicTag congestion_control_tag;
|
| + bool auto_tune_flow_control_window;
|
| };
|
|
|
| // Constructs various test permutations.
|
| @@ -157,28 +162,30 @@ vector<TestParams> GetTestParams() {
|
| for (bool client_supports_stateless_rejects : {true, false}) {
|
| for (bool server_uses_stateless_rejects_if_peer_supported :
|
| {true, false}) {
|
| - CHECK(!client_versions.empty());
|
| - // Add an entry for server and client supporting all versions.
|
| - params.push_back(
|
| - TestParams(client_versions, all_supported_versions,
|
| - client_versions.front(), use_fec,
|
| - client_supports_stateless_rejects,
|
| - server_uses_stateless_rejects_if_peer_supported,
|
| - congestion_control_tag));
|
| -
|
| - // Test client supporting all versions and server supporting 1
|
| - // version. Simulate an old server and exercise version downgrade in
|
| - // the client. Protocol negotiation should occur. Skip the i = 0
|
| - // case because it is essentially the same as the default case.
|
| - for (const QuicVersion version : client_versions) {
|
| - QuicVersionVector server_supported_versions;
|
| - server_supported_versions.push_back(version);
|
| - params.push_back(
|
| - TestParams(client_versions, server_supported_versions,
|
| - server_supported_versions.front(), use_fec,
|
| - client_supports_stateless_rejects,
|
| - server_uses_stateless_rejects_if_peer_supported,
|
| - congestion_control_tag));
|
| + for (bool auto_tune_flow_control_window : {true, false}) {
|
| + CHECK(!client_versions.empty());
|
| + // Add an entry for server and client supporting all versions.
|
| + params.push_back(TestParams(
|
| + client_versions, all_supported_versions,
|
| + client_versions.front(), use_fec,
|
| + client_supports_stateless_rejects,
|
| + server_uses_stateless_rejects_if_peer_supported,
|
| + congestion_control_tag, auto_tune_flow_control_window));
|
| +
|
| + // Test client supporting all versions and server supporting 1
|
| + // version. Simulate an old server and exercise version downgrade
|
| + // in the client. Protocol negotiation should occur. Skip the i =
|
| + // 0 case because it is essentially the same as the default case.
|
| + for (const QuicVersion version : client_versions) {
|
| + QuicVersionVector server_supported_versions;
|
| + server_supported_versions.push_back(version);
|
| + params.push_back(TestParams(
|
| + client_versions, server_supported_versions,
|
| + server_supported_versions.front(), use_fec,
|
| + client_supports_stateless_rejects,
|
| + server_uses_stateless_rejects_if_peer_supported,
|
| + congestion_control_tag, auto_tune_flow_control_window));
|
| + }
|
| }
|
| }
|
| }
|
| @@ -314,6 +321,10 @@ class EndToEndTest : public ::testing::TestWithParam<TestParams> {
|
| if (GetParam().client_supports_stateless_rejects) {
|
| copt.push_back(kSREJ);
|
| }
|
| + if (GetParam().auto_tune_flow_control_window) {
|
| + copt.push_back(kAFCW);
|
| + copt.push_back(kIFW5);
|
| + }
|
| client_config_.SetConnectionOptionsToSend(copt);
|
|
|
| // Start the server first, because CreateQuicClient() attempts
|
| @@ -464,6 +475,14 @@ class EndToEndTest : public ::testing::TestWithParam<TestParams> {
|
| GetParam().client_supports_stateless_rejects);
|
| }
|
|
|
| + void ExpectFlowControlsSynced(QuicFlowController* client,
|
| + QuicFlowController* server) {
|
| + EXPECT_EQ(QuicFlowControllerPeer::SendWindowSize(client),
|
| + QuicFlowControllerPeer::ReceiveWindowSize(server));
|
| + EXPECT_EQ(QuicFlowControllerPeer::ReceiveWindowSize(client),
|
| + QuicFlowControllerPeer::SendWindowSize(server));
|
| + }
|
| +
|
| bool initialized_;
|
| IPEndPoint server_address_;
|
| string server_hostname_;
|
| @@ -1438,8 +1457,10 @@ TEST_P(EndToEndTest, DifferentFlowControlWindows) {
|
| set_client_initial_stream_flow_control_receive_window(kClientStreamIFCW);
|
| set_client_initial_session_flow_control_receive_window(kClientSessionIFCW);
|
|
|
| - const uint32 kServerStreamIFCW = 654321;
|
| - const uint32 kServerSessionIFCW = 765432;
|
| + uint32 kServerStreamIFCW =
|
| + GetParam().auto_tune_flow_control_window ? 32 * 1024 : 654321;
|
| + uint32 kServerSessionIFCW =
|
| + GetParam().auto_tune_flow_control_window ? 48 * 1024 : 765432;
|
| set_server_initial_stream_flow_control_receive_window(kServerStreamIFCW);
|
| set_server_initial_session_flow_control_receive_window(kServerSessionIFCW);
|
|
|
| @@ -1487,8 +1508,10 @@ TEST_P(EndToEndTest, DifferentFlowControlWindows) {
|
| TEST_P(EndToEndTest, HeadersAndCryptoStreamsNoConnectionFlowControl) {
|
| // The special headers and crypto streams should be subject to per-stream flow
|
| // control limits, but should not be subject to connection level flow control.
|
| - const uint32 kStreamIFCW = 123456;
|
| - const uint32 kSessionIFCW = 234567;
|
| + const uint32 kStreamIFCW =
|
| + GetParam().auto_tune_flow_control_window ? 32 * 1024 : 123456;
|
| + const uint32 kSessionIFCW =
|
| + GetParam().auto_tune_flow_control_window ? 48 * 1024 : 234567;
|
| set_client_initial_stream_flow_control_receive_window(kStreamIFCW);
|
| set_client_initial_session_flow_control_receive_window(kSessionIFCW);
|
| set_server_initial_stream_flow_control_receive_window(kStreamIFCW);
|
| @@ -1535,6 +1558,47 @@ TEST_P(EndToEndTest, HeadersAndCryptoStreamsNoConnectionFlowControl) {
|
| server_thread_->Resume();
|
| }
|
|
|
| +TEST_P(EndToEndTest, FlowControlsSynced) {
|
| + const uint32 kClientIFCW = 64 * 1024;
|
| + const uint32 kServerIFCW = 1024 * 1024;
|
| + const float kSessionToStreamRatio = 1.5;
|
| + set_client_initial_stream_flow_control_receive_window(kClientIFCW);
|
| + set_client_initial_session_flow_control_receive_window(kSessionToStreamRatio *
|
| + kClientIFCW);
|
| + set_server_initial_stream_flow_control_receive_window(kServerIFCW);
|
| + set_server_initial_session_flow_control_receive_window(kSessionToStreamRatio *
|
| + kServerIFCW);
|
| +
|
| + ASSERT_TRUE(Initialize());
|
| +
|
| + client_->client()->WaitForCryptoHandshakeConfirmed();
|
| + server_thread_->WaitForCryptoHandshakeConfirmed();
|
| +
|
| + server_thread_->Pause();
|
| + QuicSpdySession* const client_session = client_->client()->session();
|
| + QuicDispatcher* dispatcher =
|
| + QuicServerPeer::GetDispatcher(server_thread_->server());
|
| + QuicSpdySession* server_session = dispatcher->session_map().begin()->second;
|
| +
|
| + ExpectFlowControlsSynced(client_session->flow_controller(),
|
| + server_session->flow_controller());
|
| + ExpectFlowControlsSynced(
|
| + QuicSessionPeer::GetCryptoStream(client_session)->flow_controller(),
|
| + QuicSessionPeer::GetCryptoStream(server_session)->flow_controller());
|
| + ExpectFlowControlsSynced(
|
| + QuicSpdySessionPeer::GetHeadersStream(client_session)->flow_controller(),
|
| + QuicSpdySessionPeer::GetHeadersStream(server_session)->flow_controller());
|
| +
|
| + EXPECT_EQ(static_cast<float>(QuicFlowControllerPeer::ReceiveWindowSize(
|
| + client_session->flow_controller())) /
|
| + QuicFlowControllerPeer::ReceiveWindowSize(
|
| + QuicSpdySessionPeer::GetHeadersStream(client_session)
|
| + ->flow_controller()),
|
| + kSessionToStreamRatio);
|
| +
|
| + server_thread_->Resume();
|
| +}
|
| +
|
| TEST_P(EndToEndTest, RequestWithNoBodyWillNeverSendStreamFrameWithFIN) {
|
| // A stream created on receipt of a simple request with no body will never get
|
| // a stream frame with a FIN. Verify that we don't keep track of the stream in
|
|
|