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// This test uses the safebrowsing test server published at 6// http://code.google.com/p/google-safe-browsing/ to test the safebrowsing 7// protocol implemetation. Details of the safebrowsing testing flow is 8// documented at 9// http://code.google.com/p/google-safe-browsing/wiki/ProtocolTesting 10// 11// This test launches safebrowsing test server and issues several update 12// requests against that server. Each update would get different data and after 13// each update, the test will get a list of URLs from the test server to verify 14// its repository. The test will succeed only if all updates are performed and 15// URLs match what the server expected. 16 17#include <vector> 18 19#include "base/command_line.h" 20#include "base/environment.h" 21#include "base/path_service.h" 22#include "base/process_util.h" 23#include "base/string_number_conversions.h" 24#include "base/string_util.h" 25#include "base/string_split.h" 26#include "base/synchronization/lock.h" 27#include "base/threading/platform_thread.h" 28#include "base/time.h" 29#include "base/utf_string_conversions.h" 30#include "chrome/browser/browser_process.h" 31#include "chrome/browser/profiles/profile.h" 32#include "chrome/browser/safe_browsing/protocol_manager.h" 33#include "chrome/browser/safe_browsing/safe_browsing_service.h" 34#include "chrome/common/chrome_switches.h" 35#include "chrome/common/url_constants.h" 36#include "chrome/test/in_process_browser_test.h" 37#include "content/browser/browser_thread.h" 38#include "content/browser/renderer_host/resource_dispatcher_host.h" 39#include "base/test/test_timeouts.h" 40#include "chrome/test/ui_test_utils.h" 41#include "net/base/host_resolver.h" 42#include "net/base/load_flags.h" 43#include "net/base/net_log.h" 44#include "net/test/python_utils.h" 45#include "testing/gtest/include/gtest/gtest.h" 46 47namespace { 48 49const FilePath::CharType kDataFile[] = FILE_PATH_LITERAL("testing_input.dat"); 50const char kUrlVerifyPath[] = "/safebrowsing/verify_urls"; 51const char kDBVerifyPath[] = "/safebrowsing/verify_database"; 52const char kDBResetPath[] = "/reset"; 53const char kTestCompletePath[] = "/test_complete"; 54 55struct PhishingUrl { 56 std::string url; 57 std::string list_name; 58 bool is_phishing; 59}; 60 61// Parses server response for verify_urls. The expected format is: 62// 63// first.random.url.com/ internal-test-shavar yes 64// second.random.url.com/ internal-test-shavar yes 65// ... 66bool ParsePhishingUrls(const std::string& data, 67 std::vector<PhishingUrl>* phishing_urls) { 68 if (data.empty()) 69 return false; 70 71 std::vector<std::string> urls; 72 base::SplitString(data, '\n', &urls); 73 for (size_t i = 0; i < urls.size(); ++i) { 74 if (urls[i].empty()) 75 continue; 76 PhishingUrl phishing_url; 77 std::vector<std::string> record_parts; 78 base::SplitString(urls[i], '\t', &record_parts); 79 if (record_parts.size() != 3) { 80 LOG(ERROR) << "Unexpected URL format in phishing URL list: " 81 << urls[i]; 82 return false; 83 } 84 phishing_url.url = std::string(chrome::kHttpScheme) + 85 "://" + record_parts[0]; 86 phishing_url.list_name = record_parts[1]; 87 if (record_parts[2] == "yes") { 88 phishing_url.is_phishing = true; 89 } else if (record_parts[2] == "no") { 90 phishing_url.is_phishing = false; 91 } else { 92 LOG(ERROR) << "Unrecognized expectation in " << urls[i] 93 << ": " << record_parts[2]; 94 return false; 95 } 96 phishing_urls->push_back(phishing_url); 97 } 98 return true; 99} 100 101} // namespace 102 103class SafeBrowsingTestServer { 104 public: 105 explicit SafeBrowsingTestServer(const FilePath& datafile) 106 : datafile_(datafile), 107 server_handle_(base::kNullProcessHandle) { 108 } 109 110 ~SafeBrowsingTestServer() { 111 EXPECT_EQ(base::kNullProcessHandle, server_handle_); 112 } 113 114 // Start the python server test suite. 115 bool Start() { 116 // Get path to python server script 117 FilePath testserver_path; 118 if (!PathService::Get(base::DIR_SOURCE_ROOT, &testserver_path)) { 119 LOG(ERROR) << "Failed to get DIR_SOURCE_ROOT"; 120 return false; 121 } 122 testserver_path = testserver_path 123 .Append(FILE_PATH_LITERAL("third_party")) 124 .Append(FILE_PATH_LITERAL("safe_browsing")) 125 .Append(FILE_PATH_LITERAL("testing")); 126 AppendToPythonPath(testserver_path); 127 FilePath testserver = testserver_path.Append( 128 FILE_PATH_LITERAL("safebrowsing_test_server.py")); 129 130 FilePath pyproto_code_dir; 131 if (!GetPyProtoPath(&pyproto_code_dir)) { 132 LOG(ERROR) << "Failed to get generated python protobuf dir"; 133 return false; 134 } 135 AppendToPythonPath(pyproto_code_dir); 136 pyproto_code_dir = pyproto_code_dir.Append(FILE_PATH_LITERAL("google")); 137 AppendToPythonPath(pyproto_code_dir); 138 139 FilePath python_runtime; 140 EXPECT_TRUE(GetPythonRunTime(&python_runtime)); 141 CommandLine cmd_line(python_runtime); 142 FilePath datafile = testserver_path.Append(datafile_); 143 cmd_line.AppendArgPath(testserver); 144 cmd_line.AppendSwitchASCII("port", StringPrintf("%d", kPort_)); 145 cmd_line.AppendSwitchPath("datafile", datafile); 146 147 if (!base::LaunchApp(cmd_line, false, true, &server_handle_)) { 148 LOG(ERROR) << "Failed to launch server: " 149 << cmd_line.command_line_string(); 150 return false; 151 } 152 return true; 153 } 154 155 // Stop the python server test suite. 156 bool Stop() { 157 if (server_handle_ == base::kNullProcessHandle) 158 return true; 159 160 // First check if the process has already terminated. 161 if (!base::WaitForSingleProcess(server_handle_, 0) && 162 !base::KillProcess(server_handle_, 1, true)) { 163 VLOG(1) << "Kill failed?"; 164 return false; 165 } 166 167 base::CloseProcessHandle(server_handle_); 168 server_handle_ = base::kNullProcessHandle; 169 VLOG(1) << "Stopped."; 170 return true; 171 } 172 173 static const char* Host() { 174 return kHost_; 175 } 176 177 static int Port() { 178 return kPort_; 179 } 180 181 private: 182 static const char kHost_[]; 183 static const int kPort_; 184 FilePath datafile_; 185 base::ProcessHandle server_handle_; 186 DISALLOW_COPY_AND_ASSIGN(SafeBrowsingTestServer); 187}; 188 189const char SafeBrowsingTestServer::kHost_[] = "localhost"; 190const int SafeBrowsingTestServer::kPort_ = 40102; 191 192// This starts the browser and keeps status of states related to SafeBrowsing. 193class SafeBrowsingServiceTest : public InProcessBrowserTest { 194 public: 195 SafeBrowsingServiceTest() 196 : safe_browsing_service_(NULL), 197 is_database_ready_(true), 198 is_initial_request_(false), 199 is_update_scheduled_(false), 200 is_checked_url_in_db_(false), 201 is_checked_url_safe_(false) { 202 } 203 204 virtual ~SafeBrowsingServiceTest() { 205 } 206 207 void UpdateSafeBrowsingStatus() { 208 ASSERT_TRUE(safe_browsing_service_); 209 base::AutoLock lock(update_status_mutex_); 210 is_initial_request_ = 211 safe_browsing_service_->protocol_manager_->is_initial_request(); 212 last_update_ = safe_browsing_service_->protocol_manager_->last_update(); 213 is_update_scheduled_ = 214 safe_browsing_service_->protocol_manager_->update_timer_.IsRunning(); 215 } 216 217 void ForceUpdate() { 218 ASSERT_TRUE(safe_browsing_service_); 219 safe_browsing_service_->protocol_manager_->ForceScheduleNextUpdate(0); 220 } 221 222 void CheckIsDatabaseReady() { 223 base::AutoLock lock(update_status_mutex_); 224 is_database_ready_ = 225 !safe_browsing_service_->database_update_in_progress_; 226 } 227 228 void CheckUrl(SafeBrowsingService::Client* helper, const GURL& url) { 229 ASSERT_TRUE(safe_browsing_service_); 230 base::AutoLock lock(update_status_mutex_); 231 if (safe_browsing_service_->CheckBrowseUrl(url, helper)) { 232 is_checked_url_in_db_ = false; 233 is_checked_url_safe_ = true; 234 } else { 235 // In this case, Safebrowsing service will fetch the full hash 236 // from the server and examine that. Once it is done, 237 // set_is_checked_url_safe() will be called via callback. 238 is_checked_url_in_db_ = true; 239 } 240 } 241 242 bool is_checked_url_in_db() { 243 base::AutoLock l(update_status_mutex_); 244 return is_checked_url_in_db_; 245 } 246 247 void set_is_checked_url_safe(bool safe) { 248 base::AutoLock l(update_status_mutex_); 249 is_checked_url_safe_ = safe; 250 } 251 252 bool is_checked_url_safe() { 253 base::AutoLock l(update_status_mutex_); 254 return is_checked_url_safe_; 255 } 256 257 bool is_database_ready() { 258 base::AutoLock l(update_status_mutex_); 259 return is_database_ready_; 260 } 261 262 bool is_initial_request() { 263 base::AutoLock l(update_status_mutex_); 264 return is_initial_request_; 265 } 266 267 base::Time last_update() { 268 base::AutoLock l(update_status_mutex_); 269 return last_update_; 270 } 271 272 bool is_update_scheduled() { 273 base::AutoLock l(update_status_mutex_); 274 return is_update_scheduled_; 275 } 276 277 MessageLoop* SafeBrowsingMessageLoop() { 278 return safe_browsing_service_->safe_browsing_thread_->message_loop(); 279 } 280 281 protected: 282 bool InitSafeBrowsingService() { 283 safe_browsing_service_ = 284 g_browser_process->resource_dispatcher_host()->safe_browsing_service(); 285 return safe_browsing_service_ != NULL; 286 } 287 288 virtual void SetUpCommandLine(CommandLine* command_line) { 289 // Makes sure the auto update is not triggered. This test will force the 290 // update when needed. 291 command_line->AppendSwitch(switches::kSbDisableAutoUpdate); 292 293 // This test uses loopback. No need to use IPv6 especially it makes 294 // local requests slow on Windows trybot when ipv6 local address [::1] 295 // is not setup. 296 command_line->AppendSwitch(switches::kDisableIPv6); 297 298 // TODO(lzheng): The test server does not understand download related 299 // requests. We need to fix the server. 300 command_line->AppendSwitch(switches::kSbDisableDownloadProtection); 301 302 // In this test, we fetch SafeBrowsing data and Mac key from the same 303 // server. Although in real production, they are served from different 304 // servers. 305 std::string url_prefix = 306 StringPrintf("http://%s:%d/safebrowsing", 307 SafeBrowsingTestServer::Host(), 308 SafeBrowsingTestServer::Port()); 309 command_line->AppendSwitchASCII(switches::kSbInfoURLPrefix, url_prefix); 310 command_line->AppendSwitchASCII(switches::kSbMacKeyURLPrefix, url_prefix); 311 } 312 313 void SetTestStep(int step) { 314 std::string test_step = StringPrintf("test_step=%d", step); 315 safe_browsing_service_->protocol_manager_->set_additional_query(test_step); 316 } 317 318 private: 319 SafeBrowsingService* safe_browsing_service_; 320 321 // Protects all variables below since they are read on UI thread 322 // but updated on IO thread or safebrowsing thread. 323 base::Lock update_status_mutex_; 324 325 // States associated with safebrowsing service updates. 326 bool is_database_ready_; 327 bool is_initial_request_; 328 base::Time last_update_; 329 bool is_update_scheduled_; 330 // Indicates if there is a match between a URL's prefix and safebrowsing 331 // database (thus potentially it is a phishing URL). 332 bool is_checked_url_in_db_; 333 // True if last verified URL is not a phishing URL and thus it is safe. 334 bool is_checked_url_safe_; 335 336 DISALLOW_COPY_AND_ASSIGN(SafeBrowsingServiceTest); 337}; 338 339// A ref counted helper class that handles callbacks between IO thread and UI 340// thread. 341class SafeBrowsingServiceTestHelper 342 : public base::RefCountedThreadSafe<SafeBrowsingServiceTestHelper>, 343 public SafeBrowsingService::Client, 344 public URLFetcher::Delegate { 345 public: 346 explicit SafeBrowsingServiceTestHelper( 347 SafeBrowsingServiceTest* safe_browsing_test) 348 : safe_browsing_test_(safe_browsing_test), 349 response_status_(net::URLRequestStatus::FAILED) { 350 } 351 352 // Callbacks for SafeBrowsingService::Client. 353 virtual void OnBrowseUrlCheckResult( 354 const GURL& url, SafeBrowsingService::UrlCheckResult result) { 355 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO)); 356 EXPECT_TRUE(safe_browsing_test_->is_checked_url_in_db()); 357 safe_browsing_test_->set_is_checked_url_safe( 358 result == SafeBrowsingService::SAFE); 359 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 360 NewRunnableMethod(this, 361 &SafeBrowsingServiceTestHelper::OnCheckUrlDone)); 362 } 363 virtual void OnDownloadUrlCheckResult( 364 const std::vector<GURL>& url_chain, 365 SafeBrowsingService::UrlCheckResult result) { 366 // TODO(lzheng): Add test for DownloadUrl. 367 } 368 369 virtual void OnBlockingPageComplete(bool proceed) { 370 NOTREACHED() << "Not implemented."; 371 } 372 373 // Functions and callbacks to start the safebrowsing database update. 374 void ForceUpdate() { 375 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, 376 NewRunnableMethod(this, 377 &SafeBrowsingServiceTestHelper::ForceUpdateInIOThread)); 378 // Will continue after OnForceUpdateDone(). 379 ui_test_utils::RunMessageLoop(); 380 } 381 void ForceUpdateInIOThread() { 382 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO)); 383 safe_browsing_test_->ForceUpdate(); 384 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 385 NewRunnableMethod(this, 386 &SafeBrowsingServiceTestHelper::OnForceUpdateDone)); 387 } 388 void OnForceUpdateDone() { 389 StopUILoop(); 390 } 391 392 // Functions and callbacks related to CheckUrl. These are used to verify 393 // phishing URLs. 394 void CheckUrl(const GURL& url) { 395 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, NewRunnableMethod( 396 this, &SafeBrowsingServiceTestHelper::CheckUrlOnIOThread, url)); 397 ui_test_utils::RunMessageLoop(); 398 } 399 void CheckUrlOnIOThread(const GURL& url) { 400 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO)); 401 safe_browsing_test_->CheckUrl(this, url); 402 if (!safe_browsing_test_->is_checked_url_in_db()) { 403 // Ends the checking since this URL's prefix is not in database. 404 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, NewRunnableMethod( 405 this, &SafeBrowsingServiceTestHelper::OnCheckUrlDone)); 406 } 407 // Otherwise, OnCheckUrlDone is called in OnUrlCheckResult since 408 // safebrowsing service further fetches hashes from safebrowsing server. 409 } 410 411 void OnCheckUrlDone() { 412 StopUILoop(); 413 } 414 415 // Updates status from IO Thread. 416 void CheckStatusOnIOThread() { 417 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO)); 418 safe_browsing_test_->UpdateSafeBrowsingStatus(); 419 safe_browsing_test_->SafeBrowsingMessageLoop()->PostTask( 420 FROM_HERE, NewRunnableMethod(this, 421 &SafeBrowsingServiceTestHelper::CheckIsDatabaseReady)); 422 } 423 424 // Checks status in SafeBrowsing Thread. 425 void CheckIsDatabaseReady() { 426 EXPECT_EQ(MessageLoop::current(), 427 safe_browsing_test_->SafeBrowsingMessageLoop()); 428 safe_browsing_test_->CheckIsDatabaseReady(); 429 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, NewRunnableMethod( 430 this, &SafeBrowsingServiceTestHelper::OnWaitForStatusUpdateDone)); 431 } 432 433 void OnWaitForStatusUpdateDone() { 434 StopUILoop(); 435 } 436 437 // Wait for a given period to get safebrowsing status updated. 438 void WaitForStatusUpdate(int64 wait_time_msec) { 439 BrowserThread::PostDelayedTask( 440 BrowserThread::IO, 441 FROM_HERE, 442 NewRunnableMethod(this, 443 &SafeBrowsingServiceTestHelper::CheckStatusOnIOThread), 444 wait_time_msec); 445 // Will continue after OnWaitForStatusUpdateDone(). 446 ui_test_utils::RunMessageLoop(); 447 } 448 449 void WaitTillServerReady(const char* host, int port) { 450 response_status_ = net::URLRequestStatus::FAILED; 451 GURL url(StringPrintf("http://%s:%d%s?test_step=0", 452 host, port, kDBResetPath)); 453 // TODO(lzheng): We should have a way to reliably tell when a server is 454 // ready so we could get rid of the Sleep and retry loop. 455 while (true) { 456 if (FetchUrl(url) == net::URLRequestStatus::SUCCESS) 457 break; 458 // Wait and try again if last fetch was failed. The loop will hit the 459 // timeout in OutOfProcTestRunner if the fetch can not get success 460 // response. 461 base::PlatformThread::Sleep(TestTimeouts::action_timeout_ms()); 462 } 463 } 464 465 // Calls test server to fetch database for verification. 466 net::URLRequestStatus::Status FetchDBToVerify(const char* host, int port, 467 int test_step) { 468 // TODO(lzheng): Remove chunk_type=add once it is not needed by the server. 469 GURL url(StringPrintf("http://%s:%d%s?" 470 "client=chromium&appver=1.0&pver=2.2&test_step=%d&" 471 "chunk_type=add", 472 host, port, kDBVerifyPath, test_step)); 473 return FetchUrl(url); 474 } 475 476 // Calls test server to fetch URLs for verification. 477 net::URLRequestStatus::Status FetchUrlsToVerify(const char* host, int port, 478 int test_step) { 479 GURL url(StringPrintf("http://%s:%d%s?" 480 "client=chromium&appver=1.0&pver=2.2&test_step=%d", 481 host, port, kUrlVerifyPath, test_step)); 482 return FetchUrl(url); 483 } 484 485 // Calls test server to check if test data is done. E.g.: if there is a 486 // bad URL that server expects test to fetch full hash but the test didn't, 487 // this verification will fail. 488 net::URLRequestStatus::Status VerifyTestComplete(const char* host, int port, 489 int test_step) { 490 GURL url(StringPrintf("http://%s:%d%s?test_step=%d", 491 host, port, kTestCompletePath, test_step)); 492 return FetchUrl(url); 493 } 494 495 // Callback for URLFetcher. 496 virtual void OnURLFetchComplete(const URLFetcher* source, 497 const GURL& url, 498 const net::URLRequestStatus& status, 499 int response_code, 500 const ResponseCookies& cookies, 501 const std::string& data) { 502 response_data_ = data; 503 response_status_ = status.status(); 504 StopUILoop(); 505 } 506 507 const std::string& response_data() { 508 return response_data_; 509 } 510 511 private: 512 // Stops UI loop after desired status is updated. 513 void StopUILoop() { 514 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::UI)); 515 MessageLoopForUI::current()->Quit(); 516 } 517 518 // Fetch a URL. If message_loop_started is true, starts the message loop 519 // so the caller could wait till OnURLFetchComplete is called. 520 net::URLRequestStatus::Status FetchUrl(const GURL& url) { 521 url_fetcher_.reset(new URLFetcher(url, URLFetcher::GET, this)); 522 url_fetcher_->set_load_flags(net::LOAD_DISABLE_CACHE); 523 url_fetcher_->set_request_context(Profile::GetDefaultRequestContext()); 524 url_fetcher_->Start(); 525 ui_test_utils::RunMessageLoop(); 526 return response_status_; 527 } 528 529 base::OneShotTimer<SafeBrowsingServiceTestHelper> check_update_timer_; 530 SafeBrowsingServiceTest* safe_browsing_test_; 531 scoped_ptr<URLFetcher> url_fetcher_; 532 std::string response_data_; 533 net::URLRequestStatus::Status response_status_; 534 DISALLOW_COPY_AND_ASSIGN(SafeBrowsingServiceTestHelper); 535}; 536 537IN_PROC_BROWSER_TEST_F(SafeBrowsingServiceTest, SafeBrowsingSystemTest) { 538 LOG(INFO) << "Start test"; 539 const char* server_host = SafeBrowsingTestServer::Host(); 540 int server_port = SafeBrowsingTestServer::Port(); 541 ASSERT_TRUE(InitSafeBrowsingService()); 542 543 scoped_refptr<SafeBrowsingServiceTestHelper> safe_browsing_helper( 544 new SafeBrowsingServiceTestHelper(this)); 545 int last_step = 0; 546 FilePath datafile_path = FilePath(kDataFile); 547 SafeBrowsingTestServer test_server(datafile_path); 548 ASSERT_TRUE(test_server.Start()); 549 550 // Make sure the server is running. 551 safe_browsing_helper->WaitTillServerReady(server_host, server_port); 552 553 // Waits and makes sure safebrowsing update is not happening. 554 // The wait will stop once OnWaitForStatusUpdateDone in 555 // safe_browsing_helper is called and status from safe_browsing_service_ 556 // is checked. 557 safe_browsing_helper->WaitForStatusUpdate(0); 558 EXPECT_TRUE(is_database_ready()); 559 EXPECT_TRUE(is_initial_request()); 560 EXPECT_FALSE(is_update_scheduled()); 561 EXPECT_TRUE(last_update().is_null()); 562 // Starts updates. After each update, the test will fetch a list of URLs with 563 // expected results to verify with safebrowsing service. If there is no error, 564 // the test moves on to the next step to get more update chunks. 565 // This repeats till there is no update data. 566 for (int step = 1;; step++) { 567 // Every step should be a fresh start. 568 SCOPED_TRACE(StringPrintf("step=%d", step)); 569 EXPECT_TRUE(is_database_ready()); 570 EXPECT_FALSE(is_update_scheduled()); 571 572 // Starts safebrowsing update on IO thread. Waits till scheduled 573 // update finishes. Stops waiting after kMaxWaitSecPerStep if the update 574 // could not finish. 575 base::Time now = base::Time::Now(); 576 SetTestStep(step); 577 safe_browsing_helper->ForceUpdate(); 578 579 do { 580 // Periodically pull the status. 581 safe_browsing_helper->WaitForStatusUpdate( 582 TestTimeouts::action_timeout_ms()); 583 } while (is_update_scheduled() || is_initial_request() || 584 !is_database_ready()); 585 586 587 if (last_update() < now) { 588 // This means no data available anymore. 589 break; 590 } 591 592 // Fetches URLs to verify and waits till server responses with data. 593 EXPECT_EQ(net::URLRequestStatus::SUCCESS, 594 safe_browsing_helper->FetchUrlsToVerify(server_host, 595 server_port, 596 step)); 597 598 std::vector<PhishingUrl> phishing_urls; 599 EXPECT_TRUE(ParsePhishingUrls(safe_browsing_helper->response_data(), 600 &phishing_urls)); 601 EXPECT_GT(phishing_urls.size(), 0U); 602 for (size_t j = 0; j < phishing_urls.size(); ++j) { 603 // Verifes with server if a URL is a phishing URL and waits till server 604 // responses. 605 safe_browsing_helper->CheckUrl(GURL(phishing_urls[j].url)); 606 if (phishing_urls[j].is_phishing) { 607 EXPECT_TRUE(is_checked_url_in_db()) 608 << phishing_urls[j].url 609 << " is_phishing: " << phishing_urls[j].is_phishing 610 << " test step: " << step; 611 EXPECT_FALSE(is_checked_url_safe()) 612 << phishing_urls[j].url 613 << " is_phishing: " << phishing_urls[j].is_phishing 614 << " test step: " << step; 615 } else { 616 EXPECT_TRUE(is_checked_url_safe()) 617 << phishing_urls[j].url 618 << " is_phishing: " << phishing_urls[j].is_phishing 619 << " test step: " << step; 620 } 621 } 622 // TODO(lzheng): We should verify the fetched database with local 623 // database to make sure they match. 624 EXPECT_EQ(net::URLRequestStatus::SUCCESS, 625 safe_browsing_helper->FetchDBToVerify(server_host, 626 server_port, 627 step)); 628 EXPECT_GT(safe_browsing_helper->response_data().size(), 0U); 629 last_step = step; 630 } 631 632 // Verifies with server if test is done and waits till server responses. 633 EXPECT_EQ(net::URLRequestStatus::SUCCESS, 634 safe_browsing_helper->VerifyTestComplete(server_host, 635 server_port, 636 last_step)); 637 EXPECT_EQ("yes", safe_browsing_helper->response_data()); 638 test_server.Stop(); 639} 640