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";
39 #if defined(OS_ANDROID)
40 const char kDefaultPhishList
[] = "goog-mobilephish-shavar";
41 const char kDefaultMalwareList
[] = "goog-mobilemalware-shavar";
43 const char kDefaultPhishList
[] = "goog-phish-shavar";
44 const char kDefaultMalwareList
[] = "goog-malware-shavar";
47 // Add-prefix chunk with single prefix.
48 const char kRawChunkPayload1
[] = {
49 '\0', '\0', '\0', '\x08', // 32-bit payload length in network byte order.
50 '\x08', // field 1, wire format varint
51 '\x03', // chunk_number varint 3
52 '\x22', // field 4, wire format length-delimited
53 '\x04', // varint 4 length
54 'a', 'b', 'c', 'd' // 4-byte prefix
56 const std::string
kChunkPayload1(kRawChunkPayload1
, sizeof(kRawChunkPayload1
));
58 // Add-prefix chunk_number 5 with single prefix.
59 const char kRawChunkPayload2
[] = {
60 '\0', '\0', '\0', '\x08', // 32-bit payload length in network byte order.
61 '\x08', // field 1, wire format varint
62 '\x05', // chunk_number varint 5
63 '\x22', // field 4, wire format length-delimited
64 '\x04', // varint length 4
65 'e', 'f', 'g', 'h' // 4-byte prefix
67 const std::string
kChunkPayload2(kRawChunkPayload2
, sizeof(kRawChunkPayload2
));
71 class SafeBrowsingProtocolManagerTest
: public testing::Test
{
73 std::string key_param_
;
75 virtual void SetUp() {
76 std::string key
= google_apis::GetAPIKey();
78 key_param_
= base::StringPrintf(
80 net::EscapeQueryParamValue(key
, true).c_str());
84 scoped_ptr
<SafeBrowsingProtocolManager
> CreateProtocolManager(
85 SafeBrowsingProtocolManagerDelegate
* delegate
) {
86 SafeBrowsingProtocolConfig config
;
87 config
.client_name
= kClient
;
88 config
.url_prefix
= kUrlPrefix
;
89 config
.backup_connect_error_url_prefix
= kBackupConnectUrlPrefix
;
90 config
.backup_http_error_url_prefix
= kBackupHttpUrlPrefix
;
91 config
.backup_network_error_url_prefix
= kBackupNetworkUrlPrefix
;
92 config
.version
= kAppVer
;
93 #if defined(OS_ANDROID)
94 config
.disable_connection_check
= true;
96 return scoped_ptr
<SafeBrowsingProtocolManager
>(
97 SafeBrowsingProtocolManager::Create(delegate
, NULL
, config
));
100 void ValidateUpdateFetcherRequest(
101 const net::TestURLFetcher
* url_fetcher
,
102 const std::string
& expected_prefix
) {
103 ASSERT_TRUE(url_fetcher
);
104 EXPECT_EQ(net::LOAD_DISABLE_CACHE
, url_fetcher
->GetLoadFlags());
106 std::string
expected_lists(base::StringPrintf("%s;\n%s;\n",
108 kDefaultMalwareList
));
109 EXPECT_EQ(expected_lists
, url_fetcher
->upload_data());
110 EXPECT_EQ(GURL(expected_prefix
+ "/downloads?client=unittest&appver=1.0"
111 "&pver=3.0" + key_param_
),
112 url_fetcher
->GetOriginalURL());
115 void ValidateUpdateFetcherRequest(const net::TestURLFetcher
* url_fetcher
) {
116 ValidateUpdateFetcherRequest(url_fetcher
, kUrlPrefix
);
119 void ValidateRedirectFetcherRequest(const net::TestURLFetcher
* url_fetcher
,
120 const std::string
& expected_url
) {
121 ASSERT_TRUE(url_fetcher
);
122 EXPECT_EQ(net::LOAD_DISABLE_CACHE
, url_fetcher
->GetLoadFlags());
123 EXPECT_EQ("", url_fetcher
->upload_data());
124 EXPECT_EQ(GURL(expected_url
), url_fetcher
->GetOriginalURL());
128 // Ensure that we respect section 5 of the SafeBrowsing protocol specification.
129 TEST_F(SafeBrowsingProtocolManagerTest
, TestBackOffTimes
) {
130 scoped_ptr
<SafeBrowsingProtocolManager
> pm(CreateProtocolManager(NULL
));
132 pm
->next_update_interval_
= TimeDelta::FromSeconds(1800);
133 ASSERT_TRUE(pm
->back_off_fuzz_
>= 0.0 && pm
->back_off_fuzz_
<= 1.0);
137 // No errors received so far.
138 next
= pm
->GetNextUpdateInterval(false);
139 EXPECT_EQ(next
, TimeDelta::FromSeconds(1800));
142 next
= pm
->GetNextUpdateInterval(true);
143 EXPECT_EQ(next
, TimeDelta::FromSeconds(60));
146 next
= pm
->GetNextUpdateInterval(true);
147 EXPECT_TRUE(next
>= TimeDelta::FromMinutes(30) &&
148 next
<= TimeDelta::FromMinutes(60));
151 next
= pm
->GetNextUpdateInterval(true);
152 EXPECT_TRUE(next
>= TimeDelta::FromMinutes(60) &&
153 next
<= TimeDelta::FromMinutes(120));
156 next
= pm
->GetNextUpdateInterval(true);
157 EXPECT_TRUE(next
>= TimeDelta::FromMinutes(120) &&
158 next
<= TimeDelta::FromMinutes(240));
161 next
= pm
->GetNextUpdateInterval(true);
162 EXPECT_TRUE(next
>= TimeDelta::FromMinutes(240) &&
163 next
<= TimeDelta::FromMinutes(480));
165 // 6 errors, reached max backoff.
166 next
= pm
->GetNextUpdateInterval(true);
167 EXPECT_EQ(next
, TimeDelta::FromMinutes(480));
170 next
= pm
->GetNextUpdateInterval(true);
171 EXPECT_EQ(next
, TimeDelta::FromMinutes(480));
173 // Received a successful response.
174 next
= pm
->GetNextUpdateInterval(false);
175 EXPECT_EQ(next
, TimeDelta::FromSeconds(1800));
178 TEST_F(SafeBrowsingProtocolManagerTest
, TestChunkStrings
) {
179 scoped_ptr
<SafeBrowsingProtocolManager
> pm(CreateProtocolManager(NULL
));
181 // Add and Sub chunks.
182 SBListChunkRanges
phish(kDefaultPhishList
);
183 phish
.adds
= "1,4,6,8-20,99";
184 phish
.subs
= "16,32,64-96";
185 EXPECT_EQ(base::StringPrintf("%s;a:1,4,6,8-20,99:s:16,32,64-96\n",
187 safe_browsing::FormatList(phish
));
191 EXPECT_EQ(base::StringPrintf("%s;a:1,4,6,8-20,99\n",
193 safe_browsing::FormatList(phish
));
197 phish
.subs
= "16,32,64-96";
198 EXPECT_EQ(base::StringPrintf("%s;s:16,32,64-96\n",
200 safe_browsing::FormatList(phish
));
202 // No chunks of either type.
205 EXPECT_EQ(base::StringPrintf("%s;\n", kDefaultPhishList
),
206 safe_browsing::FormatList(phish
));
209 TEST_F(SafeBrowsingProtocolManagerTest
, TestGetHashBackOffTimes
) {
210 scoped_ptr
<SafeBrowsingProtocolManager
> pm(CreateProtocolManager(NULL
));
212 // No errors or back off time yet.
213 EXPECT_EQ(0U, pm
->gethash_error_count_
);
214 EXPECT_TRUE(pm
->next_gethash_time_
.is_null());
216 Time now
= Time::Now();
219 pm
->HandleGetHashError(now
);
220 EXPECT_EQ(1U, pm
->gethash_error_count_
);
221 TimeDelta margin
= TimeDelta::FromSeconds(5); // Fudge factor.
222 Time future
= now
+ TimeDelta::FromMinutes(1);
223 EXPECT_TRUE(pm
->next_gethash_time_
>= future
- margin
&&
224 pm
->next_gethash_time_
<= future
+ margin
);
227 pm
->HandleGetHashError(now
);
228 EXPECT_EQ(2U, pm
->gethash_error_count_
);
229 EXPECT_TRUE(pm
->next_gethash_time_
>= now
+ TimeDelta::FromMinutes(30));
230 EXPECT_TRUE(pm
->next_gethash_time_
<= now
+ TimeDelta::FromMinutes(60));
233 pm
->HandleGetHashError(now
);
234 EXPECT_EQ(3U, pm
->gethash_error_count_
);
235 EXPECT_TRUE(pm
->next_gethash_time_
>= now
+ TimeDelta::FromMinutes(60));
236 EXPECT_TRUE(pm
->next_gethash_time_
<= now
+ TimeDelta::FromMinutes(120));
239 pm
->HandleGetHashError(now
);
240 EXPECT_EQ(4U, pm
->gethash_error_count_
);
241 EXPECT_TRUE(pm
->next_gethash_time_
>= now
+ TimeDelta::FromMinutes(120));
242 EXPECT_TRUE(pm
->next_gethash_time_
<= now
+ TimeDelta::FromMinutes(240));
245 pm
->HandleGetHashError(now
);
246 EXPECT_EQ(5U, pm
->gethash_error_count_
);
247 EXPECT_TRUE(pm
->next_gethash_time_
>= now
+ TimeDelta::FromMinutes(240));
248 EXPECT_TRUE(pm
->next_gethash_time_
<= now
+ TimeDelta::FromMinutes(480));
250 // 6 errors, reached max backoff.
251 pm
->HandleGetHashError(now
);
252 EXPECT_EQ(6U, pm
->gethash_error_count_
);
253 EXPECT_TRUE(pm
->next_gethash_time_
== now
+ TimeDelta::FromMinutes(480));
256 pm
->HandleGetHashError(now
);
257 EXPECT_EQ(7U, pm
->gethash_error_count_
);
258 EXPECT_TRUE(pm
->next_gethash_time_
== now
+ TimeDelta::FromMinutes(480));
261 TEST_F(SafeBrowsingProtocolManagerTest
, TestGetHashUrl
) {
262 scoped_ptr
<SafeBrowsingProtocolManager
> pm(CreateProtocolManager(NULL
));
264 EXPECT_EQ("https://prefix.com/foo/gethash?client=unittest&appver=1.0&"
265 "pver=3.0" + key_param_
, pm
->GetHashUrl().spec());
267 pm
->set_additional_query(kAdditionalQuery
);
268 EXPECT_EQ("https://prefix.com/foo/gethash?client=unittest&appver=1.0&"
269 "pver=3.0" + key_param_
+ "&additional_query",
270 pm
->GetHashUrl().spec());
273 TEST_F(SafeBrowsingProtocolManagerTest
, TestUpdateUrl
) {
274 scoped_ptr
<SafeBrowsingProtocolManager
> pm(CreateProtocolManager(NULL
));
276 EXPECT_EQ("https://prefix.com/foo/downloads?client=unittest&appver=1.0&"
277 "pver=3.0" + key_param_
, pm
->UpdateUrl().spec());
279 pm
->set_additional_query(kAdditionalQuery
);
280 EXPECT_EQ("https://prefix.com/foo/downloads?client=unittest&appver=1.0&"
281 "pver=3.0" + key_param_
+ "&additional_query",
282 pm
->UpdateUrl().spec());
285 TEST_F(SafeBrowsingProtocolManagerTest
, TestNextChunkUrl
) {
286 scoped_ptr
<SafeBrowsingProtocolManager
> pm(CreateProtocolManager(NULL
));
288 std::string url_partial
= "localhost:1234/foo/bar?foo";
289 std::string url_http_full
= "http://localhost:1234/foo/bar?foo";
290 std::string url_https_full
= "https://localhost:1234/foo/bar?foo";
291 std::string url_https_no_query
= "https://localhost:1234/foo/bar";
293 EXPECT_EQ("https://localhost:1234/foo/bar?foo",
294 pm
->NextChunkUrl(url_partial
).spec());
295 EXPECT_EQ("http://localhost:1234/foo/bar?foo",
296 pm
->NextChunkUrl(url_http_full
).spec());
297 EXPECT_EQ("https://localhost:1234/foo/bar?foo",
298 pm
->NextChunkUrl(url_https_full
).spec());
299 EXPECT_EQ("https://localhost:1234/foo/bar",
300 pm
->NextChunkUrl(url_https_no_query
).spec());
302 pm
->set_additional_query(kAdditionalQuery
);
303 EXPECT_EQ("https://localhost:1234/foo/bar?foo&additional_query",
304 pm
->NextChunkUrl(url_partial
).spec());
305 EXPECT_EQ("http://localhost:1234/foo/bar?foo&additional_query",
306 pm
->NextChunkUrl(url_http_full
).spec());
307 EXPECT_EQ("https://localhost:1234/foo/bar?foo&additional_query",
308 pm
->NextChunkUrl(url_https_full
).spec());
309 EXPECT_EQ("https://localhost:1234/foo/bar?additional_query",
310 pm
->NextChunkUrl(url_https_no_query
).spec());
315 class MockProtocolDelegate
: public SafeBrowsingProtocolManagerDelegate
{
317 MockProtocolDelegate() {}
318 virtual ~MockProtocolDelegate() {}
320 MOCK_METHOD0(UpdateStarted
, void());
321 MOCK_METHOD1(UpdateFinished
, void(bool));
322 MOCK_METHOD0(ResetDatabase
, void());
323 MOCK_METHOD1(GetChunks
, void(GetChunksCallback
));
325 // gmock does not work with scoped_ptr<> at this time. Add a local method to
326 // mock, then call that from an override. Beware of object ownership when
327 // making changes here.
328 MOCK_METHOD3(AddChunksRaw
, void(const std::string
& lists
,
329 const ScopedVector
<SBChunkData
>& chunks
,
331 virtual void AddChunks(const std::string
& list
,
332 scoped_ptr
<ScopedVector
<SBChunkData
> > chunks
,
333 AddChunksCallback callback
) OVERRIDE
{
334 AddChunksRaw(list
, *chunks
, callback
);
337 // TODO(shess): Actually test this case somewhere.
338 MOCK_METHOD1(DeleteChunksRaw
,
339 void(const std::vector
<SBChunkDelete
>& chunk_deletes
));
340 virtual void DeleteChunks(
341 scoped_ptr
<std::vector
<SBChunkDelete
> > chunk_deletes
) OVERRIDE
{
342 DeleteChunksRaw(*chunk_deletes
);
346 // |InvokeGetChunksCallback| is required because GMock's InvokeArgument action
347 // expects to use operator(), and a Callback only provides Run().
348 // TODO(cbentzel): Use ACTION or ACTION_TEMPLATE instead?
349 void InvokeGetChunksCallback(
350 const std::vector
<SBListChunkRanges
>& ranges
,
352 SafeBrowsingProtocolManagerDelegate::GetChunksCallback callback
) {
353 callback
.Run(ranges
, database_error
);
356 // |HandleAddChunks| deletes the chunks and asynchronously invokes
357 // |callback| since SafeBrowsingProtocolManager is not re-entrant at the time
358 // this is called. This guarantee is part of the
359 // SafeBrowsingProtocolManagerDelegate contract.
360 void HandleAddChunks(
361 const std::string
& unused_list
,
362 const ScopedVector
<SBChunkData
>& chunks
,
363 SafeBrowsingProtocolManagerDelegate::AddChunksCallback callback
) {
364 scoped_refptr
<base::SingleThreadTaskRunner
> task_runner(
365 base::ThreadTaskRunnerHandle::Get());
366 if (!task_runner
.get())
368 task_runner
->PostTask(FROM_HERE
, callback
);
373 // Tests that the Update protocol will be skipped if there are problems
374 // accessing the database.
375 TEST_F(SafeBrowsingProtocolManagerTest
, ProblemAccessingDatabase
) {
376 scoped_refptr
<base::TestSimpleTaskRunner
> runner(
377 new base::TestSimpleTaskRunner());
378 base::ThreadTaskRunnerHandle
runner_handler(runner
);
380 testing::StrictMock
<MockProtocolDelegate
> test_delegate
;
381 EXPECT_CALL(test_delegate
, UpdateStarted()).Times(1);
382 EXPECT_CALL(test_delegate
, GetChunks(_
)).WillOnce(
383 Invoke(testing::CreateFunctor(InvokeGetChunksCallback
,
384 std::vector
<SBListChunkRanges
>(),
386 EXPECT_CALL(test_delegate
, UpdateFinished(false)).Times(1);
388 scoped_ptr
<SafeBrowsingProtocolManager
> pm(
389 CreateProtocolManager(&test_delegate
));
391 pm
->ForceScheduleNextUpdate(TimeDelta());
392 runner
->RunPendingTasks();
394 EXPECT_TRUE(pm
->IsUpdateScheduled());
397 // Tests the contents of the POST body when there are contents in the
398 // local database. This is not exhaustive, as the actual list formatting
399 // is covered by SafeBrowsingProtocolManagerTest.TestChunkStrings.
400 TEST_F(SafeBrowsingProtocolManagerTest
, ExistingDatabase
) {
401 scoped_refptr
<base::TestSimpleTaskRunner
> runner(
402 new base::TestSimpleTaskRunner());
403 base::ThreadTaskRunnerHandle
runner_handler(runner
);
404 net::TestURLFetcherFactory url_fetcher_factory
;
406 std::vector
<SBListChunkRanges
> ranges
;
407 SBListChunkRanges
range_phish(safe_browsing_util::kPhishingList
);
408 range_phish
.adds
= "adds_phish";
409 range_phish
.subs
= "subs_phish";
410 ranges
.push_back(range_phish
);
412 SBListChunkRanges
range_unknown("unknown_list");
413 range_unknown
.adds
= "adds_unknown";
414 range_unknown
.subs
= "subs_unknown";
415 ranges
.push_back(range_unknown
);
417 testing::StrictMock
<MockProtocolDelegate
> test_delegate
;
418 EXPECT_CALL(test_delegate
, UpdateStarted()).Times(1);
419 EXPECT_CALL(test_delegate
, GetChunks(_
)).WillOnce(
420 Invoke(testing::CreateFunctor(InvokeGetChunksCallback
,
423 EXPECT_CALL(test_delegate
, UpdateFinished(true)).Times(1);
425 scoped_ptr
<SafeBrowsingProtocolManager
> pm(
426 CreateProtocolManager(&test_delegate
));
428 // Kick off initialization. This returns chunks from the DB synchronously.
429 pm
->ForceScheduleNextUpdate(TimeDelta());
430 runner
->RunPendingTasks();
432 // We should have an URLFetcher at this point in time.
433 net::TestURLFetcher
* url_fetcher
= url_fetcher_factory
.GetFetcherByID(0);
434 ASSERT_TRUE(url_fetcher
);
435 EXPECT_EQ(net::LOAD_DISABLE_CACHE
, url_fetcher
->GetLoadFlags());
436 EXPECT_EQ(base::StringPrintf("%s;a:adds_phish:s:subs_phish\n"
437 "unknown_list;a:adds_unknown:s:subs_unknown\n"
439 kDefaultPhishList
, kDefaultMalwareList
),
440 url_fetcher
->upload_data());
441 EXPECT_EQ(GURL("https://prefix.com/foo/downloads?client=unittest&appver=1.0"
442 "&pver=3.0" + key_param_
),
443 url_fetcher
->GetOriginalURL());
445 url_fetcher
->set_status(net::URLRequestStatus());
446 url_fetcher
->set_response_code(200);
447 url_fetcher
->SetResponseString(std::string());
448 url_fetcher
->delegate()->OnURLFetchComplete(url_fetcher
);
450 EXPECT_TRUE(pm
->IsUpdateScheduled());
453 TEST_F(SafeBrowsingProtocolManagerTest
, UpdateResponseBadBodyBackupSuccess
) {
454 scoped_refptr
<base::TestSimpleTaskRunner
> runner(
455 new base::TestSimpleTaskRunner());
456 base::ThreadTaskRunnerHandle
runner_handler(runner
);
457 net::TestURLFetcherFactory url_fetcher_factory
;
459 testing::StrictMock
<MockProtocolDelegate
> test_delegate
;
460 EXPECT_CALL(test_delegate
, UpdateStarted()).Times(1);
461 EXPECT_CALL(test_delegate
, GetChunks(_
)).WillOnce(
462 Invoke(testing::CreateFunctor(InvokeGetChunksCallback
,
463 std::vector
<SBListChunkRanges
>(),
465 EXPECT_CALL(test_delegate
, UpdateFinished(true)).Times(1);
467 scoped_ptr
<SafeBrowsingProtocolManager
> pm(
468 CreateProtocolManager(&test_delegate
));
470 // Kick off initialization. This returns chunks from the DB synchronously.
471 pm
->ForceScheduleNextUpdate(TimeDelta());
472 runner
->RunPendingTasks();
474 // We should have an URLFetcher at this point in time.
475 net::TestURLFetcher
* url_fetcher
= url_fetcher_factory
.GetFetcherByID(0);
476 ValidateUpdateFetcherRequest(url_fetcher
);
478 // The update response is successful, but an invalid body.
479 url_fetcher
->set_status(net::URLRequestStatus());
480 url_fetcher
->set_response_code(200);
481 url_fetcher
->SetResponseString("THIS_IS_A_BAD_RESPONSE");
482 url_fetcher
->delegate()->OnURLFetchComplete(url_fetcher
);
484 // There should now be a backup request.
485 net::TestURLFetcher
* backup_url_fetcher
=
486 url_fetcher_factory
.GetFetcherByID(1);
487 ValidateUpdateFetcherRequest(backup_url_fetcher
,
488 kBackupHttpUrlPrefix
);
490 // Respond to the backup successfully.
491 backup_url_fetcher
->set_status(net::URLRequestStatus());
492 backup_url_fetcher
->set_response_code(200);
493 backup_url_fetcher
->SetResponseString(std::string());
494 backup_url_fetcher
->delegate()->OnURLFetchComplete(backup_url_fetcher
);
496 EXPECT_TRUE(pm
->IsUpdateScheduled());
499 // Tests what happens when there is an HTTP error response to the update
500 // request, as well as an error response to the backup update request.
501 TEST_F(SafeBrowsingProtocolManagerTest
, UpdateResponseHttpErrorBackupError
) {
502 scoped_refptr
<base::TestSimpleTaskRunner
> runner(
503 new base::TestSimpleTaskRunner());
504 base::ThreadTaskRunnerHandle
runner_handler(runner
);
505 net::TestURLFetcherFactory url_fetcher_factory
;
507 testing::StrictMock
<MockProtocolDelegate
> test_delegate
;
508 EXPECT_CALL(test_delegate
, UpdateStarted()).Times(1);
509 EXPECT_CALL(test_delegate
, GetChunks(_
)).WillOnce(
510 Invoke(testing::CreateFunctor(InvokeGetChunksCallback
,
511 std::vector
<SBListChunkRanges
>(),
513 EXPECT_CALL(test_delegate
, UpdateFinished(false)).Times(1);
515 scoped_ptr
<SafeBrowsingProtocolManager
> pm(
516 CreateProtocolManager(&test_delegate
));
518 // Kick off initialization. This returns chunks from the DB synchronously.
519 pm
->ForceScheduleNextUpdate(TimeDelta());
520 runner
->RunPendingTasks();
522 // We should have an URLFetcher at this point in time.
523 net::TestURLFetcher
* url_fetcher
= url_fetcher_factory
.GetFetcherByID(0);
524 ValidateUpdateFetcherRequest(url_fetcher
);
526 // Go ahead and respond to it.
527 url_fetcher
->set_status(net::URLRequestStatus());
528 url_fetcher
->set_response_code(404);
529 url_fetcher
->SetResponseString(std::string());
530 url_fetcher
->delegate()->OnURLFetchComplete(url_fetcher
);
532 // There should now be a backup request.
533 net::TestURLFetcher
* backup_url_fetcher
=
534 url_fetcher_factory
.GetFetcherByID(1);
535 ValidateUpdateFetcherRequest(backup_url_fetcher
, kBackupHttpUrlPrefix
);
537 // Respond to the backup unsuccessfully.
538 backup_url_fetcher
->set_status(net::URLRequestStatus());
539 backup_url_fetcher
->set_response_code(404);
540 backup_url_fetcher
->SetResponseString(std::string());
541 backup_url_fetcher
->delegate()->OnURLFetchComplete(backup_url_fetcher
);
543 EXPECT_TRUE(pm
->IsUpdateScheduled());
546 // Tests what happens when there is an HTTP error response to the update
547 // request, followed by a successful response to the backup update request.
548 TEST_F(SafeBrowsingProtocolManagerTest
, UpdateResponseHttpErrorBackupSuccess
) {
549 scoped_refptr
<base::TestSimpleTaskRunner
> runner(
550 new base::TestSimpleTaskRunner());
551 base::ThreadTaskRunnerHandle
runner_handler(runner
);
552 net::TestURLFetcherFactory url_fetcher_factory
;
554 testing::StrictMock
<MockProtocolDelegate
> test_delegate
;
555 EXPECT_CALL(test_delegate
, UpdateStarted()).Times(1);
556 EXPECT_CALL(test_delegate
, GetChunks(_
)).WillOnce(
557 Invoke(testing::CreateFunctor(InvokeGetChunksCallback
,
558 std::vector
<SBListChunkRanges
>(),
560 EXPECT_CALL(test_delegate
, UpdateFinished(true)).Times(1);
562 scoped_ptr
<SafeBrowsingProtocolManager
> pm(
563 CreateProtocolManager(&test_delegate
));
565 // Kick off initialization. This returns chunks from the DB synchronously.
566 pm
->ForceScheduleNextUpdate(TimeDelta());
567 runner
->RunPendingTasks();
569 // We should have an URLFetcher at this point in time.
570 net::TestURLFetcher
* url_fetcher
= url_fetcher_factory
.GetFetcherByID(0);
571 ValidateUpdateFetcherRequest(url_fetcher
);
573 // Go ahead and respond to it.
574 url_fetcher
->set_status(net::URLRequestStatus());
575 url_fetcher
->set_response_code(404);
576 url_fetcher
->SetResponseString(std::string());
577 url_fetcher
->delegate()->OnURLFetchComplete(url_fetcher
);
579 // There should now be a backup request.
580 net::TestURLFetcher
* backup_url_fetcher
=
581 url_fetcher_factory
.GetFetcherByID(1);
582 ValidateUpdateFetcherRequest(backup_url_fetcher
,
583 kBackupHttpUrlPrefix
);
585 // Respond to the backup successfully.
586 backup_url_fetcher
->set_status(net::URLRequestStatus());
587 backup_url_fetcher
->set_response_code(200);
588 backup_url_fetcher
->SetResponseString(std::string());
589 backup_url_fetcher
->delegate()->OnURLFetchComplete(backup_url_fetcher
);
591 EXPECT_TRUE(pm
->IsUpdateScheduled());
594 // Tests what happens when there is an HTTP error response to the update
595 // request, and a timeout on the backup update request.
596 TEST_F(SafeBrowsingProtocolManagerTest
, UpdateResponseHttpErrorBackupTimeout
) {
597 scoped_refptr
<base::TestSimpleTaskRunner
> runner(
598 new base::TestSimpleTaskRunner());
599 base::ThreadTaskRunnerHandle
runner_handler(runner
);
600 net::TestURLFetcherFactory url_fetcher_factory
;
602 testing::StrictMock
<MockProtocolDelegate
> test_delegate
;
603 EXPECT_CALL(test_delegate
, UpdateStarted()).Times(1);
604 EXPECT_CALL(test_delegate
, GetChunks(_
)).WillOnce(
605 Invoke(testing::CreateFunctor(InvokeGetChunksCallback
,
606 std::vector
<SBListChunkRanges
>(),
608 EXPECT_CALL(test_delegate
, UpdateFinished(false)).Times(1);
610 scoped_ptr
<SafeBrowsingProtocolManager
> pm(
611 CreateProtocolManager(&test_delegate
));
613 // Kick off initialization. This returns chunks from the DB synchronously.
614 pm
->ForceScheduleNextUpdate(TimeDelta());
615 runner
->RunPendingTasks();
617 // We should have an URLFetcher at this point in time.
618 net::TestURLFetcher
* url_fetcher
= url_fetcher_factory
.GetFetcherByID(0);
619 ValidateUpdateFetcherRequest(url_fetcher
);
621 // Go ahead and respond to it.
622 url_fetcher
->set_status(net::URLRequestStatus());
623 url_fetcher
->set_response_code(404);
624 url_fetcher
->SetResponseString(std::string());
625 url_fetcher
->delegate()->OnURLFetchComplete(url_fetcher
);
627 // There should now be a backup request.
628 net::TestURLFetcher
* backup_url_fetcher
=
629 url_fetcher_factory
.GetFetcherByID(1);
630 ValidateUpdateFetcherRequest(backup_url_fetcher
, kBackupHttpUrlPrefix
);
632 // Either one or two calls to RunPendingTasks are needed here. The first run
633 // of RunPendingTasks will run the canceled timeout task associated with
634 // the first Update request. Depending on timing, this will either directly
635 // call the timeout task from the backup request, or schedule another task
636 // to run that in the future.
637 // TODO(cbentzel): Less fragile approach.
638 runner
->RunPendingTasks();
639 if (!pm
->IsUpdateScheduled())
640 runner
->RunPendingTasks();
641 EXPECT_TRUE(pm
->IsUpdateScheduled());
644 // Tests what happens when there is a connection error when issuing the update
645 // request, and an error with the backup update request.
646 TEST_F(SafeBrowsingProtocolManagerTest
,
647 UpdateResponseConnectionErrorBackupError
) {
648 scoped_refptr
<base::TestSimpleTaskRunner
> runner(
649 new base::TestSimpleTaskRunner());
650 base::ThreadTaskRunnerHandle
runner_handler(runner
);
651 net::TestURLFetcherFactory url_fetcher_factory
;
653 testing::StrictMock
<MockProtocolDelegate
> test_delegate
;
654 EXPECT_CALL(test_delegate
, UpdateStarted()).Times(1);
655 EXPECT_CALL(test_delegate
, GetChunks(_
)).WillOnce(
656 Invoke(testing::CreateFunctor(InvokeGetChunksCallback
,
657 std::vector
<SBListChunkRanges
>(),
659 EXPECT_CALL(test_delegate
, UpdateFinished(false)).Times(1);
661 scoped_ptr
<SafeBrowsingProtocolManager
> pm(
662 CreateProtocolManager(&test_delegate
));
664 // Kick off initialization. This returns chunks from the DB synchronously.
665 pm
->ForceScheduleNextUpdate(TimeDelta());
666 runner
->RunPendingTasks();
668 // We should have an URLFetcher at this point in time.
669 net::TestURLFetcher
* url_fetcher
= url_fetcher_factory
.GetFetcherByID(0);
670 ValidateUpdateFetcherRequest(url_fetcher
);
672 // Go ahead and respond to it.
673 url_fetcher
->set_status(net::URLRequestStatus(net::URLRequestStatus::FAILED
,
674 net::ERR_CONNECTION_RESET
));
675 url_fetcher
->delegate()->OnURLFetchComplete(url_fetcher
);
677 // There should be a backup URLFetcher now.
678 net::TestURLFetcher
* backup_url_fetcher
=
679 url_fetcher_factory
.GetFetcherByID(1);
680 ValidateUpdateFetcherRequest(backup_url_fetcher
,
681 kBackupConnectUrlPrefix
);
683 // Respond to the backup unsuccessfully.
684 backup_url_fetcher
->set_status(net::URLRequestStatus());
685 backup_url_fetcher
->set_response_code(404);
686 backup_url_fetcher
->SetResponseString(std::string());
687 backup_url_fetcher
->delegate()->OnURLFetchComplete(backup_url_fetcher
);
689 EXPECT_TRUE(pm
->IsUpdateScheduled());
692 // Tests what happens when there is a connection error when issuing the update
693 // request, and a successful response to the backup update request.
694 TEST_F(SafeBrowsingProtocolManagerTest
,
695 UpdateResponseConnectionErrorBackupSuccess
) {
696 scoped_refptr
<base::TestSimpleTaskRunner
> runner(
697 new base::TestSimpleTaskRunner());
698 base::ThreadTaskRunnerHandle
runner_handler(runner
);
699 net::TestURLFetcherFactory url_fetcher_factory
;
701 testing::StrictMock
<MockProtocolDelegate
> test_delegate
;
702 EXPECT_CALL(test_delegate
, UpdateStarted()).Times(1);
703 EXPECT_CALL(test_delegate
, GetChunks(_
)).WillOnce(
704 Invoke(testing::CreateFunctor(InvokeGetChunksCallback
,
705 std::vector
<SBListChunkRanges
>(),
707 EXPECT_CALL(test_delegate
, UpdateFinished(true)).Times(1);
709 scoped_ptr
<SafeBrowsingProtocolManager
> pm(
710 CreateProtocolManager(&test_delegate
));
712 // Kick off initialization. This returns chunks from the DB synchronously.
713 pm
->ForceScheduleNextUpdate(TimeDelta());
714 runner
->RunPendingTasks();
716 // We should have an URLFetcher at this point in time.
717 net::TestURLFetcher
* url_fetcher
= url_fetcher_factory
.GetFetcherByID(0);
718 ValidateUpdateFetcherRequest(url_fetcher
);
720 // Go ahead and respond to it.
721 url_fetcher
->set_status(net::URLRequestStatus(net::URLRequestStatus::FAILED
,
722 net::ERR_CONNECTION_RESET
));
723 url_fetcher
->delegate()->OnURLFetchComplete(url_fetcher
);
725 // There should be a backup URLFetcher now.
726 net::TestURLFetcher
* backup_url_fetcher
=
727 url_fetcher_factory
.GetFetcherByID(1);
728 ValidateUpdateFetcherRequest(backup_url_fetcher
,
729 kBackupConnectUrlPrefix
);
731 // Respond to the backup unsuccessfully.
732 backup_url_fetcher
->set_status(net::URLRequestStatus());
733 backup_url_fetcher
->set_response_code(200);
734 backup_url_fetcher
->SetResponseString(std::string());
735 backup_url_fetcher
->delegate()->OnURLFetchComplete(backup_url_fetcher
);
737 EXPECT_TRUE(pm
->IsUpdateScheduled());
739 // Tests what happens when there is a network state error when issuing the
740 // update request, and an error with the backup update request.
741 TEST_F(SafeBrowsingProtocolManagerTest
,
742 UpdateResponseNetworkErrorBackupError
) {
743 scoped_refptr
<base::TestSimpleTaskRunner
> runner(
744 new base::TestSimpleTaskRunner());
745 base::ThreadTaskRunnerHandle
runner_handler(runner
);
746 net::TestURLFetcherFactory url_fetcher_factory
;
748 testing::StrictMock
<MockProtocolDelegate
> test_delegate
;
749 EXPECT_CALL(test_delegate
, UpdateStarted()).Times(1);
750 EXPECT_CALL(test_delegate
, GetChunks(_
)).WillOnce(
751 Invoke(testing::CreateFunctor(InvokeGetChunksCallback
,
752 std::vector
<SBListChunkRanges
>(),
754 EXPECT_CALL(test_delegate
, UpdateFinished(false)).Times(1);
756 scoped_ptr
<SafeBrowsingProtocolManager
> pm(
757 CreateProtocolManager(&test_delegate
));
759 // Kick off initialization. This returns chunks from the DB synchronously.
760 pm
->ForceScheduleNextUpdate(TimeDelta());
761 runner
->RunPendingTasks();
763 // We should have an URLFetcher at this point in time.
764 net::TestURLFetcher
* url_fetcher
= url_fetcher_factory
.GetFetcherByID(0);
765 ValidateUpdateFetcherRequest(url_fetcher
);
767 // Go ahead and respond to it.
768 url_fetcher
->set_status(
769 net::URLRequestStatus(net::URLRequestStatus::FAILED
,
770 net::ERR_INTERNET_DISCONNECTED
));
771 url_fetcher
->delegate()->OnURLFetchComplete(url_fetcher
);
773 // There should be a backup URLFetcher now.
774 net::TestURLFetcher
* backup_url_fetcher
=
775 url_fetcher_factory
.GetFetcherByID(1);
776 ValidateUpdateFetcherRequest(backup_url_fetcher
,
777 kBackupNetworkUrlPrefix
);
779 // Respond to the backup unsuccessfully.
780 backup_url_fetcher
->set_status(net::URLRequestStatus());
781 backup_url_fetcher
->set_response_code(404);
782 backup_url_fetcher
->SetResponseString(std::string());
783 backup_url_fetcher
->delegate()->OnURLFetchComplete(backup_url_fetcher
);
785 EXPECT_TRUE(pm
->IsUpdateScheduled());
788 // Tests what happens when there is a network state error when issuing the
789 // update request, and a successful response to the backup update request.
790 TEST_F(SafeBrowsingProtocolManagerTest
,
791 UpdateResponseNetworkErrorBackupSuccess
) {
792 scoped_refptr
<base::TestSimpleTaskRunner
> runner(
793 new base::TestSimpleTaskRunner());
794 base::ThreadTaskRunnerHandle
runner_handler(runner
);
795 net::TestURLFetcherFactory url_fetcher_factory
;
797 testing::StrictMock
<MockProtocolDelegate
> test_delegate
;
798 EXPECT_CALL(test_delegate
, UpdateStarted()).Times(1);
799 EXPECT_CALL(test_delegate
, GetChunks(_
)).WillOnce(
800 Invoke(testing::CreateFunctor(InvokeGetChunksCallback
,
801 std::vector
<SBListChunkRanges
>(),
803 EXPECT_CALL(test_delegate
, UpdateFinished(true)).Times(1);
805 scoped_ptr
<SafeBrowsingProtocolManager
> pm(
806 CreateProtocolManager(&test_delegate
));
808 // Kick off initialization. This returns chunks from the DB synchronously.
809 pm
->ForceScheduleNextUpdate(TimeDelta());
810 runner
->RunPendingTasks();
812 // We should have an URLFetcher at this point in time.
813 net::TestURLFetcher
* url_fetcher
= url_fetcher_factory
.GetFetcherByID(0);
814 ValidateUpdateFetcherRequest(url_fetcher
);
816 // Go ahead and respond to it.
817 url_fetcher
->set_status(
818 net::URLRequestStatus(net::URLRequestStatus::FAILED
,
819 net::ERR_INTERNET_DISCONNECTED
));
820 url_fetcher
->delegate()->OnURLFetchComplete(url_fetcher
);
822 // There should be a backup URLFetcher now.
823 net::TestURLFetcher
* backup_url_fetcher
=
824 url_fetcher_factory
.GetFetcherByID(1);
825 ValidateUpdateFetcherRequest(backup_url_fetcher
,
826 kBackupNetworkUrlPrefix
);
828 // Respond to the backup unsuccessfully.
829 backup_url_fetcher
->set_status(net::URLRequestStatus());
830 backup_url_fetcher
->set_response_code(200);
831 backup_url_fetcher
->SetResponseString(std::string());
832 backup_url_fetcher
->delegate()->OnURLFetchComplete(backup_url_fetcher
);
834 EXPECT_TRUE(pm
->IsUpdateScheduled());
837 // Tests what happens when there is a timeout before an update response.
838 TEST_F(SafeBrowsingProtocolManagerTest
, UpdateResponseTimeoutBackupSuccess
) {
839 scoped_refptr
<base::TestSimpleTaskRunner
> runner(
840 new base::TestSimpleTaskRunner());
841 base::ThreadTaskRunnerHandle
runner_handler(runner
);
842 net::TestURLFetcherFactory url_fetcher_factory
;
844 testing::StrictMock
<MockProtocolDelegate
> test_delegate
;
845 EXPECT_CALL(test_delegate
, UpdateStarted()).Times(1);
846 EXPECT_CALL(test_delegate
, GetChunks(_
)).WillOnce(
847 Invoke(testing::CreateFunctor(InvokeGetChunksCallback
,
848 std::vector
<SBListChunkRanges
>(),
850 EXPECT_CALL(test_delegate
, UpdateFinished(true)).Times(1);
852 scoped_ptr
<SafeBrowsingProtocolManager
> pm(
853 CreateProtocolManager(&test_delegate
));
855 // Kick off initialization. This returns chunks from the DB synchronously.
856 pm
->ForceScheduleNextUpdate(TimeDelta());
857 runner
->RunPendingTasks();
859 // We should have an URLFetcher at this point in time.
860 net::TestURLFetcher
* url_fetcher
= url_fetcher_factory
.GetFetcherByID(0);
861 ValidateUpdateFetcherRequest(url_fetcher
);
863 // The first time RunPendingTasks is called above, the update timeout timer is
864 // not handled. This call of RunPendingTasks will handle the update.
865 runner
->RunPendingTasks();
867 // There should be a backup URLFetcher now.
868 net::TestURLFetcher
* backup_url_fetcher
=
869 url_fetcher_factory
.GetFetcherByID(1);
870 ValidateUpdateFetcherRequest(backup_url_fetcher
,
871 kBackupConnectUrlPrefix
);
873 // Respond to the backup unsuccessfully.
874 backup_url_fetcher
->set_status(net::URLRequestStatus());
875 backup_url_fetcher
->set_response_code(200);
876 backup_url_fetcher
->SetResponseString(std::string());
877 backup_url_fetcher
->delegate()->OnURLFetchComplete(backup_url_fetcher
);
879 EXPECT_TRUE(pm
->IsUpdateScheduled());
882 // Tests what happens when there is a reset command in the response.
883 TEST_F(SafeBrowsingProtocolManagerTest
, UpdateResponseReset
) {
884 scoped_refptr
<base::TestSimpleTaskRunner
> runner(
885 new base::TestSimpleTaskRunner());
886 base::ThreadTaskRunnerHandle
runner_handler(runner
);
887 net::TestURLFetcherFactory url_fetcher_factory
;
889 testing::StrictMock
<MockProtocolDelegate
> test_delegate
;
890 EXPECT_CALL(test_delegate
, UpdateStarted()).Times(1);
891 EXPECT_CALL(test_delegate
, GetChunks(_
)).WillOnce(
892 Invoke(testing::CreateFunctor(InvokeGetChunksCallback
,
893 std::vector
<SBListChunkRanges
>(),
895 EXPECT_CALL(test_delegate
, ResetDatabase()).Times(1);
896 EXPECT_CALL(test_delegate
, UpdateFinished(true)).Times(1);
898 scoped_ptr
<SafeBrowsingProtocolManager
> pm(
899 CreateProtocolManager(&test_delegate
));
901 // Kick off initialization. This returns chunks from the DB synchronously.
902 pm
->ForceScheduleNextUpdate(TimeDelta());
903 runner
->RunPendingTasks();
905 net::TestURLFetcher
* url_fetcher
= url_fetcher_factory
.GetFetcherByID(0);
906 ValidateUpdateFetcherRequest(url_fetcher
);
908 // The update response is successful, and has a reset command.
909 url_fetcher
->set_status(net::URLRequestStatus());
910 url_fetcher
->set_response_code(200);
911 url_fetcher
->SetResponseString("r:pleasereset\n");
912 url_fetcher
->delegate()->OnURLFetchComplete(url_fetcher
);
914 EXPECT_TRUE(pm
->IsUpdateScheduled());
917 // Tests a single valid update response, followed by a single redirect response
918 // that has an valid, but empty body.
919 TEST_F(SafeBrowsingProtocolManagerTest
, EmptyRedirectResponse
) {
920 scoped_refptr
<base::TestSimpleTaskRunner
> runner(
921 new base::TestSimpleTaskRunner());
922 base::ThreadTaskRunnerHandle
runner_handler(runner
);
923 net::TestURLFetcherFactory url_fetcher_factory
;
925 testing::StrictMock
<MockProtocolDelegate
> test_delegate
;
926 EXPECT_CALL(test_delegate
, UpdateStarted()).Times(1);
927 EXPECT_CALL(test_delegate
, GetChunks(_
)).WillOnce(
928 Invoke(testing::CreateFunctor(InvokeGetChunksCallback
,
929 std::vector
<SBListChunkRanges
>(),
931 EXPECT_CALL(test_delegate
, UpdateFinished(true)).Times(1);
933 scoped_ptr
<SafeBrowsingProtocolManager
> pm(
934 CreateProtocolManager(&test_delegate
));
936 // Kick off initialization. This returns chunks from the DB synchronously.
937 pm
->ForceScheduleNextUpdate(TimeDelta());
938 runner
->RunPendingTasks();
940 // The update response contains a single redirect command.
941 net::TestURLFetcher
* url_fetcher
= url_fetcher_factory
.GetFetcherByID(0);
942 ValidateUpdateFetcherRequest(url_fetcher
);
943 url_fetcher
->set_status(net::URLRequestStatus());
944 url_fetcher
->set_response_code(200);
945 url_fetcher
->SetResponseString(
946 base::StringPrintf("i:%s\n"
947 "u:redirect-server.example.com/path\n",
949 url_fetcher
->delegate()->OnURLFetchComplete(url_fetcher
);
951 // The redirect response contains an empty body.
952 net::TestURLFetcher
* chunk_url_fetcher
=
953 url_fetcher_factory
.GetFetcherByID(1);
954 ValidateRedirectFetcherRequest(
955 chunk_url_fetcher
, "https://redirect-server.example.com/path");
956 chunk_url_fetcher
->set_status(net::URLRequestStatus());
957 chunk_url_fetcher
->set_response_code(200);
958 chunk_url_fetcher
->SetResponseString(std::string());
959 chunk_url_fetcher
->delegate()->OnURLFetchComplete(chunk_url_fetcher
);
961 EXPECT_TRUE(pm
->IsUpdateScheduled());
964 // Tests a single valid update response, followed by a single redirect response
965 // that has an invalid body.
966 TEST_F(SafeBrowsingProtocolManagerTest
, InvalidRedirectResponse
) {
967 scoped_refptr
<base::TestSimpleTaskRunner
> runner(
968 new base::TestSimpleTaskRunner());
969 base::ThreadTaskRunnerHandle
runner_handler(runner
);
970 net::TestURLFetcherFactory url_fetcher_factory
;
972 testing::StrictMock
<MockProtocolDelegate
> test_delegate
;
973 EXPECT_CALL(test_delegate
, UpdateStarted()).Times(1);
974 EXPECT_CALL(test_delegate
, GetChunks(_
)).WillOnce(
975 Invoke(testing::CreateFunctor(InvokeGetChunksCallback
,
976 std::vector
<SBListChunkRanges
>(),
978 EXPECT_CALL(test_delegate
, UpdateFinished(false)).Times(1);
980 scoped_ptr
<SafeBrowsingProtocolManager
> pm(
981 CreateProtocolManager(&test_delegate
));
983 // Kick off initialization. This returns chunks from the DB synchronously.
984 pm
->ForceScheduleNextUpdate(TimeDelta());
985 runner
->RunPendingTasks();
987 // The update response contains a single redirect command.
988 net::TestURLFetcher
* url_fetcher
= url_fetcher_factory
.GetFetcherByID(0);
989 ValidateUpdateFetcherRequest(url_fetcher
);
990 url_fetcher
->set_status(net::URLRequestStatus());
991 url_fetcher
->set_response_code(200);
992 url_fetcher
->SetResponseString(
993 base::StringPrintf("i:%s\n"
994 "u:redirect-server.example.com/path\n",
996 url_fetcher
->delegate()->OnURLFetchComplete(url_fetcher
);
998 // The redirect response contains an invalid body.
999 net::TestURLFetcher
* chunk_url_fetcher
=
1000 url_fetcher_factory
.GetFetcherByID(1);
1001 ValidateRedirectFetcherRequest(
1002 chunk_url_fetcher
, "https://redirect-server.example.com/path");
1003 chunk_url_fetcher
->set_status(net::URLRequestStatus());
1004 chunk_url_fetcher
->set_response_code(200);
1005 chunk_url_fetcher
->SetResponseString("THIS IS AN INVALID RESPONSE");
1006 chunk_url_fetcher
->delegate()->OnURLFetchComplete(chunk_url_fetcher
);
1008 EXPECT_TRUE(pm
->IsUpdateScheduled());
1011 // Tests a single valid update response, followed by a single redirect response
1012 // containing chunks.
1013 TEST_F(SafeBrowsingProtocolManagerTest
, SingleRedirectResponseWithChunks
) {
1014 scoped_refptr
<base::TestSimpleTaskRunner
> runner(
1015 new base::TestSimpleTaskRunner());
1016 base::ThreadTaskRunnerHandle
runner_handler(runner
);
1017 net::TestURLFetcherFactory url_fetcher_factory
;
1019 testing::StrictMock
<MockProtocolDelegate
> test_delegate
;
1020 EXPECT_CALL(test_delegate
, UpdateStarted()).Times(1);
1021 EXPECT_CALL(test_delegate
, GetChunks(_
)).WillOnce(
1022 Invoke(testing::CreateFunctor(InvokeGetChunksCallback
,
1023 std::vector
<SBListChunkRanges
>(),
1025 EXPECT_CALL(test_delegate
, AddChunksRaw(kDefaultPhishList
, _
, _
)).WillOnce(
1026 Invoke(HandleAddChunks
));
1027 EXPECT_CALL(test_delegate
, UpdateFinished(true)).Times(1);
1029 scoped_ptr
<SafeBrowsingProtocolManager
> pm(
1030 CreateProtocolManager(&test_delegate
));
1032 // Kick off initialization. This returns chunks from the DB synchronously.
1033 pm
->ForceScheduleNextUpdate(TimeDelta());
1034 runner
->RunPendingTasks();
1036 // The update response contains a single redirect command.
1037 net::TestURLFetcher
* url_fetcher
= url_fetcher_factory
.GetFetcherByID(0);
1038 ValidateUpdateFetcherRequest(url_fetcher
);
1039 url_fetcher
->set_status(net::URLRequestStatus());
1040 url_fetcher
->set_response_code(200);
1041 url_fetcher
->SetResponseString(
1042 base::StringPrintf("i:%s\n"
1043 "u:redirect-server.example.com/path\n",
1044 kDefaultPhishList
));
1045 url_fetcher
->delegate()->OnURLFetchComplete(url_fetcher
);
1047 // The redirect response contains a single chunk.
1048 net::TestURLFetcher
* chunk_url_fetcher
=
1049 url_fetcher_factory
.GetFetcherByID(1);
1050 ValidateRedirectFetcherRequest(
1051 chunk_url_fetcher
, "https://redirect-server.example.com/path");
1052 chunk_url_fetcher
->set_status(net::URLRequestStatus());
1053 chunk_url_fetcher
->set_response_code(200);
1054 chunk_url_fetcher
->SetResponseString(kChunkPayload1
);
1055 chunk_url_fetcher
->delegate()->OnURLFetchComplete(chunk_url_fetcher
);
1057 EXPECT_FALSE(pm
->IsUpdateScheduled());
1059 // The AddChunksCallback needs to be invoked.
1060 runner
->RunPendingTasks();
1062 EXPECT_TRUE(pm
->IsUpdateScheduled());
1065 // Tests a single valid update response, followed by multiple redirect responses
1066 // containing chunks.
1067 TEST_F(SafeBrowsingProtocolManagerTest
, MultipleRedirectResponsesWithChunks
) {
1068 scoped_refptr
<base::TestSimpleTaskRunner
> runner(
1069 new base::TestSimpleTaskRunner());
1070 base::ThreadTaskRunnerHandle
runner_handler(runner
);
1071 net::TestURLFetcherFactory url_fetcher_factory
;
1073 testing::StrictMock
<MockProtocolDelegate
> test_delegate
;
1074 EXPECT_CALL(test_delegate
, UpdateStarted()).Times(1);
1075 EXPECT_CALL(test_delegate
, GetChunks(_
)).WillOnce(
1076 Invoke(testing::CreateFunctor(InvokeGetChunksCallback
,
1077 std::vector
<SBListChunkRanges
>(),
1079 EXPECT_CALL(test_delegate
, AddChunksRaw(kDefaultPhishList
, _
, _
)).
1080 WillRepeatedly(Invoke(HandleAddChunks
));
1081 EXPECT_CALL(test_delegate
, UpdateFinished(true)).Times(1);
1083 scoped_ptr
<SafeBrowsingProtocolManager
> pm(
1084 CreateProtocolManager(&test_delegate
));
1086 // Kick off initialization. This returns chunks from the DB synchronously.
1087 pm
->ForceScheduleNextUpdate(TimeDelta());
1088 runner
->RunPendingTasks();
1090 // The update response contains multiple redirect commands.
1091 net::TestURLFetcher
* url_fetcher
= url_fetcher_factory
.GetFetcherByID(0);
1092 ValidateUpdateFetcherRequest(url_fetcher
);
1093 url_fetcher
->set_status(net::URLRequestStatus());
1094 url_fetcher
->set_response_code(200);
1095 url_fetcher
->SetResponseString(
1096 base::StringPrintf("i:%s\n"
1097 "u:redirect-server.example.com/one\n"
1098 "u:redirect-server.example.com/two\n",
1099 kDefaultPhishList
));
1100 url_fetcher
->delegate()->OnURLFetchComplete(url_fetcher
);
1102 // The first redirect response contains a single chunk.
1103 net::TestURLFetcher
* first_chunk_url_fetcher
=
1104 url_fetcher_factory
.GetFetcherByID(1);
1105 ValidateRedirectFetcherRequest(
1106 first_chunk_url_fetcher
, "https://redirect-server.example.com/one");
1107 first_chunk_url_fetcher
->set_status(net::URLRequestStatus());
1108 first_chunk_url_fetcher
->set_response_code(200);
1109 first_chunk_url_fetcher
->SetResponseString(kChunkPayload1
);
1110 first_chunk_url_fetcher
->delegate()->OnURLFetchComplete(
1111 first_chunk_url_fetcher
);
1113 // Invoke the AddChunksCallback to trigger the second request.
1114 runner
->RunPendingTasks();
1116 EXPECT_FALSE(pm
->IsUpdateScheduled());
1118 // The second redirect response contains a single chunk.
1119 net::TestURLFetcher
* second_chunk_url_fetcher
=
1120 url_fetcher_factory
.GetFetcherByID(2);
1121 ValidateRedirectFetcherRequest(
1122 second_chunk_url_fetcher
, "https://redirect-server.example.com/two");
1123 second_chunk_url_fetcher
->set_status(net::URLRequestStatus());
1124 second_chunk_url_fetcher
->set_response_code(200);
1125 second_chunk_url_fetcher
->SetResponseString(kChunkPayload2
);
1126 second_chunk_url_fetcher
->delegate()->OnURLFetchComplete(
1127 second_chunk_url_fetcher
);
1129 EXPECT_FALSE(pm
->IsUpdateScheduled());
1131 // Invoke the AddChunksCallback to finish the update.
1132 runner
->RunPendingTasks();
1134 EXPECT_TRUE(pm
->IsUpdateScheduled());