OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2013 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/proxy/proxy_resolver_v8_tracing.h" | |
6 | |
7 #include "base/file_util.h" | |
8 #include "base/json/json_writer.h" | |
9 #include "base/message_loop.h" | |
10 #include "base/path_service.h" | |
11 #include "base/stl_util.h" | |
12 #include "base/string_util.h" | |
13 #include "base/stringprintf.h" | |
14 #include "base/synchronization/waitable_event.h" | |
15 #include "base/threading/platform_thread.h" | |
16 #include "base/utf_string_conversions.h" | |
17 #include "base/values.h" | |
18 #include "googleurl/src/gurl.h" | |
19 #include "net/base/mock_host_resolver.h" | |
20 #include "net/base/net_errors.h" | |
21 #include "net/base/net_log.h" | |
22 #include "net/base/net_log_unittest.h" | |
23 #include "net/base/test_completion_callback.h" | |
24 #include "net/proxy/proxy_info.h" | |
25 #include "net/proxy/proxy_resolver_error_observer.h" | |
26 #include "testing/gtest/include/gtest/gtest.h" | |
27 | |
28 namespace net { | |
29 | |
30 namespace { | |
31 | |
32 scoped_refptr<ProxyResolverScriptData> LoadData(const char* filename) { | |
33 FilePath path; | |
34 PathService::Get(base::DIR_SOURCE_ROOT, &path); | |
35 path = path.AppendASCII("net"); | |
36 path = path.AppendASCII("data"); | |
37 path = path.AppendASCII("proxy_resolver_v8_tracing_unittest"); | |
38 path = path.AppendASCII(filename); | |
39 | |
40 // Try to read the file from disk. | |
41 std::string file_contents; | |
42 bool ok = file_util::ReadFileToString(path, &file_contents); | |
43 | |
44 // If we can't load the file from disk, something is misconfigured. | |
45 if (!ok) | |
46 LOG(ERROR) << "Failed to read file: " << path.value(); | |
47 EXPECT_TRUE(ok); | |
mmenke
2013/01/18 19:59:40
Can't you just do:
EXPECT_TRUE(ok) << "Failed to
eroman
2013/01/23 03:26:02
Done.
| |
48 | |
49 // Load the PAC script into the ProxyResolver. | |
50 return ProxyResolverScriptData::FromUTF8(file_contents); | |
51 } | |
52 | |
53 std::string GetParamsJson(const CapturingNetLog::CapturedEntry& entry) { | |
54 if (!entry.params) | |
55 return std::string(); | |
56 std::string json; | |
57 base::JSONWriter::Write(entry.params.get(), &json); | |
58 return json; | |
59 } | |
60 | |
61 void InitResolver(ProxyResolverV8Tracing* resolver, const char* filename) { | |
62 TestCompletionCallback callback; | |
63 int rv = | |
64 resolver->SetPacScript(LoadData(filename), callback.callback()); | |
65 EXPECT_EQ(ERR_IO_PENDING, rv); | |
66 EXPECT_EQ(OK, callback.WaitForResult()); | |
67 } | |
68 | |
69 class MockErrorObserver : public ProxyResolverErrorObserver { | |
70 public: | |
71 virtual void OnPACScriptError(int line_number, | |
72 const string16& error) OVERRIDE { | |
73 output += StringPrintf("Error: line %d: %s\n", line_number, | |
74 UTF16ToASCII(error).c_str()); | |
75 } | |
76 std::string output; | |
77 }; | |
78 | |
79 TEST(ProxyResolverV8TracingTest, Simple) { | |
80 CapturingNetLog log; | |
81 CapturingBoundNetLog req_log; | |
82 MockHostResolver host_resolver; | |
83 MockErrorObserver* error_observer = new MockErrorObserver; | |
84 ProxyResolverV8Tracing resolver(&host_resolver, error_observer, &log); | |
85 | |
86 InitResolver(&resolver, "simple.js"); | |
87 | |
88 TestCompletionCallback callback; | |
89 ProxyInfo proxy_info; | |
90 | |
91 int rv = resolver.GetProxyForURL( | |
92 GURL("http://foo/"), &proxy_info, callback.callback(), | |
93 NULL, req_log.bound()); | |
94 | |
95 EXPECT_EQ(ERR_IO_PENDING, rv); | |
96 EXPECT_EQ(OK, callback.WaitForResult()); | |
97 | |
98 EXPECT_EQ("foo:99", | |
99 proxy_info.proxy_server().ToURI()); | |
100 | |
101 EXPECT_EQ(0u, host_resolver.num_resolve()); | |
102 EXPECT_EQ(0u, host_resolver.num_resolve_from_cache()); | |
103 | |
104 // There were no errors. | |
105 EXPECT_EQ("", error_observer->output); | |
106 | |
107 // Check the NetLogs -- nothing was logged. | |
108 EXPECT_EQ(0u, log.GetSize()); | |
109 EXPECT_EQ(0u, req_log.GetSize()); | |
110 } | |
111 | |
112 TEST(ProxyResolverV8TracingTest, JavascriptError) { | |
113 CapturingNetLog log; | |
114 CapturingBoundNetLog req_log; | |
115 MockHostResolver host_resolver; | |
116 MockErrorObserver* error_observer = new MockErrorObserver; | |
117 ProxyResolverV8Tracing resolver(&host_resolver, error_observer, &log); | |
118 | |
119 InitResolver(&resolver, "error.js"); | |
120 | |
121 TestCompletionCallback callback; | |
122 ProxyInfo proxy_info; | |
123 | |
124 int rv = resolver.GetProxyForURL( | |
125 GURL("http://foo/"), &proxy_info, callback.callback(), NULL, | |
126 req_log.bound()); | |
127 | |
128 EXPECT_EQ(ERR_IO_PENDING, rv); | |
129 EXPECT_EQ(ERR_PAC_SCRIPT_FAILED, callback.WaitForResult()); | |
130 | |
131 EXPECT_EQ(0u, host_resolver.num_resolve()); | |
132 EXPECT_EQ(0u, host_resolver.num_resolve_from_cache()); | |
133 | |
134 EXPECT_EQ("Error: line 3: Uncaught TypeError: Cannot call method 'split' " | |
135 "of null\n", error_observer->output); | |
136 | |
137 // Check the NetLogs -- there was 1 javascript error, and it was output to | |
138 // both the global log, and per-request log. | |
139 CapturingNetLog::CapturedEntryList entries_list[2]; | |
140 log.GetEntries(&entries_list[0]); | |
141 req_log.GetEntries(&entries_list[1]); | |
142 | |
143 for (size_t list_i = 0; list_i < arraysize(entries_list); list_i++) { | |
144 const CapturingNetLog::CapturedEntryList& entries = entries_list[list_i]; | |
145 EXPECT_EQ(1u, entries.size()); | |
146 EXPECT_TRUE( | |
147 LogContainsEvent(entries, 0, NetLog::TYPE_PAC_JAVASCRIPT_ERROR, | |
148 NetLog::PHASE_NONE)); | |
149 EXPECT_EQ("{\"line_number\":3,\"message\":\"Uncaught TypeError: Cannot " | |
150 "call method 'split' of null\"}", GetParamsJson(entries[0])); | |
151 } | |
152 } | |
153 | |
154 TEST(ProxyResolverV8TracingTest, TooManyAlerts) { | |
155 CapturingNetLog log; | |
156 CapturingBoundNetLog req_log; | |
157 MockHostResolver host_resolver; | |
158 MockErrorObserver* error_observer = new MockErrorObserver; | |
159 ProxyResolverV8Tracing resolver(&host_resolver, error_observer, &log); | |
160 | |
161 InitResolver(&resolver, "too_many_alerts.js"); | |
162 | |
163 TestCompletionCallback callback; | |
164 ProxyInfo proxy_info; | |
165 | |
166 int rv = resolver.GetProxyForURL( | |
167 GURL("http://foo/"), | |
168 &proxy_info, | |
169 callback.callback(), | |
170 NULL, | |
171 req_log.bound()); | |
172 | |
173 EXPECT_EQ(ERR_IO_PENDING, rv); | |
174 EXPECT_EQ(OK, callback.WaitForResult()); | |
175 | |
176 EXPECT_EQ("foo:99", | |
177 proxy_info.proxy_server().ToURI()); | |
178 | |
179 EXPECT_EQ(1u, host_resolver.num_resolve()); | |
180 EXPECT_EQ(1u, host_resolver.num_resolve_from_cache()); | |
181 | |
182 // No errors. | |
183 EXPECT_EQ("", error_observer->output); | |
184 | |
185 // Check the NetLogs -- the script generated 50 alerts, which were mirrored | |
186 // to both the global and per-request logs. | |
187 CapturingNetLog::CapturedEntryList entries_list[2]; | |
188 log.GetEntries(&entries_list[0]); | |
189 req_log.GetEntries(&entries_list[1]); | |
190 | |
191 for (size_t list_i = 0; list_i < arraysize(entries_list); list_i++) { | |
192 const CapturingNetLog::CapturedEntryList& entries = entries_list[list_i]; | |
193 EXPECT_EQ(50u, entries.size()); | |
194 for (size_t i = 0; i < 50u; ++i) { | |
195 EXPECT_TRUE( | |
196 LogContainsEvent(entries, i, NetLog::TYPE_PAC_JAVASCRIPT_ALERT, | |
197 NetLog::PHASE_NONE)); | |
198 } | |
199 } | |
200 } | |
201 | |
202 // This test runs a PAC script that issues a sequence of DNS resolves. The test | |
203 // verifies the final result, and that the underlying DNS resolver received | |
204 // the correct set of queries. | |
205 TEST(ProxyResolverV8TracingTest, Dns) { | |
206 CapturingNetLog log; | |
207 CapturingBoundNetLog req_log; | |
208 MockHostResolver host_resolver; | |
209 MockErrorObserver* error_observer = new MockErrorObserver; | |
210 ProxyResolverV8Tracing resolver(&host_resolver, error_observer, &log); | |
211 | |
212 host_resolver.rules()->AddRule("host1", "166.155.144.11"); | |
213 host_resolver.rules()->AddSimulatedFailure("host2"); | |
214 host_resolver.rules()->AddRule("host3", "166.155.144.33"); | |
215 host_resolver.rules()->AddRule("host4", "166.155.144.44"); | |
216 host_resolver.rules()->AddRule("host5", "166.155.144.55"); | |
217 host_resolver.rules()->AddRule("*", "122.133.144.155"); | |
218 | |
219 InitResolver(&resolver, "dns.js"); | |
220 | |
221 TestCompletionCallback callback; | |
222 ProxyInfo proxy_info; | |
223 | |
224 int rv = resolver.GetProxyForURL( | |
225 GURL("http://foo/"), | |
226 &proxy_info, | |
227 callback.callback(), | |
228 NULL, | |
229 req_log.bound()); | |
230 | |
231 EXPECT_EQ(ERR_IO_PENDING, rv); | |
232 EXPECT_EQ(OK, callback.WaitForResult()); | |
233 | |
234 // The test does 11 DNS resolution, however only 5 of them are unique. | |
235 EXPECT_EQ(5u, host_resolver.num_resolve()); | |
236 EXPECT_EQ(5u, host_resolver.num_resolve_from_cache()); | |
237 | |
238 const char* kExpectedResult = | |
239 "122.133.144.155-" // myIpAddress() | |
240 "null-" // dnsResolve('') | |
241 "166.155.144.11-" // dnsResolve('host1') | |
242 "null-" // dnsResolve('host2') | |
243 "166.155.144.33-" // dnsResolve('host3') | |
244 "122.133.144.155-" // myIpAddress() | |
245 "166.155.144.33-" // dnsResolve('host3') | |
246 "166.155.144.11-" // dnsResolve('host1') | |
247 "122.133.144.155-" // myIpAddress() | |
248 "null-" // dnsResolve('host2') | |
249 "166.155.144.44" // dnsResolve('host4') | |
250 ":99"; | |
251 | |
252 EXPECT_EQ(kExpectedResult, proxy_info.proxy_server().ToURI()); | |
253 | |
254 // No errors. | |
255 EXPECT_EQ("", error_observer->output); | |
256 | |
257 // Check the NetLogs -- the script generated 1 alert, mirrored to both | |
258 // the per-request and global logs. | |
259 CapturingNetLog::CapturedEntryList entries_list[2]; | |
260 log.GetEntries(&entries_list[0]); | |
261 req_log.GetEntries(&entries_list[1]); | |
262 | |
263 for (size_t list_i = 0; list_i < arraysize(entries_list); list_i++) { | |
264 const CapturingNetLog::CapturedEntryList& entries = entries_list[list_i]; | |
265 EXPECT_EQ(1u, entries.size()); | |
266 EXPECT_TRUE( | |
267 LogContainsEvent(entries, 0, NetLog::TYPE_PAC_JAVASCRIPT_ALERT, | |
268 NetLog::PHASE_NONE)); | |
269 EXPECT_EQ("{\"message\":\"iteration: 5\"}", GetParamsJson(entries[0])); | |
270 } | |
271 } | |
272 | |
273 // This test runs a weird PAC script that was designed to defeat the DNS tracing | |
274 // optimization. The proxy resolver should detect the inconsistency and | |
275 // fall-back to synchronous mode execution. | |
276 TEST(ProxyResolverV8TracingTest, FallBackToSynchronous1) { | |
277 CapturingNetLog log; | |
278 CapturingBoundNetLog req_log; | |
279 MockHostResolver host_resolver; | |
280 MockErrorObserver* error_observer = new MockErrorObserver; | |
281 ProxyResolverV8Tracing resolver(&host_resolver, error_observer, &log); | |
282 | |
283 host_resolver.rules()->AddRule("host1", "166.155.144.11"); | |
284 host_resolver.rules()->AddRule("crazy4", "133.199.111.4"); | |
285 host_resolver.rules()->AddRule("*", "122.133.144.155"); | |
286 | |
287 InitResolver(&resolver, "global_sideffects1.js"); | |
288 | |
289 TestCompletionCallback callback; | |
290 ProxyInfo proxy_info; | |
291 | |
292 int rv = resolver.GetProxyForURL(GURL("http://foo/"), &proxy_info, | |
293 callback.callback(), NULL, req_log.bound()); | |
294 EXPECT_EQ(ERR_IO_PENDING, rv); | |
295 EXPECT_EQ(OK, callback.WaitForResult()); | |
296 | |
297 // The script itself only does 2 DNS resolves, however it constructs the | |
298 // hostname using a global counter which changes on each invocation. | |
299 EXPECT_EQ(3u, host_resolver.num_resolve()); | |
300 EXPECT_EQ(2u, host_resolver.num_resolve_from_cache()); | |
301 | |
302 EXPECT_EQ("166.155.144.11-133.199.111.4:100", | |
303 proxy_info.proxy_server().ToURI()); | |
304 | |
305 // No errors. | |
306 EXPECT_EQ("", error_observer->output); | |
307 | |
308 // Check the NetLogs -- the script generated 1 alert, mirrored to both | |
309 // the per-request and global logs. | |
310 CapturingNetLog::CapturedEntryList entries_list[2]; | |
311 log.GetEntries(&entries_list[0]); | |
312 req_log.GetEntries(&entries_list[1]); | |
313 | |
314 for (size_t list_i = 0; list_i < arraysize(entries_list); list_i++) { | |
315 const CapturingNetLog::CapturedEntryList& entries = entries_list[list_i]; | |
316 EXPECT_EQ(1u, entries.size()); | |
317 EXPECT_TRUE( | |
318 LogContainsEvent(entries, 0, NetLog::TYPE_PAC_JAVASCRIPT_ALERT, | |
319 NetLog::PHASE_NONE)); | |
320 EXPECT_EQ("{\"message\":\"iteration: 4\"}", GetParamsJson(entries[0])); | |
321 } | |
322 } | |
323 | |
324 // This test runs a weird PAC script that was designed to defeat the DNS tracing | |
325 // optimization. The proxy resolver should detect the inconsistency and | |
326 // fall-back to synchronous mode execution. | |
327 TEST(ProxyResolverV8TracingTest, FallBackToSynchronous2) { | |
328 CapturingNetLog log; | |
329 CapturingBoundNetLog req_log; | |
330 MockHostResolver host_resolver; | |
331 MockErrorObserver* error_observer = new MockErrorObserver; | |
332 ProxyResolverV8Tracing resolver(&host_resolver, error_observer, &log); | |
333 | |
334 host_resolver.rules()->AddRule("host1", "166.155.144.11"); | |
335 host_resolver.rules()->AddRule("host2", "166.155.144.22"); | |
336 host_resolver.rules()->AddRule("host3", "166.155.144.33"); | |
337 host_resolver.rules()->AddRule("host4", "166.155.144.44"); | |
338 host_resolver.rules()->AddRule("*", "122.133.144.155"); | |
339 | |
340 InitResolver(&resolver, "global_sideffects2.js"); | |
341 | |
342 TestCompletionCallback callback; | |
343 ProxyInfo proxy_info; | |
344 | |
345 int rv = resolver.GetProxyForURL(GURL("http://foo/"), &proxy_info, | |
346 callback.callback(), NULL, req_log.bound()); | |
347 EXPECT_EQ(ERR_IO_PENDING, rv); | |
348 EXPECT_EQ(OK, callback.WaitForResult()); | |
349 | |
350 EXPECT_EQ(3u, host_resolver.num_resolve()); | |
351 EXPECT_EQ(2u, host_resolver.num_resolve_from_cache()); | |
352 | |
353 EXPECT_EQ("166.155.144.44:100", | |
354 proxy_info.proxy_server().ToURI()); | |
355 | |
356 // No errors. | |
357 EXPECT_EQ("", error_observer->output); | |
358 | |
359 // Check the NetLogs -- nothing was logged. | |
360 EXPECT_EQ(0u, log.GetSize()); | |
361 EXPECT_EQ(0u, req_log.GetSize()); | |
362 } | |
363 | |
364 // Tests a PAC script which does DNS resolves during initialization. | |
365 TEST(ProxyResolverV8TracingTest, DnsDuringInit) { | |
366 CapturingNetLog log; | |
367 CapturingBoundNetLog req_log; | |
368 MockHostResolver host_resolver; | |
369 MockErrorObserver* error_observer = new MockErrorObserver; | |
370 ProxyResolverV8Tracing resolver(&host_resolver, error_observer, &log); | |
371 | |
372 host_resolver.rules()->AddRule("host1", "91.13.12.1"); | |
373 host_resolver.rules()->AddRule("host2", "91.13.12.2"); | |
374 | |
375 InitResolver(&resolver, "dns_during_init.js"); | |
376 | |
377 // Initialization did 2 dnsResolves. | |
378 EXPECT_EQ(2u, host_resolver.num_resolve()); | |
379 EXPECT_EQ(0u, host_resolver.num_resolve_from_cache()); | |
380 | |
381 host_resolver.rules()->ClearRules(); | |
382 | |
383 host_resolver.rules()->AddRule("host1", "145.88.13.3"); | |
384 host_resolver.rules()->AddRule("host2", "137.89.8.45"); | |
385 | |
386 TestCompletionCallback callback; | |
387 ProxyInfo proxy_info; | |
388 | |
389 int rv = resolver.GetProxyForURL(GURL("http://foo/"), &proxy_info, | |
390 callback.callback(), NULL, req_log.bound()); | |
391 EXPECT_EQ(ERR_IO_PENDING, rv); | |
392 EXPECT_EQ(OK, callback.WaitForResult()); | |
393 | |
394 // Fetched host1 and host2 again, since the ones done during initialization | |
395 // should not have been cached. | |
396 EXPECT_EQ(4u, host_resolver.num_resolve()); | |
397 | |
398 EXPECT_EQ("91.13.12.1-91.13.12.2-145.88.13.3-137.89.8.45:99", | |
399 proxy_info.proxy_server().ToURI()); | |
400 | |
401 // Check the NetLogs -- the script generated 2 alerts during initialization. | |
402 EXPECT_EQ(0u, req_log.GetSize()); | |
403 CapturingNetLog::CapturedEntryList entries; | |
404 log.GetEntries(&entries); | |
405 | |
406 ASSERT_EQ(2u, entries.size()); | |
407 EXPECT_TRUE( | |
408 LogContainsEvent(entries, 0, NetLog::TYPE_PAC_JAVASCRIPT_ALERT, | |
409 NetLog::PHASE_NONE)); | |
410 EXPECT_TRUE( | |
411 LogContainsEvent(entries, 1, NetLog::TYPE_PAC_JAVASCRIPT_ALERT, | |
412 NetLog::PHASE_NONE)); | |
413 | |
414 EXPECT_EQ("{\"message\":\"Watsup\"}", GetParamsJson(entries[0])); | |
415 EXPECT_EQ("{\"message\":\"Watsup2\"}", GetParamsJson(entries[1])); | |
416 } | |
417 | |
418 void CrashCallback(int) { | |
419 // Be extra sure that if the callback ever gets invoked, the test will fail. | |
420 CHECK(false); | |
421 } | |
422 | |
423 // Start some requests, cancel them all, and then destroy the resolver. | |
424 // Note the execution order for this test can vary. Since multiple | |
425 // threads are involved, the cancellation may be received a different | |
426 // times. | |
427 TEST(ProxyResolverV8TracingTest, CancelAll) { | |
428 MockHostResolver host_resolver; | |
429 MockErrorObserver* error_observer = new MockErrorObserver; | |
430 ProxyResolverV8Tracing resolver(&host_resolver, error_observer, NULL); | |
431 | |
432 host_resolver.rules()->AddSimulatedFailure("*"); | |
433 | |
434 InitResolver(&resolver, "dns.js"); | |
435 | |
436 const size_t kNumRequests = 5; | |
437 ProxyInfo proxy_info[kNumRequests]; | |
438 ProxyResolver::RequestHandle request[kNumRequests]; | |
439 | |
440 for (size_t i = 0; i < kNumRequests; ++i) { | |
441 int rv = resolver.GetProxyForURL( | |
442 GURL("http://foo/"), &proxy_info[i], | |
443 base::Bind(&CrashCallback), &request[i], BoundNetLog()); | |
444 EXPECT_EQ(ERR_IO_PENDING, rv); | |
445 } | |
446 | |
447 for (size_t i = 0; i < kNumRequests; ++i) { | |
448 resolver.CancelRequest(request[i]); | |
449 } | |
450 } | |
451 | |
452 // Note the execution order for this test can vary. Since multiple | |
453 // threads are involved, the cancellation may be received a different | |
454 // times. | |
455 TEST(ProxyResolverV8TracingTest, CancelSome) { | |
456 MockHostResolver host_resolver; | |
457 MockErrorObserver* error_observer = new MockErrorObserver; | |
458 ProxyResolverV8Tracing resolver(&host_resolver, error_observer, NULL); | |
459 | |
460 host_resolver.rules()->AddSimulatedFailure("*"); | |
461 | |
462 InitResolver(&resolver, "dns.js"); | |
463 | |
464 ProxyInfo proxy_info1; | |
465 ProxyInfo proxy_info2; | |
466 ProxyResolver::RequestHandle request1; | |
467 ProxyResolver::RequestHandle request2; | |
468 TestCompletionCallback callback; | |
469 | |
470 int rv = resolver.GetProxyForURL( | |
471 GURL("http://foo/"), &proxy_info1, | |
472 base::Bind(&CrashCallback), &request1, BoundNetLog()); | |
473 | |
474 rv = resolver.GetProxyForURL( | |
475 GURL("http://foo/"), &proxy_info2, | |
476 callback.callback(), &request2, BoundNetLog()); | |
477 EXPECT_EQ(ERR_IO_PENDING, rv); | |
478 | |
479 resolver.CancelRequest(request1); | |
480 | |
481 EXPECT_EQ(OK, callback.WaitForResult()); | |
482 } | |
483 | |
484 // This implementation of HostResolver allows blocking until a resolve request | |
485 // has been received. The resolve requests it receives will never be completed. | |
486 class BlockableHostResolver : public HostResolver { | |
487 public: | |
488 BlockableHostResolver() | |
489 : was_request_cancelled_(false) { | |
490 } | |
491 | |
492 virtual int Resolve(const RequestInfo& info, | |
493 AddressList* addresses, | |
494 const CompletionCallback& callback, | |
495 RequestHandle* out_req, | |
496 const BoundNetLog& net_log) OVERRIDE { | |
497 EXPECT_FALSE(callback.is_null()); | |
498 EXPECT_TRUE(out_req); | |
499 *out_req = reinterpret_cast<RequestHandle*>(1); // Magic value. | |
500 | |
501 // Indicate to the caller that a request was received. | |
502 MessageLoop::current()->Quit(); | |
503 | |
504 // Return ERR_IO_PENDING as this request will NEVER be completed. | |
505 // Expectation is for the caller to later cancel the request. | |
506 return ERR_IO_PENDING; | |
507 } | |
508 | |
509 virtual int ResolveFromCache(const RequestInfo& info, | |
510 AddressList* addresses, | |
511 const BoundNetLog& net_log) OVERRIDE { | |
512 return ERR_DNS_CACHE_MISS; | |
513 } | |
514 | |
515 virtual void CancelRequest(RequestHandle req) OVERRIDE { | |
516 EXPECT_EQ(reinterpret_cast<RequestHandle*>(1), req); | |
517 was_request_cancelled_ = true; | |
518 } | |
519 | |
520 // Waits until Resolve() has been called. | |
521 void WaitUntilRequestIsReceived() { | |
522 MessageLoop::current()->Run(); | |
523 } | |
524 | |
525 bool was_request_cancelled() const { | |
526 return was_request_cancelled_; | |
527 } | |
528 | |
529 private: | |
530 bool was_request_cancelled_; | |
531 }; | |
532 | |
533 // This cancellation test exercises a more predictable cancellation codepath -- | |
534 // when the request has an outstanding DNS request in flight. | |
535 TEST(ProxyResolverV8TracingTest, CancelWhileOutstandingNonBlockingDns) { | |
536 BlockableHostResolver host_resolver; | |
537 MockErrorObserver* error_observer = new MockErrorObserver; | |
538 ProxyResolverV8Tracing resolver(&host_resolver, error_observer, NULL); | |
539 | |
540 InitResolver(&resolver, "dns.js"); | |
541 | |
542 ProxyInfo proxy_info; | |
543 ProxyResolver::RequestHandle request; | |
544 | |
545 int rv = resolver.GetProxyForURL( | |
546 GURL("http://foo/"), &proxy_info, | |
547 base::Bind(&CrashCallback), &request, BoundNetLog()); | |
548 | |
549 EXPECT_EQ(ERR_IO_PENDING, rv); | |
550 | |
551 host_resolver.WaitUntilRequestIsReceived(); | |
552 | |
553 resolver.CancelRequest(request); | |
554 | |
555 EXPECT_TRUE(host_resolver.was_request_cancelled()); | |
556 | |
557 // After leaving this scope, the ProxyResolver is destroyed. | |
558 // This should not cause any problems, as the outstanding work | |
559 // should have been cancelled. | |
560 } | |
561 | |
562 TEST(ProxyResolverV8TracingTest, CancelWhileOutstandingBlockingDns) { | |
563 BlockableHostResolver host_resolver; | |
564 MockErrorObserver* error_observer = new MockErrorObserver; | |
565 | |
566 ProxyResolverV8Tracing resolver(&host_resolver, error_observer, NULL); | |
567 | |
568 int rv = | |
569 resolver.SetPacScript(LoadData("dns_during_init.js"), | |
570 base::Bind(&CrashCallback)); | |
571 EXPECT_EQ(ERR_IO_PENDING, rv); | |
572 | |
573 host_resolver.WaitUntilRequestIsReceived(); | |
574 | |
575 resolver.CancelSetPacScript(); | |
576 EXPECT_TRUE(host_resolver.was_request_cancelled()); | |
577 } | |
578 | |
579 } // namespace | |
580 | |
581 } // namespace net | |
OLD | NEW |