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;
121116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#if defined(OS_ANDROID)
122116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    config.disable_connection_check = true;
123116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#endif
124a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    config.client_name = "browser_tests";
125a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    return config;
126a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  }
127a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
128a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch private:
129a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  virtual ~FakeSafeBrowsingService() {}
130a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
131a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  std::string url_prefix_;
132a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
133a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  DISALLOW_COPY_AND_ASSIGN(FakeSafeBrowsingService);
134a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch};
135a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
136a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// Factory that creates FakeSafeBrowsingService instances.
137a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochclass TestSafeBrowsingServiceFactory : public SafeBrowsingServiceFactory {
138a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch public:
139a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  explicit TestSafeBrowsingServiceFactory(const std::string& url_prefix)
140a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      : url_prefix_(url_prefix) {}
141a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
142a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  virtual SafeBrowsingService* CreateSafeBrowsingService() OVERRIDE {
143a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    return new FakeSafeBrowsingService(url_prefix_);
144a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  }
145a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
146a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch private:
147a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  std::string url_prefix_;
148a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch};
149a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This starts the browser and keeps status of states related to SafeBrowsing.
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class SafeBrowsingServerTest : public InProcessBrowserTest {
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SafeBrowsingServerTest()
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : safe_browsing_service_(NULL),
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      is_database_ready_(true),
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      is_update_scheduled_(false),
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      is_checked_url_in_db_(false),
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      is_checked_url_safe_(false) {
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~SafeBrowsingServerTest() {
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void UpdateSafeBrowsingStatus() {
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(safe_browsing_service_);
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::AutoLock lock(update_status_mutex_);
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    last_update_ = safe_browsing_service_->protocol_manager_->last_update();
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    is_update_scheduled_ =
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        safe_browsing_service_->protocol_manager_->update_timer_.IsRunning();
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ForceUpdate() {
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    content::WindowedNotificationObserver observer(
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        chrome::NOTIFICATION_SAFE_BROWSING_UPDATE_COMPLETE,
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        content::Source<SafeBrowsingDatabaseManager>(database_manager()));
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Bind(&SafeBrowsingServerTest::ForceUpdateOnIOThread,
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   this));
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    observer.Wait();
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ForceUpdateOnIOThread() {
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(safe_browsing_service_);
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    safe_browsing_service_->protocol_manager_->ForceScheduleNextUpdate(
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::TimeDelta::FromSeconds(0));
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void CheckIsDatabaseReady() {
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::AutoLock lock(update_status_mutex_);
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    is_database_ready_ = !database_manager()->database_update_in_progress_;
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void CheckUrl(SafeBrowsingDatabaseManager::Client* helper, const GURL& url) {
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(safe_browsing_service_);
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::AutoLock lock(update_status_mutex_);
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (database_manager()->CheckBrowseUrl(url, helper)) {
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      is_checked_url_in_db_ = false;
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      is_checked_url_safe_ = true;
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // In this case, Safebrowsing service will fetch the full hash
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // from the server and examine that. Once it is done,
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // set_is_checked_url_safe() will be called via callback.
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      is_checked_url_in_db_ = true;
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SafeBrowsingDatabaseManager* database_manager() {
211868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return safe_browsing_service_->database_manager().get();
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool is_checked_url_in_db() {
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::AutoLock l(update_status_mutex_);
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return is_checked_url_in_db_;
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void set_is_checked_url_safe(bool safe) {
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::AutoLock l(update_status_mutex_);
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    is_checked_url_safe_ = safe;
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool is_checked_url_safe() {
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::AutoLock l(update_status_mutex_);
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return is_checked_url_safe_;
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool is_database_ready() {
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::AutoLock l(update_status_mutex_);
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return is_database_ready_;
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Time last_update() {
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::AutoLock l(update_status_mutex_);
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return last_update_;
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool is_update_scheduled() {
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::AutoLock l(update_status_mutex_);
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return is_update_scheduled_;
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop* SafeBrowsingMessageLoop() {
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return database_manager()->safe_browsing_thread_->message_loop();
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const net::SpawnedTestServer& test_server() const {
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return *test_server_;
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool InitSafeBrowsingService() {
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    safe_browsing_service_ = g_browser_process->safe_browsing_service();
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return safe_browsing_service_ != NULL;
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
258a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  virtual void SetUp() OVERRIDE {
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::FilePath datafile_path;
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &datafile_path));
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    datafile_path = datafile_path.Append(FILE_PATH_LITERAL("third_party"))
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          .Append(FILE_PATH_LITERAL("safe_browsing"))
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          .Append(FILE_PATH_LITERAL("testing"))
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          .Append(kDataFile);
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    test_server_.reset(new LocalSafeBrowsingTestServer(datafile_path));
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(test_server_->Start());
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(INFO) << "server is " << test_server_->host_port_pair().ToString();
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
270a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    // Point to the testing server for all SafeBrowsing requests.
271a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    std::string url_prefix = test_server_->GetURL("safebrowsing").spec();
272a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    sb_factory_.reset(new TestSafeBrowsingServiceFactory(url_prefix));
273a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    SafeBrowsingService::RegisterFactory(sb_factory_.get());
274a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
275a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    InProcessBrowserTest::SetUp();
276a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  }
277a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
278a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  virtual void TearDown() OVERRIDE {
279a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    InProcessBrowserTest::TearDown();
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
281a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    SafeBrowsingService::RegisterFactory(NULL);
282a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  }
283a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
284a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // This test uses loopback. No need to use IPv6 especially it makes
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // local requests slow on Windows trybot when ipv6 local address [::1]
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // is not setup.
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    command_line->AppendSwitch(switches::kDisableIPv6);
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // TODO(lzheng): The test server does not understand download related
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // requests. We need to fix the server.
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    command_line->AppendSwitch(switches::kSbDisableDownloadProtection);
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // TODO(gcasto): Generate new testing data that includes the
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // client-side phishing whitelist.
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    command_line->AppendSwitch(
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        switches::kDisableClientSidePhishingDetection);
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // TODO(kalman): Generate new testing data that includes the extension
3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // blacklist.
3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    command_line->AppendSwitch(switches::kSbDisableExtensionBlacklist);
3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
30390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // TODO(tburkard): Generate new testing data that includes the side-effect
30490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // free whitelist.
30590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    command_line->AppendSwitch(switches::kSbDisableSideEffectFreeWhitelist);
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetTestStep(int step) {
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string test_step = base::StringPrintf("test_step=%d", step);
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    safe_browsing_service_->protocol_manager_->set_additional_query(test_step);
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
314a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  scoped_ptr<TestSafeBrowsingServiceFactory> sb_factory_;
315a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SafeBrowsingService* safe_browsing_service_;
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
318c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<net::SpawnedTestServer> test_server_;
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Protects all variables below since they are read on UI thread
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // but updated on IO thread or safebrowsing thread.
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Lock update_status_mutex_;
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // States associated with safebrowsing service updates.
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool is_database_ready_;
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Time last_update_;
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool is_update_scheduled_;
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Indicates if there is a match between a URL's prefix and safebrowsing
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // database (thus potentially it is a phishing URL).
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool is_checked_url_in_db_;
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // True if last verified URL is not a phishing URL and thus it is safe.
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool is_checked_url_safe_;
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(SafeBrowsingServerTest);
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A ref counted helper class that handles callbacks between IO thread and UI
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// thread.
3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class SafeBrowsingServerTestHelper
3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : public base::RefCountedThreadSafe<SafeBrowsingServerTestHelper>,
3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      public SafeBrowsingDatabaseManager::Client,
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      public net::URLFetcherDelegate {
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SafeBrowsingServerTestHelper(SafeBrowsingServerTest* safe_browsing_test,
3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                               net::URLRequestContextGetter* request_context)
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : safe_browsing_test_(safe_browsing_test),
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        response_status_(net::URLRequestStatus::FAILED),
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        request_context_(request_context) {
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Callbacks for SafeBrowsingDatabaseManager::Client.
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnCheckBrowseUrlResult(const GURL& url,
3531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                      SBThreatType threat_type,
3541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                      const std::string& metadata) OVERRIDE {
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(safe_browsing_test_->is_checked_url_in_db());
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    safe_browsing_test_->set_is_checked_url_safe(
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        threat_type == SB_THREAT_TYPE_SAFE);
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Bind(&SafeBrowsingServerTestHelper::OnCheckUrlDone, this));
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnBlockingPageComplete(bool proceed) {
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED() << "Not implemented.";
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Functions and callbacks related to CheckUrl. These are used to verify
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // phishing URLs.
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void CheckUrl(const GURL& url) {
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Bind(&SafeBrowsingServerTestHelper::CheckUrlOnIOThread,
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   this, url));
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    content::RunMessageLoop();
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void CheckUrlOnIOThread(const GURL& url) {
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    safe_browsing_test_->CheckUrl(this, url);
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!safe_browsing_test_->is_checked_url_in_db()) {
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Ends the checking since this URL's prefix is not in database.
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Bind(&SafeBrowsingServerTestHelper::OnCheckUrlDone, this));
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Otherwise, OnCheckUrlDone is called in OnUrlCheckResult since
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // safebrowsing service further fetches hashes from safebrowsing server.
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnCheckUrlDone() {
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StopUILoop();
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Updates status from IO Thread.
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void CheckStatusOnIOThread() {
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    safe_browsing_test_->UpdateSafeBrowsingStatus();
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    safe_browsing_test_->SafeBrowsingMessageLoop()->PostTask(FROM_HERE,
3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Bind(&SafeBrowsingServerTestHelper::CheckIsDatabaseReady, this));
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Checks status in SafeBrowsing Thread.
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void CheckIsDatabaseReady() {
40190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    EXPECT_EQ(base::MessageLoop::current(),
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              safe_browsing_test_->SafeBrowsingMessageLoop());
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    safe_browsing_test_->CheckIsDatabaseReady();
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Bind(&SafeBrowsingServerTestHelper::OnWaitForStatusUpdateDone,
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   this));
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnWaitForStatusUpdateDone() {
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StopUILoop();
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Update safebrowsing status.
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void UpdateStatus() {
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BrowserThread::PostTask(
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        BrowserThread::IO,
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FROM_HERE,
4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Bind(&SafeBrowsingServerTestHelper::CheckStatusOnIOThread, this));
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Will continue after OnWaitForStatusUpdateDone().
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    content::RunMessageLoop();
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Calls test server to fetch database for verification.
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::URLRequestStatus::Status FetchDBToVerify(
425c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const net::SpawnedTestServer& test_server,
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int test_step) {
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // TODO(lzheng): Remove chunk_type=add once it is not needed by the server.
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string path = base::StringPrintf(
429f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        "%s?client=chromium&appver=1.0&pver=3.0&test_step=%d&chunk_type=add",
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        kDBVerifyPath, test_step);
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return FetchUrl(test_server.GetURL(path));
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Calls test server to fetch URLs for verification.
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::URLRequestStatus::Status FetchUrlsToVerify(
436c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const net::SpawnedTestServer& test_server,
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int test_step) {
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string path = base::StringPrintf(
439f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        "%s?client=chromium&appver=1.0&pver=3.0&test_step=%d",
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        kUrlVerifyPath, test_step);
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return FetchUrl(test_server.GetURL(path));
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Calls test server to check if test data is done. E.g.: if there is a
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // bad URL that server expects test to fetch full hash but the test didn't,
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // this verification will fail.
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::URLRequestStatus::Status VerifyTestComplete(
448c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const net::SpawnedTestServer& test_server,
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int test_step) {
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string path = base::StringPrintf(
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        "%s?test_step=%d", kTestCompletePath, test_step);
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return FetchUrl(test_server.GetURL(path));
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Callback for URLFetcher.
4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE {
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    source->GetResponseAsString(&response_data_);
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    response_status_ = source->GetStatus().status();
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StopUILoop();
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string& response_data() {
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return response_data_;
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  friend class base::RefCountedThreadSafe<SafeBrowsingServerTestHelper>;
4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~SafeBrowsingServerTestHelper() {}
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Stops UI loop after desired status is updated.
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void StopUILoop() {
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::UI));
47390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoopForUI::current()->Quit();
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Fetch a URL. If message_loop_started is true, starts the message loop
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // so the caller could wait till OnURLFetchComplete is called.
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::URLRequestStatus::Status FetchUrl(const GURL& url) {
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    url_fetcher_.reset(net::URLFetcher::Create(
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        url, net::URLFetcher::GET, this));
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    url_fetcher_->SetLoadFlags(net::LOAD_DISABLE_CACHE);
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    url_fetcher_->SetRequestContext(request_context_);
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    url_fetcher_->Start();
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    content::RunMessageLoop();
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return response_status_;
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::OneShotTimer<SafeBrowsingServerTestHelper> check_update_timer_;
4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SafeBrowsingServerTest* safe_browsing_test_;
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<net::URLFetcher> url_fetcher_;
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data_;
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::URLRequestStatus::Status response_status_;
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::URLRequestContextGetter* request_context_;
4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(SafeBrowsingServerTestHelper);
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
497f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// TODO(shess): Disabled pending new data for third_party/safe_browsing/testing/
4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(SafeBrowsingServerTest,
499f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                       DISABLED_SafeBrowsingServerTest) {
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LOG(INFO) << "Start test";
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(InitSafeBrowsingService());
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::URLRequestContextGetter* request_context =
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      browser()->profile()->GetRequestContext();
5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<SafeBrowsingServerTestHelper> safe_browsing_helper(
5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new SafeBrowsingServerTestHelper(this, request_context));
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int last_step = 0;
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Waits and makes sure safebrowsing update is not happening.
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The wait will stop once OnWaitForStatusUpdateDone in
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // safe_browsing_helper is called and status from safe_browsing_service_
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // is checked.
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  safe_browsing_helper->UpdateStatus();
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(is_database_ready());
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(is_update_scheduled());
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(last_update().is_null());
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Starts updates. After each update, the test will fetch a list of URLs with
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // expected results to verify with safebrowsing service. If there is no error,
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the test moves on to the next step to get more update chunks.
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This repeats till there is no update data.
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int step = 1;; step++) {
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Every step should be a fresh start.
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SCOPED_TRACE(base::StringPrintf("step=%d", step));
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(is_database_ready());
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(is_update_scheduled());
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Starts safebrowsing update on IO thread. Waits till scheduled
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // update finishes.
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::Time now = base::Time::Now();
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetTestStep(step);
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ForceUpdate();
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    safe_browsing_helper->UpdateStatus();
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(is_database_ready());
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(is_update_scheduled());
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(last_update().is_null());
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (last_update() < now) {
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // This means no data available anymore.
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Fetches URLs to verify and waits till server responses with data.
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(net::URLRequestStatus::SUCCESS,
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              safe_browsing_helper->FetchUrlsToVerify(test_server(), step));
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::vector<PhishingUrl> phishing_urls;
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(ParsePhishingUrls(safe_browsing_helper->response_data(),
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  &phishing_urls));
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_GT(phishing_urls.size(), 0U);
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (size_t j = 0; j < phishing_urls.size(); ++j) {
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Verifes with server if a URL is a phishing URL and waits till server
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // responses.
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      safe_browsing_helper->CheckUrl(GURL(phishing_urls[j].url));
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (phishing_urls[j].is_phishing) {
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        EXPECT_TRUE(is_checked_url_in_db())
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)        EXPECT_FALSE(is_checked_url_safe())
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            << phishing_urls[j].url
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            << " is_phishing: " << phishing_urls[j].is_phishing
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            << " test step: " << step;
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else {
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        EXPECT_TRUE(is_checked_url_safe())
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            << phishing_urls[j].url
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            << " is_phishing: " << phishing_urls[j].is_phishing
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            << " test step: " << step;
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // TODO(lzheng): We should verify the fetched database with local
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // database to make sure they match.
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(net::URLRequestStatus::SUCCESS,
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              safe_browsing_helper->FetchDBToVerify(test_server(), step));
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_GT(safe_browsing_helper->response_data().size(), 0U);
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    last_step = step;
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verifies with server if test is done and waits till server responses.
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(net::URLRequestStatus::SUCCESS,
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            safe_browsing_helper->VerifyTestComplete(test_server(), last_step));
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("yes", safe_browsing_helper->response_data());
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
583