1 // Copyright (c) 2012 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.
6 #include "base/memory/scoped_ptr.h"
7 #include "base/memory/scoped_vector.h"
8 #include "base/strings/stringprintf.h"
9 #include "base/test/test_simple_task_runner.h"
10 #include "base/thread_task_runner_handle.h"
11 #include "base/time/time.h"
12 #include "chrome/browser/safe_browsing/chunk.pb.h"
13 #include "chrome/browser/safe_browsing/protocol_manager.h"
14 #include "chrome/browser/safe_browsing/safe_browsing_util.h"
15 #include "google_apis/google_api_keys.h"
16 #include "net/base/escape.h"
17 #include "net/base/load_flags.h"
18 #include "net/base/net_errors.h"
19 #include "net/url_request/test_url_fetcher_factory.h"
20 #include "testing/gmock/include/gmock/gmock.h"
21 #include "testing/gmock_mutant.h"
22 #include "testing/gtest/include/gtest/gtest.h"
25 using base::TimeDelta
;
27 using testing::Invoke
;
31 const char kUrlPrefix
[] = "https://prefix.com/foo";
32 const char kBackupConnectUrlPrefix
[] = "https://alt1-prefix.com/foo";
33 const char kBackupHttpUrlPrefix
[] = "https://alt2-prefix.com/foo";
34 const char kBackupNetworkUrlPrefix
[] = "https://alt3-prefix.com/foo";
35 const char kClient
[] = "unittest";
36 const char kAppVer
[] = "1.0";
37 const char kAdditionalQuery
[] = "additional_query";
38 const char kUrlSuffix
[] = "&ext=0";
40 #if defined(OS_ANDROID)
41 const char kDefaultPhishList
[] = "goog-mobilephish-shavar";
42 const char kDefaultMalwareList
[] = "goog-mobilemalware-shavar";
44 const char kDefaultPhishList
[] = "goog-phish-shavar";
45 const char kDefaultMalwareList
[] = "goog-malware-shavar";
48 // Add-prefix chunk with single prefix.
49 const char kRawChunkPayload1
[] = {
50 '\0', '\0', '\0', '\x08', // 32-bit payload length in network byte order.
51 '\x08', // field 1, wire format varint
52 '\x03', // chunk_number varint 3
53 '\x22', // field 4, wire format length-delimited
54 '\x04', // varint 4 length
55 'a', 'b', 'c', 'd' // 4-byte prefix
57 const std::string
kChunkPayload1(kRawChunkPayload1
, sizeof(kRawChunkPayload1
));
59 // Add-prefix chunk_number 5 with single prefix.
60 const char kRawChunkPayload2
[] = {
61 '\0', '\0', '\0', '\x08', // 32-bit payload length in network byte order.
62 '\x08', // field 1, wire format varint
63 '\x05', // chunk_number varint 5
64 '\x22', // field 4, wire format length-delimited
65 '\x04', // varint length 4
66 'e', 'f', 'g', 'h' // 4-byte prefix
68 const std::string
kChunkPayload2(kRawChunkPayload2
, sizeof(kRawChunkPayload2
));
72 class SafeBrowsingProtocolManagerTest
: public testing::Test
{
74 std::string key_param_
;
76 void SetUp() override
{
77 std::string key
= google_apis::GetAPIKey();
79 key_param_
= base::StringPrintf(
81 net::EscapeQueryParamValue(key
, true).c_str());
85 scoped_ptr
<SafeBrowsingProtocolManager
> CreateProtocolManager(
86 SafeBrowsingProtocolManagerDelegate
* delegate
) {
87 SafeBrowsingProtocolConfig config
;
88 config
.client_name
= kClient
;
89 config
.url_prefix
= kUrlPrefix
;
90 config
.backup_connect_error_url_prefix
= kBackupConnectUrlPrefix
;
91 config
.backup_http_error_url_prefix
= kBackupHttpUrlPrefix
;
92 config
.backup_network_error_url_prefix
= kBackupNetworkUrlPrefix
;
93 config
.version
= kAppVer
;
94 #if defined(OS_ANDROID)
95 config
.disable_connection_check
= true;
97 return scoped_ptr
<SafeBrowsingProtocolManager
>(
98 SafeBrowsingProtocolManager::Create(delegate
, NULL
, config
));
101 void ValidateUpdateFetcherRequest(const net::TestURLFetcher
* url_fetcher
,
102 const std::string
& expected_prefix
,
103 const std::string
& expected_suffix
) {
104 ASSERT_TRUE(url_fetcher
);
105 EXPECT_EQ(net::LOAD_DISABLE_CACHE
, url_fetcher
->GetLoadFlags());
107 std::string
expected_lists(base::StringPrintf("%s;\n%s;\n",
109 kDefaultMalwareList
));
110 EXPECT_EQ(expected_lists
, url_fetcher
->upload_data());
111 EXPECT_EQ(GURL(expected_prefix
+ "/downloads?client=unittest&appver=1.0"
113 key_param_
+ expected_suffix
),
114 url_fetcher
->GetOriginalURL());
117 void ValidateUpdateFetcherRequest(const net::TestURLFetcher
* url_fetcher
) {
118 ValidateUpdateFetcherRequest(url_fetcher
, kUrlPrefix
, kUrlSuffix
);
121 void ValidateRedirectFetcherRequest(const net::TestURLFetcher
* url_fetcher
,
122 const std::string
& expected_url
) {
123 ASSERT_TRUE(url_fetcher
);
124 EXPECT_EQ(net::LOAD_DISABLE_CACHE
, url_fetcher
->GetLoadFlags());
125 EXPECT_EQ("", url_fetcher
->upload_data());
126 EXPECT_EQ(GURL(expected_url
), url_fetcher
->GetOriginalURL());
130 // Ensure that we respect section 5 of the SafeBrowsing protocol specification.
131 TEST_F(SafeBrowsingProtocolManagerTest
, TestBackOffTimes
) {
132 scoped_ptr
<SafeBrowsingProtocolManager
> pm(CreateProtocolManager(NULL
));
134 pm
->next_update_interval_
= TimeDelta::FromSeconds(1800);
135 ASSERT_TRUE(pm
->back_off_fuzz_
>= 0.0 && pm
->back_off_fuzz_
<= 1.0);
139 // No errors received so far.
140 next
= pm
->GetNextUpdateInterval(false);
141 EXPECT_EQ(next
, TimeDelta::FromSeconds(1800));
144 next
= pm
->GetNextUpdateInterval(true);
145 EXPECT_EQ(next
, TimeDelta::FromSeconds(60));
148 next
= pm
->GetNextUpdateInterval(true);
149 EXPECT_TRUE(next
>= TimeDelta::FromMinutes(30) &&
150 next
<= TimeDelta::FromMinutes(60));
153 next
= pm
->GetNextUpdateInterval(true);
154 EXPECT_TRUE(next
>= TimeDelta::FromMinutes(60) &&
155 next
<= TimeDelta::FromMinutes(120));
158 next
= pm
->GetNextUpdateInterval(true);
159 EXPECT_TRUE(next
>= TimeDelta::FromMinutes(120) &&
160 next
<= TimeDelta::FromMinutes(240));
163 next
= pm
->GetNextUpdateInterval(true);
164 EXPECT_TRUE(next
>= TimeDelta::FromMinutes(240) &&
165 next
<= TimeDelta::FromMinutes(480));
167 // 6 errors, reached max backoff.
168 next
= pm
->GetNextUpdateInterval(true);
169 EXPECT_EQ(next
, TimeDelta::FromMinutes(480));
172 next
= pm
->GetNextUpdateInterval(true);
173 EXPECT_EQ(next
, TimeDelta::FromMinutes(480));
175 // Received a successful response.
176 next
= pm
->GetNextUpdateInterval(false);
177 EXPECT_EQ(next
, TimeDelta::FromSeconds(1800));
180 TEST_F(SafeBrowsingProtocolManagerTest
, TestChunkStrings
) {
181 scoped_ptr
<SafeBrowsingProtocolManager
> pm(CreateProtocolManager(NULL
));
183 // Add and Sub chunks.
184 SBListChunkRanges
phish(kDefaultPhishList
);
185 phish
.adds
= "1,4,6,8-20,99";
186 phish
.subs
= "16,32,64-96";
187 EXPECT_EQ(base::StringPrintf("%s;a:1,4,6,8-20,99:s:16,32,64-96\n",
189 safe_browsing::FormatList(phish
));
193 EXPECT_EQ(base::StringPrintf("%s;a:1,4,6,8-20,99\n",
195 safe_browsing::FormatList(phish
));
199 phish
.subs
= "16,32,64-96";
200 EXPECT_EQ(base::StringPrintf("%s;s:16,32,64-96\n",
202 safe_browsing::FormatList(phish
));
204 // No chunks of either type.
207 EXPECT_EQ(base::StringPrintf("%s;\n", kDefaultPhishList
),
208 safe_browsing::FormatList(phish
));
211 TEST_F(SafeBrowsingProtocolManagerTest
, TestGetHashBackOffTimes
) {
212 scoped_ptr
<SafeBrowsingProtocolManager
> pm(CreateProtocolManager(NULL
));
214 // No errors or back off time yet.
215 EXPECT_EQ(0U, pm
->gethash_error_count_
);
216 EXPECT_TRUE(pm
->next_gethash_time_
.is_null());
218 Time now
= Time::Now();
221 pm
->HandleGetHashError(now
);
222 EXPECT_EQ(1U, pm
->gethash_error_count_
);
223 TimeDelta margin
= TimeDelta::FromSeconds(5); // Fudge factor.
224 Time future
= now
+ TimeDelta::FromMinutes(1);
225 EXPECT_TRUE(pm
->next_gethash_time_
>= future
- margin
&&
226 pm
->next_gethash_time_
<= future
+ margin
);
229 pm
->HandleGetHashError(now
);
230 EXPECT_EQ(2U, pm
->gethash_error_count_
);
231 EXPECT_TRUE(pm
->next_gethash_time_
>= now
+ TimeDelta::FromMinutes(30));
232 EXPECT_TRUE(pm
->next_gethash_time_
<= now
+ TimeDelta::FromMinutes(60));
235 pm
->HandleGetHashError(now
);
236 EXPECT_EQ(3U, pm
->gethash_error_count_
);
237 EXPECT_TRUE(pm
->next_gethash_time_
>= now
+ TimeDelta::FromMinutes(60));
238 EXPECT_TRUE(pm
->next_gethash_time_
<= now
+ TimeDelta::FromMinutes(120));
241 pm
->HandleGetHashError(now
);
242 EXPECT_EQ(4U, pm
->gethash_error_count_
);
243 EXPECT_TRUE(pm
->next_gethash_time_
>= now
+ TimeDelta::FromMinutes(120));
244 EXPECT_TRUE(pm
->next_gethash_time_
<= now
+ TimeDelta::FromMinutes(240));
247 pm
->HandleGetHashError(now
);
248 EXPECT_EQ(5U, pm
->gethash_error_count_
);
249 EXPECT_TRUE(pm
->next_gethash_time_
>= now
+ TimeDelta::FromMinutes(240));
250 EXPECT_TRUE(pm
->next_gethash_time_
<= now
+ TimeDelta::FromMinutes(480));
252 // 6 errors, reached max backoff.
253 pm
->HandleGetHashError(now
);
254 EXPECT_EQ(6U, pm
->gethash_error_count_
);
255 EXPECT_TRUE(pm
->next_gethash_time_
== now
+ TimeDelta::FromMinutes(480));
258 pm
->HandleGetHashError(now
);
259 EXPECT_EQ(7U, pm
->gethash_error_count_
);
260 EXPECT_TRUE(pm
->next_gethash_time_
== now
+ TimeDelta::FromMinutes(480));
263 TEST_F(SafeBrowsingProtocolManagerTest
, TestGetHashUrl
) {
264 scoped_ptr
<SafeBrowsingProtocolManager
> pm(CreateProtocolManager(NULL
));
267 "https://prefix.com/foo/gethash?client=unittest&appver=1.0&"
269 key_param_
+ "&ext=0",
270 pm
->GetHashUrl(false).spec());
272 pm
->set_additional_query(kAdditionalQuery
);
274 "https://prefix.com/foo/gethash?client=unittest&appver=1.0&"
276 key_param_
+ "&additional_query&ext=1",
277 pm
->GetHashUrl(true).spec());
280 TEST_F(SafeBrowsingProtocolManagerTest
, TestUpdateUrl
) {
281 scoped_ptr
<SafeBrowsingProtocolManager
> pm(CreateProtocolManager(NULL
));
284 "https://prefix.com/foo/downloads?client=unittest&appver=1.0&"
286 key_param_
+ "&ext=1",
287 pm
->UpdateUrl(true).spec());
289 pm
->set_additional_query(kAdditionalQuery
);
291 "https://prefix.com/foo/downloads?client=unittest&appver=1.0&"
293 key_param_
+ "&additional_query&ext=0",
294 pm
->UpdateUrl(false).spec());
297 TEST_F(SafeBrowsingProtocolManagerTest
, TestNextChunkUrl
) {
298 scoped_ptr
<SafeBrowsingProtocolManager
> pm(CreateProtocolManager(NULL
));
300 std::string url_partial
= "localhost:1234/foo/bar?foo";
301 std::string url_http_full
= "http://localhost:1234/foo/bar?foo";
302 std::string url_https_full
= "https://localhost:1234/foo/bar?foo";
303 std::string url_https_no_query
= "https://localhost:1234/foo/bar";
305 EXPECT_EQ("https://localhost:1234/foo/bar?foo",
306 pm
->NextChunkUrl(url_partial
).spec());
307 EXPECT_EQ("http://localhost:1234/foo/bar?foo",
308 pm
->NextChunkUrl(url_http_full
).spec());
309 EXPECT_EQ("https://localhost:1234/foo/bar?foo",
310 pm
->NextChunkUrl(url_https_full
).spec());
311 EXPECT_EQ("https://localhost:1234/foo/bar",
312 pm
->NextChunkUrl(url_https_no_query
).spec());
314 pm
->set_additional_query(kAdditionalQuery
);
315 EXPECT_EQ("https://localhost:1234/foo/bar?foo&additional_query",
316 pm
->NextChunkUrl(url_partial
).spec());
317 EXPECT_EQ("http://localhost:1234/foo/bar?foo&additional_query",
318 pm
->NextChunkUrl(url_http_full
).spec());
319 EXPECT_EQ("https://localhost:1234/foo/bar?foo&additional_query",
320 pm
->NextChunkUrl(url_https_full
).spec());
321 EXPECT_EQ("https://localhost:1234/foo/bar?additional_query",
322 pm
->NextChunkUrl(url_https_no_query
).spec());
327 class MockProtocolDelegate
: public SafeBrowsingProtocolManagerDelegate
{
329 MockProtocolDelegate() {}
330 ~MockProtocolDelegate() override
{}
332 MOCK_METHOD0(UpdateStarted
, void());
333 MOCK_METHOD1(UpdateFinished
, void(bool));
334 MOCK_METHOD0(ResetDatabase
, void());
335 MOCK_METHOD1(GetChunks
, void(GetChunksCallback
));
337 // gmock does not work with scoped_ptr<> at this time. Add a local method to
338 // mock, then call that from an override. Beware of object ownership when
339 // making changes here.
340 MOCK_METHOD3(AddChunksRaw
, void(const std::string
& lists
,
341 const ScopedVector
<SBChunkData
>& chunks
,
343 void AddChunks(const std::string
& list
,
344 scoped_ptr
<ScopedVector
<SBChunkData
>> chunks
,
345 AddChunksCallback callback
) override
{
346 AddChunksRaw(list
, *chunks
, callback
);
349 // TODO(shess): Actually test this case somewhere.
350 MOCK_METHOD1(DeleteChunksRaw
,
351 void(const std::vector
<SBChunkDelete
>& chunk_deletes
));
353 scoped_ptr
<std::vector
<SBChunkDelete
>> chunk_deletes
) override
{
354 DeleteChunksRaw(*chunk_deletes
);
358 // |InvokeGetChunksCallback| is required because GMock's InvokeArgument action
359 // expects to use operator(), and a Callback only provides Run().
360 // TODO(cbentzel): Use ACTION or ACTION_TEMPLATE instead?
361 void InvokeGetChunksCallback(
362 const std::vector
<SBListChunkRanges
>& ranges
,
364 SafeBrowsingProtocolManagerDelegate::GetChunksCallback callback
) {
365 callback
.Run(ranges
, database_error
, false);
368 // |HandleAddChunks| deletes the chunks and asynchronously invokes
369 // |callback| since SafeBrowsingProtocolManager is not re-entrant at the time
370 // this is called. This guarantee is part of the
371 // SafeBrowsingProtocolManagerDelegate contract.
372 void HandleAddChunks(
373 const std::string
& unused_list
,
374 const ScopedVector
<SBChunkData
>& chunks
,
375 SafeBrowsingProtocolManagerDelegate::AddChunksCallback callback
) {
376 scoped_refptr
<base::SingleThreadTaskRunner
> task_runner(
377 base::ThreadTaskRunnerHandle::Get());
378 if (!task_runner
.get())
380 task_runner
->PostTask(FROM_HERE
, callback
);
385 // Tests that the Update protocol will be skipped if there are problems
386 // accessing the database.
387 TEST_F(SafeBrowsingProtocolManagerTest
, ProblemAccessingDatabase
) {
388 scoped_refptr
<base::TestSimpleTaskRunner
> runner(
389 new base::TestSimpleTaskRunner());
390 base::ThreadTaskRunnerHandle
runner_handler(runner
);
392 testing::StrictMock
<MockProtocolDelegate
> test_delegate
;
393 EXPECT_CALL(test_delegate
, UpdateStarted()).Times(1);
394 EXPECT_CALL(test_delegate
, GetChunks(_
)).WillOnce(
395 Invoke(testing::CreateFunctor(InvokeGetChunksCallback
,
396 std::vector
<SBListChunkRanges
>(),
398 EXPECT_CALL(test_delegate
, UpdateFinished(false)).Times(1);
400 scoped_ptr
<SafeBrowsingProtocolManager
> pm(
401 CreateProtocolManager(&test_delegate
));
403 pm
->ForceScheduleNextUpdate(TimeDelta());
404 runner
->RunPendingTasks();
406 EXPECT_TRUE(pm
->IsUpdateScheduled());
409 // Tests the contents of the POST body when there are contents in the
410 // local database. This is not exhaustive, as the actual list formatting
411 // is covered by SafeBrowsingProtocolManagerTest.TestChunkStrings.
412 TEST_F(SafeBrowsingProtocolManagerTest
, ExistingDatabase
) {
413 scoped_refptr
<base::TestSimpleTaskRunner
> runner(
414 new base::TestSimpleTaskRunner());
415 base::ThreadTaskRunnerHandle
runner_handler(runner
);
416 net::TestURLFetcherFactory url_fetcher_factory
;
418 std::vector
<SBListChunkRanges
> ranges
;
419 SBListChunkRanges
range_phish(safe_browsing_util::kPhishingList
);
420 range_phish
.adds
= "adds_phish";
421 range_phish
.subs
= "subs_phish";
422 ranges
.push_back(range_phish
);
424 SBListChunkRanges
range_unknown("unknown_list");
425 range_unknown
.adds
= "adds_unknown";
426 range_unknown
.subs
= "subs_unknown";
427 ranges
.push_back(range_unknown
);
429 testing::StrictMock
<MockProtocolDelegate
> test_delegate
;
430 EXPECT_CALL(test_delegate
, UpdateStarted()).Times(1);
431 EXPECT_CALL(test_delegate
, GetChunks(_
)).WillOnce(
432 Invoke(testing::CreateFunctor(InvokeGetChunksCallback
,
435 EXPECT_CALL(test_delegate
, UpdateFinished(true)).Times(1);
437 scoped_ptr
<SafeBrowsingProtocolManager
> pm(
438 CreateProtocolManager(&test_delegate
));
440 // Kick off initialization. This returns chunks from the DB synchronously.
441 pm
->ForceScheduleNextUpdate(TimeDelta());
442 runner
->RunPendingTasks();
444 // We should have an URLFetcher at this point in time.
445 net::TestURLFetcher
* url_fetcher
= url_fetcher_factory
.GetFetcherByID(0);
446 ASSERT_TRUE(url_fetcher
);
447 EXPECT_EQ(net::LOAD_DISABLE_CACHE
, url_fetcher
->GetLoadFlags());
448 EXPECT_EQ(base::StringPrintf("%s;a:adds_phish:s:subs_phish\n"
449 "unknown_list;a:adds_unknown:s:subs_unknown\n"
451 kDefaultPhishList
, kDefaultMalwareList
),
452 url_fetcher
->upload_data());
453 EXPECT_EQ(GURL("https://prefix.com/foo/downloads?client=unittest&appver=1.0"
455 key_param_
+ "&ext=0"),
456 url_fetcher
->GetOriginalURL());
458 url_fetcher
->set_status(net::URLRequestStatus());
459 url_fetcher
->set_response_code(200);
460 url_fetcher
->SetResponseString(std::string());
461 url_fetcher
->delegate()->OnURLFetchComplete(url_fetcher
);
463 EXPECT_TRUE(pm
->IsUpdateScheduled());
466 TEST_F(SafeBrowsingProtocolManagerTest
, UpdateResponseBadBodyBackupSuccess
) {
467 scoped_refptr
<base::TestSimpleTaskRunner
> runner(
468 new base::TestSimpleTaskRunner());
469 base::ThreadTaskRunnerHandle
runner_handler(runner
);
470 net::TestURLFetcherFactory url_fetcher_factory
;
472 testing::StrictMock
<MockProtocolDelegate
> test_delegate
;
473 EXPECT_CALL(test_delegate
, UpdateStarted()).Times(1);
474 EXPECT_CALL(test_delegate
, GetChunks(_
)).WillOnce(
475 Invoke(testing::CreateFunctor(InvokeGetChunksCallback
,
476 std::vector
<SBListChunkRanges
>(),
478 EXPECT_CALL(test_delegate
, UpdateFinished(true)).Times(1);
480 scoped_ptr
<SafeBrowsingProtocolManager
> pm(
481 CreateProtocolManager(&test_delegate
));
483 // Kick off initialization. This returns chunks from the DB synchronously.
484 pm
->ForceScheduleNextUpdate(TimeDelta());
485 runner
->RunPendingTasks();
487 // We should have an URLFetcher at this point in time.
488 net::TestURLFetcher
* url_fetcher
= url_fetcher_factory
.GetFetcherByID(0);
489 ValidateUpdateFetcherRequest(url_fetcher
);
491 // The update response is successful, but an invalid body.
492 url_fetcher
->set_status(net::URLRequestStatus());
493 url_fetcher
->set_response_code(200);
494 url_fetcher
->SetResponseString("THIS_IS_A_BAD_RESPONSE");
495 url_fetcher
->delegate()->OnURLFetchComplete(url_fetcher
);
497 // There should now be a backup request.
498 net::TestURLFetcher
* backup_url_fetcher
=
499 url_fetcher_factory
.GetFetcherByID(1);
500 ValidateUpdateFetcherRequest(backup_url_fetcher
, kBackupHttpUrlPrefix
, "");
502 // Respond to the backup successfully.
503 backup_url_fetcher
->set_status(net::URLRequestStatus());
504 backup_url_fetcher
->set_response_code(200);
505 backup_url_fetcher
->SetResponseString(std::string());
506 backup_url_fetcher
->delegate()->OnURLFetchComplete(backup_url_fetcher
);
508 EXPECT_TRUE(pm
->IsUpdateScheduled());
511 // Tests what happens when there is an HTTP error response to the update
512 // request, as well as an error response to the backup update request.
513 TEST_F(SafeBrowsingProtocolManagerTest
, UpdateResponseHttpErrorBackupError
) {
514 scoped_refptr
<base::TestSimpleTaskRunner
> runner(
515 new base::TestSimpleTaskRunner());
516 base::ThreadTaskRunnerHandle
runner_handler(runner
);
517 net::TestURLFetcherFactory url_fetcher_factory
;
519 testing::StrictMock
<MockProtocolDelegate
> test_delegate
;
520 EXPECT_CALL(test_delegate
, UpdateStarted()).Times(1);
521 EXPECT_CALL(test_delegate
, GetChunks(_
)).WillOnce(
522 Invoke(testing::CreateFunctor(InvokeGetChunksCallback
,
523 std::vector
<SBListChunkRanges
>(),
525 EXPECT_CALL(test_delegate
, UpdateFinished(false)).Times(1);
527 scoped_ptr
<SafeBrowsingProtocolManager
> pm(
528 CreateProtocolManager(&test_delegate
));
530 // Kick off initialization. This returns chunks from the DB synchronously.
531 pm
->ForceScheduleNextUpdate(TimeDelta());
532 runner
->RunPendingTasks();
534 // We should have an URLFetcher at this point in time.
535 net::TestURLFetcher
* url_fetcher
= url_fetcher_factory
.GetFetcherByID(0);
536 ValidateUpdateFetcherRequest(url_fetcher
);
538 // Go ahead and respond to it.
539 url_fetcher
->set_status(net::URLRequestStatus());
540 url_fetcher
->set_response_code(404);
541 url_fetcher
->SetResponseString(std::string());
542 url_fetcher
->delegate()->OnURLFetchComplete(url_fetcher
);
544 // There should now be a backup request.
545 net::TestURLFetcher
* backup_url_fetcher
=
546 url_fetcher_factory
.GetFetcherByID(1);
547 ValidateUpdateFetcherRequest(backup_url_fetcher
, kBackupHttpUrlPrefix
, "");
549 // Respond to the backup unsuccessfully.
550 backup_url_fetcher
->set_status(net::URLRequestStatus());
551 backup_url_fetcher
->set_response_code(404);
552 backup_url_fetcher
->SetResponseString(std::string());
553 backup_url_fetcher
->delegate()->OnURLFetchComplete(backup_url_fetcher
);
555 EXPECT_TRUE(pm
->IsUpdateScheduled());
558 // Tests what happens when there is an HTTP error response to the update
559 // request, followed by a successful response to the backup update request.
560 TEST_F(SafeBrowsingProtocolManagerTest
, UpdateResponseHttpErrorBackupSuccess
) {
561 scoped_refptr
<base::TestSimpleTaskRunner
> runner(
562 new base::TestSimpleTaskRunner());
563 base::ThreadTaskRunnerHandle
runner_handler(runner
);
564 net::TestURLFetcherFactory url_fetcher_factory
;
566 testing::StrictMock
<MockProtocolDelegate
> test_delegate
;
567 EXPECT_CALL(test_delegate
, UpdateStarted()).Times(1);
568 EXPECT_CALL(test_delegate
, GetChunks(_
)).WillOnce(
569 Invoke(testing::CreateFunctor(InvokeGetChunksCallback
,
570 std::vector
<SBListChunkRanges
>(),
572 EXPECT_CALL(test_delegate
, UpdateFinished(true)).Times(1);
574 scoped_ptr
<SafeBrowsingProtocolManager
> pm(
575 CreateProtocolManager(&test_delegate
));
577 // Kick off initialization. This returns chunks from the DB synchronously.
578 pm
->ForceScheduleNextUpdate(TimeDelta());
579 runner
->RunPendingTasks();
581 // We should have an URLFetcher at this point in time.
582 net::TestURLFetcher
* url_fetcher
= url_fetcher_factory
.GetFetcherByID(0);
583 ValidateUpdateFetcherRequest(url_fetcher
);
585 // Go ahead and respond to it.
586 url_fetcher
->set_status(net::URLRequestStatus());
587 url_fetcher
->set_response_code(404);
588 url_fetcher
->SetResponseString(std::string());
589 url_fetcher
->delegate()->OnURLFetchComplete(url_fetcher
);
591 // There should now be a backup request.
592 net::TestURLFetcher
* backup_url_fetcher
=
593 url_fetcher_factory
.GetFetcherByID(1);
594 ValidateUpdateFetcherRequest(backup_url_fetcher
, kBackupHttpUrlPrefix
, "");
596 // Respond to the backup successfully.
597 backup_url_fetcher
->set_status(net::URLRequestStatus());
598 backup_url_fetcher
->set_response_code(200);
599 backup_url_fetcher
->SetResponseString(std::string());
600 backup_url_fetcher
->delegate()->OnURLFetchComplete(backup_url_fetcher
);
602 EXPECT_TRUE(pm
->IsUpdateScheduled());
605 // Tests what happens when there is an HTTP error response to the update
606 // request, and a timeout on the backup update request.
607 TEST_F(SafeBrowsingProtocolManagerTest
, UpdateResponseHttpErrorBackupTimeout
) {
608 scoped_refptr
<base::TestSimpleTaskRunner
> runner(
609 new base::TestSimpleTaskRunner());
610 base::ThreadTaskRunnerHandle
runner_handler(runner
);
611 net::TestURLFetcherFactory url_fetcher_factory
;
613 testing::StrictMock
<MockProtocolDelegate
> test_delegate
;
614 EXPECT_CALL(test_delegate
, UpdateStarted()).Times(1);
615 EXPECT_CALL(test_delegate
, GetChunks(_
)).WillOnce(
616 Invoke(testing::CreateFunctor(InvokeGetChunksCallback
,
617 std::vector
<SBListChunkRanges
>(),
619 EXPECT_CALL(test_delegate
, UpdateFinished(false)).Times(1);
621 scoped_ptr
<SafeBrowsingProtocolManager
> pm(
622 CreateProtocolManager(&test_delegate
));
624 // Kick off initialization. This returns chunks from the DB synchronously.
625 pm
->ForceScheduleNextUpdate(TimeDelta());
626 runner
->RunPendingTasks();
628 // We should have an URLFetcher at this point in time.
629 net::TestURLFetcher
* url_fetcher
= url_fetcher_factory
.GetFetcherByID(0);
630 ValidateUpdateFetcherRequest(url_fetcher
);
632 // Go ahead and respond to it.
633 url_fetcher
->set_status(net::URLRequestStatus());
634 url_fetcher
->set_response_code(404);
635 url_fetcher
->SetResponseString(std::string());
636 url_fetcher
->delegate()->OnURLFetchComplete(url_fetcher
);
638 // There should now be a backup request.
639 net::TestURLFetcher
* backup_url_fetcher
=
640 url_fetcher_factory
.GetFetcherByID(1);
641 ValidateUpdateFetcherRequest(backup_url_fetcher
, kBackupHttpUrlPrefix
, "");
643 // Either one or two calls to RunPendingTasks are needed here. The first run
644 // of RunPendingTasks will run the canceled timeout task associated with
645 // the first Update request. Depending on timing, this will either directly
646 // call the timeout task from the backup request, or schedule another task
647 // to run that in the future.
648 // TODO(cbentzel): Less fragile approach.
649 runner
->RunPendingTasks();
650 if (!pm
->IsUpdateScheduled())
651 runner
->RunPendingTasks();
652 EXPECT_TRUE(pm
->IsUpdateScheduled());
655 // Tests what happens when there is a connection error when issuing the update
656 // request, and an error with the backup update request.
657 TEST_F(SafeBrowsingProtocolManagerTest
,
658 UpdateResponseConnectionErrorBackupError
) {
659 scoped_refptr
<base::TestSimpleTaskRunner
> runner(
660 new base::TestSimpleTaskRunner());
661 base::ThreadTaskRunnerHandle
runner_handler(runner
);
662 net::TestURLFetcherFactory url_fetcher_factory
;
664 testing::StrictMock
<MockProtocolDelegate
> test_delegate
;
665 EXPECT_CALL(test_delegate
, UpdateStarted()).Times(1);
666 EXPECT_CALL(test_delegate
, GetChunks(_
)).WillOnce(
667 Invoke(testing::CreateFunctor(InvokeGetChunksCallback
,
668 std::vector
<SBListChunkRanges
>(),
670 EXPECT_CALL(test_delegate
, UpdateFinished(false)).Times(1);
672 scoped_ptr
<SafeBrowsingProtocolManager
> pm(
673 CreateProtocolManager(&test_delegate
));
675 // Kick off initialization. This returns chunks from the DB synchronously.
676 pm
->ForceScheduleNextUpdate(TimeDelta());
677 runner
->RunPendingTasks();
679 // We should have an URLFetcher at this point in time.
680 net::TestURLFetcher
* url_fetcher
= url_fetcher_factory
.GetFetcherByID(0);
681 ValidateUpdateFetcherRequest(url_fetcher
);
683 // Go ahead and respond to it.
684 url_fetcher
->set_status(net::URLRequestStatus(net::URLRequestStatus::FAILED
,
685 net::ERR_CONNECTION_RESET
));
686 url_fetcher
->delegate()->OnURLFetchComplete(url_fetcher
);
688 // There should be a backup URLFetcher now.
689 net::TestURLFetcher
* backup_url_fetcher
=
690 url_fetcher_factory
.GetFetcherByID(1);
691 ValidateUpdateFetcherRequest(backup_url_fetcher
, kBackupConnectUrlPrefix
, "");
693 // Respond to the backup unsuccessfully.
694 backup_url_fetcher
->set_status(net::URLRequestStatus());
695 backup_url_fetcher
->set_response_code(404);
696 backup_url_fetcher
->SetResponseString(std::string());
697 backup_url_fetcher
->delegate()->OnURLFetchComplete(backup_url_fetcher
);
699 EXPECT_TRUE(pm
->IsUpdateScheduled());
702 // Tests what happens when there is a connection error when issuing the update
703 // request, and a successful response to the backup update request.
704 TEST_F(SafeBrowsingProtocolManagerTest
,
705 UpdateResponseConnectionErrorBackupSuccess
) {
706 scoped_refptr
<base::TestSimpleTaskRunner
> runner(
707 new base::TestSimpleTaskRunner());
708 base::ThreadTaskRunnerHandle
runner_handler(runner
);
709 net::TestURLFetcherFactory url_fetcher_factory
;
711 testing::StrictMock
<MockProtocolDelegate
> test_delegate
;
712 EXPECT_CALL(test_delegate
, UpdateStarted()).Times(1);
713 EXPECT_CALL(test_delegate
, GetChunks(_
)).WillOnce(
714 Invoke(testing::CreateFunctor(InvokeGetChunksCallback
,
715 std::vector
<SBListChunkRanges
>(),
717 EXPECT_CALL(test_delegate
, UpdateFinished(true)).Times(1);
719 scoped_ptr
<SafeBrowsingProtocolManager
> pm(
720 CreateProtocolManager(&test_delegate
));
722 // Kick off initialization. This returns chunks from the DB synchronously.
723 pm
->ForceScheduleNextUpdate(TimeDelta());
724 runner
->RunPendingTasks();
726 // We should have an URLFetcher at this point in time.
727 net::TestURLFetcher
* url_fetcher
= url_fetcher_factory
.GetFetcherByID(0);
728 ValidateUpdateFetcherRequest(url_fetcher
);
730 // Go ahead and respond to it.
731 url_fetcher
->set_status(net::URLRequestStatus(net::URLRequestStatus::FAILED
,
732 net::ERR_CONNECTION_RESET
));
733 url_fetcher
->delegate()->OnURLFetchComplete(url_fetcher
);
735 // There should be a backup URLFetcher now.
736 net::TestURLFetcher
* backup_url_fetcher
=
737 url_fetcher_factory
.GetFetcherByID(1);
738 ValidateUpdateFetcherRequest(backup_url_fetcher
, kBackupConnectUrlPrefix
, "");
740 // Respond to the backup unsuccessfully.
741 backup_url_fetcher
->set_status(net::URLRequestStatus());
742 backup_url_fetcher
->set_response_code(200);
743 backup_url_fetcher
->SetResponseString(std::string());
744 backup_url_fetcher
->delegate()->OnURLFetchComplete(backup_url_fetcher
);
746 EXPECT_TRUE(pm
->IsUpdateScheduled());
748 // Tests what happens when there is a network state error when issuing the
749 // update request, and an error with the backup update request.
750 TEST_F(SafeBrowsingProtocolManagerTest
,
751 UpdateResponseNetworkErrorBackupError
) {
752 scoped_refptr
<base::TestSimpleTaskRunner
> runner(
753 new base::TestSimpleTaskRunner());
754 base::ThreadTaskRunnerHandle
runner_handler(runner
);
755 net::TestURLFetcherFactory url_fetcher_factory
;
757 testing::StrictMock
<MockProtocolDelegate
> test_delegate
;
758 EXPECT_CALL(test_delegate
, UpdateStarted()).Times(1);
759 EXPECT_CALL(test_delegate
, GetChunks(_
)).WillOnce(
760 Invoke(testing::CreateFunctor(InvokeGetChunksCallback
,
761 std::vector
<SBListChunkRanges
>(),
763 EXPECT_CALL(test_delegate
, UpdateFinished(false)).Times(1);
765 scoped_ptr
<SafeBrowsingProtocolManager
> pm(
766 CreateProtocolManager(&test_delegate
));
768 // Kick off initialization. This returns chunks from the DB synchronously.
769 pm
->ForceScheduleNextUpdate(TimeDelta());
770 runner
->RunPendingTasks();
772 // We should have an URLFetcher at this point in time.
773 net::TestURLFetcher
* url_fetcher
= url_fetcher_factory
.GetFetcherByID(0);
774 ValidateUpdateFetcherRequest(url_fetcher
);
776 // Go ahead and respond to it.
777 url_fetcher
->set_status(
778 net::URLRequestStatus(net::URLRequestStatus::FAILED
,
779 net::ERR_INTERNET_DISCONNECTED
));
780 url_fetcher
->delegate()->OnURLFetchComplete(url_fetcher
);
782 // There should be a backup URLFetcher now.
783 net::TestURLFetcher
* backup_url_fetcher
=
784 url_fetcher_factory
.GetFetcherByID(1);
785 ValidateUpdateFetcherRequest(backup_url_fetcher
, kBackupNetworkUrlPrefix
, "");
787 // Respond to the backup unsuccessfully.
788 backup_url_fetcher
->set_status(net::URLRequestStatus());
789 backup_url_fetcher
->set_response_code(404);
790 backup_url_fetcher
->SetResponseString(std::string());
791 backup_url_fetcher
->delegate()->OnURLFetchComplete(backup_url_fetcher
);
793 EXPECT_TRUE(pm
->IsUpdateScheduled());
796 // Tests what happens when there is a network state error when issuing the
797 // update request, and a successful response to the backup update request.
798 TEST_F(SafeBrowsingProtocolManagerTest
,
799 UpdateResponseNetworkErrorBackupSuccess
) {
800 scoped_refptr
<base::TestSimpleTaskRunner
> runner(
801 new base::TestSimpleTaskRunner());
802 base::ThreadTaskRunnerHandle
runner_handler(runner
);
803 net::TestURLFetcherFactory url_fetcher_factory
;
805 testing::StrictMock
<MockProtocolDelegate
> test_delegate
;
806 EXPECT_CALL(test_delegate
, UpdateStarted()).Times(1);
807 EXPECT_CALL(test_delegate
, GetChunks(_
)).WillOnce(
808 Invoke(testing::CreateFunctor(InvokeGetChunksCallback
,
809 std::vector
<SBListChunkRanges
>(),
811 EXPECT_CALL(test_delegate
, UpdateFinished(true)).Times(1);
813 scoped_ptr
<SafeBrowsingProtocolManager
> pm(
814 CreateProtocolManager(&test_delegate
));
816 // Kick off initialization. This returns chunks from the DB synchronously.
817 pm
->ForceScheduleNextUpdate(TimeDelta());
818 runner
->RunPendingTasks();
820 // We should have an URLFetcher at this point in time.
821 net::TestURLFetcher
* url_fetcher
= url_fetcher_factory
.GetFetcherByID(0);
822 ValidateUpdateFetcherRequest(url_fetcher
);
824 // Go ahead and respond to it.
825 url_fetcher
->set_status(
826 net::URLRequestStatus(net::URLRequestStatus::FAILED
,
827 net::ERR_INTERNET_DISCONNECTED
));
828 url_fetcher
->delegate()->OnURLFetchComplete(url_fetcher
);
830 // There should be a backup URLFetcher now.
831 net::TestURLFetcher
* backup_url_fetcher
=
832 url_fetcher_factory
.GetFetcherByID(1);
833 ValidateUpdateFetcherRequest(backup_url_fetcher
, kBackupNetworkUrlPrefix
, "");
835 // Respond to the backup unsuccessfully.
836 backup_url_fetcher
->set_status(net::URLRequestStatus());
837 backup_url_fetcher
->set_response_code(200);
838 backup_url_fetcher
->SetResponseString(std::string());
839 backup_url_fetcher
->delegate()->OnURLFetchComplete(backup_url_fetcher
);
841 EXPECT_TRUE(pm
->IsUpdateScheduled());
844 // Tests what happens when there is a timeout before an update response.
845 TEST_F(SafeBrowsingProtocolManagerTest
, UpdateResponseTimeoutBackupSuccess
) {
846 scoped_refptr
<base::TestSimpleTaskRunner
> runner(
847 new base::TestSimpleTaskRunner());
848 base::ThreadTaskRunnerHandle
runner_handler(runner
);
849 net::TestURLFetcherFactory url_fetcher_factory
;
851 testing::StrictMock
<MockProtocolDelegate
> test_delegate
;
852 EXPECT_CALL(test_delegate
, UpdateStarted()).Times(1);
853 EXPECT_CALL(test_delegate
, GetChunks(_
)).WillOnce(
854 Invoke(testing::CreateFunctor(InvokeGetChunksCallback
,
855 std::vector
<SBListChunkRanges
>(),
857 EXPECT_CALL(test_delegate
, UpdateFinished(true)).Times(1);
859 scoped_ptr
<SafeBrowsingProtocolManager
> pm(
860 CreateProtocolManager(&test_delegate
));
862 // Kick off initialization. This returns chunks from the DB synchronously.
863 pm
->ForceScheduleNextUpdate(TimeDelta());
864 runner
->RunPendingTasks();
866 // We should have an URLFetcher at this point in time.
867 net::TestURLFetcher
* url_fetcher
= url_fetcher_factory
.GetFetcherByID(0);
868 ValidateUpdateFetcherRequest(url_fetcher
);
870 // The first time RunPendingTasks is called above, the update timeout timer is
871 // not handled. This call of RunPendingTasks will handle the update.
872 runner
->RunPendingTasks();
874 // There should be a backup URLFetcher now.
875 net::TestURLFetcher
* backup_url_fetcher
=
876 url_fetcher_factory
.GetFetcherByID(1);
877 ValidateUpdateFetcherRequest(backup_url_fetcher
, kBackupConnectUrlPrefix
, "");
879 // Respond to the backup unsuccessfully.
880 backup_url_fetcher
->set_status(net::URLRequestStatus());
881 backup_url_fetcher
->set_response_code(200);
882 backup_url_fetcher
->SetResponseString(std::string());
883 backup_url_fetcher
->delegate()->OnURLFetchComplete(backup_url_fetcher
);
885 EXPECT_TRUE(pm
->IsUpdateScheduled());
888 // Tests what happens when there is a reset command in the response.
889 TEST_F(SafeBrowsingProtocolManagerTest
, UpdateResponseReset
) {
890 scoped_refptr
<base::TestSimpleTaskRunner
> runner(
891 new base::TestSimpleTaskRunner());
892 base::ThreadTaskRunnerHandle
runner_handler(runner
);
893 net::TestURLFetcherFactory url_fetcher_factory
;
895 testing::StrictMock
<MockProtocolDelegate
> test_delegate
;
896 EXPECT_CALL(test_delegate
, UpdateStarted()).Times(1);
897 EXPECT_CALL(test_delegate
, GetChunks(_
)).WillOnce(
898 Invoke(testing::CreateFunctor(InvokeGetChunksCallback
,
899 std::vector
<SBListChunkRanges
>(),
901 EXPECT_CALL(test_delegate
, ResetDatabase()).Times(1);
902 EXPECT_CALL(test_delegate
, UpdateFinished(true)).Times(1);
904 scoped_ptr
<SafeBrowsingProtocolManager
> pm(
905 CreateProtocolManager(&test_delegate
));
907 // Kick off initialization. This returns chunks from the DB synchronously.
908 pm
->ForceScheduleNextUpdate(TimeDelta());
909 runner
->RunPendingTasks();
911 net::TestURLFetcher
* url_fetcher
= url_fetcher_factory
.GetFetcherByID(0);
912 ValidateUpdateFetcherRequest(url_fetcher
);
914 // The update response is successful, and has a reset command.
915 url_fetcher
->set_status(net::URLRequestStatus());
916 url_fetcher
->set_response_code(200);
917 url_fetcher
->SetResponseString("r:pleasereset\n");
918 url_fetcher
->delegate()->OnURLFetchComplete(url_fetcher
);
920 EXPECT_TRUE(pm
->IsUpdateScheduled());
923 // Tests a single valid update response, followed by a single redirect response
924 // that has an valid, but empty body.
925 TEST_F(SafeBrowsingProtocolManagerTest
, EmptyRedirectResponse
) {
926 scoped_refptr
<base::TestSimpleTaskRunner
> runner(
927 new base::TestSimpleTaskRunner());
928 base::ThreadTaskRunnerHandle
runner_handler(runner
);
929 net::TestURLFetcherFactory url_fetcher_factory
;
931 testing::StrictMock
<MockProtocolDelegate
> test_delegate
;
932 EXPECT_CALL(test_delegate
, UpdateStarted()).Times(1);
933 EXPECT_CALL(test_delegate
, GetChunks(_
)).WillOnce(
934 Invoke(testing::CreateFunctor(InvokeGetChunksCallback
,
935 std::vector
<SBListChunkRanges
>(),
937 EXPECT_CALL(test_delegate
, UpdateFinished(true)).Times(1);
939 scoped_ptr
<SafeBrowsingProtocolManager
> pm(
940 CreateProtocolManager(&test_delegate
));
942 // Kick off initialization. This returns chunks from the DB synchronously.
943 pm
->ForceScheduleNextUpdate(TimeDelta());
944 runner
->RunPendingTasks();
946 // The update response contains a single redirect command.
947 net::TestURLFetcher
* url_fetcher
= url_fetcher_factory
.GetFetcherByID(0);
948 ValidateUpdateFetcherRequest(url_fetcher
);
949 url_fetcher
->set_status(net::URLRequestStatus());
950 url_fetcher
->set_response_code(200);
951 url_fetcher
->SetResponseString(
952 base::StringPrintf("i:%s\n"
953 "u:redirect-server.example.com/path\n",
955 url_fetcher
->delegate()->OnURLFetchComplete(url_fetcher
);
957 // The redirect response contains an empty body.
958 net::TestURLFetcher
* chunk_url_fetcher
=
959 url_fetcher_factory
.GetFetcherByID(1);
960 ValidateRedirectFetcherRequest(
961 chunk_url_fetcher
, "https://redirect-server.example.com/path");
962 chunk_url_fetcher
->set_status(net::URLRequestStatus());
963 chunk_url_fetcher
->set_response_code(200);
964 chunk_url_fetcher
->SetResponseString(std::string());
965 chunk_url_fetcher
->delegate()->OnURLFetchComplete(chunk_url_fetcher
);
967 EXPECT_TRUE(pm
->IsUpdateScheduled());
970 // Tests a single valid update response, followed by a single redirect response
971 // that has an invalid body.
972 TEST_F(SafeBrowsingProtocolManagerTest
, InvalidRedirectResponse
) {
973 scoped_refptr
<base::TestSimpleTaskRunner
> runner(
974 new base::TestSimpleTaskRunner());
975 base::ThreadTaskRunnerHandle
runner_handler(runner
);
976 net::TestURLFetcherFactory url_fetcher_factory
;
978 testing::StrictMock
<MockProtocolDelegate
> test_delegate
;
979 EXPECT_CALL(test_delegate
, UpdateStarted()).Times(1);
980 EXPECT_CALL(test_delegate
, GetChunks(_
)).WillOnce(
981 Invoke(testing::CreateFunctor(InvokeGetChunksCallback
,
982 std::vector
<SBListChunkRanges
>(),
984 EXPECT_CALL(test_delegate
, UpdateFinished(false)).Times(1);
986 scoped_ptr
<SafeBrowsingProtocolManager
> pm(
987 CreateProtocolManager(&test_delegate
));
989 // Kick off initialization. This returns chunks from the DB synchronously.
990 pm
->ForceScheduleNextUpdate(TimeDelta());
991 runner
->RunPendingTasks();
993 // The update response contains a single redirect command.
994 net::TestURLFetcher
* url_fetcher
= url_fetcher_factory
.GetFetcherByID(0);
995 ValidateUpdateFetcherRequest(url_fetcher
);
996 url_fetcher
->set_status(net::URLRequestStatus());
997 url_fetcher
->set_response_code(200);
998 url_fetcher
->SetResponseString(
999 base::StringPrintf("i:%s\n"
1000 "u:redirect-server.example.com/path\n",
1001 kDefaultPhishList
));
1002 url_fetcher
->delegate()->OnURLFetchComplete(url_fetcher
);
1004 // The redirect response contains an invalid body.
1005 net::TestURLFetcher
* chunk_url_fetcher
=
1006 url_fetcher_factory
.GetFetcherByID(1);
1007 ValidateRedirectFetcherRequest(
1008 chunk_url_fetcher
, "https://redirect-server.example.com/path");
1009 chunk_url_fetcher
->set_status(net::URLRequestStatus());
1010 chunk_url_fetcher
->set_response_code(200);
1011 chunk_url_fetcher
->SetResponseString("THIS IS AN INVALID RESPONSE");
1012 chunk_url_fetcher
->delegate()->OnURLFetchComplete(chunk_url_fetcher
);
1014 EXPECT_TRUE(pm
->IsUpdateScheduled());
1017 // Tests a single valid update response, followed by a single redirect response
1018 // containing chunks.
1019 TEST_F(SafeBrowsingProtocolManagerTest
, SingleRedirectResponseWithChunks
) {
1020 scoped_refptr
<base::TestSimpleTaskRunner
> runner(
1021 new base::TestSimpleTaskRunner());
1022 base::ThreadTaskRunnerHandle
runner_handler(runner
);
1023 net::TestURLFetcherFactory url_fetcher_factory
;
1025 testing::StrictMock
<MockProtocolDelegate
> test_delegate
;
1026 EXPECT_CALL(test_delegate
, UpdateStarted()).Times(1);
1027 EXPECT_CALL(test_delegate
, GetChunks(_
)).WillOnce(
1028 Invoke(testing::CreateFunctor(InvokeGetChunksCallback
,
1029 std::vector
<SBListChunkRanges
>(),
1031 EXPECT_CALL(test_delegate
, AddChunksRaw(kDefaultPhishList
, _
, _
)).WillOnce(
1032 Invoke(HandleAddChunks
));
1033 EXPECT_CALL(test_delegate
, UpdateFinished(true)).Times(1);
1035 scoped_ptr
<SafeBrowsingProtocolManager
> pm(
1036 CreateProtocolManager(&test_delegate
));
1038 // Kick off initialization. This returns chunks from the DB synchronously.
1039 pm
->ForceScheduleNextUpdate(TimeDelta());
1040 runner
->RunPendingTasks();
1042 // The update response contains a single redirect command.
1043 net::TestURLFetcher
* url_fetcher
= url_fetcher_factory
.GetFetcherByID(0);
1044 ValidateUpdateFetcherRequest(url_fetcher
);
1045 url_fetcher
->set_status(net::URLRequestStatus());
1046 url_fetcher
->set_response_code(200);
1047 url_fetcher
->SetResponseString(
1048 base::StringPrintf("i:%s\n"
1049 "u:redirect-server.example.com/path\n",
1050 kDefaultPhishList
));
1051 url_fetcher
->delegate()->OnURLFetchComplete(url_fetcher
);
1053 // The redirect response contains a single chunk.
1054 net::TestURLFetcher
* chunk_url_fetcher
=
1055 url_fetcher_factory
.GetFetcherByID(1);
1056 ValidateRedirectFetcherRequest(
1057 chunk_url_fetcher
, "https://redirect-server.example.com/path");
1058 chunk_url_fetcher
->set_status(net::URLRequestStatus());
1059 chunk_url_fetcher
->set_response_code(200);
1060 chunk_url_fetcher
->SetResponseString(kChunkPayload1
);
1061 chunk_url_fetcher
->delegate()->OnURLFetchComplete(chunk_url_fetcher
);
1063 EXPECT_FALSE(pm
->IsUpdateScheduled());
1065 // The AddChunksCallback needs to be invoked.
1066 runner
->RunPendingTasks();
1068 EXPECT_TRUE(pm
->IsUpdateScheduled());
1071 // Tests a single valid update response, followed by multiple redirect responses
1072 // containing chunks.
1073 TEST_F(SafeBrowsingProtocolManagerTest
, MultipleRedirectResponsesWithChunks
) {
1074 scoped_refptr
<base::TestSimpleTaskRunner
> runner(
1075 new base::TestSimpleTaskRunner());
1076 base::ThreadTaskRunnerHandle
runner_handler(runner
);
1077 net::TestURLFetcherFactory url_fetcher_factory
;
1079 testing::StrictMock
<MockProtocolDelegate
> test_delegate
;
1080 EXPECT_CALL(test_delegate
, UpdateStarted()).Times(1);
1081 EXPECT_CALL(test_delegate
, GetChunks(_
)).WillOnce(
1082 Invoke(testing::CreateFunctor(InvokeGetChunksCallback
,
1083 std::vector
<SBListChunkRanges
>(),
1085 EXPECT_CALL(test_delegate
, AddChunksRaw(kDefaultPhishList
, _
, _
)).
1086 WillRepeatedly(Invoke(HandleAddChunks
));
1087 EXPECT_CALL(test_delegate
, UpdateFinished(true)).Times(1);
1089 scoped_ptr
<SafeBrowsingProtocolManager
> pm(
1090 CreateProtocolManager(&test_delegate
));
1092 // Kick off initialization. This returns chunks from the DB synchronously.
1093 pm
->ForceScheduleNextUpdate(TimeDelta());
1094 runner
->RunPendingTasks();
1096 // The update response contains multiple redirect commands.
1097 net::TestURLFetcher
* url_fetcher
= url_fetcher_factory
.GetFetcherByID(0);
1098 ValidateUpdateFetcherRequest(url_fetcher
);
1099 url_fetcher
->set_status(net::URLRequestStatus());
1100 url_fetcher
->set_response_code(200);
1101 url_fetcher
->SetResponseString(
1102 base::StringPrintf("i:%s\n"
1103 "u:redirect-server.example.com/one\n"
1104 "u:redirect-server.example.com/two\n",
1105 kDefaultPhishList
));
1106 url_fetcher
->delegate()->OnURLFetchComplete(url_fetcher
);
1108 // The first redirect response contains a single chunk.
1109 net::TestURLFetcher
* first_chunk_url_fetcher
=
1110 url_fetcher_factory
.GetFetcherByID(1);
1111 ValidateRedirectFetcherRequest(
1112 first_chunk_url_fetcher
, "https://redirect-server.example.com/one");
1113 first_chunk_url_fetcher
->set_status(net::URLRequestStatus());
1114 first_chunk_url_fetcher
->set_response_code(200);
1115 first_chunk_url_fetcher
->SetResponseString(kChunkPayload1
);
1116 first_chunk_url_fetcher
->delegate()->OnURLFetchComplete(
1117 first_chunk_url_fetcher
);
1119 // Invoke the AddChunksCallback to trigger the second request.
1120 runner
->RunPendingTasks();
1122 EXPECT_FALSE(pm
->IsUpdateScheduled());
1124 // The second redirect response contains a single chunk.
1125 net::TestURLFetcher
* second_chunk_url_fetcher
=
1126 url_fetcher_factory
.GetFetcherByID(2);
1127 ValidateRedirectFetcherRequest(
1128 second_chunk_url_fetcher
, "https://redirect-server.example.com/two");
1129 second_chunk_url_fetcher
->set_status(net::URLRequestStatus());
1130 second_chunk_url_fetcher
->set_response_code(200);
1131 second_chunk_url_fetcher
->SetResponseString(kChunkPayload2
);
1132 second_chunk_url_fetcher
->delegate()->OnURLFetchComplete(
1133 second_chunk_url_fetcher
);
1135 EXPECT_FALSE(pm
->IsUpdateScheduled());
1137 // Invoke the AddChunksCallback to finish the update.
1138 runner
->RunPendingTasks();
1140 EXPECT_TRUE(pm
->IsUpdateScheduled());