Chromium Code Reviews| 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 |