15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This test uses the safebrowsing test server published at
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// http://code.google.com/p/google-safe-browsing/ to test the safebrowsing
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// protocol implemetation. Details of the safebrowsing testing flow is
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// documented at
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// http://code.google.com/p/google-safe-browsing/wiki/ProtocolTesting
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This test launches safebrowsing test server and issues several update
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// requests against that server. Each update would get different data and after
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// each update, the test will get a list of URLs from the test server to verify
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// its repository. The test will succeed only if all updates are performed and
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// URLs match what the server expected.
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector>
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/environment.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/path_service.h"
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_number_conversions.h"
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_split.h"
25868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h"
26868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/synchronization/lock.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/test/test_timeouts.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/platform_thread.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread.h"
31eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h"
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/browser_process.h"
337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chrome_notification_types.h"
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/safe_browsing/database_manager.h"
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/safe_browsing/local_safebrowsing_test_server.h"
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/safe_browsing/protocol_manager.h"
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/safe_browsing/safe_browsing_service.h"
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser.h"
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_switches.h"
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/url_constants.h"
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/test/base/in_process_browser_test.h"
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/test/base/ui_test_utils.h"
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_context.h"
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/test/test_browser_thread.h"
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/load_flags.h"
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_log.h"
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/dns/host_resolver.h"
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/test/python_utils.h"
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_fetcher.h"
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_fetcher_delegate.h"
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_status.h"
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread;
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const base::FilePath::CharType kDataFile[] =
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FILE_PATH_LITERAL("testing_input_nomac.dat");
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kUrlVerifyPath[] = "safebrowsing/verify_urls";
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kDBVerifyPath[] = "safebrowsing/verify_database";
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kTestCompletePath[] = "test_complete";
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct PhishingUrl {
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string url;
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string list_name;
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool is_phishing;
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Parses server response for verify_urls. The expected format is:
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// first.random.url.com/   internal-test-shavar   yes
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// second.random.url.com/  internal-test-shavar   yes
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ...
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ParsePhishingUrls(const std::string& data,
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       std::vector<PhishingUrl>* phishing_urls) {
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (data.empty())
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<std::string> urls;
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::SplitString(data, '\n', &urls);
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < urls.size(); ++i) {
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (urls[i].empty())
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue;
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PhishingUrl phishing_url;
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::vector<std::string> record_parts;
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::SplitString(urls[i], '\t', &record_parts);
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (record_parts.size() != 3) {
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(ERROR) << "Unexpected URL format in phishing URL list: "
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 << urls[i];
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
94010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    phishing_url.url = std::string(url::kHttpScheme) + "://" + record_parts[0];
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    phishing_url.list_name = record_parts[1];
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (record_parts[2] == "yes") {
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      phishing_url.is_phishing = true;
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (record_parts[2] == "no") {
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      phishing_url.is_phishing = false;
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(ERROR) << "Unrecognized expectation in " << urls[i]
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 << ": " << record_parts[2];
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    phishing_urls->push_back(phishing_url);
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
110a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochclass FakeSafeBrowsingService : public SafeBrowsingService {
111a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch public:
112a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  explicit FakeSafeBrowsingService(const std::string& url_prefix)
113a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      : url_prefix_(url_prefix) {}
114a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
115a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  virtual SafeBrowsingProtocolConfig GetProtocolConfig() const OVERRIDE {
116a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    SafeBrowsingProtocolConfig config;
117a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    config.url_prefix = url_prefix_;
118a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    // Makes sure the auto update is not triggered. The tests will force the
119a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    // update when needed.
120a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    config.disable_auto_update = true;
121a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    config.client_name = "browser_tests";
122a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    return config;
123a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  }
124a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
125a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch private:
126a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  virtual ~FakeSafeBrowsingService() {}
127a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
128a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  std::string url_prefix_;
129a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
130a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  DISALLOW_COPY_AND_ASSIGN(FakeSafeBrowsingService);
131a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch};
132a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
133a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// Factory that creates FakeSafeBrowsingService instances.
134a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochclass TestSafeBrowsingServiceFactory : public SafeBrowsingServiceFactory {
135a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch public:
136a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  explicit TestSafeBrowsingServiceFactory(const std::string& url_prefix)
137a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      : url_prefix_(url_prefix) {}
138a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
139a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  virtual SafeBrowsingService* CreateSafeBrowsingService() OVERRIDE {
140a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    return new FakeSafeBrowsingService(url_prefix_);
141a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  }
142a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
143a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch private:
144a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  std::string url_prefix_;
145a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch};
146a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This starts the browser and keeps status of states related to SafeBrowsing.
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class SafeBrowsingServerTest : public InProcessBrowserTest {
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SafeBrowsingServerTest()
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : safe_browsing_service_(NULL),
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      is_database_ready_(true),
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      is_update_scheduled_(false),
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      is_checked_url_in_db_(false),
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      is_checked_url_safe_(false) {
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~SafeBrowsingServerTest() {
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void UpdateSafeBrowsingStatus() {
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(safe_browsing_service_);
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::AutoLock lock(update_status_mutex_);
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    last_update_ = safe_browsing_service_->protocol_manager_->last_update();
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    is_update_scheduled_ =
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        safe_browsing_service_->protocol_manager_->update_timer_.IsRunning();
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ForceUpdate() {
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    content::WindowedNotificationObserver observer(
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        chrome::NOTIFICATION_SAFE_BROWSING_UPDATE_COMPLETE,
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        content::Source<SafeBrowsingDatabaseManager>(database_manager()));
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Bind(&SafeBrowsingServerTest::ForceUpdateOnIOThread,
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   this));
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    observer.Wait();
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ForceUpdateOnIOThread() {
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(safe_browsing_service_);
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    safe_browsing_service_->protocol_manager_->ForceScheduleNextUpdate(
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::TimeDelta::FromSeconds(0));
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void CheckIsDatabaseReady() {
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::AutoLock lock(update_status_mutex_);
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    is_database_ready_ = !database_manager()->database_update_in_progress_;
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void CheckUrl(SafeBrowsingDatabaseManager::Client* helper, const GURL& url) {
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(safe_browsing_service_);
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::AutoLock lock(update_status_mutex_);
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (database_manager()->CheckBrowseUrl(url, helper)) {
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      is_checked_url_in_db_ = false;
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      is_checked_url_safe_ = true;
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // In this case, Safebrowsing service will fetch the full hash
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // from the server and examine that. Once it is done,
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // set_is_checked_url_safe() will be called via callback.
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      is_checked_url_in_db_ = true;
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SafeBrowsingDatabaseManager* database_manager() {
208868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return safe_browsing_service_->database_manager().get();
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool is_checked_url_in_db() {
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::AutoLock l(update_status_mutex_);
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return is_checked_url_in_db_;
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void set_is_checked_url_safe(bool safe) {
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::AutoLock l(update_status_mutex_);
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    is_checked_url_safe_ = safe;
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool is_checked_url_safe() {
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::AutoLock l(update_status_mutex_);
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return is_checked_url_safe_;
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool is_database_ready() {
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::AutoLock l(update_status_mutex_);
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return is_database_ready_;
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Time last_update() {
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::AutoLock l(update_status_mutex_);
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return last_update_;
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool is_update_scheduled() {
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::AutoLock l(update_status_mutex_);
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return is_update_scheduled_;
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop* SafeBrowsingMessageLoop() {
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return database_manager()->safe_browsing_thread_->message_loop();
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const net::SpawnedTestServer& test_server() const {
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return *test_server_;
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool InitSafeBrowsingService() {
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    safe_browsing_service_ = g_browser_process->safe_browsing_service();
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return safe_browsing_service_ != NULL;
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  virtual void SetUp() OVERRIDE {
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::FilePath datafile_path;
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &datafile_path));
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    datafile_path = datafile_path.Append(FILE_PATH_LITERAL("third_party"))
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          .Append(FILE_PATH_LITERAL("safe_browsing"))
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          .Append(FILE_PATH_LITERAL("testing"))
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          .Append(kDataFile);
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    test_server_.reset(new LocalSafeBrowsingTestServer(datafile_path));
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(test_server_->Start());
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(INFO) << "server is " << test_server_->host_port_pair().ToString();
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
267a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    // Point to the testing server for all SafeBrowsing requests.
268a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    std::string url_prefix = test_server_->GetURL("safebrowsing").spec();
269a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    sb_factory_.reset(new TestSafeBrowsingServiceFactory(url_prefix));
270a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    SafeBrowsingService::RegisterFactory(sb_factory_.get());
271a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
272a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    InProcessBrowserTest::SetUp();
273a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  }
274a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
275a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  virtual void TearDown() OVERRIDE {
276a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    InProcessBrowserTest::TearDown();
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
278a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    SafeBrowsingService::RegisterFactory(NULL);
279a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  }
280a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
281a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // This test uses loopback. No need to use IPv6 especially it makes
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // local requests slow on Windows trybot when ipv6 local address [::1]
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // is not setup.
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    command_line->AppendSwitch(switches::kDisableIPv6);
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // TODO(lzheng): The test server does not understand download related
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // requests. We need to fix the server.
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    command_line->AppendSwitch(switches::kSbDisableDownloadProtection);
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // TODO(gcasto): Generate new testing data that includes the
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // client-side phishing whitelist.
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    command_line->AppendSwitch(
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        switches::kDisableClientSidePhishingDetection);
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // TODO(kalman): Generate new testing data that includes the extension
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // blacklist.
2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    command_line->AppendSwitch(switches::kSbDisableExtensionBlacklist);
2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
30090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // TODO(tburkard): Generate new testing data that includes the side-effect
30190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // free whitelist.
30290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    command_line->AppendSwitch(switches::kSbDisableSideEffectFreeWhitelist);
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetTestStep(int step) {
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string test_step = base::StringPrintf("test_step=%d", step);
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    safe_browsing_service_->protocol_manager_->set_additional_query(test_step);
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
311a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  scoped_ptr<TestSafeBrowsingServiceFactory> sb_factory_;
312a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SafeBrowsingService* safe_browsing_service_;
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<net::SpawnedTestServer> test_server_;
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Protects all variables below since they are read on UI thread
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // but updated on IO thread or safebrowsing thread.
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Lock update_status_mutex_;
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // States associated with safebrowsing service updates.
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool is_database_ready_;
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Time last_update_;
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool is_update_scheduled_;
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Indicates if there is a match between a URL's prefix and safebrowsing
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // database (thus potentially it is a phishing URL).
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool is_checked_url_in_db_;
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // True if last verified URL is not a phishing URL and thus it is safe.
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool is_checked_url_safe_;
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(SafeBrowsingServerTest);
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A ref counted helper class that handles callbacks between IO thread and UI
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// thread.
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class SafeBrowsingServerTestHelper
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : public base::RefCountedThreadSafe<SafeBrowsingServerTestHelper>,
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      public SafeBrowsingDatabaseManager::Client,
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      public net::URLFetcherDelegate {
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SafeBrowsingServerTestHelper(SafeBrowsingServerTest* safe_browsing_test,
3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                               net::URLRequestContextGetter* request_context)
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : safe_browsing_test_(safe_browsing_test),
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        response_status_(net::URLRequestStatus::FAILED),
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        request_context_(request_context) {
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Callbacks for SafeBrowsingDatabaseManager::Client.
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnCheckBrowseUrlResult(const GURL& url,
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      SBThreatType threat_type) OVERRIDE {
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(safe_browsing_test_->is_checked_url_in_db());
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    safe_browsing_test_->set_is_checked_url_safe(
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        threat_type == SB_THREAT_TYPE_SAFE);
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Bind(&SafeBrowsingServerTestHelper::OnCheckUrlDone, this));
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnBlockingPageComplete(bool proceed) {
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED() << "Not implemented.";
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Functions and callbacks related to CheckUrl. These are used to verify
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // phishing URLs.
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void CheckUrl(const GURL& url) {
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Bind(&SafeBrowsingServerTestHelper::CheckUrlOnIOThread,
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   this, url));
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    content::RunMessageLoop();
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void CheckUrlOnIOThread(const GURL& url) {
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    safe_browsing_test_->CheckUrl(this, url);
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!safe_browsing_test_->is_checked_url_in_db()) {
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Ends the checking since this URL's prefix is not in database.
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Bind(&SafeBrowsingServerTestHelper::OnCheckUrlDone, this));
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Otherwise, OnCheckUrlDone is called in OnUrlCheckResult since
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // safebrowsing service further fetches hashes from safebrowsing server.
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnCheckUrlDone() {
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StopUILoop();
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Updates status from IO Thread.
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void CheckStatusOnIOThread() {
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    safe_browsing_test_->UpdateSafeBrowsingStatus();
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    safe_browsing_test_->SafeBrowsingMessageLoop()->PostTask(FROM_HERE,
3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Bind(&SafeBrowsingServerTestHelper::CheckIsDatabaseReady, this));
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Checks status in SafeBrowsing Thread.
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void CheckIsDatabaseReady() {
39790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    EXPECT_EQ(base::MessageLoop::current(),
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              safe_browsing_test_->SafeBrowsingMessageLoop());
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    safe_browsing_test_->CheckIsDatabaseReady();
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Bind(&SafeBrowsingServerTestHelper::OnWaitForStatusUpdateDone,
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   this));
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnWaitForStatusUpdateDone() {
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StopUILoop();
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Update safebrowsing status.
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void UpdateStatus() {
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BrowserThread::PostTask(
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        BrowserThread::IO,
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FROM_HERE,
4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Bind(&SafeBrowsingServerTestHelper::CheckStatusOnIOThread, this));
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Will continue after OnWaitForStatusUpdateDone().
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    content::RunMessageLoop();
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Calls test server to fetch database for verification.
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::URLRequestStatus::Status FetchDBToVerify(
421c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const net::SpawnedTestServer& test_server,
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int test_step) {
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // TODO(lzheng): Remove chunk_type=add once it is not needed by the server.
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string path = base::StringPrintf(
425f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        "%s?client=chromium&appver=1.0&pver=3.0&test_step=%d&chunk_type=add",
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        kDBVerifyPath, test_step);
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return FetchUrl(test_server.GetURL(path));
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Calls test server to fetch URLs for verification.
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::URLRequestStatus::Status FetchUrlsToVerify(
432c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const net::SpawnedTestServer& test_server,
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int test_step) {
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string path = base::StringPrintf(
435f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        "%s?client=chromium&appver=1.0&pver=3.0&test_step=%d",
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        kUrlVerifyPath, test_step);
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return FetchUrl(test_server.GetURL(path));
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Calls test server to check if test data is done. E.g.: if there is a
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // bad URL that server expects test to fetch full hash but the test didn't,
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // this verification will fail.
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::URLRequestStatus::Status VerifyTestComplete(
444c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const net::SpawnedTestServer& test_server,
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int test_step) {
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string path = base::StringPrintf(
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        "%s?test_step=%d", kTestCompletePath, test_step);
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return FetchUrl(test_server.GetURL(path));
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Callback for URLFetcher.
4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE {
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    source->GetResponseAsString(&response_data_);
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    response_status_ = source->GetStatus().status();
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StopUILoop();
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string& response_data() {
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return response_data_;
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  friend class base::RefCountedThreadSafe<SafeBrowsingServerTestHelper>;
4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~SafeBrowsingServerTestHelper() {}
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Stops UI loop after desired status is updated.
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void StopUILoop() {
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::UI));
46990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoopForUI::current()->Quit();
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Fetch a URL. If message_loop_started is true, starts the message loop
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // so the caller could wait till OnURLFetchComplete is called.
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::URLRequestStatus::Status FetchUrl(const GURL& url) {
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    url_fetcher_.reset(net::URLFetcher::Create(
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        url, net::URLFetcher::GET, this));
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    url_fetcher_->SetLoadFlags(net::LOAD_DISABLE_CACHE);
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    url_fetcher_->SetRequestContext(request_context_);
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    url_fetcher_->Start();
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    content::RunMessageLoop();
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return response_status_;
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::OneShotTimer<SafeBrowsingServerTestHelper> check_update_timer_;
4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SafeBrowsingServerTest* safe_browsing_test_;
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<net::URLFetcher> url_fetcher_;
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data_;
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::URLRequestStatus::Status response_status_;
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::URLRequestContextGetter* request_context_;
4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(SafeBrowsingServerTestHelper);
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
493f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// TODO(shess): Disabled pending new data for third_party/safe_browsing/testing/
4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(SafeBrowsingServerTest,
495f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                       DISABLED_SafeBrowsingServerTest) {
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LOG(INFO) << "Start test";
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(InitSafeBrowsingService());
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::URLRequestContextGetter* request_context =
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      browser()->profile()->GetRequestContext();
5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<SafeBrowsingServerTestHelper> safe_browsing_helper(
5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new SafeBrowsingServerTestHelper(this, request_context));
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int last_step = 0;
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Waits and makes sure safebrowsing update is not happening.
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The wait will stop once OnWaitForStatusUpdateDone in
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // safe_browsing_helper is called and status from safe_browsing_service_
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // is checked.
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  safe_browsing_helper->UpdateStatus();
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(is_database_ready());
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(is_update_scheduled());
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(last_update().is_null());
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Starts updates. After each update, the test will fetch a list of URLs with
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // expected results to verify with safebrowsing service. If there is no error,
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the test moves on to the next step to get more update chunks.
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This repeats till there is no update data.
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int step = 1;; step++) {
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Every step should be a fresh start.
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SCOPED_TRACE(base::StringPrintf("step=%d", step));
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(is_database_ready());
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(is_update_scheduled());
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Starts safebrowsing update on IO thread. Waits till scheduled
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // update finishes.
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::Time now = base::Time::Now();
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetTestStep(step);
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ForceUpdate();
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    safe_browsing_helper->UpdateStatus();
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(is_database_ready());
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(is_update_scheduled());
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(last_update().is_null());
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (last_update() < now) {
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // This means no data available anymore.
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Fetches URLs to verify and waits till server responses with data.
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(net::URLRequestStatus::SUCCESS,
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              safe_browsing_helper->FetchUrlsToVerify(test_server(), step));
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::vector<PhishingUrl> phishing_urls;
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(ParsePhishingUrls(safe_browsing_helper->response_data(),
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  &phishing_urls));
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_GT(phishing_urls.size(), 0U);
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (size_t j = 0; j < phishing_urls.size(); ++j) {
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Verifes with server if a URL is a phishing URL and waits till server
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // responses.
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      safe_browsing_helper->CheckUrl(GURL(phishing_urls[j].url));
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (phishing_urls[j].is_phishing) {
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        EXPECT_TRUE(is_checked_url_in_db())
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            << phishing_urls[j].url
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            << " is_phishing: " << phishing_urls[j].is_phishing
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            << " test step: " << step;
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        EXPECT_FALSE(is_checked_url_safe())
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            << phishing_urls[j].url
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            << " is_phishing: " << phishing_urls[j].is_phishing
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            << " test step: " << step;
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else {
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        EXPECT_TRUE(is_checked_url_safe())
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            << phishing_urls[j].url
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            << " is_phishing: " << phishing_urls[j].is_phishing
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            << " test step: " << step;
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // TODO(lzheng): We should verify the fetched database with local
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // database to make sure they match.
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(net::URLRequestStatus::SUCCESS,
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              safe_browsing_helper->FetchDBToVerify(test_server(), step));
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_GT(safe_browsing_helper->response_data().size(), 0U);
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    last_step = step;
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verifies with server if test is done and waits till server responses.
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(net::URLRequestStatus::SUCCESS,
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            safe_browsing_helper->VerifyTestComplete(test_server(), last_step));
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("yes", safe_browsing_helper->response_data());
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
579