| OLD | NEW |
| (Empty) |
| 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. | |
| 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 <stddef.h> | |
| 20 | |
| 21 #include "base/bind.h" | |
| 22 #include "base/command_line.h" | |
| 23 #include "base/environment.h" | |
| 24 #include "base/macros.h" | |
| 25 #include "base/path_service.h" | |
| 26 #include "base/strings/string_number_conversions.h" | |
| 27 #include "base/strings/string_split.h" | |
| 28 #include "base/strings/stringprintf.h" | |
| 29 #include "base/strings/utf_string_conversions.h" | |
| 30 #include "base/synchronization/lock.h" | |
| 31 #include "base/test/test_timeouts.h" | |
| 32 #include "base/threading/platform_thread.h" | |
| 33 #include "base/threading/thread.h" | |
| 34 #include "base/time/time.h" | |
| 35 #include "chrome/browser/browser_process.h" | |
| 36 #include "chrome/browser/chrome_notification_types.h" | |
| 37 #include "chrome/browser/profiles/profile.h" | |
| 38 #include "chrome/browser/safe_browsing/local_database_manager.h" | |
| 39 #include "chrome/browser/safe_browsing/local_safebrowsing_test_server.h" | |
| 40 #include "chrome/browser/safe_browsing/protocol_manager.h" | |
| 41 #include "chrome/browser/safe_browsing/test_safe_browsing_service.h" | |
| 42 #include "chrome/browser/ui/browser.h" | |
| 43 #include "chrome/common/chrome_switches.h" | |
| 44 #include "chrome/common/url_constants.h" | |
| 45 #include "chrome/test/base/in_process_browser_test.h" | |
| 46 #include "components/safe_browsing_db/database_manager.h" | |
| 47 #include "content/public/browser/browser_context.h" | |
| 48 #include "content/public/test/test_browser_thread.h" | |
| 49 #include "content/public/test/test_utils.h" | |
| 50 #include "net/base/load_flags.h" | |
| 51 #include "net/dns/host_resolver.h" | |
| 52 #include "net/log/net_log.h" | |
| 53 #include "net/test/python_utils.h" | |
| 54 #include "net/test/spawned_test_server/spawned_test_server.h" | |
| 55 #include "net/url_request/url_fetcher.h" | |
| 56 #include "net/url_request/url_fetcher_delegate.h" | |
| 57 #include "net/url_request/url_request_status.h" | |
| 58 #include "testing/gtest/include/gtest/gtest.h" | |
| 59 | |
| 60 using content::BrowserThread; | |
| 61 | |
| 62 #ifndef SAFE_BROWSING_DB_LOCAL | |
| 63 #error This test requires the SAFE_BROWSING_DB_LOCAL implementation. | |
| 64 #endif | |
| 65 | |
| 66 namespace safe_browsing { | |
| 67 | |
| 68 namespace { | |
| 69 | |
| 70 const base::FilePath::CharType kDataFile[] = | |
| 71 FILE_PATH_LITERAL("testing_input_nomac.dat"); | |
| 72 const char kUrlVerifyPath[] = "safebrowsing/verify_urls"; | |
| 73 const char kDBVerifyPath[] = "safebrowsing/verify_database"; | |
| 74 const char kTestCompletePath[] = "test_complete"; | |
| 75 | |
| 76 struct PhishingUrl { | |
| 77 std::string url; | |
| 78 std::string list_name; | |
| 79 bool is_phishing; | |
| 80 }; | |
| 81 | |
| 82 // Parses server response for verify_urls. The expected format is: | |
| 83 // | |
| 84 // first.random.url.com/ internal-test-shavar yes | |
| 85 // second.random.url.com/ internal-test-shavar yes | |
| 86 // ... | |
| 87 bool ParsePhishingUrls(const std::string& data, | |
| 88 std::vector<PhishingUrl>* phishing_urls) { | |
| 89 if (data.empty()) | |
| 90 return false; | |
| 91 | |
| 92 for (const base::StringPiece& url_str : base::SplitStringPiece( | |
| 93 data, "\n", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY)) { | |
| 94 PhishingUrl phishing_url; | |
| 95 std::vector<std::string> record_parts = base::SplitString( | |
| 96 url_str, "\t", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); | |
| 97 if (record_parts.size() != 3) { | |
| 98 LOG(ERROR) << "Unexpected URL format in phishing URL list: " | |
| 99 << url_str.as_string(); | |
| 100 return false; | |
| 101 } | |
| 102 phishing_url.url = std::string(url::kHttpScheme) + "://" + record_parts[0]; | |
| 103 phishing_url.list_name = record_parts[1]; | |
| 104 if (record_parts[2] == "yes") { | |
| 105 phishing_url.is_phishing = true; | |
| 106 } else if (record_parts[2] == "no") { | |
| 107 phishing_url.is_phishing = false; | |
| 108 } else { | |
| 109 LOG(ERROR) << "Unrecognized expectation in " << url_str.as_string() | |
| 110 << ": " << record_parts[2]; | |
| 111 return false; | |
| 112 } | |
| 113 phishing_urls->push_back(phishing_url); | |
| 114 } | |
| 115 return true; | |
| 116 } | |
| 117 | |
| 118 } // namespace | |
| 119 | |
| 120 // This starts the browser and keeps status of states related to SafeBrowsing. | |
| 121 class SafeBrowsingServerTest : public InProcessBrowserTest { | |
| 122 public: | |
| 123 SafeBrowsingServerTest() | |
| 124 : is_database_ready_(true), | |
| 125 is_update_scheduled_(false), | |
| 126 is_checked_url_in_db_(false), | |
| 127 is_checked_url_safe_(false) {} | |
| 128 | |
| 129 ~SafeBrowsingServerTest() override {} | |
| 130 | |
| 131 void UpdateSafeBrowsingStatus() { | |
| 132 ASSERT_TRUE(sb_factory_->test_safe_browsing_service()); | |
| 133 base::AutoLock lock(update_status_mutex_); | |
| 134 last_update_ = sb_factory_->test_safe_browsing_service() | |
| 135 ->protocol_manager_->last_update(); | |
| 136 is_update_scheduled_ = sb_factory_->test_safe_browsing_service() | |
| 137 ->protocol_manager_->update_timer_.IsRunning(); | |
| 138 } | |
| 139 | |
| 140 void ForceUpdate() { | |
| 141 content::WindowedNotificationObserver observer( | |
| 142 chrome::NOTIFICATION_SAFE_BROWSING_UPDATE_COMPLETE, | |
| 143 content::Source<SafeBrowsingDatabaseManager>(database_manager())); | |
| 144 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, | |
| 145 base::Bind(&SafeBrowsingServerTest::ForceUpdateOnIOThread, | |
| 146 this)); | |
| 147 observer.Wait(); | |
| 148 } | |
| 149 | |
| 150 void ForceUpdateOnIOThread() { | |
| 151 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
| 152 ASSERT_TRUE(sb_factory_->test_safe_browsing_service()); | |
| 153 sb_factory_->test_safe_browsing_service() | |
| 154 ->protocol_manager_->ForceScheduleNextUpdate( | |
| 155 base::TimeDelta::FromSeconds(0)); | |
| 156 } | |
| 157 | |
| 158 | |
| 159 void CheckIsDatabaseReady() { | |
| 160 base::AutoLock lock(update_status_mutex_); | |
| 161 is_database_ready_ = | |
| 162 !local_database_manager()->database_update_in_progress_; | |
| 163 } | |
| 164 | |
| 165 void CheckUrl(SafeBrowsingDatabaseManager::Client* helper, const GURL& url) { | |
| 166 ASSERT_TRUE(sb_factory_->test_safe_browsing_service()); | |
| 167 base::AutoLock lock(update_status_mutex_); | |
| 168 if (database_manager()->CheckBrowseUrl(url, helper)) { | |
| 169 is_checked_url_in_db_ = false; | |
| 170 is_checked_url_safe_ = true; | |
| 171 } else { | |
| 172 // In this case, Safebrowsing service will fetch the full hash | |
| 173 // from the server and examine that. Once it is done, | |
| 174 // set_is_checked_url_safe() will be called via callback. | |
| 175 is_checked_url_in_db_ = true; | |
| 176 } | |
| 177 } | |
| 178 | |
| 179 SafeBrowsingDatabaseManager* database_manager() { | |
| 180 return sb_factory_->test_safe_browsing_service()->database_manager().get(); | |
| 181 } | |
| 182 | |
| 183 // TODO(nparker): Remove the need for this by wiring in our own | |
| 184 // SafeBrowsingDatabaseManager factory and keep a ptr to the subclass. | |
| 185 LocalSafeBrowsingDatabaseManager* local_database_manager() { | |
| 186 return static_cast<LocalSafeBrowsingDatabaseManager*>(database_manager()); | |
| 187 } | |
| 188 | |
| 189 | |
| 190 bool is_checked_url_in_db() { | |
| 191 base::AutoLock l(update_status_mutex_); | |
| 192 return is_checked_url_in_db_; | |
| 193 } | |
| 194 | |
| 195 void set_is_checked_url_safe(bool safe) { | |
| 196 base::AutoLock l(update_status_mutex_); | |
| 197 is_checked_url_safe_ = safe; | |
| 198 } | |
| 199 | |
| 200 bool is_checked_url_safe() { | |
| 201 base::AutoLock l(update_status_mutex_); | |
| 202 return is_checked_url_safe_; | |
| 203 } | |
| 204 | |
| 205 bool is_database_ready() { | |
| 206 base::AutoLock l(update_status_mutex_); | |
| 207 return is_database_ready_; | |
| 208 } | |
| 209 | |
| 210 base::Time last_update() { | |
| 211 base::AutoLock l(update_status_mutex_); | |
| 212 return last_update_; | |
| 213 } | |
| 214 | |
| 215 bool is_update_scheduled() { | |
| 216 base::AutoLock l(update_status_mutex_); | |
| 217 return is_update_scheduled_; | |
| 218 } | |
| 219 | |
| 220 scoped_refptr<base::SequencedTaskRunner> SafeBrowsingTaskRunner() { | |
| 221 return local_database_manager()->safe_browsing_task_runner_; | |
| 222 } | |
| 223 | |
| 224 const net::SpawnedTestServer& spawned_test_server() const { | |
| 225 return *test_server_; | |
| 226 } | |
| 227 | |
| 228 protected: | |
| 229 void SetProtocolConfigURLPrefix(const std::string& url_prefix) { | |
| 230 SafeBrowsingProtocolConfig config; | |
| 231 config.url_prefix = url_prefix; | |
| 232 // Makes sure the auto update is not triggered. The tests will force the | |
| 233 // update when needed. | |
| 234 config.disable_auto_update = true; | |
| 235 config.client_name = "browser_tests"; | |
| 236 sb_factory_->SetTestProtocolConfig(config); | |
| 237 } | |
| 238 | |
| 239 void SetUp() override { | |
| 240 base::FilePath datafile_path; | |
| 241 ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &datafile_path)); | |
| 242 | |
| 243 datafile_path = datafile_path.Append(FILE_PATH_LITERAL("third_party")) | |
| 244 .Append(FILE_PATH_LITERAL("safe_browsing")) | |
| 245 .Append(FILE_PATH_LITERAL("testing")) | |
| 246 .Append(kDataFile); | |
| 247 test_server_.reset(new LocalSafeBrowsingTestServer(datafile_path)); | |
| 248 ASSERT_TRUE(test_server_->Start()); | |
| 249 LOG(INFO) << "server is " << test_server_->host_port_pair().ToString(); | |
| 250 | |
| 251 sb_factory_.reset(new TestSafeBrowsingServiceFactory()); | |
| 252 // Point to the testing server for all SafeBrowsing requests. | |
| 253 SetProtocolConfigURLPrefix(test_server_->GetURL("safebrowsing").spec()); | |
| 254 SafeBrowsingService::RegisterFactory(sb_factory_.get()); | |
| 255 | |
| 256 InProcessBrowserTest::SetUp(); | |
| 257 } | |
| 258 | |
| 259 void TearDown() override { | |
| 260 InProcessBrowserTest::TearDown(); | |
| 261 | |
| 262 SafeBrowsingService::RegisterFactory(NULL); | |
| 263 } | |
| 264 | |
| 265 void SetUpCommandLine(base::CommandLine* command_line) override { | |
| 266 // TODO(lzheng): The test server does not understand download related | |
| 267 // requests. We need to fix the server. | |
| 268 command_line->AppendSwitch(switches::kSbDisableDownloadProtection); | |
| 269 | |
| 270 // TODO(gcasto): Generate new testing data that includes the | |
| 271 // client-side phishing whitelist. | |
| 272 command_line->AppendSwitch( | |
| 273 switches::kDisableClientSidePhishingDetection); | |
| 274 | |
| 275 // TODO(kalman): Generate new testing data that includes the extension | |
| 276 // blacklist. | |
| 277 command_line->AppendSwitch(switches::kSbDisableExtensionBlacklist); | |
| 278 } | |
| 279 | |
| 280 void SetTestStep(int step) { | |
| 281 std::string test_step = base::StringPrintf("test_step=%d", step); | |
| 282 sb_factory_->test_safe_browsing_service() | |
| 283 ->protocol_manager_->set_additional_query(test_step); | |
| 284 } | |
| 285 | |
| 286 std::unique_ptr<TestSafeBrowsingServiceFactory> sb_factory_; | |
| 287 | |
| 288 private: | |
| 289 std::unique_ptr<net::SpawnedTestServer> test_server_; | |
| 290 | |
| 291 // Protects all variables below since they are read on UI thread | |
| 292 // but updated on IO thread or safebrowsing thread. | |
| 293 base::Lock update_status_mutex_; | |
| 294 | |
| 295 // States associated with safebrowsing service updates. | |
| 296 bool is_database_ready_; | |
| 297 base::Time last_update_; | |
| 298 bool is_update_scheduled_; | |
| 299 // Indicates if there is a match between a URL's prefix and safebrowsing | |
| 300 // database (thus potentially it is a phishing URL). | |
| 301 bool is_checked_url_in_db_; | |
| 302 // True if last verified URL is not a phishing URL and thus it is safe. | |
| 303 bool is_checked_url_safe_; | |
| 304 | |
| 305 DISALLOW_COPY_AND_ASSIGN(SafeBrowsingServerTest); | |
| 306 }; | |
| 307 | |
| 308 // A ref counted helper class that handles callbacks between IO thread and UI | |
| 309 // thread. | |
| 310 class SafeBrowsingServerTestHelper | |
| 311 : public base::RefCountedThreadSafe<SafeBrowsingServerTestHelper>, | |
| 312 public SafeBrowsingDatabaseManager::Client, | |
| 313 public net::URLFetcherDelegate { | |
| 314 public: | |
| 315 SafeBrowsingServerTestHelper(SafeBrowsingServerTest* safe_browsing_test, | |
| 316 net::URLRequestContextGetter* request_context) | |
| 317 : safe_browsing_test_(safe_browsing_test), | |
| 318 response_status_(net::URLRequestStatus::FAILED), | |
| 319 request_context_(request_context) { | |
| 320 } | |
| 321 | |
| 322 // Callbacks for SafeBrowsingDatabaseManager::Client. | |
| 323 void OnCheckBrowseUrlResult(const GURL& url, | |
| 324 SBThreatType threat_type, | |
| 325 const ThreatMetadata& metadata) override { | |
| 326 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
| 327 EXPECT_TRUE(safe_browsing_test_->is_checked_url_in_db()); | |
| 328 safe_browsing_test_->set_is_checked_url_safe( | |
| 329 threat_type == SB_THREAT_TYPE_SAFE); | |
| 330 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | |
| 331 base::Bind(&SafeBrowsingServerTestHelper::OnCheckUrlDone, this)); | |
| 332 } | |
| 333 | |
| 334 virtual void OnBlockingPageComplete(bool proceed) { | |
| 335 NOTREACHED() << "Not implemented."; | |
| 336 } | |
| 337 | |
| 338 // Functions and callbacks related to CheckUrl. These are used to verify | |
| 339 // phishing URLs. | |
| 340 void CheckUrl(const GURL& url) { | |
| 341 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, | |
| 342 base::Bind(&SafeBrowsingServerTestHelper::CheckUrlOnIOThread, | |
| 343 this, url)); | |
| 344 content::RunMessageLoop(); | |
| 345 } | |
| 346 void CheckUrlOnIOThread(const GURL& url) { | |
| 347 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
| 348 safe_browsing_test_->CheckUrl(this, url); | |
| 349 if (!safe_browsing_test_->is_checked_url_in_db()) { | |
| 350 // Ends the checking since this URL's prefix is not in database. | |
| 351 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | |
| 352 base::Bind(&SafeBrowsingServerTestHelper::OnCheckUrlDone, this)); | |
| 353 } | |
| 354 // Otherwise, OnCheckUrlDone is called in OnUrlCheckResult since | |
| 355 // safebrowsing service further fetches hashes from safebrowsing server. | |
| 356 } | |
| 357 | |
| 358 void OnCheckUrlDone() { | |
| 359 StopUILoop(); | |
| 360 } | |
| 361 | |
| 362 // Updates status from IO Thread. | |
| 363 void CheckStatusOnIOThread() { | |
| 364 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
| 365 safe_browsing_test_->UpdateSafeBrowsingStatus(); | |
| 366 safe_browsing_test_->SafeBrowsingTaskRunner()->PostTask( | |
| 367 FROM_HERE, | |
| 368 base::Bind(&SafeBrowsingServerTestHelper::CheckIsDatabaseReady, this)); | |
| 369 } | |
| 370 | |
| 371 // Checks status in SafeBrowsing Thread. | |
| 372 void CheckIsDatabaseReady() { | |
| 373 EXPECT_TRUE(safe_browsing_test_->SafeBrowsingTaskRunner() | |
| 374 ->RunsTasksOnCurrentThread()); | |
| 375 safe_browsing_test_->CheckIsDatabaseReady(); | |
| 376 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | |
| 377 base::Bind(&SafeBrowsingServerTestHelper::OnWaitForStatusUpdateDone, | |
| 378 this)); | |
| 379 } | |
| 380 | |
| 381 void OnWaitForStatusUpdateDone() { | |
| 382 StopUILoop(); | |
| 383 } | |
| 384 | |
| 385 // Update safebrowsing status. | |
| 386 void UpdateStatus() { | |
| 387 BrowserThread::PostTask( | |
| 388 BrowserThread::IO, | |
| 389 FROM_HERE, | |
| 390 base::Bind(&SafeBrowsingServerTestHelper::CheckStatusOnIOThread, this)); | |
| 391 // Will continue after OnWaitForStatusUpdateDone(). | |
| 392 content::RunMessageLoop(); | |
| 393 } | |
| 394 | |
| 395 // Calls test server to fetch database for verification. | |
| 396 net::URLRequestStatus::Status FetchDBToVerify( | |
| 397 const net::SpawnedTestServer& test_server, | |
| 398 int test_step) { | |
| 399 // TODO(lzheng): Remove chunk_type=add once it is not needed by the server. | |
| 400 std::string path = base::StringPrintf( | |
| 401 "%s?client=chromium&appver=1.0&pver=3.0&test_step=%d&chunk_type=add", | |
| 402 kDBVerifyPath, test_step); | |
| 403 return FetchUrl(test_server.GetURL(path)); | |
| 404 } | |
| 405 | |
| 406 // Calls test server to fetch URLs for verification. | |
| 407 net::URLRequestStatus::Status FetchUrlsToVerify( | |
| 408 const net::SpawnedTestServer& test_server, | |
| 409 int test_step) { | |
| 410 std::string path = base::StringPrintf( | |
| 411 "%s?client=chromium&appver=1.0&pver=3.0&test_step=%d", | |
| 412 kUrlVerifyPath, test_step); | |
| 413 return FetchUrl(test_server.GetURL(path)); | |
| 414 } | |
| 415 | |
| 416 // Calls test server to check if test data is done. E.g.: if there is a | |
| 417 // bad URL that server expects test to fetch full hash but the test didn't, | |
| 418 // this verification will fail. | |
| 419 net::URLRequestStatus::Status VerifyTestComplete( | |
| 420 const net::SpawnedTestServer& test_server, | |
| 421 int test_step) { | |
| 422 std::string path = base::StringPrintf( | |
| 423 "%s?test_step=%d", kTestCompletePath, test_step); | |
| 424 return FetchUrl(test_server.GetURL(path)); | |
| 425 } | |
| 426 | |
| 427 // Callback for URLFetcher. | |
| 428 void OnURLFetchComplete(const net::URLFetcher* source) override { | |
| 429 source->GetResponseAsString(&response_data_); | |
| 430 response_status_ = source->GetStatus().status(); | |
| 431 StopUILoop(); | |
| 432 } | |
| 433 | |
| 434 const std::string& response_data() { | |
| 435 return response_data_; | |
| 436 } | |
| 437 | |
| 438 private: | |
| 439 friend class base::RefCountedThreadSafe<SafeBrowsingServerTestHelper>; | |
| 440 ~SafeBrowsingServerTestHelper() override {} | |
| 441 | |
| 442 // Stops UI loop after desired status is updated. | |
| 443 void StopUILoop() { | |
| 444 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 445 base::MessageLoopForUI::current()->QuitWhenIdle(); | |
| 446 } | |
| 447 | |
| 448 // Fetch a URL. If message_loop_started is true, starts the message loop | |
| 449 // so the caller could wait till OnURLFetchComplete is called. | |
| 450 net::URLRequestStatus::Status FetchUrl(const GURL& url) { | |
| 451 url_fetcher_ = net::URLFetcher::Create(url, net::URLFetcher::GET, this); | |
| 452 url_fetcher_->SetLoadFlags(net::LOAD_DISABLE_CACHE); | |
| 453 url_fetcher_->SetRequestContext(request_context_); | |
| 454 url_fetcher_->Start(); | |
| 455 content::RunMessageLoop(); | |
| 456 return response_status_; | |
| 457 } | |
| 458 | |
| 459 base::OneShotTimer check_update_timer_; | |
| 460 SafeBrowsingServerTest* safe_browsing_test_; | |
| 461 std::unique_ptr<net::URLFetcher> url_fetcher_; | |
| 462 std::string response_data_; | |
| 463 net::URLRequestStatus::Status response_status_; | |
| 464 net::URLRequestContextGetter* request_context_; | |
| 465 DISALLOW_COPY_AND_ASSIGN(SafeBrowsingServerTestHelper); | |
| 466 }; | |
| 467 | |
| 468 // TODO(shess): Disabled pending new data for third_party/safe_browsing/testing/ | |
| 469 IN_PROC_BROWSER_TEST_F(SafeBrowsingServerTest, | |
| 470 DISABLED_SafeBrowsingServerTest) { | |
| 471 ASSERT_TRUE(sb_factory_->test_safe_browsing_service() != NULL); | |
| 472 | |
| 473 net::URLRequestContextGetter* request_context = | |
| 474 browser()->profile()->GetRequestContext(); | |
| 475 scoped_refptr<SafeBrowsingServerTestHelper> safe_browsing_helper( | |
| 476 new SafeBrowsingServerTestHelper(this, request_context)); | |
| 477 int last_step = 0; | |
| 478 | |
| 479 // Waits and makes sure safebrowsing update is not happening. | |
| 480 // The wait will stop once OnWaitForStatusUpdateDone in | |
| 481 // safe_browsing_helper is called and status from test_safe_browsing_service | |
| 482 // is checked. | |
| 483 safe_browsing_helper->UpdateStatus(); | |
| 484 EXPECT_TRUE(is_database_ready()); | |
| 485 EXPECT_FALSE(is_update_scheduled()); | |
| 486 EXPECT_TRUE(last_update().is_null()); | |
| 487 // Starts updates. After each update, the test will fetch a list of URLs with | |
| 488 // expected results to verify with safebrowsing service. If there is no error, | |
| 489 // the test moves on to the next step to get more update chunks. | |
| 490 // This repeats till there is no update data. | |
| 491 for (int step = 1;; step++) { | |
| 492 // Every step should be a fresh start. | |
| 493 SCOPED_TRACE(base::StringPrintf("step=%d", step)); | |
| 494 EXPECT_TRUE(is_database_ready()); | |
| 495 EXPECT_FALSE(is_update_scheduled()); | |
| 496 | |
| 497 // Starts safebrowsing update on IO thread. Waits till scheduled | |
| 498 // update finishes. | |
| 499 base::Time now = base::Time::Now(); | |
| 500 SetTestStep(step); | |
| 501 ForceUpdate(); | |
| 502 | |
| 503 safe_browsing_helper->UpdateStatus(); | |
| 504 EXPECT_TRUE(is_database_ready()); | |
| 505 EXPECT_FALSE(is_update_scheduled()); | |
| 506 EXPECT_FALSE(last_update().is_null()); | |
| 507 if (last_update() < now) { | |
| 508 // This means no data available anymore. | |
| 509 break; | |
| 510 } | |
| 511 | |
| 512 // Fetches URLs to verify and waits till server responses with data. | |
| 513 EXPECT_EQ( | |
| 514 net::URLRequestStatus::SUCCESS, | |
| 515 safe_browsing_helper->FetchUrlsToVerify(spawned_test_server(), step)); | |
| 516 | |
| 517 std::vector<PhishingUrl> phishing_urls; | |
| 518 EXPECT_TRUE(ParsePhishingUrls(safe_browsing_helper->response_data(), | |
| 519 &phishing_urls)); | |
| 520 EXPECT_GT(phishing_urls.size(), 0U); | |
| 521 for (size_t j = 0; j < phishing_urls.size(); ++j) { | |
| 522 // Verifes with server if a URL is a phishing URL and waits till server | |
| 523 // responses. | |
| 524 safe_browsing_helper->CheckUrl(GURL(phishing_urls[j].url)); | |
| 525 if (phishing_urls[j].is_phishing) { | |
| 526 EXPECT_TRUE(is_checked_url_in_db()) | |
| 527 << phishing_urls[j].url | |
| 528 << " is_phishing: " << phishing_urls[j].is_phishing | |
| 529 << " test step: " << step; | |
| 530 EXPECT_FALSE(is_checked_url_safe()) | |
| 531 << phishing_urls[j].url | |
| 532 << " is_phishing: " << phishing_urls[j].is_phishing | |
| 533 << " test step: " << step; | |
| 534 } else { | |
| 535 EXPECT_TRUE(is_checked_url_safe()) | |
| 536 << phishing_urls[j].url | |
| 537 << " is_phishing: " << phishing_urls[j].is_phishing | |
| 538 << " test step: " << step; | |
| 539 } | |
| 540 } | |
| 541 // TODO(lzheng): We should verify the fetched database with local | |
| 542 // database to make sure they match. | |
| 543 EXPECT_EQ( | |
| 544 net::URLRequestStatus::SUCCESS, | |
| 545 safe_browsing_helper->FetchDBToVerify(spawned_test_server(), step)); | |
| 546 EXPECT_GT(safe_browsing_helper->response_data().size(), 0U); | |
| 547 last_step = step; | |
| 548 } | |
| 549 | |
| 550 // Verifies with server if test is done and waits till server responses. | |
| 551 EXPECT_EQ(net::URLRequestStatus::SUCCESS, | |
| 552 safe_browsing_helper->VerifyTestComplete(spawned_test_server(), | |
| 553 last_step)); | |
| 554 EXPECT_EQ("yes", safe_browsing_helper->response_data()); | |
| 555 } | |
| 556 | |
| 557 } // namespace safe_browsing | |
| OLD | NEW |