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