blob: 68920a26169b66a87649241a55e2a194cc54ce2e [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
7#include "base/rand_util.h"
8#include "base/run_loop.h"
9#include "base/string_util.h"
10#include "net/base/mock_host_resolver.h"
11#include "net/http/http_response_headers.h"
12#include "net/http/http_response_info.h"
13#include "net/http/http_util.h"
14#include "net/quic/quic_http_stream.h"
15#include "net/quic/test_tools/mock_clock.h"
16#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 {
21
22namespace test {
23
24class QuicStreamFactoryTest : public ::testing::Test {
25 protected:
26 QuicStreamFactoryTest()
27 : factory_(&host_resolver_, &socket_factory_,
28 base::Bind(&QuicStreamFactoryTest::GenerateGuid), &clock_),
29 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
70 QuicAckFrame ack(largest_received, QuicTime(), least_unacked);
[email protected]e13201d82012-12-12 05:00:3271
72 return scoped_ptr<QuicEncryptedPacket>(
73 ConstructPacket(header, QuicFrame(&ack)));
74 }
75
[email protected]26f3f8e2012-12-13 21:07:1976 // Returns a newly created packet to send congestion feedback data.
77 scoped_ptr<QuicEncryptedPacket> ConstructFeedbackPacket(
78 QuicPacketSequenceNumber sequence_number) {
79 QuicPacketHeader header;
80 header.guid = 0xDEADBEEF;
81 header.packet_sequence_number = sequence_number;
82 header.flags = PACKET_FLAGS_NONE;
83 header.fec_group = 0;
84
85 QuicCongestionFeedbackFrame frame;
86 frame.type = kTCP;
87 frame.tcp.accumulated_number_of_lost_packets = 0;
88 frame.tcp.receive_window = 16000;
89
90 return scoped_ptr<QuicEncryptedPacket>(
91 ConstructPacket(header, QuicFrame(&frame)));
92 }
93
[email protected]e13201d82012-12-12 05:00:3294 scoped_ptr<QuicEncryptedPacket> ConstructPacket(
95 const QuicPacketHeader& header,
96 const QuicFrame& frame) {
97 QuicFramer framer(QuicDecrypter::Create(kNULL),
98 QuicEncrypter::Create(kNULL));
99 QuicFrames frames;
100 frames.push_back(frame);
101 QuicPacket* packet;
102 framer.ConstructFrameDataPacket(header, frames, &packet);
103 QuicEncryptedPacket* encrypted = framer.EncryptPacket(*packet);
104 delete packet;
105 return scoped_ptr<QuicEncryptedPacket>(encrypted);
106 }
107
108 MockHostResolver host_resolver_;
109 MockClientSocketFactory socket_factory_;
110 MockClock clock_;
111 QuicStreamFactory factory_;
112 HostPortProxyPair host_port_proxy_pair_;
113 BoundNetLog net_log_;
114 TestCompletionCallback callback_;
115
116 private:
117 static uint64 GenerateGuid() {
118 return 0xDEADBEEF;
119 }
120};
121
122TEST_F(QuicStreamFactoryTest, CreateIfSessionExists) {
123 EXPECT_EQ(NULL, factory_.CreateIfSessionExists(host_port_proxy_pair_,
124 net_log_).get());
125}
126
127TEST_F(QuicStreamFactoryTest, Create) {
128 scoped_ptr<QuicEncryptedPacket> chlo(ConstructChlo());
129 scoped_ptr<QuicEncryptedPacket> ack(ConstructAckPacket(1, 1));
[email protected]26f3f8e2012-12-13 21:07:19130 scoped_ptr<QuicEncryptedPacket> feedback(ConstructFeedbackPacket(3));
131 scoped_ptr<QuicEncryptedPacket> rst3(ConstructRstPacket(4, 3));
132 scoped_ptr<QuicEncryptedPacket> rst5(ConstructRstPacket(5, 5));
133 scoped_ptr<QuicEncryptedPacket> rst7(ConstructRstPacket(6, 7));
[email protected]e13201d82012-12-12 05:00:32134 MockWrite writes[] = {
135 MockWrite(SYNCHRONOUS, chlo->data(), chlo->length()),
136 MockWrite(SYNCHRONOUS, ack->data(), ack->length()),
[email protected]26f3f8e2012-12-13 21:07:19137 MockWrite(SYNCHRONOUS, feedback->data(), feedback->length()),
[email protected]e13201d82012-12-12 05:00:32138 MockWrite(SYNCHRONOUS, rst3->data(), rst3->length()),
139 MockWrite(SYNCHRONOUS, rst5->data(), rst5->length()),
140 MockWrite(SYNCHRONOUS, rst7->data(), rst7->length()),
141 };
142 scoped_ptr<QuicEncryptedPacket> shlo(ConstructShlo());
143 scoped_ptr<QuicEncryptedPacket> ack2(ConstructAckPacket(2, 0));
144 MockRead reads[] = {
145 MockRead(SYNCHRONOUS, shlo->data(), shlo->length()),
146 MockRead(SYNCHRONOUS, ack2->data(), ack2->length()),
147 MockRead(ASYNC, OK), // EOF
148 };
149 StaticSocketDataProvider socket_data(reads, arraysize(reads),
150 writes, arraysize(writes));
151 socket_factory_.AddSocketDataProvider(&socket_data);
152
153 QuicStreamRequest request(&factory_);
154 EXPECT_EQ(ERR_IO_PENDING, request.Request(host_port_proxy_pair_, net_log_,
155 callback_.callback()));
156
157 EXPECT_EQ(OK, callback_.WaitForResult());
158 scoped_ptr<QuicHttpStream> stream = request.ReleaseStream();
159
160 // Will reset stream 3.
161 stream = factory_.CreateIfSessionExists(host_port_proxy_pair_, net_log_);
162 EXPECT_TRUE(stream.get());
163
164 QuicStreamRequest request2(&factory_);
165 EXPECT_EQ(OK, request2.Request(host_port_proxy_pair_, net_log_,
166 callback_.callback()));
167 stream = request2.ReleaseStream(); // Will reset stream 5.
168 stream.reset(); // Will reset stream 7.
169
170 EXPECT_TRUE(socket_data.at_read_eof());
171 EXPECT_TRUE(socket_data.at_write_eof());
172}
173
174TEST_F(QuicStreamFactoryTest, CreateError) {
175 StaticSocketDataProvider socket_data(NULL, 0, NULL, 0);
176 socket_factory_.AddSocketDataProvider(&socket_data);
177
178 host_resolver_.rules()->AddSimulatedFailure("www.google.com");
179
180 QuicStreamRequest request(&factory_);
181 EXPECT_EQ(ERR_IO_PENDING, request.Request(host_port_proxy_pair_, net_log_,
182 callback_.callback()));
183
184 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, callback_.WaitForResult());
185
186 EXPECT_TRUE(socket_data.at_read_eof());
187 EXPECT_TRUE(socket_data.at_write_eof());
188}
189
190TEST_F(QuicStreamFactoryTest, CancelCreate) {
191 scoped_ptr<QuicEncryptedPacket> chlo(ConstructChlo());
192 scoped_ptr<QuicEncryptedPacket> ack(ConstructAckPacket(1, 1));
[email protected]26f3f8e2012-12-13 21:07:19193 scoped_ptr<QuicEncryptedPacket> feedback(ConstructFeedbackPacket(3));
194 scoped_ptr<QuicEncryptedPacket> rst3(ConstructRstPacket(4, 3));
[email protected]e13201d82012-12-12 05:00:32195
196 MockWrite writes[] = {
197 MockWrite(SYNCHRONOUS, chlo->data(), chlo->length()),
198 MockWrite(SYNCHRONOUS, ack->data(), ack->length()),
[email protected]26f3f8e2012-12-13 21:07:19199 MockWrite(SYNCHRONOUS, feedback->data(), feedback->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
231
232} // namespace net