Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(291)

Side by Side Diff: net/proxy/proxy_resolver_v8_tracing_unittest.cc

Issue 11885009: Improve performance of proxy resolver by tracing DNS dependencies. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: whitespace changes Created 7 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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) {
mmenke 2013/01/24 21:06:33 nit: Suggest "LoadScript" or "LoadScriptData", si
eroman 2013/01/25 03:02:01 Done.
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 EXPECT_TRUE(ok) << "Failed to read file: " << path.value();
46
47 // Load the PAC script into the ProxyResolver.
48 return ProxyResolverScriptData::FromUTF8(file_contents);
49 }
50
51 std::string GetParamsJson(const CapturingNetLog::CapturedEntry& entry) {
52 if (!entry.params)
53 return std::string();
54 std::string json;
55 base::JSONWriter::Write(entry.params.get(), &json);
56 return json;
57 }
58
59 void InitResolver(ProxyResolverV8Tracing* resolver, const char* filename) {
60 TestCompletionCallback callback;
61 int rv =
62 resolver->SetPacScript(LoadData(filename), callback.callback());
mmenke 2013/01/24 21:06:33 nit: Looks to me like this will fit on one line,
eroman 2013/01/25 03:02:01 Comes out to 81 chars now that I have renamed Load
63 EXPECT_EQ(ERR_IO_PENDING, rv);
64 EXPECT_EQ(OK, callback.WaitForResult());
65 }
66
67 class MockErrorObserver : public ProxyResolverErrorObserver {
68 public:
69 virtual void OnPACScriptError(int line_number,
70 const string16& error) OVERRIDE {
71 output += StringPrintf("Error: line %d: %s\n", line_number,
72 UTF16ToASCII(error).c_str());
73 }
74 std::string output;
75 };
76
77 TEST(ProxyResolverV8TracingTest, Simple) {
78 CapturingNetLog log;
79 CapturingBoundNetLog req_log;
mmenke 2013/01/24 21:06:33 nit: Google C++ style guide is pretty anti-abbrev
eroman 2013/01/25 03:02:01 Done.
80 MockHostResolver host_resolver;
81 MockErrorObserver* error_observer = new MockErrorObserver;
82 ProxyResolverV8Tracing resolver(&host_resolver, error_observer, &log);
mmenke 2013/01/24 21:06:33 May want to put some of these in a text fixture.
eroman 2013/01/25 03:02:01 I have gone back and forth on that. The problem I
mmenke 2013/01/25 05:03:28 These tests aren't quite as boiler-platey as I ini
83
84 InitResolver(&resolver, "simple.js");
85
86 TestCompletionCallback callback;
87 ProxyInfo proxy_info;
88
89 int rv = resolver.GetProxyForURL(
90 GURL("http://foo/"), &proxy_info, callback.callback(),
91 NULL, req_log.bound());
92
93 EXPECT_EQ(ERR_IO_PENDING, rv);
94 EXPECT_EQ(OK, callback.WaitForResult());
mmenke 2013/01/24 21:06:33 Could also put these in a function to make the tes
eroman 2013/01/25 03:02:01 Unless you feel this is worthwhile, I plan to leav
95
96 EXPECT_EQ("foo:99",
97 proxy_info.proxy_server().ToURI());
mmenke 2013/01/24 21:06:33 nit: Can fit on a single line.
eroman 2013/01/25 03:02:01 Done.
98
99 EXPECT_EQ(0u, host_resolver.num_resolve());
100 EXPECT_EQ(0u, host_resolver.num_resolve_from_cache());
101
102 // There were no errors.
103 EXPECT_EQ("", error_observer->output);
104
105 // Check the NetLogs -- nothing was logged.
106 EXPECT_EQ(0u, log.GetSize());
107 EXPECT_EQ(0u, req_log.GetSize());
108 }
109
110 TEST(ProxyResolverV8TracingTest, JavascriptError) {
mmenke 2013/01/24 21:06:33 Worth testing alert and then an error, in the non-
eroman 2013/01/25 03:02:01 Done -- I modified this existing test rather than
111 CapturingNetLog log;
112 CapturingBoundNetLog req_log;
113 MockHostResolver host_resolver;
114 MockErrorObserver* error_observer = new MockErrorObserver;
115 ProxyResolverV8Tracing resolver(&host_resolver, error_observer, &log);
116
117 InitResolver(&resolver, "error.js");
118
119 TestCompletionCallback callback;
120 ProxyInfo proxy_info;
121
122 int rv = resolver.GetProxyForURL(
123 GURL("http://foo/"), &proxy_info, callback.callback(), NULL,
124 req_log.bound());
125
126 EXPECT_EQ(ERR_IO_PENDING, rv);
127 EXPECT_EQ(ERR_PAC_SCRIPT_FAILED, callback.WaitForResult());
128
129 EXPECT_EQ(0u, host_resolver.num_resolve());
130 EXPECT_EQ(0u, host_resolver.num_resolve_from_cache());
131
132 EXPECT_EQ("Error: line 3: Uncaught TypeError: Cannot call method 'split' "
133 "of null\n", error_observer->output);
134
135 // Check the NetLogs -- there was 1 javascript error, and it was output to
136 // both the global log, and per-request log.
137 CapturingNetLog::CapturedEntryList entries_list[2];
138 log.GetEntries(&entries_list[0]);
139 req_log.GetEntries(&entries_list[1]);
140
141 for (size_t list_i = 0; list_i < arraysize(entries_list); list_i++) {
142 const CapturingNetLog::CapturedEntryList& entries = entries_list[list_i];
143 EXPECT_EQ(1u, entries.size());
144 EXPECT_TRUE(
145 LogContainsEvent(entries, 0, NetLog::TYPE_PAC_JAVASCRIPT_ERROR,
146 NetLog::PHASE_NONE));
147 EXPECT_EQ("{\"line_number\":3,\"message\":\"Uncaught TypeError: Cannot "
148 "call method 'split' of null\"}", GetParamsJson(entries[0]));
149 }
150 }
151
152 TEST(ProxyResolverV8TracingTest, TooManyAlerts) {
mmenke 2013/01/24 21:06:33 Suggest alerts with 0-length bodies, just to be co
eroman 2013/01/25 03:02:01 Done.
153 CapturingNetLog log;
154 CapturingBoundNetLog req_log;
155 MockHostResolver host_resolver;
156 MockErrorObserver* error_observer = new MockErrorObserver;
157 ProxyResolverV8Tracing resolver(&host_resolver, error_observer, &log);
158
159 InitResolver(&resolver, "too_many_alerts.js");
160
161 TestCompletionCallback callback;
162 ProxyInfo proxy_info;
163
164 int rv = resolver.GetProxyForURL(
165 GURL("http://foo/"),
166 &proxy_info,
167 callback.callback(),
168 NULL,
169 req_log.bound());
170
171 EXPECT_EQ(ERR_IO_PENDING, rv);
172 EXPECT_EQ(OK, callback.WaitForResult());
173
174 EXPECT_EQ("foo:99",
175 proxy_info.proxy_server().ToURI());
mmenke 2013/01/24 21:06:33 nit: Can fit on one less line.
eroman 2013/01/25 03:02:01 Done.
176
177 EXPECT_EQ(1u, host_resolver.num_resolve());
178 EXPECT_EQ(1u, host_resolver.num_resolve_from_cache());
179
180 // No errors.
181 EXPECT_EQ("", error_observer->output);
182
183 // Check the NetLogs -- the script generated 50 alerts, which were mirrored
184 // to both the global and per-request logs.
185 CapturingNetLog::CapturedEntryList entries_list[2];
186 log.GetEntries(&entries_list[0]);
187 req_log.GetEntries(&entries_list[1]);
188
189 for (size_t list_i = 0; list_i < arraysize(entries_list); list_i++) {
190 const CapturingNetLog::CapturedEntryList& entries = entries_list[list_i];
191 EXPECT_EQ(50u, entries.size());
192 for (size_t i = 0; i < 50u; ++i) {
193 EXPECT_TRUE(
194 LogContainsEvent(entries, i, NetLog::TYPE_PAC_JAVASCRIPT_ALERT,
195 NetLog::PHASE_NONE));
196 }
197 }
198 }
199
200 // This test runs a PAC script that issues a sequence of DNS resolves. The test
201 // verifies the final result, and that the underlying DNS resolver received
202 // the correct set of queries.
203 TEST(ProxyResolverV8TracingTest, Dns) {
204 CapturingNetLog log;
205 CapturingBoundNetLog req_log;
206 MockHostResolver host_resolver;
207 MockErrorObserver* error_observer = new MockErrorObserver;
208 ProxyResolverV8Tracing resolver(&host_resolver, error_observer, &log);
209
210 host_resolver.rules()->AddRule("host1", "166.155.144.11");
211 host_resolver.rules()->AddSimulatedFailure("host2");
212 host_resolver.rules()->AddRule("host3", "166.155.144.33");
213 host_resolver.rules()->AddRule("host4", "166.155.144.44");
214 host_resolver.rules()->AddRule("host5", "166.155.144.55");
215 host_resolver.rules()->AddRule("*", "122.133.144.155");
216
217 InitResolver(&resolver, "dns.js");
218
219 TestCompletionCallback callback;
220 ProxyInfo proxy_info;
221
222 int rv = resolver.GetProxyForURL(
223 GURL("http://foo/"),
224 &proxy_info,
225 callback.callback(),
226 NULL,
227 req_log.bound());
228
229 EXPECT_EQ(ERR_IO_PENDING, rv);
230 EXPECT_EQ(OK, callback.WaitForResult());
231
232 // The test does 11 DNS resolution, however only 5 of them are unique.
233 EXPECT_EQ(5u, host_resolver.num_resolve());
234 EXPECT_EQ(5u, host_resolver.num_resolve_from_cache());
235
236 const char* kExpectedResult =
237 "122.133.144.155-" // myIpAddress()
238 "null-" // dnsResolve('')
239 "166.155.144.11-" // dnsResolve('host1')
240 "null-" // dnsResolve('host2')
241 "166.155.144.33-" // dnsResolve('host3')
242 "122.133.144.155-" // myIpAddress()
243 "166.155.144.33-" // dnsResolve('host3')
244 "166.155.144.11-" // dnsResolve('host1')
245 "122.133.144.155-" // myIpAddress()
246 "null-" // dnsResolve('host2')
247 "166.155.144.44" // dnsResolve('host4')
248 ":99";
249
250 EXPECT_EQ(kExpectedResult, proxy_info.proxy_server().ToURI());
251
252 // No errors.
253 EXPECT_EQ("", error_observer->output);
254
255 // Check the NetLogs -- the script generated 1 alert, mirrored to both
256 // the per-request and global logs.
257 CapturingNetLog::CapturedEntryList entries_list[2];
258 log.GetEntries(&entries_list[0]);
259 req_log.GetEntries(&entries_list[1]);
260
261 for (size_t list_i = 0; list_i < arraysize(entries_list); list_i++) {
262 const CapturingNetLog::CapturedEntryList& entries = entries_list[list_i];
263 EXPECT_EQ(1u, entries.size());
264 EXPECT_TRUE(
265 LogContainsEvent(entries, 0, NetLog::TYPE_PAC_JAVASCRIPT_ALERT,
266 NetLog::PHASE_NONE));
267 EXPECT_EQ("{\"message\":\"iteration: 5\"}", GetParamsJson(entries[0]));
268 }
269 }
270
271 // This test runs a weird PAC script that was designed to defeat the DNS tracing
272 // optimization. The proxy resolver should detect the inconsistency and
273 // fall-back to synchronous mode execution.
274 TEST(ProxyResolverV8TracingTest, FallBackToSynchronous1) {
275 CapturingNetLog log;
276 CapturingBoundNetLog req_log;
277 MockHostResolver host_resolver;
278 MockErrorObserver* error_observer = new MockErrorObserver;
279 ProxyResolverV8Tracing resolver(&host_resolver, error_observer, &log);
280
281 host_resolver.rules()->AddRule("host1", "166.155.144.11");
282 host_resolver.rules()->AddRule("crazy4", "133.199.111.4");
283 host_resolver.rules()->AddRule("*", "122.133.144.155");
284
285 InitResolver(&resolver, "global_sideffects1.js");
286
287 TestCompletionCallback callback;
288 ProxyInfo proxy_info;
289
290 int rv = resolver.GetProxyForURL(GURL("http://foo/"), &proxy_info,
291 callback.callback(), NULL, req_log.bound());
292 EXPECT_EQ(ERR_IO_PENDING, rv);
293 EXPECT_EQ(OK, callback.WaitForResult());
294
295 // The script itself only does 2 DNS resolves, however it constructs the
mmenke 2013/01/24 21:06:33 nit: "2 DNS resolves per execution"
eroman 2013/01/25 03:02:01 Done.
296 // hostname using a global counter which changes on each invocation.
297 EXPECT_EQ(3u, host_resolver.num_resolve());
298 EXPECT_EQ(2u, host_resolver.num_resolve_from_cache());
299
300 EXPECT_EQ("166.155.144.11-133.199.111.4:100",
301 proxy_info.proxy_server().ToURI());
302
303 // No errors.
304 EXPECT_EQ("", error_observer->output);
305
306 // Check the NetLogs -- the script generated 1 alert, mirrored to both
307 // the per-request and global logs.
308 CapturingNetLog::CapturedEntryList entries_list[2];
309 log.GetEntries(&entries_list[0]);
310 req_log.GetEntries(&entries_list[1]);
311
312 for (size_t list_i = 0; list_i < arraysize(entries_list); list_i++) {
313 const CapturingNetLog::CapturedEntryList& entries = entries_list[list_i];
314 EXPECT_EQ(1u, entries.size());
315 EXPECT_TRUE(
316 LogContainsEvent(entries, 0, NetLog::TYPE_PAC_JAVASCRIPT_ALERT,
317 NetLog::PHASE_NONE));
318 EXPECT_EQ("{\"message\":\"iteration: 4\"}", GetParamsJson(entries[0]));
319 }
320 }
321
322 // This test runs a weird PAC script that was designed to defeat the DNS tracing
323 // optimization. The proxy resolver should detect the inconsistency and
324 // fall-back to synchronous mode execution.
325 TEST(ProxyResolverV8TracingTest, FallBackToSynchronous2) {
326 CapturingNetLog log;
327 CapturingBoundNetLog req_log;
328 MockHostResolver host_resolver;
329 MockErrorObserver* error_observer = new MockErrorObserver;
330 ProxyResolverV8Tracing resolver(&host_resolver, error_observer, &log);
331
332 host_resolver.rules()->AddRule("host1", "166.155.144.11");
333 host_resolver.rules()->AddRule("host2", "166.155.144.22");
334 host_resolver.rules()->AddRule("host3", "166.155.144.33");
335 host_resolver.rules()->AddRule("host4", "166.155.144.44");
336 host_resolver.rules()->AddRule("*", "122.133.144.155");
337
338 InitResolver(&resolver, "global_sideffects2.js");
339
340 TestCompletionCallback callback;
341 ProxyInfo proxy_info;
342
343 int rv = resolver.GetProxyForURL(GURL("http://foo/"), &proxy_info,
344 callback.callback(), NULL, req_log.bound());
345 EXPECT_EQ(ERR_IO_PENDING, rv);
346 EXPECT_EQ(OK, callback.WaitForResult());
347
348 EXPECT_EQ(3u, host_resolver.num_resolve());
349 EXPECT_EQ(2u, host_resolver.num_resolve_from_cache());
350
351 EXPECT_EQ("166.155.144.44:100",
352 proxy_info.proxy_server().ToURI());
mmenke 2013/01/24 21:06:33 nit: Fits on a single line.
eroman 2013/01/25 03:02:01 Done.
353
354 // No errors.
355 EXPECT_EQ("", error_observer->output);
356
357 // Check the NetLogs -- nothing was logged.
358 EXPECT_EQ(0u, log.GetSize());
359 EXPECT_EQ(0u, req_log.GetSize());
360 }
361
362 // Tests a PAC script which does DNS resolves during initialization.
363 TEST(ProxyResolverV8TracingTest, DnsDuringInit) {
364 CapturingNetLog log;
365 CapturingBoundNetLog req_log;
366 MockHostResolver host_resolver;
367 MockErrorObserver* error_observer = new MockErrorObserver;
368 ProxyResolverV8Tracing resolver(&host_resolver, error_observer, &log);
369
370 host_resolver.rules()->AddRule("host1", "91.13.12.1");
371 host_resolver.rules()->AddRule("host2", "91.13.12.2");
372
373 InitResolver(&resolver, "dns_during_init.js");
374
375 // Initialization did 2 dnsResolves.
376 EXPECT_EQ(2u, host_resolver.num_resolve());
377 EXPECT_EQ(0u, host_resolver.num_resolve_from_cache());
378
379 host_resolver.rules()->ClearRules();
380
381 host_resolver.rules()->AddRule("host1", "145.88.13.3");
382 host_resolver.rules()->AddRule("host2", "137.89.8.45");
383
384 TestCompletionCallback callback;
385 ProxyInfo proxy_info;
386
387 int rv = resolver.GetProxyForURL(GURL("http://foo/"), &proxy_info,
388 callback.callback(), NULL, req_log.bound());
389 EXPECT_EQ(ERR_IO_PENDING, rv);
390 EXPECT_EQ(OK, callback.WaitForResult());
391
392 // Fetched host1 and host2 again, since the ones done during initialization
393 // should not have been cached.
394 EXPECT_EQ(4u, host_resolver.num_resolve());
395
396 EXPECT_EQ("91.13.12.1-91.13.12.2-145.88.13.3-137.89.8.45:99",
397 proxy_info.proxy_server().ToURI());
398
399 // Check the NetLogs -- the script generated 2 alerts during initialization.
400 EXPECT_EQ(0u, req_log.GetSize());
401 CapturingNetLog::CapturedEntryList entries;
402 log.GetEntries(&entries);
403
404 ASSERT_EQ(2u, entries.size());
405 EXPECT_TRUE(
406 LogContainsEvent(entries, 0, NetLog::TYPE_PAC_JAVASCRIPT_ALERT,
407 NetLog::PHASE_NONE));
408 EXPECT_TRUE(
409 LogContainsEvent(entries, 1, NetLog::TYPE_PAC_JAVASCRIPT_ALERT,
410 NetLog::PHASE_NONE));
411
412 EXPECT_EQ("{\"message\":\"Watsup\"}", GetParamsJson(entries[0]));
413 EXPECT_EQ("{\"message\":\"Watsup2\"}", GetParamsJson(entries[1]));
414 }
415
416 void CrashCallback(int) {
417 // Be extra sure that if the callback ever gets invoked, the test will fail.
418 CHECK(false);
mmenke 2013/01/24 21:06:33 Can't we just do expect/assert here?
eroman 2013/01/25 03:02:01 Call me paranoid, but I feel more comfortable with
mmenke 2013/01/25 05:03:28 Amusingly, was some grumping over CHECK's in testi
419 }
420
421 // Start some requests, cancel them all, and then destroy the resolver.
422 // Note the execution order for this test can vary. Since multiple
423 // threads are involved, the cancellation may be received a different
424 // times.
425 TEST(ProxyResolverV8TracingTest, CancelAll) {
mmenke 2013/01/24 21:06:33 Suggest a more deterministic cancellation test, wh
mmenke 2013/01/24 21:06:33 Another potential test, looking for clean destruct
eroman 2013/01/25 03:02:01 Let me get back on this one (want to respond to th
mmenke 2013/01/25 05:03:28 That's why I was suggesting another test, rather t
426 MockHostResolver host_resolver;
427 MockErrorObserver* error_observer = new MockErrorObserver;
428 ProxyResolverV8Tracing resolver(&host_resolver, error_observer, NULL);
429
430 host_resolver.rules()->AddSimulatedFailure("*");
431
432 InitResolver(&resolver, "dns.js");
433
434 const size_t kNumRequests = 5;
435 ProxyInfo proxy_info[kNumRequests];
436 ProxyResolver::RequestHandle request[kNumRequests];
437
438 for (size_t i = 0; i < kNumRequests; ++i) {
439 int rv = resolver.GetProxyForURL(
440 GURL("http://foo/"), &proxy_info[i],
441 base::Bind(&CrashCallback), &request[i], BoundNetLog());
442 EXPECT_EQ(ERR_IO_PENDING, rv);
443 }
444
445 for (size_t i = 0; i < kNumRequests; ++i) {
446 resolver.CancelRequest(request[i]);
447 }
mmenke 2013/01/24 21:06:33 Suggest a MessageLoop::RunAllPending(); at the end
eroman 2013/01/25 03:02:01 I suspect that not running the message loop before
mmenke 2013/01/25 05:07:46 I'm not sure about this, either way. If we have q
mmenke 2013/01/29 20:19:08 Did you check if those final posted jobs ever run
eroman 2013/01/29 21:03:21 There are two sets of tasks to consider: (a) Thos
mmenke 2013/01/29 21:10:47 Yea, I meant the ones posted to the origin message
eroman 2013/01/29 21:13:34 Yep, that is exactly what I was planning too :) Wi
448 }
449
450 // Note the execution order for this test can vary. Since multiple
451 // threads are involved, the cancellation may be received a different
452 // times.
453 TEST(ProxyResolverV8TracingTest, CancelSome) {
454 MockHostResolver host_resolver;
455 MockErrorObserver* error_observer = new MockErrorObserver;
456 ProxyResolverV8Tracing resolver(&host_resolver, error_observer, NULL);
457
458 host_resolver.rules()->AddSimulatedFailure("*");
459
460 InitResolver(&resolver, "dns.js");
461
462 ProxyInfo proxy_info1;
463 ProxyInfo proxy_info2;
464 ProxyResolver::RequestHandle request1;
465 ProxyResolver::RequestHandle request2;
466 TestCompletionCallback callback;
467
468 int rv = resolver.GetProxyForURL(
469 GURL("http://foo/"), &proxy_info1,
470 base::Bind(&CrashCallback), &request1, BoundNetLog());
mmenke 2013/01/24 21:06:33 EXPECT_EQ(ERR_IO_PENDING, rv);?
eroman 2013/01/25 03:02:01 Done.
471
472 rv = resolver.GetProxyForURL(
473 GURL("http://foo/"), &proxy_info2,
474 callback.callback(), &request2, BoundNetLog());
475 EXPECT_EQ(ERR_IO_PENDING, rv);
476
477 resolver.CancelRequest(request1);
478
479 EXPECT_EQ(OK, callback.WaitForResult());
480 }
mmenke 2013/01/24 21:06:33 Looks like we never cancel a request that has an o
481
482 // This implementation of HostResolver allows blocking until a resolve request
483 // has been received. The resolve requests it receives will never be completed.
484 class BlockableHostResolver : public HostResolver {
485 public:
486 BlockableHostResolver()
487 : was_request_cancelled_(false) {
488 }
489
490 virtual int Resolve(const RequestInfo& info,
491 AddressList* addresses,
492 const CompletionCallback& callback,
493 RequestHandle* out_req,
494 const BoundNetLog& net_log) OVERRIDE {
495 EXPECT_FALSE(callback.is_null());
496 EXPECT_TRUE(out_req);
497 *out_req = reinterpret_cast<RequestHandle*>(1); // Magic value.
498
499 // Indicate to the caller that a request was received.
500 MessageLoop::current()->Quit();
501
502 // Return ERR_IO_PENDING as this request will NEVER be completed.
503 // Expectation is for the caller to later cancel the request.
504 return ERR_IO_PENDING;
505 }
506
507 virtual int ResolveFromCache(const RequestInfo& info,
508 AddressList* addresses,
509 const BoundNetLog& net_log) OVERRIDE {
510 return ERR_DNS_CACHE_MISS;
511 }
512
513 virtual void CancelRequest(RequestHandle req) OVERRIDE {
514 EXPECT_EQ(reinterpret_cast<RequestHandle*>(1), req);
515 was_request_cancelled_ = true;
516 }
517
518 // Waits until Resolve() has been called.
519 void WaitUntilRequestIsReceived() {
520 MessageLoop::current()->Run();
521 }
522
523 bool was_request_cancelled() const {
524 return was_request_cancelled_;
525 }
526
527 private:
528 bool was_request_cancelled_;
529 };
530
531 // This cancellation test exercises a more predictable cancellation codepath --
532 // when the request has an outstanding DNS request in flight.
533 TEST(ProxyResolverV8TracingTest, CancelWhileOutstandingNonBlockingDns) {
534 BlockableHostResolver host_resolver;
535 MockErrorObserver* error_observer = new MockErrorObserver;
536 ProxyResolverV8Tracing resolver(&host_resolver, error_observer, NULL);
537
538 InitResolver(&resolver, "dns.js");
539
540 ProxyInfo proxy_info;
541 ProxyResolver::RequestHandle request;
542
543 int rv = resolver.GetProxyForURL(
544 GURL("http://foo/"), &proxy_info,
545 base::Bind(&CrashCallback), &request, BoundNetLog());
546
547 EXPECT_EQ(ERR_IO_PENDING, rv);
548
549 host_resolver.WaitUntilRequestIsReceived();
550
551 resolver.CancelRequest(request);
552
553 EXPECT_TRUE(host_resolver.was_request_cancelled());
554
555 // After leaving this scope, the ProxyResolver is destroyed.
556 // This should not cause any problems, as the outstanding work
557 // should have been cancelled.
558 }
559
560 TEST(ProxyResolverV8TracingTest, CancelWhileOutstandingBlockingDns) {
561 BlockableHostResolver host_resolver;
562 MockErrorObserver* error_observer = new MockErrorObserver;
563
564 ProxyResolverV8Tracing resolver(&host_resolver, error_observer, NULL);
565
566 int rv =
567 resolver.SetPacScript(LoadData("dns_during_init.js"),
568 base::Bind(&CrashCallback));
569 EXPECT_EQ(ERR_IO_PENDING, rv);
570
571 host_resolver.WaitUntilRequestIsReceived();
572
573 resolver.CancelSetPacScript();
574 EXPECT_TRUE(host_resolver.was_request_cancelled());
575 }
576
577 } // namespace
578
579 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698