blob: 8543eeb32d4a0db67a60e160e48d58df799912a0 [file] [log] [blame]
[email protected]e13201d82012-12-12 05:00:321// 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.
4
5#include "net/quic/quic_stream_factory.h"
6
[email protected]e13201d82012-12-12 05:00:327#include "base/run_loop.h"
8#include "base/string_util.h"
9#include "net/base/mock_host_resolver.h"
10#include "net/http/http_response_headers.h"
11#include "net/http/http_response_info.h"
12#include "net/http/http_util.h"
13#include "net/quic/quic_http_stream.h"
14#include "net/quic/test_tools/mock_clock.h"
[email protected]9558c5d32012-12-22 00:08:1415#include "net/quic/test_tools/mock_random.h"
[email protected]e13201d82012-12-12 05:00:3216#include "net/quic/test_tools/quic_test_utils.h"
17#include "net/socket/socket_test_util.h"
18#include "testing/gtest/include/gtest/gtest.h"
19
20namespace net {
[email protected]e13201d82012-12-12 05:00:3221namespace test {
22
23class QuicStreamFactoryTest : public ::testing::Test {
24 protected:
25 QuicStreamFactoryTest()
26 : factory_(&host_resolver_, &socket_factory_,
[email protected]9558c5d32012-12-22 00:08:1427 &random_generator_,
[email protected]f1e97e92012-12-16 04:53:2528 new MockClock()),
[email protected]e13201d82012-12-12 05:00:3229 host_port_proxy_pair_(HostPortPair("www.google.com", 443),
30 ProxyServer::Direct()) {
31 }
32
33 scoped_ptr<QuicEncryptedPacket> ConstructChlo() {
34 scoped_ptr<QuicPacket> chlo(ConstructHandshakePacket(0xDEADBEEF, kCHLO));
35 QuicFramer framer(QuicDecrypter::Create(kNULL),
36 QuicEncrypter::Create(kNULL));
37 return scoped_ptr<QuicEncryptedPacket>(framer.EncryptPacket(*chlo));
38 }
39
40 scoped_ptr<QuicEncryptedPacket> ConstructShlo() {
41 scoped_ptr<QuicPacket> shlo(ConstructHandshakePacket(0xDEADBEEF, kSHLO));
42 QuicFramer framer(QuicDecrypter::Create(kNULL),
43 QuicEncrypter::Create(kNULL));
44 return scoped_ptr<QuicEncryptedPacket>(framer.EncryptPacket(*shlo));
45 }
46
47 scoped_ptr<QuicEncryptedPacket> ConstructRstPacket(
48 QuicPacketSequenceNumber num,
49 QuicStreamId stream_id) {
50 QuicPacketHeader header;
51 header.guid = 0xDEADBEEF;
52 header.packet_sequence_number = num;
53 header.flags = PACKET_FLAGS_NONE;
54 header.fec_group = 0;
55
56 QuicRstStreamFrame rst(stream_id, 0, QUIC_NO_ERROR);
57 return scoped_ptr<QuicEncryptedPacket>(
58 ConstructPacket(header, QuicFrame(&rst)));
59 }
60
61 scoped_ptr<QuicEncryptedPacket> ConstructAckPacket(
62 QuicPacketSequenceNumber largest_received,
63 QuicPacketSequenceNumber least_unacked) {
64 QuicPacketHeader header;
65 header.guid = 0xDEADBEEF;
66 header.packet_sequence_number = 2;
67 header.flags = PACKET_FLAGS_NONE;
68 header.fec_group = 0;
69
[email protected]7884ecad2012-12-14 22:55:1570 QuicAckFrame ack(largest_received, least_unacked);
[email protected]e13201d82012-12-12 05:00:3271
[email protected]dda3e9b2012-12-22 21:49:2572 QuicCongestionFeedbackFrame feedback;
73 feedback.type = kTCP;
74 feedback.tcp.accumulated_number_of_lost_packets = 0;
75 feedback.tcp.receive_window = 16000;
76
77 QuicFramer framer(QuicDecrypter::Create(kNULL),
78 QuicEncrypter::Create(kNULL));
79 QuicFrames frames;
80 frames.push_back(QuicFrame(&ack));
81 frames.push_back(QuicFrame(&feedback));
82 scoped_ptr<QuicPacket> packet(
83 framer.ConstructFrameDataPacket(header, frames));
84 return scoped_ptr<QuicEncryptedPacket>(framer.EncryptPacket(*packet));
[email protected]e13201d82012-12-12 05:00:3285 }
86
[email protected]26f3f8e2012-12-13 21:07:1987 // Returns a newly created packet to send congestion feedback data.
88 scoped_ptr<QuicEncryptedPacket> ConstructFeedbackPacket(
89 QuicPacketSequenceNumber sequence_number) {
90 QuicPacketHeader header;
91 header.guid = 0xDEADBEEF;
92 header.packet_sequence_number = sequence_number;
93 header.flags = PACKET_FLAGS_NONE;
94 header.fec_group = 0;
95
96 QuicCongestionFeedbackFrame frame;
97 frame.type = kTCP;
98 frame.tcp.accumulated_number_of_lost_packets = 0;
99 frame.tcp.receive_window = 16000;
100
101 return scoped_ptr<QuicEncryptedPacket>(
102 ConstructPacket(header, QuicFrame(&frame)));
103 }
104
[email protected]e13201d82012-12-12 05:00:32105 scoped_ptr<QuicEncryptedPacket> ConstructPacket(
106 const QuicPacketHeader& header,
107 const QuicFrame& frame) {
108 QuicFramer framer(QuicDecrypter::Create(kNULL),
109 QuicEncrypter::Create(kNULL));
110 QuicFrames frames;
111 frames.push_back(frame);
[email protected]610a7e942012-12-18 00:21:39112 scoped_ptr<QuicPacket> packet(
113 framer.ConstructFrameDataPacket(header, frames));
114 return scoped_ptr<QuicEncryptedPacket>(framer.EncryptPacket(*packet));
[email protected]e13201d82012-12-12 05:00:32115 }
116
117 MockHostResolver host_resolver_;
118 MockClientSocketFactory socket_factory_;
[email protected]9558c5d32012-12-22 00:08:14119 MockRandom random_generator_;
[email protected]e13201d82012-12-12 05:00:32120 QuicStreamFactory factory_;
121 HostPortProxyPair host_port_proxy_pair_;
122 BoundNetLog net_log_;
123 TestCompletionCallback callback_;
[email protected]e13201d82012-12-12 05:00:32124};
125
126TEST_F(QuicStreamFactoryTest, CreateIfSessionExists) {
127 EXPECT_EQ(NULL, factory_.CreateIfSessionExists(host_port_proxy_pair_,
128 net_log_).get());
129}
130
131TEST_F(QuicStreamFactoryTest, Create) {
132 scoped_ptr<QuicEncryptedPacket> chlo(ConstructChlo());
133 scoped_ptr<QuicEncryptedPacket> ack(ConstructAckPacket(1, 1));
[email protected]dda3e9b2012-12-22 21:49:25134 scoped_ptr<QuicEncryptedPacket> rst3(ConstructRstPacket(3, 3));
135 scoped_ptr<QuicEncryptedPacket> rst5(ConstructRstPacket(4, 5));
136 scoped_ptr<QuicEncryptedPacket> rst7(ConstructRstPacket(5, 7));
[email protected]e13201d82012-12-12 05:00:32137 MockWrite writes[] = {
138 MockWrite(SYNCHRONOUS, chlo->data(), chlo->length()),
139 MockWrite(SYNCHRONOUS, ack->data(), ack->length()),
140 MockWrite(SYNCHRONOUS, rst3->data(), rst3->length()),
141 MockWrite(SYNCHRONOUS, rst5->data(), rst5->length()),
142 MockWrite(SYNCHRONOUS, rst7->data(), rst7->length()),
143 };
144 scoped_ptr<QuicEncryptedPacket> shlo(ConstructShlo());
145 scoped_ptr<QuicEncryptedPacket> ack2(ConstructAckPacket(2, 0));
146 MockRead reads[] = {
147 MockRead(SYNCHRONOUS, shlo->data(), shlo->length()),
148 MockRead(SYNCHRONOUS, ack2->data(), ack2->length()),
149 MockRead(ASYNC, OK), // EOF
150 };
151 StaticSocketDataProvider socket_data(reads, arraysize(reads),
152 writes, arraysize(writes));
153 socket_factory_.AddSocketDataProvider(&socket_data);
154
155 QuicStreamRequest request(&factory_);
156 EXPECT_EQ(ERR_IO_PENDING, request.Request(host_port_proxy_pair_, net_log_,
157 callback_.callback()));
158
159 EXPECT_EQ(OK, callback_.WaitForResult());
160 scoped_ptr<QuicHttpStream> stream = request.ReleaseStream();
161
162 // Will reset stream 3.
163 stream = factory_.CreateIfSessionExists(host_port_proxy_pair_, net_log_);
164 EXPECT_TRUE(stream.get());
165
166 QuicStreamRequest request2(&factory_);
167 EXPECT_EQ(OK, request2.Request(host_port_proxy_pair_, net_log_,
168 callback_.callback()));
169 stream = request2.ReleaseStream(); // Will reset stream 5.
170 stream.reset(); // Will reset stream 7.
171
172 EXPECT_TRUE(socket_data.at_read_eof());
173 EXPECT_TRUE(socket_data.at_write_eof());
174}
175
176TEST_F(QuicStreamFactoryTest, CreateError) {
177 StaticSocketDataProvider socket_data(NULL, 0, NULL, 0);
178 socket_factory_.AddSocketDataProvider(&socket_data);
179
180 host_resolver_.rules()->AddSimulatedFailure("www.google.com");
181
182 QuicStreamRequest request(&factory_);
183 EXPECT_EQ(ERR_IO_PENDING, request.Request(host_port_proxy_pair_, net_log_,
184 callback_.callback()));
185
186 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, callback_.WaitForResult());
187
188 EXPECT_TRUE(socket_data.at_read_eof());
189 EXPECT_TRUE(socket_data.at_write_eof());
190}
191
192TEST_F(QuicStreamFactoryTest, CancelCreate) {
193 scoped_ptr<QuicEncryptedPacket> chlo(ConstructChlo());
194 scoped_ptr<QuicEncryptedPacket> ack(ConstructAckPacket(1, 1));
[email protected]dda3e9b2012-12-22 21:49:25195 scoped_ptr<QuicEncryptedPacket> rst3(ConstructRstPacket(3, 3));
[email protected]e13201d82012-12-12 05:00:32196
197 MockWrite writes[] = {
198 MockWrite(SYNCHRONOUS, chlo->data(), chlo->length()),
199 MockWrite(SYNCHRONOUS, ack->data(), ack->length()),
[email protected]e13201d82012-12-12 05:00:32200 MockWrite(SYNCHRONOUS, rst3->data(), rst3->length()),
201 };
202 scoped_ptr<QuicEncryptedPacket> shlo(ConstructShlo());
203 scoped_ptr<QuicEncryptedPacket> ack2(ConstructAckPacket(2, 0));
204 MockRead reads[] = {
205 MockRead(SYNCHRONOUS, shlo->data(), shlo->length()),
206 MockRead(SYNCHRONOUS, ack2->data(), ack2->length()),
207 MockRead(ASYNC, OK), // EOF
208 };
209 StaticSocketDataProvider socket_data(reads, arraysize(reads),
210 writes, arraysize(writes));
211 socket_factory_.AddSocketDataProvider(&socket_data);
212 {
213 QuicStreamRequest request(&factory_);
214 EXPECT_EQ(ERR_IO_PENDING, request.Request(host_port_proxy_pair_, net_log_,
215 callback_.callback()));
216 }
217
218 base::RunLoop run_loop;
219 run_loop.RunUntilIdle();
220
221 scoped_ptr<QuicHttpStream> stream(
222 factory_.CreateIfSessionExists(host_port_proxy_pair_, net_log_));
223 EXPECT_TRUE(stream.get());
224 stream.reset();
225
226 EXPECT_TRUE(socket_data.at_read_eof());
227 EXPECT_TRUE(socket_data.at_write_eof());
228}
229
230} // namespace test
[email protected]e13201d82012-12-12 05:00:32231} // namespace net