OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 <vector> | 5 #include <vector> |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
9 #include "base/compiler_specific.h" | 9 #include "base/compiler_specific.h" |
10 #include "base/format_macros.h" | 10 #include "base/format_macros.h" |
(...skipping 20 matching lines...) Expand all Loading... | |
31 #include "net/url_request/url_fetcher_delegate.h" | 31 #include "net/url_request/url_fetcher_delegate.h" |
32 #include "net/url_request/url_request_context.h" | 32 #include "net/url_request/url_request_context.h" |
33 #include "net/url_request/url_request_context_getter.h" | 33 #include "net/url_request/url_request_context_getter.h" |
34 #include "net/url_request/url_request_test_util.h" | 34 #include "net/url_request/url_request_test_util.h" |
35 #include "testing/gtest/include/gtest/gtest.h" | 35 #include "testing/gtest/include/gtest/gtest.h" |
36 | 36 |
37 namespace net { | 37 namespace net { |
38 | 38 |
39 namespace { | 39 namespace { |
40 | 40 |
41 int kMaxExpectedResponseLength = 2048; | |
mef
2014/03/27 15:03:45
const
gunsch
2014/03/27 15:52:39
Done.
| |
42 | |
41 void SetTimedOutAndQuitLoop(const base::WeakPtr<bool> timed_out, | 43 void SetTimedOutAndQuitLoop(const base::WeakPtr<bool> timed_out, |
42 const base::Closure& quit_loop_func) { | 44 const base::Closure& quit_loop_func) { |
43 if (timed_out) { | 45 if (timed_out) { |
44 *timed_out = true; | 46 *timed_out = true; |
45 quit_loop_func.Run(); | 47 quit_loop_func.Run(); |
46 } | 48 } |
47 } | 49 } |
48 | 50 |
49 bool RunLoopWithTimeout(base::RunLoop* run_loop) { | 51 bool RunLoopWithTimeout(base::RunLoop* run_loop) { |
50 bool timed_out = false; | 52 bool timed_out = false; |
(...skipping 28 matching lines...) Expand all Loading... | |
79 return ERR_TIMED_OUT; | 81 return ERR_TIMED_OUT; |
80 return connect_result_; | 82 return connect_result_; |
81 } | 83 } |
82 | 84 |
83 void Send(const std::string& data) { | 85 void Send(const std::string& data) { |
84 write_buffer_ = | 86 write_buffer_ = |
85 new DrainableIOBuffer(new StringIOBuffer(data), data.length()); | 87 new DrainableIOBuffer(new StringIOBuffer(data), data.length()); |
86 Write(); | 88 Write(); |
87 } | 89 } |
88 | 90 |
91 bool Read(std::string* data) { | |
92 base::RunLoop run_loop; | |
93 Read(run_loop.QuitClosure()); | |
94 bool success = RunLoopWithTimeout(&run_loop); | |
95 std::string io_buffer_contents(read_buffer_->data()); | |
96 *data = io_buffer_contents.substr(0, bytes_received_); | |
97 return success; | |
98 } | |
99 | |
89 private: | 100 private: |
90 void OnConnect(const base::Closure& quit_loop, int result) { | 101 void OnConnect(const base::Closure& quit_loop, int result) { |
91 connect_result_ = result; | 102 connect_result_ = result; |
92 quit_loop.Run(); | 103 quit_loop.Run(); |
93 } | 104 } |
94 | 105 |
95 void Write() { | 106 void Write() { |
96 int result = socket_->Write( | 107 int result = socket_->Write( |
97 write_buffer_.get(), | 108 write_buffer_.get(), |
98 write_buffer_->BytesRemaining(), | 109 write_buffer_->BytesRemaining(), |
99 base::Bind(&TestHttpClient::OnWrite, base::Unretained(this))); | 110 base::Bind(&TestHttpClient::OnWrite, base::Unretained(this))); |
100 if (result != ERR_IO_PENDING) | 111 if (result != ERR_IO_PENDING) |
101 OnWrite(result); | 112 OnWrite(result); |
102 } | 113 } |
103 | 114 |
104 void OnWrite(int result) { | 115 void OnWrite(int result) { |
105 ASSERT_GT(result, 0); | 116 ASSERT_GT(result, 0); |
106 write_buffer_->DidConsume(result); | 117 write_buffer_->DidConsume(result); |
107 if (write_buffer_->BytesRemaining()) | 118 if (write_buffer_->BytesRemaining()) |
108 Write(); | 119 Write(); |
109 } | 120 } |
110 | 121 |
122 void Read(const base::Closure& quit_loop) { | |
123 read_buffer_ = new IOBufferWithSize(kMaxExpectedResponseLength); | |
124 int result = socket_->Read(read_buffer_, kMaxExpectedResponseLength, | |
mef
2014/03/27 15:03:45
nit: I believe kMaxExpectedResponseLength goes on
gunsch
2014/03/27 15:52:39
Done.
| |
125 base::Bind(&TestHttpClient::OnRead, | |
126 base::Unretained(this), | |
127 quit_loop)); | |
128 if (result != ERR_IO_PENDING) | |
129 OnRead(quit_loop, result); | |
130 } | |
131 | |
132 void OnRead(const base::Closure& quit_loop, int result) { | |
133 bytes_received_ = result; | |
134 quit_loop.Run(); | |
135 } | |
136 | |
137 base::Closure run_loop_quit_func_; | |
Ryan Sleevi
2014/03/27 20:59:46
You shouldn't need this separate RunLoop helper. Y
gunsch
2014/03/27 23:41:17
Done, thanks for the tip. That's a lot simpler.
| |
138 scoped_refptr<IOBufferWithSize> read_buffer_; | |
111 scoped_refptr<DrainableIOBuffer> write_buffer_; | 139 scoped_refptr<DrainableIOBuffer> write_buffer_; |
112 scoped_ptr<TCPClientSocket> socket_; | 140 scoped_ptr<TCPClientSocket> socket_; |
141 int bytes_received_; | |
113 int connect_result_; | 142 int connect_result_; |
114 }; | 143 }; |
115 | 144 |
116 } // namespace | 145 } // namespace |
117 | 146 |
118 class HttpServerTest : public testing::Test, | 147 class HttpServerTest : public testing::Test, |
119 public HttpServer::Delegate { | 148 public HttpServer::Delegate { |
120 public: | 149 public: |
121 HttpServerTest() : quit_after_request_count_(0) {} | 150 HttpServerTest() : quit_after_request_count_(0) {} |
122 | 151 |
123 virtual void SetUp() OVERRIDE { | 152 virtual void SetUp() OVERRIDE { |
124 TCPListenSocketFactory socket_factory("127.0.0.1", 0); | 153 TCPListenSocketFactory socket_factory("127.0.0.1", 0); |
125 server_ = new HttpServer(socket_factory, this); | 154 server_ = new HttpServer(socket_factory, this); |
126 ASSERT_EQ(OK, server_->GetLocalAddress(&server_address_)); | 155 ASSERT_EQ(OK, server_->GetLocalAddress(&server_address_)); |
127 } | 156 } |
128 | 157 |
129 virtual void OnHttpRequest(int connection_id, | 158 virtual void OnHttpRequest(int connection_id, |
130 const HttpServerRequestInfo& info) OVERRIDE { | 159 const HttpServerRequestInfo& info) OVERRIDE { |
131 requests_.push_back(info); | 160 requests_.push_back(info); |
161 connection_ids_.push_back(connection_id); | |
132 if (requests_.size() == quit_after_request_count_) | 162 if (requests_.size() == quit_after_request_count_) |
133 run_loop_quit_func_.Run(); | 163 run_loop_quit_func_.Run(); |
134 } | 164 } |
135 | 165 |
136 virtual void OnWebSocketRequest(int connection_id, | 166 virtual void OnWebSocketRequest(int connection_id, |
137 const HttpServerRequestInfo& info) OVERRIDE { | 167 const HttpServerRequestInfo& info) OVERRIDE { |
138 NOTREACHED(); | 168 NOTREACHED(); |
139 } | 169 } |
140 | 170 |
141 virtual void OnWebSocketMessage(int connection_id, | 171 virtual void OnWebSocketMessage(int connection_id, |
142 const std::string& data) OVERRIDE { | 172 const std::string& data) OVERRIDE { |
143 NOTREACHED(); | 173 NOTREACHED(); |
144 } | 174 } |
145 | 175 |
146 virtual void OnClose(int connection_id) OVERRIDE {} | 176 virtual void OnClose(int connection_id) OVERRIDE {} |
mef
2014/03/27 15:03:45
Should it remove the |connection_id| from |connect
gunsch
2014/03/27 15:52:39
I lean towards _no_, to keep |requests_| and |conn
| |
147 | 177 |
148 bool RunUntilRequestsReceived(size_t count) { | 178 bool RunUntilRequestsReceived(size_t count) { |
149 quit_after_request_count_ = count; | 179 quit_after_request_count_ = count; |
150 if (requests_.size() == count) | 180 if (requests_.size() == count) |
151 return true; | 181 return true; |
152 | 182 |
153 base::RunLoop run_loop; | 183 base::RunLoop run_loop; |
154 run_loop_quit_func_ = run_loop.QuitClosure(); | 184 run_loop_quit_func_ = run_loop.QuitClosure(); |
155 bool success = RunLoopWithTimeout(&run_loop); | 185 bool success = RunLoopWithTimeout(&run_loop); |
156 run_loop_quit_func_.Reset(); | 186 run_loop_quit_func_.Reset(); |
157 return success; | 187 return success; |
158 } | 188 } |
159 | 189 |
160 protected: | 190 protected: |
161 scoped_refptr<HttpServer> server_; | 191 scoped_refptr<HttpServer> server_; |
162 IPEndPoint server_address_; | 192 IPEndPoint server_address_; |
163 base::Closure run_loop_quit_func_; | 193 base::Closure run_loop_quit_func_; |
164 std::vector<HttpServerRequestInfo> requests_; | 194 std::vector<HttpServerRequestInfo> requests_; |
195 std::vector<int> connection_ids_; | |
165 | 196 |
166 private: | 197 private: |
167 size_t quit_after_request_count_; | 198 size_t quit_after_request_count_; |
168 }; | 199 }; |
169 | 200 |
170 TEST_F(HttpServerTest, Request) { | 201 TEST_F(HttpServerTest, Request) { |
171 TestHttpClient client; | 202 TestHttpClient client; |
172 ASSERT_EQ(OK, client.ConnectAndWait(server_address_)); | 203 ASSERT_EQ(OK, client.ConnectAndWait(server_address_)); |
173 client.Send("GET /test HTTP/1.1\r\n\r\n"); | 204 client.Send("GET /test HTTP/1.1\r\n\r\n"); |
174 ASSERT_TRUE(RunUntilRequestsReceived(1)); | 205 ASSERT_TRUE(RunUntilRequestsReceived(1)); |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
254 &delegate)); | 285 &delegate)); |
255 fetcher->SetRequestContext(request_context_getter.get()); | 286 fetcher->SetRequestContext(request_context_getter.get()); |
256 fetcher->AddExtraRequestHeader( | 287 fetcher->AddExtraRequestHeader( |
257 base::StringPrintf("content-length:%d", 1 << 30)); | 288 base::StringPrintf("content-length:%d", 1 << 30)); |
258 fetcher->Start(); | 289 fetcher->Start(); |
259 | 290 |
260 ASSERT_TRUE(RunLoopWithTimeout(&run_loop)); | 291 ASSERT_TRUE(RunLoopWithTimeout(&run_loop)); |
261 ASSERT_EQ(0u, requests_.size()); | 292 ASSERT_EQ(0u, requests_.size()); |
262 } | 293 } |
263 | 294 |
295 TEST_F(HttpServerTest, Send200) { | |
296 TestHttpClient client; | |
297 ASSERT_EQ(OK, client.ConnectAndWait(server_address_)); | |
298 client.Send("GET /test HTTP/1.1\r\n\r\n"); | |
299 ASSERT_TRUE(RunUntilRequestsReceived(1)); | |
300 server_->Send200(connection_ids_[0], "Response!", "text/plain"); | |
301 | |
302 std::string response; | |
303 ASSERT_TRUE(client.Read(&response)); | |
304 ASSERT_TRUE(StartsWithASCII(response, "HTTP/1.1 200 OK", true)); | |
305 ASSERT_TRUE(response.find("Response!") != std::string::npos); | |
306 } | |
307 | |
308 TEST_F(HttpServerTest, SendRaw) { | |
309 TestHttpClient client; | |
310 ASSERT_EQ(OK, client.ConnectAndWait(server_address_)); | |
311 client.Send("GET /test HTTP/1.1\r\n\r\n"); | |
312 ASSERT_TRUE(RunUntilRequestsReceived(1)); | |
313 server_->SendRaw(connection_ids_[0], "Raw Data "); | |
314 server_->SendRaw(connection_ids_[0], "More Data"); | |
315 server_->SendRaw(connection_ids_[0], "Third Piece of Data"); | |
316 | |
317 std::string response; | |
318 ASSERT_TRUE(client.Read(&response)); | |
mef
2014/03/27 15:03:45
Would it make sense to also test a scenario where
gunsch
2014/03/27 15:52:39
Sure, I extended the MultipleRequestsOnSameConnect
gunsch
2014/03/27 18:40:32
I just went ahead and made this a std::pair. I thi
| |
319 ASSERT_EQ("Raw Data More DataThird Piece of Data", response); | |
320 } | |
321 | |
264 namespace { | 322 namespace { |
265 | 323 |
266 class MockStreamListenSocket : public StreamListenSocket { | 324 class MockStreamListenSocket : public StreamListenSocket { |
267 public: | 325 public: |
268 MockStreamListenSocket(StreamListenSocket::Delegate* delegate) | 326 MockStreamListenSocket(StreamListenSocket::Delegate* delegate) |
269 : StreamListenSocket(kInvalidSocket, delegate) {} | 327 : StreamListenSocket(kInvalidSocket, delegate) {} |
270 | 328 |
271 virtual void Accept() OVERRIDE { NOTREACHED(); } | 329 virtual void Accept() OVERRIDE { NOTREACHED(); } |
272 | 330 |
273 private: | 331 private: |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
311 client.Send("GET /test2 HTTP/1.1\r\n\r\n"); | 369 client.Send("GET /test2 HTTP/1.1\r\n\r\n"); |
312 ASSERT_TRUE(RunUntilRequestsReceived(2)); | 370 ASSERT_TRUE(RunUntilRequestsReceived(2)); |
313 ASSERT_EQ("/test2", requests_[1].path); | 371 ASSERT_EQ("/test2", requests_[1].path); |
314 | 372 |
315 client.Send("GET /test3 HTTP/1.1\r\n\r\n"); | 373 client.Send("GET /test3 HTTP/1.1\r\n\r\n"); |
316 ASSERT_TRUE(RunUntilRequestsReceived(3)); | 374 ASSERT_TRUE(RunUntilRequestsReceived(3)); |
317 ASSERT_EQ("/test3", requests_[2].path); | 375 ASSERT_EQ("/test3", requests_[2].path); |
318 } | 376 } |
319 | 377 |
320 } // namespace net | 378 } // namespace net |
OLD | NEW |