Refactoring: Create per-connection packet writers in QuicDispatcher.
[chromium-blink-merge.git] / net / quic / quic_client_session_test.cc
blob39b2ae5a2c0537b585e480b9d42eeb5691989eae
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
3 // found in the LICENSE file.
5 #include "net/quic/quic_client_session.h"
7 #include <vector>
9 #include "base/base64.h"
10 #include "base/files/file_path.h"
11 #include "base/rand_util.h"
12 #include "net/base/capturing_net_log.h"
13 #include "net/base/test_completion_callback.h"
14 #include "net/base/test_data_directory.h"
15 #include "net/cert/cert_verify_result.h"
16 #include "net/http/transport_security_state.h"
17 #include "net/quic/crypto/aes_128_gcm_12_encrypter.h"
18 #include "net/quic/crypto/crypto_protocol.h"
19 #include "net/quic/crypto/proof_verifier_chromium.h"
20 #include "net/quic/crypto/quic_decrypter.h"
21 #include "net/quic/crypto/quic_encrypter.h"
22 #include "net/quic/crypto/quic_server_info.h"
23 #include "net/quic/test_tools/crypto_test_utils.h"
24 #include "net/quic/test_tools/quic_client_session_peer.h"
25 #include "net/quic/test_tools/quic_test_utils.h"
26 #include "net/quic/test_tools/simple_quic_framer.h"
27 #include "net/socket/socket_test_util.h"
28 #include "net/spdy/spdy_test_utils.h"
29 #include "net/test/cert_test_util.h"
30 #include "net/udp/datagram_client_socket.h"
32 using testing::_;
34 namespace net {
35 namespace test {
36 namespace {
38 const char kServerHostname[] = "www.example.org";
39 const uint16 kServerPort = 80;
41 class QuicClientSessionTest : public ::testing::TestWithParam<QuicVersion> {
42 protected:
43 QuicClientSessionTest()
44 : connection_(
45 new PacketSavingConnection(false, SupportedVersions(GetParam()))),
46 session_(connection_, GetSocket().Pass(), NULL, NULL,
47 &transport_security_state_,
48 make_scoped_ptr((QuicServerInfo*)NULL),
49 QuicServerId(kServerHostname, kServerPort, false,
50 PRIVACY_MODE_DISABLED),
51 DefaultQuicConfig(), &crypto_config_,
52 base::MessageLoop::current()->message_loop_proxy().get(),
53 &net_log_) {
54 session_.InitializeSession();
55 session_.config()->SetDefaults();
56 crypto_config_.SetDefaults();
59 virtual void TearDown() OVERRIDE {
60 session_.CloseSessionOnError(ERR_ABORTED);
63 scoped_ptr<DatagramClientSocket> GetSocket() {
64 socket_factory_.AddSocketDataProvider(&socket_data_);
65 return socket_factory_.CreateDatagramClientSocket(
66 DatagramSocket::DEFAULT_BIND, base::Bind(&base::RandInt),
67 &net_log_, NetLog::Source());
70 void CompleteCryptoHandshake() {
71 ASSERT_EQ(ERR_IO_PENDING,
72 session_.CryptoConnect(false, callback_.callback()));
73 CryptoTestUtils::HandshakeWithFakeServer(
74 connection_, session_.GetCryptoStream());
75 ASSERT_EQ(OK, callback_.WaitForResult());
78 PacketSavingConnection* connection_;
79 CapturingNetLog net_log_;
80 MockClientSocketFactory socket_factory_;
81 StaticSocketDataProvider socket_data_;
82 TransportSecurityState transport_security_state_;
83 QuicClientSession session_;
84 MockClock clock_;
85 MockRandom random_;
86 QuicConnectionVisitorInterface* visitor_;
87 TestCompletionCallback callback_;
88 QuicCryptoClientConfig crypto_config_;
91 INSTANTIATE_TEST_CASE_P(Tests, QuicClientSessionTest,
92 ::testing::ValuesIn(QuicSupportedVersions()));
94 TEST_P(QuicClientSessionTest, CryptoConnect) {
95 CompleteCryptoHandshake();
98 TEST_P(QuicClientSessionTest, MaxNumStreams) {
99 CompleteCryptoHandshake();
101 std::vector<QuicReliableClientStream*> streams;
102 for (size_t i = 0; i < kDefaultMaxStreamsPerConnection; i++) {
103 QuicReliableClientStream* stream = session_.CreateOutgoingDataStream();
104 EXPECT_TRUE(stream);
105 streams.push_back(stream);
107 EXPECT_FALSE(session_.CreateOutgoingDataStream());
109 // Close a stream and ensure I can now open a new one.
110 session_.CloseStream(streams[0]->id());
111 EXPECT_TRUE(session_.CreateOutgoingDataStream());
114 TEST_P(QuicClientSessionTest, MaxNumStreamsViaRequest) {
115 CompleteCryptoHandshake();
117 std::vector<QuicReliableClientStream*> streams;
118 for (size_t i = 0; i < kDefaultMaxStreamsPerConnection; i++) {
119 QuicReliableClientStream* stream = session_.CreateOutgoingDataStream();
120 EXPECT_TRUE(stream);
121 streams.push_back(stream);
124 QuicReliableClientStream* stream;
125 QuicClientSession::StreamRequest stream_request;
126 TestCompletionCallback callback;
127 ASSERT_EQ(ERR_IO_PENDING,
128 stream_request.StartRequest(session_.GetWeakPtr(), &stream,
129 callback.callback()));
131 // Close a stream and ensure I can now open a new one.
132 session_.CloseStream(streams[0]->id());
133 ASSERT_TRUE(callback.have_result());
134 EXPECT_EQ(OK, callback.WaitForResult());
135 EXPECT_TRUE(stream != NULL);
138 TEST_P(QuicClientSessionTest, GoAwayReceived) {
139 CompleteCryptoHandshake();
141 // After receiving a GoAway, I should no longer be able to create outgoing
142 // streams.
143 session_.OnGoAway(QuicGoAwayFrame(QUIC_PEER_GOING_AWAY, 1u, "Going away."));
144 EXPECT_EQ(NULL, session_.CreateOutgoingDataStream());
147 TEST_P(QuicClientSessionTest, CanPool) {
148 // Load a cert that is valid for:
149 // www.example.org
150 // mail.example.org
151 // www.example.com
153 ProofVerifyDetailsChromium details;
154 details.cert_verify_result.verified_cert =
155 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
156 ASSERT_TRUE(details.cert_verify_result.verified_cert);
158 session_.OnProofVerifyDetailsAvailable(details);
159 CompleteCryptoHandshake();
162 EXPECT_TRUE(session_.CanPool("www.example.org"));
163 EXPECT_TRUE(session_.CanPool("mail.example.org"));
164 EXPECT_TRUE(session_.CanPool("mail.example.com"));
165 EXPECT_FALSE(session_.CanPool("mail.google.com"));
168 TEST_P(QuicClientSessionTest, ConnectionPooledWithTlsChannelId) {
169 // Load a cert that is valid for:
170 // www.example.org
171 // mail.example.org
172 // www.example.com
174 ProofVerifyDetailsChromium details;
175 details.cert_verify_result.verified_cert =
176 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
177 ASSERT_TRUE(details.cert_verify_result.verified_cert);
179 session_.OnProofVerifyDetailsAvailable(details);
180 CompleteCryptoHandshake();
181 QuicClientSessionPeer::SetChannelIDSent(&session_, true);
183 EXPECT_TRUE(session_.CanPool("www.example.org"));
184 EXPECT_TRUE(session_.CanPool("mail.example.org"));
185 EXPECT_FALSE(session_.CanPool("mail.example.com"));
186 EXPECT_FALSE(session_.CanPool("mail.google.com"));
189 TEST_P(QuicClientSessionTest, ConnectionNotPooledWithDifferentPin) {
190 uint8 primary_pin = 1;
191 uint8 backup_pin = 2;
192 uint8 bad_pin = 3;
193 AddPin(&transport_security_state_, "mail.example.org", primary_pin,
194 backup_pin);
196 ProofVerifyDetailsChromium details;
197 details.cert_verify_result.verified_cert =
198 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
199 details.cert_verify_result.is_issued_by_known_root = true;
200 details.cert_verify_result.public_key_hashes.push_back(
201 GetTestHashValue(bad_pin));
203 ASSERT_TRUE(details.cert_verify_result.verified_cert);
205 session_.OnProofVerifyDetailsAvailable(details);
206 CompleteCryptoHandshake();
207 QuicClientSessionPeer::SetChannelIDSent(&session_, true);
209 EXPECT_FALSE(session_.CanPool("mail.example.org"));
212 TEST_P(QuicClientSessionTest, ConnectionPooledWithMatchingPin) {
213 uint8 primary_pin = 1;
214 uint8 backup_pin = 2;
215 AddPin(&transport_security_state_, "mail.example.org", primary_pin,
216 backup_pin);
218 ProofVerifyDetailsChromium details;
219 details.cert_verify_result.verified_cert =
220 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
221 details.cert_verify_result.is_issued_by_known_root = true;
222 details.cert_verify_result.public_key_hashes.push_back(
223 GetTestHashValue(primary_pin));
225 ASSERT_TRUE(details.cert_verify_result.verified_cert);
227 session_.OnProofVerifyDetailsAvailable(details);
228 CompleteCryptoHandshake();
229 QuicClientSessionPeer::SetChannelIDSent(&session_, true);
231 EXPECT_TRUE(session_.CanPool("mail.example.org"));
234 } // namespace
235 } // namespace test
236 } // namespace net