OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "net/proxy/proxy_resolver_v8_tracing.h" | |
6 | |
7 #include "base/file_util.h" | |
8 #include "base/json/json_writer.h" | |
9 #include "base/message_loop.h" | |
10 #include "base/path_service.h" | |
11 #include "base/stl_util.h" | |
12 #include "base/string_util.h" | |
13 #include "base/stringprintf.h" | |
14 #include "base/synchronization/waitable_event.h" | |
15 #include "base/threading/platform_thread.h" | |
16 #include "base/utf_string_conversions.h" | |
17 #include "base/values.h" | |
18 #include "googleurl/src/gurl.h" | |
19 #include "net/base/mock_host_resolver.h" | |
20 #include "net/base/net_errors.h" | |
21 #include "net/base/net_log.h" | |
22 #include "net/base/net_log_unittest.h" | |
23 #include "net/base/test_completion_callback.h" | |
24 #include "net/proxy/proxy_info.h" | |
25 #include "net/proxy/proxy_resolver_error_observer.h" | |
26 #include "testing/gtest/include/gtest/gtest.h" | |
27 | |
28 namespace net { | |
29 | |
30 namespace { | |
31 | |
32 scoped_refptr<ProxyResolverScriptData> LoadData(const char* filename) { | |
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 | |
OLD | NEW |