1 // Copyright (c) 2011 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 <vector>
6
7 #include "base/string_util.h"
8 #include "base/utf_string_conversions.h"
9 #include "net/base/net_errors.h"
10 #include "net/base/net_log.h"
11 #include "net/base/net_log_unittest.h"
12 #include "net/base/test_completion_callback.h"
13 #include "net/proxy/init_proxy_resolver.h"
14 #include "net/proxy/proxy_config.h"
15 #include "net/proxy/proxy_resolver.h"
16 #include "net/proxy/proxy_script_fetcher.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18
19 namespace net {
20 namespace {
21
22 enum Error {
23 kFailedDownloading = -100,
24 kFailedParsing = -200,
25 };
26
27 class Rules {
28 public:
29 struct Rule {
Rulenet::__anon55575f0e0111::Rules::Rule30 Rule(const GURL& url,
31 int fetch_error,
32 int set_pac_error)
33 : url(url),
34 fetch_error(fetch_error),
35 set_pac_error(set_pac_error) {
36 }
37
textnet::__anon55575f0e0111::Rules::Rule38 string16 text() const {
39 if (set_pac_error == OK)
40 return UTF8ToUTF16(url.spec() + "!valid-script");
41 if (fetch_error == OK)
42 return UTF8ToUTF16(url.spec() + "!invalid-script");
43 return string16();
44 }
45
46 GURL url;
47 int fetch_error;
48 int set_pac_error;
49 };
50
AddSuccessRule(const char * url)51 Rule AddSuccessRule(const char* url) {
52 Rule rule(GURL(url), OK /*fetch_error*/, OK /*set_pac_error*/);
53 rules_.push_back(rule);
54 return rule;
55 }
56
AddFailDownloadRule(const char * url)57 void AddFailDownloadRule(const char* url) {
58 rules_.push_back(Rule(GURL(url), kFailedDownloading /*fetch_error*/,
59 ERR_UNEXPECTED /*set_pac_error*/));
60 }
61
AddFailParsingRule(const char * url)62 void AddFailParsingRule(const char* url) {
63 rules_.push_back(Rule(GURL(url), OK /*fetch_error*/,
64 kFailedParsing /*set_pac_error*/));
65 }
66
GetRuleByUrl(const GURL & url) const67 const Rule& GetRuleByUrl(const GURL& url) const {
68 for (RuleList::const_iterator it = rules_.begin(); it != rules_.end();
69 ++it) {
70 if (it->url == url)
71 return *it;
72 }
73 LOG(FATAL) << "Rule not found for " << url;
74 return rules_[0];
75 }
76
GetRuleByText(const string16 & text) const77 const Rule& GetRuleByText(const string16& text) const {
78 for (RuleList::const_iterator it = rules_.begin(); it != rules_.end();
79 ++it) {
80 if (it->text() == text)
81 return *it;
82 }
83 LOG(FATAL) << "Rule not found for " << text;
84 return rules_[0];
85 }
86
87 private:
88 typedef std::vector<Rule> RuleList;
89 RuleList rules_;
90 };
91
92 class RuleBasedProxyScriptFetcher : public ProxyScriptFetcher {
93 public:
RuleBasedProxyScriptFetcher(const Rules * rules)94 explicit RuleBasedProxyScriptFetcher(const Rules* rules) : rules_(rules) {}
95
96 // ProxyScriptFetcher implementation.
Fetch(const GURL & url,string16 * text,CompletionCallback * callback)97 virtual int Fetch(const GURL& url,
98 string16* text,
99 CompletionCallback* callback) {
100 const Rules::Rule& rule = rules_->GetRuleByUrl(url);
101 int rv = rule.fetch_error;
102 EXPECT_NE(ERR_UNEXPECTED, rv);
103 if (rv == OK)
104 *text = rule.text();
105 return rv;
106 }
107
Cancel()108 virtual void Cancel() {}
109
GetRequestContext()110 virtual URLRequestContext* GetRequestContext() { return NULL; }
111
112 private:
113 const Rules* rules_;
114 };
115
116 class RuleBasedProxyResolver : public ProxyResolver {
117 public:
RuleBasedProxyResolver(const Rules * rules,bool expects_pac_bytes)118 RuleBasedProxyResolver(const Rules* rules, bool expects_pac_bytes)
119 : ProxyResolver(expects_pac_bytes), rules_(rules) {}
120
121 // ProxyResolver implementation:
GetProxyForURL(const GURL &,ProxyInfo *,CompletionCallback *,RequestHandle *,const BoundNetLog &)122 virtual int GetProxyForURL(const GURL& /*url*/,
123 ProxyInfo* /*results*/,
124 CompletionCallback* /*callback*/,
125 RequestHandle* /*request_handle*/,
126 const BoundNetLog& /*net_log*/) {
127 NOTREACHED();
128 return ERR_UNEXPECTED;
129 }
130
CancelRequest(RequestHandle request_handle)131 virtual void CancelRequest(RequestHandle request_handle) {
132 NOTREACHED();
133 }
134
CancelSetPacScript()135 virtual void CancelSetPacScript() {
136 NOTREACHED();
137 }
138
SetPacScript(const scoped_refptr<ProxyResolverScriptData> & script_data,CompletionCallback * callback)139 virtual int SetPacScript(
140 const scoped_refptr<ProxyResolverScriptData>& script_data,
141 CompletionCallback* callback) {
142
143 const GURL url =
144 script_data->type() == ProxyResolverScriptData::TYPE_SCRIPT_URL ?
145 script_data->url() : GURL();
146
147 const Rules::Rule& rule = expects_pac_bytes() ?
148 rules_->GetRuleByText(script_data->utf16()) :
149 rules_->GetRuleByUrl(url);
150
151 int rv = rule.set_pac_error;
152 EXPECT_NE(ERR_UNEXPECTED, rv);
153
154 if (expects_pac_bytes()) {
155 EXPECT_EQ(rule.text(), script_data->utf16());
156 } else {
157 EXPECT_EQ(rule.url, url);
158 }
159
160 if (rv == OK)
161 script_data_ = script_data;
162 return rv;
163 }
164
script_data() const165 const ProxyResolverScriptData* script_data() const { return script_data_; }
166
167 private:
168 const Rules* rules_;
169 scoped_refptr<ProxyResolverScriptData> script_data_;
170 };
171
172 // Succeed using custom PAC script.
TEST(InitProxyResolverTest,CustomPacSucceeds)173 TEST(InitProxyResolverTest, CustomPacSucceeds) {
174 Rules rules;
175 RuleBasedProxyResolver resolver(&rules, true /*expects_pac_bytes*/);
176 RuleBasedProxyScriptFetcher fetcher(&rules);
177
178 ProxyConfig config;
179 config.set_pac_url(GURL("http://custom/proxy.pac"));
180
181 Rules::Rule rule = rules.AddSuccessRule("http://custom/proxy.pac");
182
183 TestCompletionCallback callback;
184 CapturingNetLog log(CapturingNetLog::kUnbounded);
185 InitProxyResolver init(&resolver, &fetcher, &log);
186 EXPECT_EQ(OK, init.Init(config, base::TimeDelta(), NULL, &callback));
187 EXPECT_EQ(rule.text(), resolver.script_data()->utf16());
188
189 // Check the NetLog was filled correctly.
190 CapturingNetLog::EntryList entries;
191 log.GetEntries(&entries);
192
193 EXPECT_EQ(6u, entries.size());
194 EXPECT_TRUE(LogContainsBeginEvent(
195 entries, 0, NetLog::TYPE_INIT_PROXY_RESOLVER));
196 EXPECT_TRUE(LogContainsBeginEvent(
197 entries, 1, NetLog::TYPE_INIT_PROXY_RESOLVER_FETCH_PAC_SCRIPT));
198 EXPECT_TRUE(LogContainsEndEvent(
199 entries, 2, NetLog::TYPE_INIT_PROXY_RESOLVER_FETCH_PAC_SCRIPT));
200 EXPECT_TRUE(LogContainsBeginEvent(
201 entries, 3, NetLog::TYPE_INIT_PROXY_RESOLVER_SET_PAC_SCRIPT));
202 EXPECT_TRUE(LogContainsEndEvent(
203 entries, 4, NetLog::TYPE_INIT_PROXY_RESOLVER_SET_PAC_SCRIPT));
204 EXPECT_TRUE(LogContainsEndEvent(
205 entries, 5, NetLog::TYPE_INIT_PROXY_RESOLVER));
206 }
207
208 // Fail downloading the custom PAC script.
TEST(InitProxyResolverTest,CustomPacFails1)209 TEST(InitProxyResolverTest, CustomPacFails1) {
210 Rules rules;
211 RuleBasedProxyResolver resolver(&rules, true /*expects_pac_bytes*/);
212 RuleBasedProxyScriptFetcher fetcher(&rules);
213
214 ProxyConfig config;
215 config.set_pac_url(GURL("http://custom/proxy.pac"));
216
217 rules.AddFailDownloadRule("http://custom/proxy.pac");
218
219 TestCompletionCallback callback;
220 CapturingNetLog log(CapturingNetLog::kUnbounded);
221 InitProxyResolver init(&resolver, &fetcher, &log);
222 EXPECT_EQ(kFailedDownloading,
223 init.Init(config, base::TimeDelta(), NULL, &callback));
224 EXPECT_EQ(NULL, resolver.script_data());
225
226 // Check the NetLog was filled correctly.
227 CapturingNetLog::EntryList entries;
228 log.GetEntries(&entries);
229
230 EXPECT_EQ(4u, entries.size());
231 EXPECT_TRUE(LogContainsBeginEvent(
232 entries, 0, NetLog::TYPE_INIT_PROXY_RESOLVER));
233 EXPECT_TRUE(LogContainsBeginEvent(
234 entries, 1, NetLog::TYPE_INIT_PROXY_RESOLVER_FETCH_PAC_SCRIPT));
235 EXPECT_TRUE(LogContainsEndEvent(
236 entries, 2, NetLog::TYPE_INIT_PROXY_RESOLVER_FETCH_PAC_SCRIPT));
237 EXPECT_TRUE(LogContainsEndEvent(
238 entries, 3, NetLog::TYPE_INIT_PROXY_RESOLVER));
239 }
240
241 // Fail parsing the custom PAC script.
TEST(InitProxyResolverTest,CustomPacFails2)242 TEST(InitProxyResolverTest, CustomPacFails2) {
243 Rules rules;
244 RuleBasedProxyResolver resolver(&rules, true /*expects_pac_bytes*/);
245 RuleBasedProxyScriptFetcher fetcher(&rules);
246
247 ProxyConfig config;
248 config.set_pac_url(GURL("http://custom/proxy.pac"));
249
250 rules.AddFailParsingRule("http://custom/proxy.pac");
251
252 TestCompletionCallback callback;
253 InitProxyResolver init(&resolver, &fetcher, NULL);
254 EXPECT_EQ(kFailedParsing,
255 init.Init(config, base::TimeDelta(), NULL, &callback));
256 EXPECT_EQ(NULL, resolver.script_data());
257 }
258
259 // Fail downloading the custom PAC script, because the fetcher was NULL.
TEST(InitProxyResolverTest,HasNullProxyScriptFetcher)260 TEST(InitProxyResolverTest, HasNullProxyScriptFetcher) {
261 Rules rules;
262 RuleBasedProxyResolver resolver(&rules, true /*expects_pac_bytes*/);
263
264 ProxyConfig config;
265 config.set_pac_url(GURL("http://custom/proxy.pac"));
266
267 TestCompletionCallback callback;
268 InitProxyResolver init(&resolver, NULL, NULL);
269 EXPECT_EQ(ERR_UNEXPECTED,
270 init.Init(config, base::TimeDelta(), NULL, &callback));
271 EXPECT_EQ(NULL, resolver.script_data());
272 }
273
274 // Succeeds in choosing autodetect (wpad).
TEST(InitProxyResolverTest,AutodetectSuccess)275 TEST(InitProxyResolverTest, AutodetectSuccess) {
276 Rules rules;
277 RuleBasedProxyResolver resolver(&rules, true /*expects_pac_bytes*/);
278 RuleBasedProxyScriptFetcher fetcher(&rules);
279
280 ProxyConfig config;
281 config.set_auto_detect(true);
282
283 Rules::Rule rule = rules.AddSuccessRule("http://wpad/wpad.dat");
284
285 TestCompletionCallback callback;
286 InitProxyResolver init(&resolver, &fetcher, NULL);
287 EXPECT_EQ(OK, init.Init(config, base::TimeDelta(), NULL, &callback));
288 EXPECT_EQ(rule.text(), resolver.script_data()->utf16());
289 }
290
291 // Fails at WPAD (downloading), but succeeds in choosing the custom PAC.
TEST(InitProxyResolverTest,AutodetectFailCustomSuccess1)292 TEST(InitProxyResolverTest, AutodetectFailCustomSuccess1) {
293 Rules rules;
294 RuleBasedProxyResolver resolver(&rules, true /*expects_pac_bytes*/);
295 RuleBasedProxyScriptFetcher fetcher(&rules);
296
297 ProxyConfig config;
298 config.set_auto_detect(true);
299 config.set_pac_url(GURL("http://custom/proxy.pac"));
300
301 rules.AddFailDownloadRule("http://wpad/wpad.dat");
302 Rules::Rule rule = rules.AddSuccessRule("http://custom/proxy.pac");
303
304 TestCompletionCallback callback;
305 InitProxyResolver init(&resolver, &fetcher, NULL);
306 EXPECT_EQ(OK, init.Init(config, base::TimeDelta(), NULL, &callback));
307 EXPECT_EQ(rule.text(), resolver.script_data()->utf16());
308 }
309
310 // Fails at WPAD (parsing), but succeeds in choosing the custom PAC.
TEST(InitProxyResolverTest,AutodetectFailCustomSuccess2)311 TEST(InitProxyResolverTest, AutodetectFailCustomSuccess2) {
312 Rules rules;
313 RuleBasedProxyResolver resolver(&rules, true /*expects_pac_bytes*/);
314 RuleBasedProxyScriptFetcher fetcher(&rules);
315
316 ProxyConfig config;
317 config.set_auto_detect(true);
318 config.set_pac_url(GURL("http://custom/proxy.pac"));
319 config.proxy_rules().ParseFromString("unused-manual-proxy:99");
320
321 rules.AddFailParsingRule("http://wpad/wpad.dat");
322 Rules::Rule rule = rules.AddSuccessRule("http://custom/proxy.pac");
323
324 TestCompletionCallback callback;
325 CapturingNetLog log(CapturingNetLog::kUnbounded);
326
327 ProxyConfig effective_config;
328 InitProxyResolver init(&resolver, &fetcher, &log);
329 EXPECT_EQ(OK, init.Init(config, base::TimeDelta(),
330 &effective_config, &callback));
331 EXPECT_EQ(rule.text(), resolver.script_data()->utf16());
332
333 // Verify that the effective configuration no longer contains auto detect or
334 // any of the manual settings.
335 EXPECT_TRUE(effective_config.Equals(
336 ProxyConfig::CreateFromCustomPacURL(GURL("http://custom/proxy.pac"))));
337
338 // Check the NetLog was filled correctly.
339 // (Note that the Fetch and Set states are repeated since both WPAD and custom
340 // PAC scripts are tried).
341 CapturingNetLog::EntryList entries;
342 log.GetEntries(&entries);
343
344 EXPECT_EQ(11u, entries.size());
345 EXPECT_TRUE(LogContainsBeginEvent(
346 entries, 0, NetLog::TYPE_INIT_PROXY_RESOLVER));
347 EXPECT_TRUE(LogContainsBeginEvent(
348 entries, 1, NetLog::TYPE_INIT_PROXY_RESOLVER_FETCH_PAC_SCRIPT));
349 EXPECT_TRUE(LogContainsEndEvent(
350 entries, 2, NetLog::TYPE_INIT_PROXY_RESOLVER_FETCH_PAC_SCRIPT));
351 EXPECT_TRUE(LogContainsBeginEvent(
352 entries, 3, NetLog::TYPE_INIT_PROXY_RESOLVER_SET_PAC_SCRIPT));
353 EXPECT_TRUE(LogContainsEndEvent(
354 entries, 4, NetLog::TYPE_INIT_PROXY_RESOLVER_SET_PAC_SCRIPT));
355 EXPECT_TRUE(LogContainsEvent(
356 entries, 5,
357 NetLog::TYPE_INIT_PROXY_RESOLVER_FALLING_BACK_TO_NEXT_PAC_URL,
358 NetLog::PHASE_NONE));
359 EXPECT_TRUE(LogContainsBeginEvent(
360 entries, 6, NetLog::TYPE_INIT_PROXY_RESOLVER_FETCH_PAC_SCRIPT));
361 EXPECT_TRUE(LogContainsEndEvent(
362 entries, 7, NetLog::TYPE_INIT_PROXY_RESOLVER_FETCH_PAC_SCRIPT));
363 EXPECT_TRUE(LogContainsBeginEvent(
364 entries, 8, NetLog::TYPE_INIT_PROXY_RESOLVER_SET_PAC_SCRIPT));
365 EXPECT_TRUE(LogContainsEndEvent(
366 entries, 9, NetLog::TYPE_INIT_PROXY_RESOLVER_SET_PAC_SCRIPT));
367 EXPECT_TRUE(LogContainsEndEvent(
368 entries, 10, NetLog::TYPE_INIT_PROXY_RESOLVER));
369 }
370
371 // Fails at WPAD (downloading), and fails at custom PAC (downloading).
TEST(InitProxyResolverTest,AutodetectFailCustomFails1)372 TEST(InitProxyResolverTest, AutodetectFailCustomFails1) {
373 Rules rules;
374 RuleBasedProxyResolver resolver(&rules, true /*expects_pac_bytes*/);
375 RuleBasedProxyScriptFetcher fetcher(&rules);
376
377 ProxyConfig config;
378 config.set_auto_detect(true);
379 config.set_pac_url(GURL("http://custom/proxy.pac"));
380
381 rules.AddFailDownloadRule("http://wpad/wpad.dat");
382 rules.AddFailDownloadRule("http://custom/proxy.pac");
383
384 TestCompletionCallback callback;
385 InitProxyResolver init(&resolver, &fetcher, NULL);
386 EXPECT_EQ(kFailedDownloading,
387 init.Init(config, base::TimeDelta(), NULL, &callback));
388 EXPECT_EQ(NULL, resolver.script_data());
389 }
390
391 // Fails at WPAD (downloading), and fails at custom PAC (parsing).
TEST(InitProxyResolverTest,AutodetectFailCustomFails2)392 TEST(InitProxyResolverTest, AutodetectFailCustomFails2) {
393 Rules rules;
394 RuleBasedProxyResolver resolver(&rules, true /*expects_pac_bytes*/);
395 RuleBasedProxyScriptFetcher fetcher(&rules);
396
397 ProxyConfig config;
398 config.set_auto_detect(true);
399 config.set_pac_url(GURL("http://custom/proxy.pac"));
400
401 rules.AddFailDownloadRule("http://wpad/wpad.dat");
402 rules.AddFailParsingRule("http://custom/proxy.pac");
403
404 TestCompletionCallback callback;
405 InitProxyResolver init(&resolver, &fetcher, NULL);
406 EXPECT_EQ(kFailedParsing,
407 init.Init(config, base::TimeDelta(), NULL, &callback));
408 EXPECT_EQ(NULL, resolver.script_data());
409 }
410
411 // Fails at WPAD (parsing), but succeeds in choosing the custom PAC.
412 // This is the same as AutodetectFailCustomSuccess2, but using a ProxyResolver
413 // that doesn't |expects_pac_bytes|.
TEST(InitProxyResolverTest,AutodetectFailCustomSuccess2_NoFetch)414 TEST(InitProxyResolverTest, AutodetectFailCustomSuccess2_NoFetch) {
415 Rules rules;
416 RuleBasedProxyResolver resolver(&rules, false /*expects_pac_bytes*/);
417 RuleBasedProxyScriptFetcher fetcher(&rules);
418
419 ProxyConfig config;
420 config.set_auto_detect(true);
421 config.set_pac_url(GURL("http://custom/proxy.pac"));
422
423 rules.AddFailParsingRule(""); // Autodetect.
424 Rules::Rule rule = rules.AddSuccessRule("http://custom/proxy.pac");
425
426 TestCompletionCallback callback;
427 InitProxyResolver init(&resolver, &fetcher, NULL);
428 EXPECT_EQ(OK, init.Init(config, base::TimeDelta(), NULL, &callback));
429 EXPECT_EQ(rule.url, resolver.script_data()->url());
430 }
431
432 // This is a copy-paste of CustomPacFails1, with the exception that we give it
433 // a 1 millisecond delay. This means it will now complete asynchronously.
434 // Moreover, we test the NetLog to make sure it logged the pause.
TEST(InitProxyResolverTest,CustomPacFails1_WithPositiveDelay)435 TEST(InitProxyResolverTest, CustomPacFails1_WithPositiveDelay) {
436 Rules rules;
437 RuleBasedProxyResolver resolver(&rules, true /*expects_pac_bytes*/);
438 RuleBasedProxyScriptFetcher fetcher(&rules);
439
440 ProxyConfig config;
441 config.set_pac_url(GURL("http://custom/proxy.pac"));
442
443 rules.AddFailDownloadRule("http://custom/proxy.pac");
444
445 TestCompletionCallback callback;
446 CapturingNetLog log(CapturingNetLog::kUnbounded);
447 InitProxyResolver init(&resolver, &fetcher, &log);
448 EXPECT_EQ(ERR_IO_PENDING,
449 init.Init(config, base::TimeDelta::FromMilliseconds(1),
450 NULL, &callback));
451
452 EXPECT_EQ(kFailedDownloading, callback.WaitForResult());
453 EXPECT_EQ(NULL, resolver.script_data());
454
455 // Check the NetLog was filled correctly.
456 CapturingNetLog::EntryList entries;
457 log.GetEntries(&entries);
458
459 EXPECT_EQ(6u, entries.size());
460 EXPECT_TRUE(LogContainsBeginEvent(
461 entries, 0, NetLog::TYPE_INIT_PROXY_RESOLVER));
462 EXPECT_TRUE(LogContainsBeginEvent(
463 entries, 1, NetLog::TYPE_INIT_PROXY_RESOLVER_WAIT));
464 EXPECT_TRUE(LogContainsEndEvent(
465 entries, 2, NetLog::TYPE_INIT_PROXY_RESOLVER_WAIT));
466 EXPECT_TRUE(LogContainsBeginEvent(
467 entries, 3, NetLog::TYPE_INIT_PROXY_RESOLVER_FETCH_PAC_SCRIPT));
468 EXPECT_TRUE(LogContainsEndEvent(
469 entries, 4, NetLog::TYPE_INIT_PROXY_RESOLVER_FETCH_PAC_SCRIPT));
470 EXPECT_TRUE(LogContainsEndEvent(
471 entries, 5, NetLog::TYPE_INIT_PROXY_RESOLVER));
472 }
473
474 // This is a copy-paste of CustomPacFails1, with the exception that we give it
475 // a -5 second delay instead of a 0 ms delay. This change should have no effect
476 // so the rest of the test is unchanged.
TEST(InitProxyResolverTest,CustomPacFails1_WithNegativeDelay)477 TEST(InitProxyResolverTest, CustomPacFails1_WithNegativeDelay) {
478 Rules rules;
479 RuleBasedProxyResolver resolver(&rules, true /*expects_pac_bytes*/);
480 RuleBasedProxyScriptFetcher fetcher(&rules);
481
482 ProxyConfig config;
483 config.set_pac_url(GURL("http://custom/proxy.pac"));
484
485 rules.AddFailDownloadRule("http://custom/proxy.pac");
486
487 TestCompletionCallback callback;
488 CapturingNetLog log(CapturingNetLog::kUnbounded);
489 InitProxyResolver init(&resolver, &fetcher, &log);
490 EXPECT_EQ(kFailedDownloading,
491 init.Init(config, base::TimeDelta::FromSeconds(-5),
492 NULL, &callback));
493 EXPECT_EQ(NULL, resolver.script_data());
494
495 // Check the NetLog was filled correctly.
496 CapturingNetLog::EntryList entries;
497 log.GetEntries(&entries);
498
499 EXPECT_EQ(4u, entries.size());
500 EXPECT_TRUE(LogContainsBeginEvent(
501 entries, 0, NetLog::TYPE_INIT_PROXY_RESOLVER));
502 EXPECT_TRUE(LogContainsBeginEvent(
503 entries, 1, NetLog::TYPE_INIT_PROXY_RESOLVER_FETCH_PAC_SCRIPT));
504 EXPECT_TRUE(LogContainsEndEvent(
505 entries, 2, NetLog::TYPE_INIT_PROXY_RESOLVER_FETCH_PAC_SCRIPT));
506 EXPECT_TRUE(LogContainsEndEvent(
507 entries, 3, NetLog::TYPE_INIT_PROXY_RESOLVER));
508 }
509
510 } // namespace
511 } // namespace net
512