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

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

Issue 367963003: Separate client and server pushed streams limits. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 5 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
« net/spdy/spdy_session.h ('K') | « net/spdy/spdy_session.cc ('k') | no next file » | 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/bind.h" 7 #include "base/bind.h"
8 #include "base/callback.h" 8 #include "base/callback.h"
9 #include "base/memory/scoped_ptr.h" 9 #include "base/memory/scoped_ptr.h"
10 #include "base/run_loop.h" 10 #include "base/run_loop.h"
(...skipping 4526 matching lines...) Expand 10 before | Expand all | Expand 10 after
4537 SpdyHeaderBlock::const_iterator it = response_headers.find("alpha"); 4537 SpdyHeaderBlock::const_iterator it = response_headers.find("alpha");
4538 std::string alpha_val = 4538 std::string alpha_val =
4539 (it == response_headers.end()) ? std::string() : it->second; 4539 (it == response_headers.end()) ? std::string() : it->second;
4540 EXPECT_EQ("beta", alpha_val); 4540 EXPECT_EQ("beta", alpha_val);
4541 4541
4542 GURL request_url = 4542 GURL request_url =
4543 GetUrlFromHeaderBlock(request_headers, spdy_util_.spdy_version(), true); 4543 GetUrlFromHeaderBlock(request_headers, spdy_util_.spdy_version(), true);
4544 EXPECT_EQ(kStreamUrl, request_url); 4544 EXPECT_EQ(kStreamUrl, request_url);
4545 } 4545 }
4546 4546
4547 // Regression. Sorta. Push streams and client streams were sharing a single
4548 // limit for a long time.
4549 TEST_P(SpdySessionTest, PushedStreamShouldNotCountToClientConcurrencyLimit) {
4550 SettingsMap new_settings;
4551 new_settings[SETTINGS_MAX_CONCURRENT_STREAMS] =
4552 SettingsFlagsAndValue(SETTINGS_FLAG_NONE, 2);
4553 scoped_ptr<SpdyFrame> settings_frame(
4554 spdy_util_.ConstructSpdySettings(new_settings));
4555 scoped_ptr<SpdyFrame> pushed(spdy_util_.ConstructSpdyPush(
4556 NULL, 0, 2, 1, "http://www.google.com/a.dat"));
4557 MockRead reads[] = {
4558 CreateMockRead(*settings_frame), CreateMockRead(*pushed, 3),
4559 MockRead(ASYNC, 0, 4),
4560 };
4561
4562 scoped_ptr<SpdyFrame> settings_ack(spdy_util_.ConstructSpdySettingsAck());
4563 scoped_ptr<SpdyFrame> req(
4564 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
4565 MockWrite writes[] = {
4566 CreateMockWrite(*settings_ack, 1), CreateMockWrite(*req, 2),
4567 };
4568
4569 DeterministicSocketData data(
4570 reads, arraysize(reads), writes, arraysize(writes));
4571 MockConnect connect_data(SYNCHRONOUS, OK);
4572 data.set_connect_data(connect_data);
4573 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
4574
4575 CreateDeterministicNetworkSession();
4576
4577 base::WeakPtr<SpdySession> session =
4578 CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
4579
4580 // Read the settings frame.
4581 data.RunFor(1);
4582
4583 GURL url1(kDefaultURL);
4584 base::WeakPtr<SpdyStream> spdy_stream1 = CreateStreamSynchronously(
4585 SPDY_REQUEST_RESPONSE_STREAM, session, url1, LOWEST, BoundNetLog());
4586 ASSERT_TRUE(spdy_stream1.get() != NULL);
4587 EXPECT_EQ(0u, spdy_stream1->stream_id());
4588 test::StreamDelegateDoNothing delegate1(spdy_stream1);
4589 spdy_stream1->SetDelegate(&delegate1);
4590
4591 EXPECT_EQ(0u, session->num_active_streams());
4592 EXPECT_EQ(1u, session->num_created_streams());
4593 EXPECT_EQ(0u, session->num_pushed_streams());
4594 EXPECT_EQ(0u, session->num_active_pushed_streams());
4595
4596 scoped_ptr<SpdyHeaderBlock> headers(
4597 spdy_util_.ConstructGetHeaderBlock(url1.spec()));
4598 spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
4599 EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders());
4600
4601 // Run until 1st stream is activated.
4602 EXPECT_EQ(0u, delegate1.stream_id());
4603 data.RunFor(2);
4604 EXPECT_EQ(1u, delegate1.stream_id());
4605 EXPECT_EQ(1u, session->num_active_streams());
4606 EXPECT_EQ(0u, session->num_created_streams());
4607 EXPECT_EQ(0u, session->num_pushed_streams());
4608 EXPECT_EQ(0u, session->num_active_pushed_streams());
4609
4610 // Run until pushed stream is created.
4611 data.RunFor(1);
4612 EXPECT_EQ(2u, session->num_active_streams());
4613 EXPECT_EQ(0u, session->num_created_streams());
4614 EXPECT_EQ(1u, session->num_pushed_streams());
4615 EXPECT_EQ(1u, session->num_active_pushed_streams());
4616
4617 // Second stream should not be stalled, although we have 2 active streams, but
4618 // one of them is push stream and should not be taken into account when we
4619 // create streams on the client.
Johnny 2014/07/07 19:58:50 Nice!
4620 base::WeakPtr<SpdyStream> spdy_stream2 = CreateStreamSynchronously(
4621 SPDY_REQUEST_RESPONSE_STREAM, session, url1, LOWEST, BoundNetLog());
4622 EXPECT_TRUE(spdy_stream2.get() != NULL);
4623 EXPECT_EQ(2u, session->num_active_streams());
4624 EXPECT_EQ(1u, session->num_created_streams());
4625 EXPECT_EQ(1u, session->num_pushed_streams());
4626 EXPECT_EQ(1u, session->num_active_pushed_streams());
4627
4628 // Read EOF.
4629 data.RunFor(1);
4630 }
4631
4632 TEST_P(SpdySessionTest, RejectPushedStreamExceedingConcurrencyLimit) {
4633 scoped_ptr<SpdyFrame> push_a(spdy_util_.ConstructSpdyPush(
4634 NULL, 0, 2, 1, "http://www.google.com/a.dat"));
4635 scoped_ptr<SpdyFrame> push_b(spdy_util_.ConstructSpdyPush(
4636 NULL, 0, 4, 1, "http://www.google.com/b.dat"));
4637 MockRead reads[] = {
4638 CreateMockRead(*push_a, 1), CreateMockRead(*push_b, 2),
4639 MockRead(ASYNC, 0, 4),
4640 };
4641
4642 scoped_ptr<SpdyFrame> req(
4643 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
4644 scoped_ptr<SpdyFrame> rst(
4645 spdy_util_.ConstructSpdyRstStream(4, RST_STREAM_REFUSED_STREAM));
4646 MockWrite writes[] = {
4647 CreateMockWrite(*req, 0), CreateMockWrite(*rst, 3),
4648 };
4649
4650 DeterministicSocketData data(
4651 reads, arraysize(reads), writes, arraysize(writes));
4652 MockConnect connect_data(SYNCHRONOUS, OK);
4653 data.set_connect_data(connect_data);
4654 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
4655
4656 CreateDeterministicNetworkSession();
4657
4658 base::WeakPtr<SpdySession> session =
4659 CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
4660 session->set_max_concurrent_pushed_streams(1);
4661
4662 GURL url1(kDefaultURL);
4663 base::WeakPtr<SpdyStream> spdy_stream1 = CreateStreamSynchronously(
4664 SPDY_REQUEST_RESPONSE_STREAM, session, url1, LOWEST, BoundNetLog());
4665 ASSERT_TRUE(spdy_stream1.get() != NULL);
4666 EXPECT_EQ(0u, spdy_stream1->stream_id());
4667 test::StreamDelegateDoNothing delegate1(spdy_stream1);
4668 spdy_stream1->SetDelegate(&delegate1);
4669
4670 EXPECT_EQ(0u, session->num_active_streams());
4671 EXPECT_EQ(1u, session->num_created_streams());
4672 EXPECT_EQ(0u, session->num_pushed_streams());
4673 EXPECT_EQ(0u, session->num_active_pushed_streams());
4674
4675 scoped_ptr<SpdyHeaderBlock> headers(
4676 spdy_util_.ConstructGetHeaderBlock(url1.spec()));
4677 spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
4678 EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders());
4679
4680 // Run until 1st stream is activated.
4681 EXPECT_EQ(0u, delegate1.stream_id());
4682 data.RunFor(1);
4683 EXPECT_EQ(1u, delegate1.stream_id());
4684 EXPECT_EQ(1u, session->num_active_streams());
4685 EXPECT_EQ(0u, session->num_created_streams());
4686 EXPECT_EQ(0u, session->num_pushed_streams());
4687 EXPECT_EQ(0u, session->num_active_pushed_streams());
4688
4689 // Run until pushed stream is created.
4690 data.RunFor(1);
4691 EXPECT_EQ(2u, session->num_active_streams());
4692 EXPECT_EQ(0u, session->num_created_streams());
4693 EXPECT_EQ(1u, session->num_pushed_streams());
4694 EXPECT_EQ(1u, session->num_active_pushed_streams());
4695
4696 // Reset incoming pushed stream.
4697 data.RunFor(2);
4698 EXPECT_EQ(2u, session->num_active_streams());
4699 EXPECT_EQ(0u, session->num_created_streams());
4700 EXPECT_EQ(1u, session->num_pushed_streams());
4701 EXPECT_EQ(1u, session->num_active_pushed_streams());
4702
4703 // Read EOF.
4704 data.RunFor(1);
4705 }
4706
4707 TEST_P(SpdySessionTest, IgnoreReservedRemoteStreamsCount) {
4708 // Streams in reserved remote state exist only in SPDY4.
4709 if (spdy_util_.spdy_version() < SPDY4)
4710 return;
4711
4712 scoped_ptr<SpdyFrame> push_a(spdy_util_.ConstructSpdyPush(
4713 NULL, 0, 2, 1, "http://www.google.com/a.dat"));
4714 scoped_ptr<SpdyHeaderBlock> push_headers(new SpdyHeaderBlock);
4715 spdy_util_.AddUrlToHeaderBlock("http://www.google.com/b.dat",
4716 push_headers.get());
4717 scoped_ptr<SpdyFrame> push_b(
4718 spdy_util_.ConstructInitialSpdyPushFrame(push_headers.Pass(), 4, 1));
4719 scoped_ptr<SpdyFrame> headers_b(
4720 spdy_util_.ConstructSpdyPushHeaders(4, NULL, 0));
4721 MockRead reads[] = {
4722 CreateMockRead(*push_a, 1), CreateMockRead(*push_b, 2),
4723 CreateMockRead(*headers_b, 3), MockRead(ASYNC, 0, 5),
4724 };
4725
4726 scoped_ptr<SpdyFrame> req(
4727 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
4728 scoped_ptr<SpdyFrame> rst(
4729 spdy_util_.ConstructSpdyRstStream(4, RST_STREAM_REFUSED_STREAM));
4730 MockWrite writes[] = {
4731 CreateMockWrite(*req, 0), CreateMockWrite(*rst, 4),
4732 };
4733
4734 DeterministicSocketData data(
4735 reads, arraysize(reads), writes, arraysize(writes));
4736 MockConnect connect_data(SYNCHRONOUS, OK);
4737 data.set_connect_data(connect_data);
4738 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
4739
4740 CreateDeterministicNetworkSession();
4741
4742 base::WeakPtr<SpdySession> session =
4743 CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
4744 session->set_max_concurrent_pushed_streams(1);
4745
4746 GURL url1(kDefaultURL);
4747 base::WeakPtr<SpdyStream> spdy_stream1 = CreateStreamSynchronously(
4748 SPDY_REQUEST_RESPONSE_STREAM, session, url1, LOWEST, BoundNetLog());
4749 ASSERT_TRUE(spdy_stream1.get() != NULL);
4750 EXPECT_EQ(0u, spdy_stream1->stream_id());
4751 test::StreamDelegateDoNothing delegate1(spdy_stream1);
4752 spdy_stream1->SetDelegate(&delegate1);
4753
4754 EXPECT_EQ(0u, session->num_active_streams());
4755 EXPECT_EQ(1u, session->num_created_streams());
4756 EXPECT_EQ(0u, session->num_pushed_streams());
4757 EXPECT_EQ(0u, session->num_active_pushed_streams());
4758
4759 scoped_ptr<SpdyHeaderBlock> headers(
4760 spdy_util_.ConstructGetHeaderBlock(url1.spec()));
4761 spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND);
4762 EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders());
4763
4764 // Run until 1st stream is activated.
4765 EXPECT_EQ(0u, delegate1.stream_id());
4766 data.RunFor(1);
4767 EXPECT_EQ(1u, delegate1.stream_id());
4768 EXPECT_EQ(1u, session->num_active_streams());
4769 EXPECT_EQ(0u, session->num_created_streams());
4770 EXPECT_EQ(0u, session->num_pushed_streams());
4771 EXPECT_EQ(0u, session->num_active_pushed_streams());
4772
4773 // Run until pushed stream is created.
4774 data.RunFor(1);
4775 EXPECT_EQ(2u, session->num_active_streams());
4776 EXPECT_EQ(0u, session->num_created_streams());
4777 EXPECT_EQ(1u, session->num_pushed_streams());
4778 EXPECT_EQ(1u, session->num_active_pushed_streams());
4779
4780 // Accept promised stream. It should not count towards pushed stream limit.
4781 data.RunFor(1);
4782 EXPECT_EQ(3u, session->num_active_streams());
4783 EXPECT_EQ(0u, session->num_created_streams());
4784 EXPECT_EQ(2u, session->num_pushed_streams());
4785 EXPECT_EQ(1u, session->num_active_pushed_streams());
4786
4787 // Reset last pushed stream upon headers reception as it is going to be 2nd,
4788 // while we accept only one.
4789 data.RunFor(2);
4790 EXPECT_EQ(2u, session->num_active_streams());
4791 EXPECT_EQ(0u, session->num_created_streams());
4792 EXPECT_EQ(1u, session->num_pushed_streams());
4793 EXPECT_EQ(1u, session->num_active_pushed_streams());
4794
4795 // Read EOF.
4796 data.RunFor(1);
4797 }
4798
4547 TEST(MapFramerErrorToProtocolError, MapsValues) { 4799 TEST(MapFramerErrorToProtocolError, MapsValues) {
4548 CHECK_EQ( 4800 CHECK_EQ(
4549 SPDY_ERROR_INVALID_CONTROL_FRAME, 4801 SPDY_ERROR_INVALID_CONTROL_FRAME,
4550 MapFramerErrorToProtocolError(SpdyFramer::SPDY_INVALID_CONTROL_FRAME)); 4802 MapFramerErrorToProtocolError(SpdyFramer::SPDY_INVALID_CONTROL_FRAME));
4551 CHECK_EQ( 4803 CHECK_EQ(
4552 SPDY_ERROR_INVALID_DATA_FRAME_FLAGS, 4804 SPDY_ERROR_INVALID_DATA_FRAME_FLAGS,
4553 MapFramerErrorToProtocolError(SpdyFramer::SPDY_INVALID_DATA_FRAME_FLAGS)); 4805 MapFramerErrorToProtocolError(SpdyFramer::SPDY_INVALID_DATA_FRAME_FLAGS));
4554 CHECK_EQ( 4806 CHECK_EQ(
4555 SPDY_ERROR_GOAWAY_FRAME_CORRUPT, 4807 SPDY_ERROR_GOAWAY_FRAME_CORRUPT,
4556 MapFramerErrorToProtocolError(SpdyFramer::SPDY_GOAWAY_FRAME_CORRUPT)); 4808 MapFramerErrorToProtocolError(SpdyFramer::SPDY_GOAWAY_FRAME_CORRUPT));
(...skipping 30 matching lines...) Expand all
4587 CHECK_EQ(GOAWAY_PROTOCOL_ERROR, 4839 CHECK_EQ(GOAWAY_PROTOCOL_ERROR,
4588 MapNetErrorToGoAwayStatus(ERR_SPDY_PROTOCOL_ERROR)); 4840 MapNetErrorToGoAwayStatus(ERR_SPDY_PROTOCOL_ERROR));
4589 CHECK_EQ(GOAWAY_COMPRESSION_ERROR, 4841 CHECK_EQ(GOAWAY_COMPRESSION_ERROR,
4590 MapNetErrorToGoAwayStatus(ERR_SPDY_COMPRESSION_ERROR)); 4842 MapNetErrorToGoAwayStatus(ERR_SPDY_COMPRESSION_ERROR));
4591 CHECK_EQ(GOAWAY_FRAME_SIZE_ERROR, 4843 CHECK_EQ(GOAWAY_FRAME_SIZE_ERROR,
4592 MapNetErrorToGoAwayStatus(ERR_SPDY_FRAME_SIZE_ERROR)); 4844 MapNetErrorToGoAwayStatus(ERR_SPDY_FRAME_SIZE_ERROR));
4593 CHECK_EQ(GOAWAY_PROTOCOL_ERROR, MapNetErrorToGoAwayStatus(ERR_UNEXPECTED)); 4845 CHECK_EQ(GOAWAY_PROTOCOL_ERROR, MapNetErrorToGoAwayStatus(ERR_UNEXPECTED));
4594 } 4846 }
4595 4847
4596 } // namespace net 4848 } // namespace net
OLDNEW
« net/spdy/spdy_session.h ('K') | « net/spdy/spdy_session.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698