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/files/file_util.h" | |
8 #include "base/message_loop/message_loop.h" | |
9 #include "base/path_service.h" | |
10 #include "base/stl_util.h" | |
11 #include "base/strings/string_util.h" | |
12 #include "base/strings/stringprintf.h" | |
13 #include "base/strings/utf_string_conversions.h" | |
14 #include "base/synchronization/waitable_event.h" | |
15 #include "base/threading/platform_thread.h" | |
16 #include "base/values.h" | |
17 #include "net/base/net_errors.h" | |
18 #include "net/base/net_log.h" | |
19 #include "net/base/net_log_unittest.h" | |
20 #include "net/base/test_completion_callback.h" | |
21 #include "net/dns/host_cache.h" | |
22 #include "net/dns/mock_host_resolver.h" | |
23 #include "net/proxy/proxy_info.h" | |
24 #include "net/proxy/proxy_resolver_error_observer.h" | |
25 #include "testing/gtest/include/gtest/gtest.h" | |
26 #include "url/gurl.h" | |
27 | |
28 namespace net { | |
29 | |
30 namespace { | |
31 | |
32 class ProxyResolverV8TracingTest : public testing::Test { | |
33 public: | |
34 void TearDown() override { | |
35 // Drain any pending messages, which may be left over from cancellation. | |
36 // This way they get reliably run as part of the current test, rather than | |
37 // spilling into the next test's execution. | |
38 base::MessageLoop::current()->RunUntilIdle(); | |
39 } | |
40 }; | |
41 | |
42 scoped_refptr<ProxyResolverScriptData> LoadScriptData(const char* filename) { | |
43 base::FilePath path; | |
44 PathService::Get(base::DIR_SOURCE_ROOT, &path); | |
45 path = path.AppendASCII("net"); | |
46 path = path.AppendASCII("data"); | |
47 path = path.AppendASCII("proxy_resolver_v8_tracing_unittest"); | |
48 path = path.AppendASCII(filename); | |
49 | |
50 // Try to read the file from disk. | |
51 std::string file_contents; | |
52 bool ok = base::ReadFileToString(path, &file_contents); | |
53 | |
54 // If we can't load the file from disk, something is misconfigured. | |
55 EXPECT_TRUE(ok) << "Failed to read file: " << path.value(); | |
56 | |
57 // Load the PAC script into the ProxyResolver. | |
58 return ProxyResolverScriptData::FromUTF8(file_contents); | |
59 } | |
60 | |
61 void InitResolver(ProxyResolverV8Tracing* resolver, const char* filename) { | |
62 TestCompletionCallback callback; | |
63 int rv = | |
64 resolver->SetPacScript(LoadScriptData(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 MockErrorObserver() : event_(true, false) {} | |
72 | |
73 void OnPACScriptError(int line_number, const base::string16& error) override { | |
74 { | |
75 base::AutoLock l(lock_); | |
76 output += base::StringPrintf("Error: line %d: %s\n", line_number, | |
77 base::UTF16ToASCII(error).c_str()); | |
78 } | |
79 event_.Signal(); | |
80 } | |
81 | |
82 std::string GetOutput() { | |
83 base::AutoLock l(lock_); | |
84 return output; | |
85 } | |
86 | |
87 void WaitForOutput() { | |
88 event_.Wait(); | |
89 } | |
90 | |
91 private: | |
92 base::Lock lock_; | |
93 std::string output; | |
94 | |
95 base::WaitableEvent event_; | |
96 }; | |
97 | |
98 TEST_F(ProxyResolverV8TracingTest, Simple) { | |
99 CapturingNetLog log; | |
100 CapturingBoundNetLog request_log; | |
101 MockCachingHostResolver host_resolver; | |
102 MockErrorObserver* error_observer = new MockErrorObserver; | |
103 ProxyResolverV8Tracing resolver(&host_resolver, error_observer, &log); | |
104 | |
105 InitResolver(&resolver, "simple.js"); | |
106 | |
107 TestCompletionCallback callback; | |
108 ProxyInfo proxy_info; | |
109 | |
110 int rv = resolver.GetProxyForURL( | |
111 GURL("http://foo/"), &proxy_info, callback.callback(), | |
112 NULL, request_log.bound()); | |
113 | |
114 EXPECT_EQ(ERR_IO_PENDING, rv); | |
115 EXPECT_EQ(OK, callback.WaitForResult()); | |
116 | |
117 EXPECT_EQ("foo:99", proxy_info.proxy_server().ToURI()); | |
118 | |
119 EXPECT_EQ(0u, host_resolver.num_resolve()); | |
120 | |
121 // There were no errors. | |
122 EXPECT_EQ("", error_observer->GetOutput()); | |
123 | |
124 // Check the NetLogs -- nothing was logged. | |
125 EXPECT_EQ(0u, log.GetSize()); | |
126 EXPECT_EQ(0u, request_log.GetSize()); | |
127 } | |
128 | |
129 TEST_F(ProxyResolverV8TracingTest, JavascriptError) { | |
130 CapturingNetLog log; | |
131 CapturingBoundNetLog request_log; | |
132 MockCachingHostResolver host_resolver; | |
133 MockErrorObserver* error_observer = new MockErrorObserver; | |
134 ProxyResolverV8Tracing resolver(&host_resolver, error_observer, &log); | |
135 | |
136 InitResolver(&resolver, "error.js"); | |
137 | |
138 TestCompletionCallback callback; | |
139 ProxyInfo proxy_info; | |
140 | |
141 int rv = resolver.GetProxyForURL( | |
142 GURL("http://throw-an-error/"), &proxy_info, callback.callback(), NULL, | |
143 request_log.bound()); | |
144 | |
145 EXPECT_EQ(ERR_IO_PENDING, rv); | |
146 EXPECT_EQ(ERR_PAC_SCRIPT_FAILED, callback.WaitForResult()); | |
147 | |
148 EXPECT_EQ(0u, host_resolver.num_resolve()); | |
149 | |
150 EXPECT_EQ("Error: line 5: Uncaught TypeError: Cannot read property 'split' " | |
151 "of null\n", error_observer->GetOutput()); | |
152 | |
153 // Check the NetLogs -- there was 1 alert and 1 javascript error, and they | |
154 // were output to both the global log, and per-request log. | |
155 CapturingNetLog::CapturedEntryList entries_list[2]; | |
156 log.GetEntries(&entries_list[0]); | |
157 request_log.GetEntries(&entries_list[1]); | |
158 | |
159 for (size_t list_i = 0; list_i < arraysize(entries_list); list_i++) { | |
160 const CapturingNetLog::CapturedEntryList& entries = entries_list[list_i]; | |
161 EXPECT_EQ(2u, entries.size()); | |
162 EXPECT_TRUE( | |
163 LogContainsEvent(entries, 0, NetLog::TYPE_PAC_JAVASCRIPT_ALERT, | |
164 NetLog::PHASE_NONE)); | |
165 EXPECT_TRUE( | |
166 LogContainsEvent(entries, 1, NetLog::TYPE_PAC_JAVASCRIPT_ERROR, | |
167 NetLog::PHASE_NONE)); | |
168 | |
169 EXPECT_EQ("{\"message\":\"Prepare to DIE!\"}", entries[0].GetParamsJson()); | |
170 EXPECT_EQ("{\"line_number\":5,\"message\":\"Uncaught TypeError: Cannot " | |
171 "read property 'split' of null\"}", entries[1].GetParamsJson()); | |
172 } | |
173 } | |
174 | |
175 TEST_F(ProxyResolverV8TracingTest, TooManyAlerts) { | |
176 CapturingNetLog log; | |
177 CapturingBoundNetLog request_log; | |
178 MockCachingHostResolver host_resolver; | |
179 MockErrorObserver* error_observer = new MockErrorObserver; | |
180 ProxyResolverV8Tracing resolver(&host_resolver, error_observer, &log); | |
181 | |
182 InitResolver(&resolver, "too_many_alerts.js"); | |
183 | |
184 TestCompletionCallback callback; | |
185 ProxyInfo proxy_info; | |
186 | |
187 int rv = resolver.GetProxyForURL( | |
188 GURL("http://foo/"), | |
189 &proxy_info, | |
190 callback.callback(), | |
191 NULL, | |
192 request_log.bound()); | |
193 | |
194 EXPECT_EQ(ERR_IO_PENDING, rv); | |
195 EXPECT_EQ(OK, callback.WaitForResult()); | |
196 | |
197 // Iteration1 does a DNS resolve | |
198 // Iteration2 exceeds the alert buffer | |
199 // Iteration3 runs in blocking mode and completes | |
200 EXPECT_EQ("foo:3", proxy_info.proxy_server().ToURI()); | |
201 | |
202 EXPECT_EQ(1u, host_resolver.num_resolve()); | |
203 | |
204 // No errors. | |
205 EXPECT_EQ("", error_observer->GetOutput()); | |
206 | |
207 // Check the NetLogs -- the script generated 50 alerts, which were mirrored | |
208 // to both the global and per-request logs. | |
209 CapturingNetLog::CapturedEntryList entries_list[2]; | |
210 log.GetEntries(&entries_list[0]); | |
211 request_log.GetEntries(&entries_list[1]); | |
212 | |
213 for (size_t list_i = 0; list_i < arraysize(entries_list); list_i++) { | |
214 const CapturingNetLog::CapturedEntryList& entries = entries_list[list_i]; | |
215 EXPECT_EQ(50u, entries.size()); | |
216 for (size_t i = 0; i < entries.size(); ++i) { | |
217 ASSERT_TRUE( | |
218 LogContainsEvent(entries, i, NetLog::TYPE_PAC_JAVASCRIPT_ALERT, | |
219 NetLog::PHASE_NONE)); | |
220 } | |
221 } | |
222 } | |
223 | |
224 // Verify that buffered alerts cannot grow unboundedly, even when the message is | |
225 // empty string. | |
226 TEST_F(ProxyResolverV8TracingTest, TooManyEmptyAlerts) { | |
227 CapturingNetLog log; | |
228 CapturingBoundNetLog request_log; | |
229 MockCachingHostResolver host_resolver; | |
230 MockErrorObserver* error_observer = new MockErrorObserver; | |
231 ProxyResolverV8Tracing resolver(&host_resolver, error_observer, &log); | |
232 | |
233 InitResolver(&resolver, "too_many_empty_alerts.js"); | |
234 | |
235 TestCompletionCallback callback; | |
236 ProxyInfo proxy_info; | |
237 | |
238 int rv = resolver.GetProxyForURL( | |
239 GURL("http://foo/"), | |
240 &proxy_info, | |
241 callback.callback(), | |
242 NULL, | |
243 request_log.bound()); | |
244 | |
245 EXPECT_EQ(ERR_IO_PENDING, rv); | |
246 EXPECT_EQ(OK, callback.WaitForResult()); | |
247 | |
248 EXPECT_EQ("foo:3", proxy_info.proxy_server().ToURI()); | |
249 | |
250 EXPECT_EQ(1u, host_resolver.num_resolve()); | |
251 | |
252 // No errors. | |
253 EXPECT_EQ("", error_observer->GetOutput()); | |
254 | |
255 // Check the NetLogs -- the script generated 50 alerts, which were mirrored | |
256 // to both the global and per-request logs. | |
257 CapturingNetLog::CapturedEntryList entries_list[2]; | |
258 log.GetEntries(&entries_list[0]); | |
259 request_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(1000u, entries.size()); | |
264 for (size_t i = 0; i < entries.size(); ++i) { | |
265 ASSERT_TRUE( | |
266 LogContainsEvent(entries, i, NetLog::TYPE_PAC_JAVASCRIPT_ALERT, | |
267 NetLog::PHASE_NONE)); | |
268 } | |
269 } | |
270 } | |
271 | |
272 // This test runs a PAC script that issues a sequence of DNS resolves. The test | |
273 // verifies the final result, and that the underlying DNS resolver received | |
274 // the correct set of queries. | |
275 TEST_F(ProxyResolverV8TracingTest, Dns) { | |
276 CapturingNetLog log; | |
277 CapturingBoundNetLog request_log; | |
278 MockCachingHostResolver host_resolver; | |
279 MockErrorObserver* error_observer = new MockErrorObserver; | |
280 ProxyResolverV8Tracing resolver(&host_resolver, error_observer, &log); | |
281 | |
282 host_resolver.rules()->AddRuleForAddressFamily( | |
283 "host1", ADDRESS_FAMILY_IPV4, "166.155.144.44"); | |
284 host_resolver.rules() | |
285 ->AddIPLiteralRule("host1", "::1,192.168.1.1", std::string()); | |
286 host_resolver.rules()->AddSimulatedFailure("host2"); | |
287 host_resolver.rules()->AddRule("host3", "166.155.144.33"); | |
288 host_resolver.rules()->AddRule("host5", "166.155.144.55"); | |
289 host_resolver.rules()->AddSimulatedFailure("host6"); | |
290 host_resolver.rules()->AddRuleForAddressFamily( | |
291 "*", ADDRESS_FAMILY_IPV4, "122.133.144.155"); | |
292 host_resolver.rules()->AddRule("*", "133.122.100.200"); | |
293 | |
294 InitResolver(&resolver, "dns.js"); | |
295 | |
296 TestCompletionCallback callback; | |
297 ProxyInfo proxy_info; | |
298 | |
299 int rv = resolver.GetProxyForURL( | |
300 GURL("http://foo/"), | |
301 &proxy_info, | |
302 callback.callback(), | |
303 NULL, | |
304 request_log.bound()); | |
305 | |
306 EXPECT_EQ(ERR_IO_PENDING, rv); | |
307 EXPECT_EQ(OK, callback.WaitForResult()); | |
308 | |
309 // The test does 13 DNS resolution, however only 7 of them are unique. | |
310 EXPECT_EQ(7u, host_resolver.num_resolve()); | |
311 | |
312 const char* kExpectedResult = | |
313 "122.133.144.155-" // myIpAddress() | |
314 "null-" // dnsResolve('') | |
315 "__1_192.168.1.1-" // dnsResolveEx('host1') | |
316 "null-" // dnsResolve('host2') | |
317 "166.155.144.33-" // dnsResolve('host3') | |
318 "122.133.144.155-" // myIpAddress() | |
319 "166.155.144.33-" // dnsResolve('host3') | |
320 "__1_192.168.1.1-" // dnsResolveEx('host1') | |
321 "122.133.144.155-" // myIpAddress() | |
322 "null-" // dnsResolve('host2') | |
323 "-" // dnsResolveEx('host6') | |
324 "133.122.100.200-" // myIpAddressEx() | |
325 "166.155.144.44" // dnsResolve('host1') | |
326 ":99"; | |
327 | |
328 EXPECT_EQ(kExpectedResult, proxy_info.proxy_server().ToURI()); | |
329 | |
330 // No errors. | |
331 EXPECT_EQ("", error_observer->GetOutput()); | |
332 | |
333 // Check the NetLogs -- the script generated 1 alert, mirrored to both | |
334 // the per-request and global logs. | |
335 CapturingNetLog::CapturedEntryList entries_list[2]; | |
336 log.GetEntries(&entries_list[0]); | |
337 request_log.GetEntries(&entries_list[1]); | |
338 | |
339 for (size_t list_i = 0; list_i < arraysize(entries_list); list_i++) { | |
340 const CapturingNetLog::CapturedEntryList& entries = entries_list[list_i]; | |
341 EXPECT_EQ(1u, entries.size()); | |
342 EXPECT_TRUE( | |
343 LogContainsEvent(entries, 0, NetLog::TYPE_PAC_JAVASCRIPT_ALERT, | |
344 NetLog::PHASE_NONE)); | |
345 EXPECT_EQ("{\"message\":\"iteration: 7\"}", entries[0].GetParamsJson()); | |
346 } | |
347 } | |
348 | |
349 // This test runs a PAC script that does "myIpAddress()" followed by | |
350 // "dnsResolve()". This requires 2 restarts. However once the HostResolver's | |
351 // cache is warmed, subsequent calls should take 0 restarts. | |
352 TEST_F(ProxyResolverV8TracingTest, DnsChecksCache) { | |
353 CapturingNetLog log; | |
354 CapturingBoundNetLog request_log; | |
355 MockCachingHostResolver host_resolver; | |
356 MockErrorObserver* error_observer = new MockErrorObserver; | |
357 ProxyResolverV8Tracing resolver(&host_resolver, error_observer, &log); | |
358 | |
359 host_resolver.rules()->AddRule("foopy", "166.155.144.11"); | |
360 host_resolver.rules()->AddRule("*", "122.133.144.155"); | |
361 | |
362 InitResolver(&resolver, "simple_dns.js"); | |
363 | |
364 TestCompletionCallback callback1; | |
365 TestCompletionCallback callback2; | |
366 ProxyInfo proxy_info; | |
367 | |
368 int rv = resolver.GetProxyForURL( | |
369 GURL("http://foopy/req1"), | |
370 &proxy_info, | |
371 callback1.callback(), | |
372 NULL, | |
373 request_log.bound()); | |
374 | |
375 EXPECT_EQ(ERR_IO_PENDING, rv); | |
376 EXPECT_EQ(OK, callback1.WaitForResult()); | |
377 | |
378 // The test does 2 DNS resolutions. | |
379 EXPECT_EQ(2u, host_resolver.num_resolve()); | |
380 | |
381 // The first request took 2 restarts, hence on g_iteration=3. | |
382 EXPECT_EQ("166.155.144.11:3", proxy_info.proxy_server().ToURI()); | |
383 | |
384 rv = resolver.GetProxyForURL( | |
385 GURL("http://foopy/req2"), | |
386 &proxy_info, | |
387 callback2.callback(), | |
388 NULL, | |
389 request_log.bound()); | |
390 | |
391 EXPECT_EQ(ERR_IO_PENDING, rv); | |
392 EXPECT_EQ(OK, callback2.WaitForResult()); | |
393 | |
394 EXPECT_EQ(4u, host_resolver.num_resolve()); | |
395 | |
396 // This time no restarts were required, so g_iteration incremented by 1. | |
397 EXPECT_EQ("166.155.144.11:4", proxy_info.proxy_server().ToURI()); | |
398 | |
399 // No errors. | |
400 EXPECT_EQ("", error_observer->GetOutput()); | |
401 | |
402 EXPECT_EQ(0u, log.GetSize()); | |
403 EXPECT_EQ(0u, request_log.GetSize()); | |
404 } | |
405 | |
406 // This test runs a weird PAC script that was designed to defeat the DNS tracing | |
407 // optimization. The proxy resolver should detect the inconsistency and | |
408 // fall-back to synchronous mode execution. | |
409 TEST_F(ProxyResolverV8TracingTest, FallBackToSynchronous1) { | |
410 CapturingNetLog log; | |
411 CapturingBoundNetLog request_log; | |
412 MockCachingHostResolver host_resolver; | |
413 MockErrorObserver* error_observer = new MockErrorObserver; | |
414 ProxyResolverV8Tracing resolver(&host_resolver, error_observer, &log); | |
415 | |
416 host_resolver.rules()->AddRule("host1", "166.155.144.11"); | |
417 host_resolver.rules()->AddRule("crazy4", "133.199.111.4"); | |
418 host_resolver.rules()->AddRule("*", "122.133.144.155"); | |
419 | |
420 InitResolver(&resolver, "global_sideffects1.js"); | |
421 | |
422 TestCompletionCallback callback; | |
423 ProxyInfo proxy_info; | |
424 | |
425 int rv = resolver.GetProxyForURL( | |
426 GURL("http://foo/"), &proxy_info, callback.callback(), NULL, | |
427 request_log.bound()); | |
428 EXPECT_EQ(ERR_IO_PENDING, rv); | |
429 EXPECT_EQ(OK, callback.WaitForResult()); | |
430 | |
431 // The script itself only does 2 DNS resolves per execution, however it | |
432 // constructs the hostname using a global counter which changes on each | |
433 // invocation. | |
434 EXPECT_EQ(3u, host_resolver.num_resolve()); | |
435 | |
436 EXPECT_EQ("166.155.144.11-133.199.111.4:100", | |
437 proxy_info.proxy_server().ToURI()); | |
438 | |
439 // No errors. | |
440 EXPECT_EQ("", error_observer->GetOutput()); | |
441 | |
442 // Check the NetLogs -- the script generated 1 alert, mirrored to both | |
443 // the per-request and global logs. | |
444 CapturingNetLog::CapturedEntryList entries_list[2]; | |
445 log.GetEntries(&entries_list[0]); | |
446 request_log.GetEntries(&entries_list[1]); | |
447 | |
448 for (size_t list_i = 0; list_i < arraysize(entries_list); list_i++) { | |
449 const CapturingNetLog::CapturedEntryList& entries = entries_list[list_i]; | |
450 EXPECT_EQ(1u, entries.size()); | |
451 EXPECT_TRUE( | |
452 LogContainsEvent(entries, 0, NetLog::TYPE_PAC_JAVASCRIPT_ALERT, | |
453 NetLog::PHASE_NONE)); | |
454 EXPECT_EQ("{\"message\":\"iteration: 4\"}", entries[0].GetParamsJson()); | |
455 } | |
456 } | |
457 | |
458 // This test runs a weird PAC script that was designed to defeat the DNS tracing | |
459 // optimization. The proxy resolver should detect the inconsistency and | |
460 // fall-back to synchronous mode execution. | |
461 TEST_F(ProxyResolverV8TracingTest, FallBackToSynchronous2) { | |
462 CapturingNetLog log; | |
463 CapturingBoundNetLog request_log; | |
464 MockCachingHostResolver host_resolver; | |
465 MockErrorObserver* error_observer = new MockErrorObserver; | |
466 ProxyResolverV8Tracing resolver(&host_resolver, error_observer, &log); | |
467 | |
468 host_resolver.rules()->AddRule("host1", "166.155.144.11"); | |
469 host_resolver.rules()->AddRule("host2", "166.155.144.22"); | |
470 host_resolver.rules()->AddRule("host3", "166.155.144.33"); | |
471 host_resolver.rules()->AddRule("host4", "166.155.144.44"); | |
472 host_resolver.rules()->AddRule("*", "122.133.144.155"); | |
473 | |
474 InitResolver(&resolver, "global_sideffects2.js"); | |
475 | |
476 TestCompletionCallback callback; | |
477 ProxyInfo proxy_info; | |
478 | |
479 int rv = resolver.GetProxyForURL( | |
480 GURL("http://foo/"), &proxy_info, callback.callback(), NULL, | |
481 request_log.bound()); | |
482 EXPECT_EQ(ERR_IO_PENDING, rv); | |
483 EXPECT_EQ(OK, callback.WaitForResult()); | |
484 | |
485 EXPECT_EQ(3u, host_resolver.num_resolve()); | |
486 | |
487 EXPECT_EQ("166.155.144.44:100", proxy_info.proxy_server().ToURI()); | |
488 | |
489 // No errors. | |
490 EXPECT_EQ("", error_observer->GetOutput()); | |
491 | |
492 // Check the NetLogs -- nothing was logged. | |
493 EXPECT_EQ(0u, log.GetSize()); | |
494 EXPECT_EQ(0u, request_log.GetSize()); | |
495 } | |
496 | |
497 // This test runs a weird PAC script that yields a never ending sequence | |
498 // of DNS resolves when restarting. Running it will hit the maximum | |
499 // DNS resolves per request limit (20) after which every DNS resolve will | |
500 // fail. | |
501 TEST_F(ProxyResolverV8TracingTest, InfiniteDNSSequence) { | |
502 CapturingNetLog log; | |
503 CapturingBoundNetLog request_log; | |
504 MockCachingHostResolver host_resolver; | |
505 MockErrorObserver* error_observer = new MockErrorObserver; | |
506 ProxyResolverV8Tracing resolver(&host_resolver, error_observer, &log); | |
507 | |
508 host_resolver.rules()->AddRule("host*", "166.155.144.11"); | |
509 host_resolver.rules()->AddRule("*", "122.133.144.155"); | |
510 | |
511 InitResolver(&resolver, "global_sideffects3.js"); | |
512 | |
513 TestCompletionCallback callback; | |
514 ProxyInfo proxy_info; | |
515 | |
516 int rv = resolver.GetProxyForURL( | |
517 GURL("http://foo/"), &proxy_info, callback.callback(), NULL, | |
518 request_log.bound()); | |
519 EXPECT_EQ(ERR_IO_PENDING, rv); | |
520 EXPECT_EQ(OK, callback.WaitForResult()); | |
521 | |
522 EXPECT_EQ(20u, host_resolver.num_resolve()); | |
523 | |
524 EXPECT_EQ( | |
525 "166.155.144.11-166.155.144.11-166.155.144.11-166.155.144.11-" | |
526 "166.155.144.11-166.155.144.11-166.155.144.11-166.155.144.11-" | |
527 "166.155.144.11-166.155.144.11-166.155.144.11-166.155.144.11-" | |
528 "166.155.144.11-166.155.144.11-166.155.144.11-166.155.144.11-" | |
529 "166.155.144.11-166.155.144.11-166.155.144.11-166.155.144.11-" | |
530 "null:21", proxy_info.proxy_server().ToURI()); | |
531 | |
532 // No errors. | |
533 EXPECT_EQ("", error_observer->GetOutput()); | |
534 | |
535 // Check the NetLogs -- 1 alert was logged. | |
536 EXPECT_EQ(1u, log.GetSize()); | |
537 EXPECT_EQ(1u, request_log.GetSize()); | |
538 } | |
539 | |
540 // This test runs a weird PAC script that yields a never ending sequence | |
541 // of DNS resolves when restarting. Running it will hit the maximum | |
542 // DNS resolves per request limit (20) after which every DNS resolve will | |
543 // fail. | |
544 TEST_F(ProxyResolverV8TracingTest, InfiniteDNSSequence2) { | |
545 CapturingNetLog log; | |
546 CapturingBoundNetLog request_log; | |
547 MockCachingHostResolver host_resolver; | |
548 MockErrorObserver* error_observer = new MockErrorObserver; | |
549 ProxyResolverV8Tracing resolver(&host_resolver, error_observer, &log); | |
550 | |
551 host_resolver.rules()->AddRule("host*", "166.155.144.11"); | |
552 host_resolver.rules()->AddRule("*", "122.133.144.155"); | |
553 | |
554 InitResolver(&resolver, "global_sideffects4.js"); | |
555 | |
556 TestCompletionCallback callback; | |
557 ProxyInfo proxy_info; | |
558 | |
559 int rv = resolver.GetProxyForURL( | |
560 GURL("http://foo/"), &proxy_info, callback.callback(), NULL, | |
561 request_log.bound()); | |
562 EXPECT_EQ(ERR_IO_PENDING, rv); | |
563 EXPECT_EQ(OK, callback.WaitForResult()); | |
564 | |
565 EXPECT_EQ(20u, host_resolver.num_resolve()); | |
566 | |
567 EXPECT_EQ("null21:34", proxy_info.proxy_server().ToURI()); | |
568 | |
569 // No errors. | |
570 EXPECT_EQ("", error_observer->GetOutput()); | |
571 | |
572 // Check the NetLogs -- 1 alert was logged. | |
573 EXPECT_EQ(1u, log.GetSize()); | |
574 EXPECT_EQ(1u, request_log.GetSize()); | |
575 } | |
576 | |
577 void DnsDuringInitHelper(bool synchronous_host_resolver) { | |
578 CapturingNetLog log; | |
579 CapturingBoundNetLog request_log; | |
580 MockCachingHostResolver host_resolver; | |
581 host_resolver.set_synchronous_mode(synchronous_host_resolver); | |
582 MockErrorObserver* error_observer = new MockErrorObserver; | |
583 ProxyResolverV8Tracing resolver(&host_resolver, error_observer, &log); | |
584 | |
585 host_resolver.rules()->AddRule("host1", "91.13.12.1"); | |
586 host_resolver.rules()->AddRule("host2", "91.13.12.2"); | |
587 | |
588 InitResolver(&resolver, "dns_during_init.js"); | |
589 | |
590 // Initialization did 2 dnsResolves. | |
591 EXPECT_EQ(2u, host_resolver.num_resolve()); | |
592 | |
593 host_resolver.rules()->ClearRules(); | |
594 host_resolver.GetHostCache()->clear(); | |
595 | |
596 host_resolver.rules()->AddRule("host1", "145.88.13.3"); | |
597 host_resolver.rules()->AddRule("host2", "137.89.8.45"); | |
598 | |
599 TestCompletionCallback callback; | |
600 ProxyInfo proxy_info; | |
601 | |
602 int rv = resolver.GetProxyForURL( | |
603 GURL("http://foo/"), &proxy_info, callback.callback(), NULL, | |
604 request_log.bound()); | |
605 EXPECT_EQ(ERR_IO_PENDING, rv); | |
606 EXPECT_EQ(OK, callback.WaitForResult()); | |
607 | |
608 // Fetched host1 and host2 again, since the ones done during initialization | |
609 // should not have been cached. | |
610 EXPECT_EQ(4u, host_resolver.num_resolve()); | |
611 | |
612 EXPECT_EQ("91.13.12.1-91.13.12.2-145.88.13.3-137.89.8.45:99", | |
613 proxy_info.proxy_server().ToURI()); | |
614 | |
615 // Check the NetLogs -- the script generated 2 alerts during initialization. | |
616 EXPECT_EQ(0u, request_log.GetSize()); | |
617 CapturingNetLog::CapturedEntryList entries; | |
618 log.GetEntries(&entries); | |
619 | |
620 ASSERT_EQ(2u, entries.size()); | |
621 EXPECT_TRUE( | |
622 LogContainsEvent(entries, 0, NetLog::TYPE_PAC_JAVASCRIPT_ALERT, | |
623 NetLog::PHASE_NONE)); | |
624 EXPECT_TRUE( | |
625 LogContainsEvent(entries, 1, NetLog::TYPE_PAC_JAVASCRIPT_ALERT, | |
626 NetLog::PHASE_NONE)); | |
627 | |
628 EXPECT_EQ("{\"message\":\"Watsup\"}", entries[0].GetParamsJson()); | |
629 EXPECT_EQ("{\"message\":\"Watsup2\"}", entries[1].GetParamsJson()); | |
630 } | |
631 | |
632 // Tests a PAC script which does DNS resolves during initialization. | |
633 TEST_F(ProxyResolverV8TracingTest, DnsDuringInit) { | |
634 // Test with both both a host resolver that always completes asynchronously, | |
635 // and then again with one that completes synchronously. | |
636 DnsDuringInitHelper(false); | |
637 DnsDuringInitHelper(true); | |
638 } | |
639 | |
640 void CrashCallback(int) { | |
641 // Be extra sure that if the callback ever gets invoked, the test will fail. | |
642 CHECK(false); | |
643 } | |
644 | |
645 // Start some requests, cancel them all, and then destroy the resolver. | |
646 // Note the execution order for this test can vary. Since multiple | |
647 // threads are involved, the cancellation may be received a different | |
648 // times. | |
649 TEST_F(ProxyResolverV8TracingTest, CancelAll) { | |
650 MockCachingHostResolver host_resolver; | |
651 MockErrorObserver* error_observer = new MockErrorObserver; | |
652 ProxyResolverV8Tracing resolver(&host_resolver, error_observer, NULL); | |
653 | |
654 host_resolver.rules()->AddSimulatedFailure("*"); | |
655 | |
656 InitResolver(&resolver, "dns.js"); | |
657 | |
658 const size_t kNumRequests = 5; | |
659 ProxyInfo proxy_info[kNumRequests]; | |
660 ProxyResolver::RequestHandle request[kNumRequests]; | |
661 | |
662 for (size_t i = 0; i < kNumRequests; ++i) { | |
663 int rv = resolver.GetProxyForURL( | |
664 GURL("http://foo/"), &proxy_info[i], | |
665 base::Bind(&CrashCallback), &request[i], BoundNetLog()); | |
666 EXPECT_EQ(ERR_IO_PENDING, rv); | |
667 } | |
668 | |
669 for (size_t i = 0; i < kNumRequests; ++i) { | |
670 resolver.CancelRequest(request[i]); | |
671 } | |
672 } | |
673 | |
674 // Note the execution order for this test can vary. Since multiple | |
675 // threads are involved, the cancellation may be received a different | |
676 // times. | |
677 TEST_F(ProxyResolverV8TracingTest, CancelSome) { | |
678 MockCachingHostResolver host_resolver; | |
679 MockErrorObserver* error_observer = new MockErrorObserver; | |
680 ProxyResolverV8Tracing resolver(&host_resolver, error_observer, NULL); | |
681 | |
682 host_resolver.rules()->AddSimulatedFailure("*"); | |
683 | |
684 InitResolver(&resolver, "dns.js"); | |
685 | |
686 ProxyInfo proxy_info1; | |
687 ProxyInfo proxy_info2; | |
688 ProxyResolver::RequestHandle request1; | |
689 ProxyResolver::RequestHandle request2; | |
690 TestCompletionCallback callback; | |
691 | |
692 int rv = resolver.GetProxyForURL( | |
693 GURL("http://foo/"), &proxy_info1, | |
694 base::Bind(&CrashCallback), &request1, BoundNetLog()); | |
695 EXPECT_EQ(ERR_IO_PENDING, rv); | |
696 | |
697 rv = resolver.GetProxyForURL( | |
698 GURL("http://foo/"), &proxy_info2, | |
699 callback.callback(), &request2, BoundNetLog()); | |
700 EXPECT_EQ(ERR_IO_PENDING, rv); | |
701 | |
702 resolver.CancelRequest(request1); | |
703 | |
704 EXPECT_EQ(OK, callback.WaitForResult()); | |
705 } | |
706 | |
707 // Cancel a request after it has finished running on the worker thread, and has | |
708 // posted a task the completion task back to origin thread. | |
709 TEST_F(ProxyResolverV8TracingTest, CancelWhilePendingCompletionTask) { | |
710 MockCachingHostResolver host_resolver; | |
711 MockErrorObserver* error_observer = new MockErrorObserver; | |
712 ProxyResolverV8Tracing resolver(&host_resolver, error_observer, NULL); | |
713 | |
714 host_resolver.rules()->AddSimulatedFailure("*"); | |
715 | |
716 InitResolver(&resolver, "error.js"); | |
717 | |
718 ProxyInfo proxy_info1; | |
719 ProxyInfo proxy_info2; | |
720 ProxyInfo proxy_info3; | |
721 ProxyResolver::RequestHandle request1; | |
722 ProxyResolver::RequestHandle request2; | |
723 ProxyResolver::RequestHandle request3; | |
724 TestCompletionCallback callback; | |
725 | |
726 int rv = resolver.GetProxyForURL( | |
727 GURL("http://foo/"), &proxy_info1, | |
728 base::Bind(&CrashCallback), &request1, BoundNetLog()); | |
729 EXPECT_EQ(ERR_IO_PENDING, rv); | |
730 | |
731 rv = resolver.GetProxyForURL( | |
732 GURL("http://throw-an-error/"), &proxy_info2, | |
733 callback.callback(), &request2, BoundNetLog()); | |
734 EXPECT_EQ(ERR_IO_PENDING, rv); | |
735 | |
736 // Wait until the first request has finished running on the worker thread. | |
737 // (The second request will output an error). | |
738 error_observer->WaitForOutput(); | |
739 | |
740 // Cancel the first request, while it has a pending completion task on | |
741 // the origin thread. | |
742 resolver.CancelRequest(request1); | |
743 | |
744 EXPECT_EQ(ERR_PAC_SCRIPT_FAILED, callback.WaitForResult()); | |
745 | |
746 // Start another request, to make sure it is able to complete. | |
747 rv = resolver.GetProxyForURL( | |
748 GURL("http://i-have-no-idea-what-im-doing/"), &proxy_info3, | |
749 callback.callback(), &request3, BoundNetLog()); | |
750 EXPECT_EQ(ERR_IO_PENDING, rv); | |
751 | |
752 EXPECT_EQ(OK, callback.WaitForResult()); | |
753 | |
754 EXPECT_EQ("i-approve-this-message:42", | |
755 proxy_info3.proxy_server().ToURI()); | |
756 } | |
757 | |
758 // This implementation of HostResolver allows blocking until a resolve request | |
759 // has been received. The resolve requests it receives will never be completed. | |
760 class BlockableHostResolver : public HostResolver { | |
761 public: | |
762 BlockableHostResolver() | |
763 : num_cancelled_requests_(0), waiting_for_resolve_(false) {} | |
764 | |
765 int Resolve(const RequestInfo& info, | |
766 RequestPriority priority, | |
767 AddressList* addresses, | |
768 const CompletionCallback& callback, | |
769 RequestHandle* out_req, | |
770 const BoundNetLog& net_log) override { | |
771 EXPECT_FALSE(callback.is_null()); | |
772 EXPECT_TRUE(out_req); | |
773 | |
774 if (!action_.is_null()) | |
775 action_.Run(); | |
776 | |
777 // Indicate to the caller that a request was received. | |
778 EXPECT_TRUE(waiting_for_resolve_); | |
779 base::MessageLoop::current()->Quit(); | |
780 | |
781 // This line is intentionally after action_.Run(), since one of the | |
782 // tests does a cancellation inside of Resolve(), and it is more | |
783 // interesting if *out_req hasn't been written yet at that point. | |
784 *out_req = reinterpret_cast<RequestHandle*>(1); // Magic value. | |
785 | |
786 // Return ERR_IO_PENDING as this request will NEVER be completed. | |
787 // Expectation is for the caller to later cancel the request. | |
788 return ERR_IO_PENDING; | |
789 } | |
790 | |
791 int ResolveFromCache(const RequestInfo& info, | |
792 AddressList* addresses, | |
793 const BoundNetLog& net_log) override { | |
794 NOTREACHED(); | |
795 return ERR_DNS_CACHE_MISS; | |
796 } | |
797 | |
798 void CancelRequest(RequestHandle req) override { | |
799 EXPECT_EQ(reinterpret_cast<RequestHandle*>(1), req); | |
800 num_cancelled_requests_++; | |
801 } | |
802 | |
803 void SetAction(const base::Callback<void(void)>& action) { | |
804 action_ = action; | |
805 } | |
806 | |
807 // Waits until Resolve() has been called. | |
808 void WaitUntilRequestIsReceived() { | |
809 waiting_for_resolve_ = true; | |
810 base::MessageLoop::current()->Run(); | |
811 DCHECK(waiting_for_resolve_); | |
812 waiting_for_resolve_ = false; | |
813 } | |
814 | |
815 int num_cancelled_requests() const { | |
816 return num_cancelled_requests_; | |
817 } | |
818 | |
819 private: | |
820 int num_cancelled_requests_; | |
821 bool waiting_for_resolve_; | |
822 base::Callback<void(void)> action_; | |
823 }; | |
824 | |
825 // This cancellation test exercises a more predictable cancellation codepath -- | |
826 // when the request has an outstanding DNS request in flight. | |
827 TEST_F(ProxyResolverV8TracingTest, CancelWhileOutstandingNonBlockingDns) { | |
828 BlockableHostResolver host_resolver; | |
829 MockErrorObserver* error_observer = new MockErrorObserver; | |
830 ProxyResolverV8Tracing resolver(&host_resolver, error_observer, NULL); | |
831 | |
832 InitResolver(&resolver, "dns.js"); | |
833 | |
834 ProxyInfo proxy_info1; | |
835 ProxyInfo proxy_info2; | |
836 ProxyResolver::RequestHandle request1; | |
837 ProxyResolver::RequestHandle request2; | |
838 | |
839 int rv = resolver.GetProxyForURL( | |
840 GURL("http://foo/req1"), &proxy_info1, | |
841 base::Bind(&CrashCallback), &request1, BoundNetLog()); | |
842 | |
843 EXPECT_EQ(ERR_IO_PENDING, rv); | |
844 | |
845 host_resolver.WaitUntilRequestIsReceived(); | |
846 | |
847 rv = resolver.GetProxyForURL( | |
848 GURL("http://foo/req2"), &proxy_info2, | |
849 base::Bind(&CrashCallback), &request2, BoundNetLog()); | |
850 | |
851 EXPECT_EQ(ERR_IO_PENDING, rv); | |
852 | |
853 host_resolver.WaitUntilRequestIsReceived(); | |
854 | |
855 resolver.CancelRequest(request1); | |
856 resolver.CancelRequest(request2); | |
857 | |
858 EXPECT_EQ(2, host_resolver.num_cancelled_requests()); | |
859 | |
860 // After leaving this scope, the ProxyResolver is destroyed. | |
861 // This should not cause any problems, as the outstanding work | |
862 // should have been cancelled. | |
863 } | |
864 | |
865 void CancelRequestAndPause(ProxyResolverV8Tracing* resolver, | |
866 ProxyResolver::RequestHandle request) { | |
867 resolver->CancelRequest(request); | |
868 | |
869 // Sleep for a little bit. This makes it more likely for the worker | |
870 // thread to have returned from its call, and serves as a regression | |
871 // test for http://crbug.com/173373. | |
872 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(30)); | |
873 } | |
874 | |
875 // In non-blocking mode, the worker thread actually does block for | |
876 // a short time to see if the result is in the DNS cache. Test | |
877 // cancellation while the worker thread is waiting on this event. | |
878 TEST_F(ProxyResolverV8TracingTest, CancelWhileBlockedInNonBlockingDns) { | |
879 BlockableHostResolver host_resolver; | |
880 MockErrorObserver* error_observer = new MockErrorObserver; | |
881 ProxyResolverV8Tracing resolver(&host_resolver, error_observer, NULL); | |
882 | |
883 InitResolver(&resolver, "dns.js"); | |
884 | |
885 ProxyInfo proxy_info; | |
886 ProxyResolver::RequestHandle request; | |
887 | |
888 int rv = resolver.GetProxyForURL( | |
889 GURL("http://foo/"), &proxy_info, | |
890 base::Bind(&CrashCallback), &request, BoundNetLog()); | |
891 | |
892 EXPECT_EQ(ERR_IO_PENDING, rv); | |
893 | |
894 host_resolver.SetAction( | |
895 base::Bind(CancelRequestAndPause, &resolver, request)); | |
896 | |
897 host_resolver.WaitUntilRequestIsReceived(); | |
898 | |
899 // At this point the host resolver ran Resolve(), and should have cancelled | |
900 // the request. | |
901 | |
902 EXPECT_EQ(1, host_resolver.num_cancelled_requests()); | |
903 } | |
904 | |
905 // Cancel the request while there is a pending DNS request, however before | |
906 // the request is sent to the host resolver. | |
907 TEST_F(ProxyResolverV8TracingTest, CancelWhileBlockedInNonBlockingDns2) { | |
908 MockCachingHostResolver host_resolver; | |
909 MockErrorObserver* error_observer = new MockErrorObserver; | |
910 ProxyResolverV8Tracing resolver(&host_resolver, error_observer, NULL); | |
911 | |
912 InitResolver(&resolver, "dns.js"); | |
913 | |
914 ProxyInfo proxy_info; | |
915 ProxyResolver::RequestHandle request; | |
916 | |
917 int rv = resolver.GetProxyForURL( | |
918 GURL("http://foo/"), &proxy_info, | |
919 base::Bind(&CrashCallback), &request, BoundNetLog()); | |
920 | |
921 EXPECT_EQ(ERR_IO_PENDING, rv); | |
922 | |
923 // Wait a bit, so the DNS task has hopefully been posted. The test will | |
924 // work whatever the delay is here, but it is most useful if the delay | |
925 // is large enough to allow a task to be posted back. | |
926 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(10)); | |
927 resolver.CancelRequest(request); | |
928 | |
929 EXPECT_EQ(0u, host_resolver.num_resolve()); | |
930 } | |
931 | |
932 TEST_F(ProxyResolverV8TracingTest, CancelSetPacWhileOutstandingBlockingDns) { | |
933 BlockableHostResolver host_resolver; | |
934 MockErrorObserver* error_observer = new MockErrorObserver; | |
935 | |
936 ProxyResolverV8Tracing resolver(&host_resolver, error_observer, NULL); | |
937 | |
938 int rv = | |
939 resolver.SetPacScript(LoadScriptData("dns_during_init.js"), | |
940 base::Bind(&CrashCallback)); | |
941 EXPECT_EQ(ERR_IO_PENDING, rv); | |
942 | |
943 host_resolver.WaitUntilRequestIsReceived(); | |
944 | |
945 resolver.CancelSetPacScript(); | |
946 EXPECT_EQ(1, host_resolver.num_cancelled_requests()); | |
947 } | |
948 | |
949 // This tests that the execution of a PAC script is terminated when the DNS | |
950 // dependencies are missing. If the test fails, then it will hang. | |
951 TEST_F(ProxyResolverV8TracingTest, Terminate) { | |
952 CapturingNetLog log; | |
953 CapturingBoundNetLog request_log; | |
954 MockCachingHostResolver host_resolver; | |
955 MockErrorObserver* error_observer = new MockErrorObserver; | |
956 ProxyResolverV8Tracing resolver(&host_resolver, error_observer, &log); | |
957 | |
958 host_resolver.rules()->AddRule("host1", "182.111.0.222"); | |
959 host_resolver.rules()->AddRule("host2", "111.33.44.55"); | |
960 | |
961 InitResolver(&resolver, "terminate.js"); | |
962 | |
963 TestCompletionCallback callback; | |
964 ProxyInfo proxy_info; | |
965 | |
966 int rv = resolver.GetProxyForURL( | |
967 GURL("http://foopy/req1"), | |
968 &proxy_info, | |
969 callback.callback(), | |
970 NULL, | |
971 request_log.bound()); | |
972 | |
973 EXPECT_EQ(ERR_IO_PENDING, rv); | |
974 EXPECT_EQ(OK, callback.WaitForResult()); | |
975 | |
976 // The test does 2 DNS resolutions. | |
977 EXPECT_EQ(2u, host_resolver.num_resolve()); | |
978 | |
979 EXPECT_EQ("foopy:3", proxy_info.proxy_server().ToURI()); | |
980 | |
981 // No errors. | |
982 EXPECT_EQ("", error_observer->GetOutput()); | |
983 | |
984 EXPECT_EQ(0u, log.GetSize()); | |
985 EXPECT_EQ(0u, request_log.GetSize()); | |
986 } | |
987 | |
988 // Tests that multiple instances of ProxyResolverV8Tracing can coexist and run | |
989 // correctly at the same time. This is relevant because at the moment (time | |
990 // this test was written) each ProxyResolverV8Tracing creates its own thread to | |
991 // run V8 on, however each thread is operating on the same v8::Isolate. | |
992 TEST_F(ProxyResolverV8TracingTest, MultipleResolvers) { | |
993 // ------------------------ | |
994 // Setup resolver0 | |
995 // ------------------------ | |
996 MockHostResolver host_resolver0; | |
997 host_resolver0.rules()->AddRuleForAddressFamily( | |
998 "host1", ADDRESS_FAMILY_IPV4, "166.155.144.44"); | |
999 host_resolver0.rules() | |
1000 ->AddIPLiteralRule("host1", "::1,192.168.1.1", std::string()); | |
1001 host_resolver0.rules()->AddSimulatedFailure("host2"); | |
1002 host_resolver0.rules()->AddRule("host3", "166.155.144.33"); | |
1003 host_resolver0.rules()->AddRule("host5", "166.155.144.55"); | |
1004 host_resolver0.rules()->AddSimulatedFailure("host6"); | |
1005 host_resolver0.rules()->AddRuleForAddressFamily( | |
1006 "*", ADDRESS_FAMILY_IPV4, "122.133.144.155"); | |
1007 host_resolver0.rules()->AddRule("*", "133.122.100.200"); | |
1008 ProxyResolverV8Tracing resolver0( | |
1009 &host_resolver0, new MockErrorObserver, NULL); | |
1010 InitResolver(&resolver0, "dns.js"); | |
1011 | |
1012 // ------------------------ | |
1013 // Setup resolver1 | |
1014 // ------------------------ | |
1015 ProxyResolverV8Tracing resolver1( | |
1016 &host_resolver0, new MockErrorObserver, NULL); | |
1017 InitResolver(&resolver1, "dns.js"); | |
1018 | |
1019 // ------------------------ | |
1020 // Setup resolver2 | |
1021 // ------------------------ | |
1022 ProxyResolverV8Tracing resolver2( | |
1023 &host_resolver0, new MockErrorObserver, NULL); | |
1024 InitResolver(&resolver2, "simple.js"); | |
1025 | |
1026 // ------------------------ | |
1027 // Setup resolver3 | |
1028 // ------------------------ | |
1029 MockHostResolver host_resolver3; | |
1030 host_resolver3.rules()->AddRule("foo", "166.155.144.33"); | |
1031 ProxyResolverV8Tracing resolver3( | |
1032 &host_resolver3, new MockErrorObserver, NULL); | |
1033 InitResolver(&resolver3, "simple_dns.js"); | |
1034 | |
1035 // ------------------------ | |
1036 // Queue up work for each resolver (which will be running in parallel). | |
1037 // ------------------------ | |
1038 | |
1039 ProxyResolverV8Tracing* resolver[] = { | |
1040 &resolver0, &resolver1, &resolver2, &resolver3, | |
1041 }; | |
1042 | |
1043 const size_t kNumResolvers = arraysize(resolver); | |
1044 const size_t kNumIterations = 20; | |
1045 const size_t kNumResults = kNumResolvers * kNumIterations; | |
1046 TestCompletionCallback callback[kNumResults]; | |
1047 ProxyInfo proxy_info[kNumResults]; | |
1048 | |
1049 for (size_t i = 0; i < kNumResults; ++i) { | |
1050 size_t resolver_i = i % kNumResolvers; | |
1051 int rv = resolver[resolver_i]->GetProxyForURL( | |
1052 GURL("http://foo/"), &proxy_info[i], callback[i].callback(), NULL, | |
1053 BoundNetLog()); | |
1054 EXPECT_EQ(ERR_IO_PENDING, rv); | |
1055 } | |
1056 | |
1057 // ------------------------ | |
1058 // Verify all of the results. | |
1059 // ------------------------ | |
1060 | |
1061 const char* kExpectedForDnsJs = | |
1062 "122.133.144.155-" // myIpAddress() | |
1063 "null-" // dnsResolve('') | |
1064 "__1_192.168.1.1-" // dnsResolveEx('host1') | |
1065 "null-" // dnsResolve('host2') | |
1066 "166.155.144.33-" // dnsResolve('host3') | |
1067 "122.133.144.155-" // myIpAddress() | |
1068 "166.155.144.33-" // dnsResolve('host3') | |
1069 "__1_192.168.1.1-" // dnsResolveEx('host1') | |
1070 "122.133.144.155-" // myIpAddress() | |
1071 "null-" // dnsResolve('host2') | |
1072 "-" // dnsResolveEx('host6') | |
1073 "133.122.100.200-" // myIpAddressEx() | |
1074 "166.155.144.44" // dnsResolve('host1') | |
1075 ":99"; | |
1076 | |
1077 for (size_t i = 0; i < kNumResults; ++i) { | |
1078 size_t resolver_i = i % kNumResolvers; | |
1079 EXPECT_EQ(OK, callback[i].WaitForResult()); | |
1080 | |
1081 std::string proxy_uri = proxy_info[i].proxy_server().ToURI(); | |
1082 | |
1083 if (resolver_i == 0 || resolver_i == 1) { | |
1084 EXPECT_EQ(kExpectedForDnsJs, proxy_uri); | |
1085 } else if (resolver_i == 2) { | |
1086 EXPECT_EQ("foo:99", proxy_uri); | |
1087 } else if (resolver_i == 3) { | |
1088 EXPECT_EQ("166.155.144.33:", | |
1089 proxy_uri.substr(0, proxy_uri.find(':') + 1)); | |
1090 } else { | |
1091 NOTREACHED(); | |
1092 } | |
1093 } | |
1094 } | |
1095 | |
1096 } // namespace | |
1097 | |
1098 } // namespace net | |
OLD | NEW |