| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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 "base/waitable_event.h" | 5 #include "base/waitable_event.h" |
| 6 #include "googleurl/src/gurl.h" | 6 #include "googleurl/src/gurl.h" |
| 7 #include "net/base/load_log.h" | 7 #include "net/base/net_log.h" |
| 8 #include "net/base/load_log_unittest.h" | 8 #include "net/base/net_log_unittest.h" |
| 9 #include "net/base/net_errors.h" | 9 #include "net/base/net_errors.h" |
| 10 #include "net/base/test_completion_callback.h" | 10 #include "net/base/test_completion_callback.h" |
| 11 #include "net/proxy/proxy_info.h" | 11 #include "net/proxy/proxy_info.h" |
| 12 #include "net/proxy/single_threaded_proxy_resolver.h" | 12 #include "net/proxy/single_threaded_proxy_resolver.h" |
| 13 #include "testing/gtest/include/gtest/gtest.h" | 13 #include "testing/gtest/include/gtest/gtest.h" |
| 14 | 14 |
| 15 namespace net { | 15 namespace net { |
| 16 namespace { | 16 namespace { |
| 17 | 17 |
| 18 // A synchronous mock ProxyResolver implementation, which can be used in | 18 // A synchronous mock ProxyResolver implementation, which can be used in |
| 19 // conjunction with SingleThreadedProxyResolver. | 19 // conjunction with SingleThreadedProxyResolver. |
| 20 // - returns a single-item proxy list with the query's host. | 20 // - returns a single-item proxy list with the query's host. |
| 21 class MockProxyResolver : public ProxyResolver { | 21 class MockProxyResolver : public ProxyResolver { |
| 22 public: | 22 public: |
| 23 MockProxyResolver() | 23 MockProxyResolver() |
| 24 : ProxyResolver(true /*expects_pac_bytes*/), | 24 : ProxyResolver(true /*expects_pac_bytes*/), |
| 25 wrong_loop_(MessageLoop::current()), | 25 wrong_loop_(MessageLoop::current()), |
| 26 request_count_(0), | 26 request_count_(0), |
| 27 purge_count_(0), | 27 purge_count_(0), |
| 28 resolve_latency_ms_(0) {} | 28 resolve_latency_ms_(0) {} |
| 29 | 29 |
| 30 // ProxyResolver implementation: | 30 // ProxyResolver implementation: |
| 31 virtual int GetProxyForURL(const GURL& query_url, | 31 virtual int GetProxyForURL(const GURL& query_url, |
| 32 ProxyInfo* results, | 32 ProxyInfo* results, |
| 33 CompletionCallback* callback, | 33 CompletionCallback* callback, |
| 34 RequestHandle* request, | 34 RequestHandle* request, |
| 35 LoadLog* load_log) { | 35 const BoundNetLog& net_log) { |
| 36 if (resolve_latency_ms_) | 36 if (resolve_latency_ms_) |
| 37 PlatformThread::Sleep(resolve_latency_ms_); | 37 PlatformThread::Sleep(resolve_latency_ms_); |
| 38 | 38 |
| 39 CheckIsOnWorkerThread(); | 39 CheckIsOnWorkerThread(); |
| 40 | 40 |
| 41 EXPECT_TRUE(callback == NULL); | 41 EXPECT_TRUE(callback == NULL); |
| 42 EXPECT_TRUE(request == NULL); | 42 EXPECT_TRUE(request == NULL); |
| 43 | 43 |
| 44 // Write something into |load_log| (doesn't really have any meaning.) | 44 // Write something into |net_log| (doesn't really have any meaning.) |
| 45 LoadLog::BeginEvent(load_log, LoadLog::TYPE_PROXY_RESOLVER_V8_DNS_RESOLVE); | 45 net_log.BeginEvent(NetLog::TYPE_PROXY_RESOLVER_V8_DNS_RESOLVE); |
| 46 | 46 |
| 47 results->UseNamedProxy(query_url.host()); | 47 results->UseNamedProxy(query_url.host()); |
| 48 | 48 |
| 49 // Return a success code which represents the request's order. | 49 // Return a success code which represents the request's order. |
| 50 return request_count_++; | 50 return request_count_++; |
| 51 } | 51 } |
| 52 | 52 |
| 53 virtual void CancelRequest(RequestHandle request) { | 53 virtual void CancelRequest(RequestHandle request) { |
| 54 NOTREACHED(); | 54 NOTREACHED(); |
| 55 } | 55 } |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 117 } | 117 } |
| 118 | 118 |
| 119 void WaitUntilBlocked() { | 119 void WaitUntilBlocked() { |
| 120 blocked_.Wait(); | 120 blocked_.Wait(); |
| 121 } | 121 } |
| 122 | 122 |
| 123 virtual int GetProxyForURL(const GURL& query_url, | 123 virtual int GetProxyForURL(const GURL& query_url, |
| 124 ProxyInfo* results, | 124 ProxyInfo* results, |
| 125 CompletionCallback* callback, | 125 CompletionCallback* callback, |
| 126 RequestHandle* request, | 126 RequestHandle* request, |
| 127 LoadLog* load_log) { | 127 const BoundNetLog& net_log) { |
| 128 if (should_block_) { | 128 if (should_block_) { |
| 129 blocked_.Signal(); | 129 blocked_.Signal(); |
| 130 unblocked_.Wait(); | 130 unblocked_.Wait(); |
| 131 } | 131 } |
| 132 | 132 |
| 133 return MockProxyResolver::GetProxyForURL( | 133 return MockProxyResolver::GetProxyForURL( |
| 134 query_url, results, callback, request, load_log); | 134 query_url, results, callback, request, net_log); |
| 135 } | 135 } |
| 136 | 136 |
| 137 private: | 137 private: |
| 138 bool should_block_; | 138 bool should_block_; |
| 139 base::WaitableEvent unblocked_; | 139 base::WaitableEvent unblocked_; |
| 140 base::WaitableEvent blocked_; | 140 base::WaitableEvent blocked_; |
| 141 }; | 141 }; |
| 142 | 142 |
| 143 TEST(SingleThreadedProxyResolverTest, Basic) { | 143 TEST(SingleThreadedProxyResolverTest, Basic) { |
| 144 MockProxyResolver* mock = new MockProxyResolver; | 144 MockProxyResolver* mock = new MockProxyResolver; |
| 145 SingleThreadedProxyResolver resolver(mock); | 145 SingleThreadedProxyResolver resolver(mock); |
| 146 | 146 |
| 147 int rv; | 147 int rv; |
| 148 | 148 |
| 149 EXPECT_TRUE(resolver.expects_pac_bytes()); | 149 EXPECT_TRUE(resolver.expects_pac_bytes()); |
| 150 | 150 |
| 151 // Call SetPacScriptByData() -- verify that it reaches the synchronous | 151 // Call SetPacScriptByData() -- verify that it reaches the synchronous |
| 152 // resolver. | 152 // resolver. |
| 153 TestCompletionCallback set_script_callback; | 153 TestCompletionCallback set_script_callback; |
| 154 rv = resolver.SetPacScriptByData("pac script bytes", &set_script_callback); | 154 rv = resolver.SetPacScriptByData("pac script bytes", &set_script_callback); |
| 155 EXPECT_EQ(ERR_IO_PENDING, rv); | 155 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 156 EXPECT_EQ(OK, set_script_callback.WaitForResult()); | 156 EXPECT_EQ(OK, set_script_callback.WaitForResult()); |
| 157 EXPECT_EQ("pac script bytes", mock->last_pac_bytes()); | 157 EXPECT_EQ("pac script bytes", mock->last_pac_bytes()); |
| 158 | 158 |
| 159 // Start request 0. | 159 // Start request 0. |
| 160 TestCompletionCallback callback0; | 160 TestCompletionCallback callback0; |
| 161 scoped_refptr<LoadLog> log0(new LoadLog(LoadLog::kUnbounded)); | 161 CapturingBoundNetLog log0(CapturingNetLog::kUnbounded); |
| 162 ProxyInfo results0; | 162 ProxyInfo results0; |
| 163 rv = resolver.GetProxyForURL( | 163 rv = resolver.GetProxyForURL( |
| 164 GURL("http://request0"), &results0, &callback0, NULL, log0); | 164 GURL("http://request0"), &results0, &callback0, NULL, log0.bound()); |
| 165 EXPECT_EQ(ERR_IO_PENDING, rv); | 165 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 166 | 166 |
| 167 // Wait for request 0 to finish. | 167 // Wait for request 0 to finish. |
| 168 rv = callback0.WaitForResult(); | 168 rv = callback0.WaitForResult(); |
| 169 EXPECT_EQ(0, rv); | 169 EXPECT_EQ(0, rv); |
| 170 EXPECT_EQ("PROXY request0:80", results0.ToPacString()); | 170 EXPECT_EQ("PROXY request0:80", results0.ToPacString()); |
| 171 | 171 |
| 172 // The mock proxy resolver should have written 1 log entry. And | 172 // The mock proxy resolver should have written 1 log entry. And |
| 173 // on completion, this should have been copied into |log0|. | 173 // on completion, this should have been copied into |log0|. |
| 174 EXPECT_EQ(1u, log0->entries().size()); | 174 EXPECT_EQ(1u, log0.entries().size()); |
| 175 | 175 |
| 176 // Start 3 more requests (request1 to request3). | 176 // Start 3 more requests (request1 to request3). |
| 177 | 177 |
| 178 TestCompletionCallback callback1; | 178 TestCompletionCallback callback1; |
| 179 ProxyInfo results1; | 179 ProxyInfo results1; |
| 180 rv = resolver.GetProxyForURL( | 180 rv = resolver.GetProxyForURL( |
| 181 GURL("http://request1"), &results1, &callback1, NULL, NULL); | 181 GURL("http://request1"), &results1, &callback1, NULL, NULL); |
| 182 EXPECT_EQ(ERR_IO_PENDING, rv); | 182 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 183 | 183 |
| 184 TestCompletionCallback callback2; | 184 TestCompletionCallback callback2; |
| (...skipping 29 matching lines...) Expand all Loading... |
| 214 resolver.PurgeMemory(); | 214 resolver.PurgeMemory(); |
| 215 // There is no way to get a callback directly when PurgeMemory() completes, so | 215 // There is no way to get a callback directly when PurgeMemory() completes, so |
| 216 // we queue up a dummy request after the PurgeMemory() call and wait until it | 216 // we queue up a dummy request after the PurgeMemory() call and wait until it |
| 217 // finishes to ensure PurgeMemory() has had a chance to run. | 217 // finishes to ensure PurgeMemory() has had a chance to run. |
| 218 TestCompletionCallback dummy_callback; | 218 TestCompletionCallback dummy_callback; |
| 219 rv = resolver.SetPacScriptByData("dummy", &dummy_callback); | 219 rv = resolver.SetPacScriptByData("dummy", &dummy_callback); |
| 220 EXPECT_EQ(OK, dummy_callback.WaitForResult()); | 220 EXPECT_EQ(OK, dummy_callback.WaitForResult()); |
| 221 EXPECT_EQ(1, mock->purge_count()); | 221 EXPECT_EQ(1, mock->purge_count()); |
| 222 } | 222 } |
| 223 | 223 |
| 224 // Tests that the LoadLog is updated to include the time the request was waiting | 224 // Tests that the NetLog is updated to include the time the request was waiting |
| 225 // to be scheduled to a thread. | 225 // to be scheduled to a thread. |
| 226 TEST(SingleThreadedProxyResolverTest, UpdatesLoadLogWithThreadWait) { | 226 TEST(SingleThreadedProxyResolverTest, UpdatesNetLogWithThreadWait) { |
| 227 BlockableProxyResolver* mock = new BlockableProxyResolver; | 227 BlockableProxyResolver* mock = new BlockableProxyResolver; |
| 228 SingleThreadedProxyResolver resolver(mock); | 228 SingleThreadedProxyResolver resolver(mock); |
| 229 | 229 |
| 230 int rv; | 230 int rv; |
| 231 | 231 |
| 232 // Block the proxy resolver, so no request can complete. | 232 // Block the proxy resolver, so no request can complete. |
| 233 mock->Block(); | 233 mock->Block(); |
| 234 | 234 |
| 235 // Start request 0. | 235 // Start request 0. |
| 236 ProxyResolver::RequestHandle request0; | 236 ProxyResolver::RequestHandle request0; |
| 237 TestCompletionCallback callback0; | 237 TestCompletionCallback callback0; |
| 238 ProxyInfo results0; | 238 ProxyInfo results0; |
| 239 scoped_refptr<LoadLog> log0(new LoadLog(LoadLog::kUnbounded)); | 239 CapturingBoundNetLog log0(CapturingNetLog::kUnbounded); |
| 240 rv = resolver.GetProxyForURL( | 240 rv = resolver.GetProxyForURL( |
| 241 GURL("http://request0"), &results0, &callback0, &request0, log0); | 241 GURL("http://request0"), &results0, &callback0, &request0, log0.bound()); |
| 242 EXPECT_EQ(ERR_IO_PENDING, rv); | 242 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 243 | 243 |
| 244 // Start 2 more requests (request1 and request2). | 244 // Start 2 more requests (request1 and request2). |
| 245 | 245 |
| 246 TestCompletionCallback callback1; | 246 TestCompletionCallback callback1; |
| 247 ProxyInfo results1; | 247 ProxyInfo results1; |
| 248 scoped_refptr<LoadLog> log1(new LoadLog(LoadLog::kUnbounded)); | 248 CapturingBoundNetLog log1(CapturingNetLog::kUnbounded); |
| 249 rv = resolver.GetProxyForURL( | 249 rv = resolver.GetProxyForURL( |
| 250 GURL("http://request1"), &results1, &callback1, NULL, log1); | 250 GURL("http://request1"), &results1, &callback1, NULL, log1.bound()); |
| 251 EXPECT_EQ(ERR_IO_PENDING, rv); | 251 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 252 | 252 |
| 253 ProxyResolver::RequestHandle request2; | 253 ProxyResolver::RequestHandle request2; |
| 254 TestCompletionCallback callback2; | 254 TestCompletionCallback callback2; |
| 255 ProxyInfo results2; | 255 ProxyInfo results2; |
| 256 scoped_refptr<LoadLog> log2(new LoadLog(LoadLog::kUnbounded)); | 256 CapturingBoundNetLog log2(CapturingNetLog::kUnbounded); |
| 257 rv = resolver.GetProxyForURL( | 257 rv = resolver.GetProxyForURL( |
| 258 GURL("http://request2"), &results2, &callback2, &request2, log2); | 258 GURL("http://request2"), &results2, &callback2, &request2, log2.bound()); |
| 259 EXPECT_EQ(ERR_IO_PENDING, rv); | 259 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 260 | 260 |
| 261 // Unblock the worker thread so the requests can continue running. | 261 // Unblock the worker thread so the requests can continue running. |
| 262 mock->WaitUntilBlocked(); | 262 mock->WaitUntilBlocked(); |
| 263 mock->Unblock(); | 263 mock->Unblock(); |
| 264 | 264 |
| 265 // Check that request 0 completed as expected. | 265 // Check that request 0 completed as expected. |
| 266 // The LoadLog only has 1 entry (that came from the mock proxy resolver.) | 266 // The NetLog only has 1 entry (that came from the mock proxy resolver.) |
| 267 EXPECT_EQ(0, callback0.WaitForResult()); | 267 EXPECT_EQ(0, callback0.WaitForResult()); |
| 268 EXPECT_EQ("PROXY request0:80", results0.ToPacString()); | 268 EXPECT_EQ("PROXY request0:80", results0.ToPacString()); |
| 269 ASSERT_EQ(1u, log0->entries().size()); | 269 ASSERT_EQ(1u, log0.entries().size()); |
| 270 | 270 |
| 271 // Check that request 1 completed as expected. | 271 // Check that request 1 completed as expected. |
| 272 EXPECT_EQ(1, callback1.WaitForResult()); | 272 EXPECT_EQ(1, callback1.WaitForResult()); |
| 273 EXPECT_EQ("PROXY request1:80", results1.ToPacString()); | 273 EXPECT_EQ("PROXY request1:80", results1.ToPacString()); |
| 274 ASSERT_EQ(3u, log1->entries().size()); | 274 ASSERT_EQ(3u, log1.entries().size()); |
| 275 EXPECT_TRUE(LogContainsBeginEvent( | 275 EXPECT_TRUE(LogContainsBeginEvent( |
| 276 *log1, 0, LoadLog::TYPE_WAITING_FOR_SINGLE_PROXY_RESOLVER_THREAD)); | 276 log1.entries(), 0, |
| 277 NetLog::TYPE_WAITING_FOR_SINGLE_PROXY_RESOLVER_THREAD)); |
| 277 EXPECT_TRUE(LogContainsEndEvent( | 278 EXPECT_TRUE(LogContainsEndEvent( |
| 278 *log1, 1, LoadLog::TYPE_WAITING_FOR_SINGLE_PROXY_RESOLVER_THREAD)); | 279 log1.entries(), 1, |
| 280 NetLog::TYPE_WAITING_FOR_SINGLE_PROXY_RESOLVER_THREAD)); |
| 279 | 281 |
| 280 // Check that request 2 completed as expected. | 282 // Check that request 2 completed as expected. |
| 281 EXPECT_EQ(2, callback2.WaitForResult()); | 283 EXPECT_EQ(2, callback2.WaitForResult()); |
| 282 EXPECT_EQ("PROXY request2:80", results2.ToPacString()); | 284 EXPECT_EQ("PROXY request2:80", results2.ToPacString()); |
| 283 ASSERT_EQ(3u, log2->entries().size()); | 285 ASSERT_EQ(3u, log2.entries().size()); |
| 284 EXPECT_TRUE(LogContainsBeginEvent( | 286 EXPECT_TRUE(LogContainsBeginEvent( |
| 285 *log2, 0, LoadLog::TYPE_WAITING_FOR_SINGLE_PROXY_RESOLVER_THREAD)); | 287 log2.entries(), 0, |
| 288 NetLog::TYPE_WAITING_FOR_SINGLE_PROXY_RESOLVER_THREAD)); |
| 286 EXPECT_TRUE(LogContainsEndEvent( | 289 EXPECT_TRUE(LogContainsEndEvent( |
| 287 *log2, 1, LoadLog::TYPE_WAITING_FOR_SINGLE_PROXY_RESOLVER_THREAD)); | 290 log2.entries(), 1, |
| 291 NetLog::TYPE_WAITING_FOR_SINGLE_PROXY_RESOLVER_THREAD)); |
| 288 } | 292 } |
| 289 | 293 |
| 290 // Cancel a request which is in progress, and then cancel a request which | 294 // Cancel a request which is in progress, and then cancel a request which |
| 291 // is pending. | 295 // is pending. |
| 292 TEST(SingleThreadedProxyResolverTest, CancelRequest) { | 296 TEST(SingleThreadedProxyResolverTest, CancelRequest) { |
| 293 BlockableProxyResolver* mock = new BlockableProxyResolver; | 297 BlockableProxyResolver* mock = new BlockableProxyResolver; |
| 294 SingleThreadedProxyResolver resolver(mock); | 298 SingleThreadedProxyResolver resolver(mock); |
| 295 | 299 |
| 296 int rv; | 300 int rv; |
| 297 | 301 |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 460 rv = callback1.WaitForResult(); | 464 rv = callback1.WaitForResult(); |
| 461 EXPECT_EQ(1, rv); | 465 EXPECT_EQ(1, rv); |
| 462 EXPECT_EQ("PROXY request1:80", results1.ToPacString()); | 466 EXPECT_EQ("PROXY request1:80", results1.ToPacString()); |
| 463 | 467 |
| 464 // The SetPacScript callback should never have been completed. | 468 // The SetPacScript callback should never have been completed. |
| 465 EXPECT_FALSE(set_pac_script_callback.have_result()); | 469 EXPECT_FALSE(set_pac_script_callback.have_result()); |
| 466 } | 470 } |
| 467 | 471 |
| 468 } // namespace | 472 } // namespace |
| 469 } // namespace net | 473 } // namespace net |
| OLD | NEW |