| Index: chrome/browser/safe_browsing/safe_browsing_test.cc
|
| ===================================================================
|
| --- chrome/browser/safe_browsing/safe_browsing_test.cc (revision 62990)
|
| +++ chrome/browser/safe_browsing/safe_browsing_test.cc (working copy)
|
| @@ -1,19 +1,200 @@
|
| // Copyright (c) 2010 The Chromium Authors. All rights reserved.
|
| // Use of this source code is governed by a BSD-style license that can be
|
| // found in the LICENSE file.
|
| +//
|
| +// This test uses the safebrowsing test server published at
|
| +// http://code.google.com/p/google-safe-browsing/ to test the safebrowsing
|
| +// protocol implemetation. Details of the safebrowsing testing flow is
|
| +// documented at
|
| +// http://code.google.com/p/google-safe-browsing/wiki/ProtocolTesting
|
| +//
|
| +// This test launches safebrowsing test server and issues several update
|
| +// requests against that server. Each update would get different data and after
|
| +// each update, the test will get a list of URLs from the test server to verify
|
| +// its repository. The test will succeed only if all updates are performed and
|
| +// URLs match what the server expected.
|
|
|
| +#include <vector>
|
| +
|
| #include "base/command_line.h"
|
| +#include "base/condition_variable.h"
|
| +#include "base/environment.h"
|
| #include "base/lock.h"
|
| +#include "base/path_service.h"
|
| +#include "base/process_util.h"
|
| +#include "base/string_number_conversions.h"
|
| +#include "base/string_util.h"
|
| +#include "base/string_split.h"
|
| +#include "base/time.h"
|
| +#include "base/utf_string_conversions.h"
|
| #include "chrome/browser/browser_process.h"
|
| #include "chrome/browser/browser_thread.h"
|
| +#include "chrome/browser/profile.h"
|
| #include "chrome/browser/renderer_host/resource_dispatcher_host.h"
|
| #include "chrome/browser/safe_browsing/protocol_manager.h"
|
| #include "chrome/browser/safe_browsing/safe_browsing_service.h"
|
| #include "chrome/common/chrome_switches.h"
|
| +#include "chrome/common/url_constants.h"
|
| #include "chrome/test/in_process_browser_test.h"
|
| +#include "base/test/test_timeouts.h"
|
| #include "chrome/test/ui_test_utils.h"
|
| +#include "net/base/host_resolver.h"
|
| +#include "net/base/load_flags.h"
|
| +#include "net/base/net_log.h"
|
| +#include "net/test/python_utils.h"
|
| #include "testing/gtest/include/gtest/gtest.h"
|
|
|
| +namespace {
|
| +
|
| +const FilePath::CharType kDataFile[] = FILE_PATH_LITERAL("testing_input.dat");
|
| +const char kUrlVerifyPath[] = "/safebrowsing/verify_urls";
|
| +const char kDBVerifyPath[] = "/safebrowsing/verify_database";
|
| +const char kDBResetPath[] = "/reset";
|
| +const char kTestCompletePath[] = "/test_complete";
|
| +
|
| +struct PhishingUrl {
|
| + std::string url;
|
| + std::string list_name;
|
| + bool is_phishing;
|
| +};
|
| +
|
| +// Parses server response for verify_urls. The expected format is:
|
| +//
|
| +// first.random.url.com/ internal-test-shavar yes
|
| +// second.random.url.com/ internal-test-shavar yes
|
| +// ...
|
| +bool ParsePhishingUrls(const std::string& data,
|
| + std::vector<PhishingUrl>* phishing_urls) {
|
| + if (data.empty())
|
| + return false;
|
| +
|
| + std::vector<std::string> urls;
|
| + base::SplitString(data, '\n', &urls);
|
| + for (size_t i = 0; i < urls.size(); ++i) {
|
| + if (urls[i].empty())
|
| + continue;
|
| + PhishingUrl phishing_url;
|
| + std::vector<std::string> record_parts;
|
| + base::SplitString(urls[i], '\t', &record_parts);
|
| + if (record_parts.size() != 3) {
|
| + LOG(ERROR) << "Unexpected URL format in phishing URL list: "
|
| + << urls[i];
|
| + return false;
|
| + }
|
| + phishing_url.url = std::string(chrome::kHttpScheme) +
|
| + "://" + record_parts[0];
|
| + phishing_url.list_name = record_parts[1];
|
| + if (record_parts[2] == "yes") {
|
| + phishing_url.is_phishing = true;
|
| + } else if (record_parts[2] == "no") {
|
| + phishing_url.is_phishing = false;
|
| + } else {
|
| + LOG(ERROR) << "Unrecognized expectation in " << urls[i]
|
| + << ": " << record_parts[2];
|
| + return false;
|
| + }
|
| + phishing_urls->push_back(phishing_url);
|
| + }
|
| + return true;
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +class SafeBrowsingTestServer {
|
| + public:
|
| + explicit SafeBrowsingTestServer(const FilePath& datafile)
|
| + : datafile_(datafile),
|
| + server_handle_(base::kNullProcessHandle) {
|
| + }
|
| +
|
| + ~SafeBrowsingTestServer() {
|
| + EXPECT_EQ(base::kNullProcessHandle, server_handle_);
|
| + }
|
| +
|
| + // Start the python server test suite.
|
| + bool Start() {
|
| + // Get path to python server script
|
| + FilePath testserver_path;
|
| + if (!PathService::Get(base::DIR_SOURCE_ROOT, &testserver_path)) {
|
| + LOG(ERROR) << "Failed to get DIR_SOURCE_ROOT";
|
| + return false;
|
| + }
|
| + testserver_path = testserver_path
|
| + .Append(FILE_PATH_LITERAL("third_party"))
|
| + .Append(FILE_PATH_LITERAL("safe_browsing"))
|
| + .Append(FILE_PATH_LITERAL("testing"));
|
| + AppendToPythonPath(testserver_path);
|
| + FilePath testserver = testserver_path.Append(
|
| + FILE_PATH_LITERAL("safebrowsing_test_server.py"));
|
| +
|
| + FilePath pyproto_code_dir;
|
| + if (!PathService::Get(base::DIR_EXE, &pyproto_code_dir)) {
|
| + LOG(ERROR) << "Failed to get DIR_EXE";
|
| + return false;
|
| + }
|
| + pyproto_code_dir = pyproto_code_dir.Append(FILE_PATH_LITERAL("pyproto"));
|
| + AppendToPythonPath(pyproto_code_dir);
|
| + pyproto_code_dir = pyproto_code_dir.Append(FILE_PATH_LITERAL("google"));
|
| + AppendToPythonPath(pyproto_code_dir);
|
| +
|
| + FilePath python_runtime;
|
| + EXPECT_TRUE(GetPythonRunTime(&python_runtime));
|
| + CommandLine cmd_line(python_runtime);
|
| + FilePath datafile = testserver_path.Append(datafile_);
|
| + cmd_line.AppendArgPath(testserver);
|
| + cmd_line.AppendSwitchASCII("port", StringPrintf("%d", kPort_));
|
| + cmd_line.AppendSwitchPath("datafile", datafile);
|
| +
|
| + if (!base::LaunchApp(cmd_line, false, true, &server_handle_)) {
|
| + LOG(ERROR) << "Failed to launch server: "
|
| + << cmd_line.command_line_string();
|
| + return false;
|
| + }
|
| + return true;
|
| + }
|
| +
|
| + // Stop the python server test suite.
|
| + bool Stop() {
|
| + if (server_handle_ == base::kNullProcessHandle) {
|
| + return true;
|
| + }
|
| +
|
| + // First check if the process has already terminated.
|
| + bool ret = base::WaitForSingleProcess(server_handle_, 0);
|
| + if (!ret) {
|
| + ret = base::KillProcess(server_handle_, 1, true);
|
| + }
|
| +
|
| + if (ret) {
|
| + base::CloseProcessHandle(server_handle_);
|
| + server_handle_ = base::kNullProcessHandle;
|
| + LOG(INFO) << "Stopped.";
|
| + } else {
|
| + LOG(INFO) << "Kill failed?";
|
| + return false;
|
| + }
|
| + return true;
|
| + }
|
| +
|
| + static const char* Host() {
|
| + return kHost_;
|
| + }
|
| +
|
| + static int Port() {
|
| + return kPort_;
|
| + }
|
| +
|
| + private:
|
| + static const char kHost_[];
|
| + static const int kPort_;
|
| + FilePath datafile_;
|
| + base::ProcessHandle server_handle_;
|
| + DISALLOW_COPY_AND_ASSIGN(SafeBrowsingTestServer);
|
| +};
|
| +
|
| +const char SafeBrowsingTestServer::kHost_[] = "localhost";
|
| +const int SafeBrowsingTestServer::kPort_ = 40102;
|
| +
|
| // This starts the browser and keeps status of states related to SafeBrowsing.
|
| class SafeBrowsingServiceTest : public InProcessBrowserTest {
|
| public:
|
| @@ -22,11 +203,15 @@
|
| is_database_ready_(true),
|
| is_initial_request_(false),
|
| is_update_scheduled_(false),
|
| - is_url_match_in_db_(false) {
|
| + is_checked_url_in_db_(false),
|
| + is_checked_url_safe_(false) {
|
| }
|
|
|
| + virtual ~SafeBrowsingServiceTest() {
|
| + }
|
| +
|
| void UpdateSafeBrowsingStatus() {
|
| - CHECK(safe_browsing_service_);
|
| + ASSERT_TRUE(safe_browsing_service_);
|
| AutoLock lock(update_status_mutex_);
|
| is_initial_request_ =
|
| safe_browsing_service_->protocol_manager_->is_initial_request();
|
| @@ -35,6 +220,11 @@
|
| safe_browsing_service_->protocol_manager_->update_timer_.IsRunning();
|
| }
|
|
|
| + void ForceUpdate() {
|
| + ASSERT_TRUE(safe_browsing_service_);
|
| + safe_browsing_service_->protocol_manager_->ForceScheduleNextUpdate(0);
|
| + }
|
| +
|
| void CheckIsDatabaseReady() {
|
| AutoLock lock(update_status_mutex_);
|
| is_database_ready_ =
|
| @@ -42,20 +232,34 @@
|
| }
|
|
|
| void CheckUrl(SafeBrowsingService::Client* helper, const GURL& url) {
|
| - CHECK(safe_browsing_service_);
|
| + ASSERT_TRUE(safe_browsing_service_);
|
| AutoLock lock(update_status_mutex_);
|
| - if (!safe_browsing_service_->CheckUrl(url, helper)) {
|
| - safe_browsing_service_->CancelCheck(helper);
|
| - is_url_match_in_db_ = false;
|
| + if (safe_browsing_service_->CheckUrl(url, helper)) {
|
| + is_checked_url_in_db_ = false;
|
| + is_checked_url_safe_ = true;
|
| + } else {
|
| + // In this case, Safebrowsing service will fetch the full hash
|
| + // from the server and examine that. Once it is done,
|
| + // set_is_checked_url_safe() will be called via callback.
|
| + is_checked_url_in_db_ = true;
|
| }
|
| - is_url_match_in_db_ = true;
|
| }
|
|
|
| - bool is_url_match_in_db() {
|
| + bool is_checked_url_in_db() {
|
| AutoLock l(update_status_mutex_);
|
| - return is_url_match_in_db_;
|
| + return is_checked_url_in_db_;
|
| }
|
|
|
| + void set_is_checked_url_safe(bool safe) {
|
| + AutoLock l(update_status_mutex_);
|
| + is_checked_url_safe_ = safe;
|
| + }
|
| +
|
| + bool is_checked_url_safe() {
|
| + AutoLock l(update_status_mutex_);
|
| + return is_checked_url_safe_;
|
| + }
|
| +
|
| bool is_database_ready() {
|
| AutoLock l(update_status_mutex_);
|
| return is_database_ready_;
|
| @@ -81,17 +285,33 @@
|
| }
|
|
|
| protected:
|
| - void InitSafeBrowsingService() {
|
| + bool InitSafeBrowsingService() {
|
| safe_browsing_service_ =
|
| g_browser_process->resource_dispatcher_host()->safe_browsing_service();
|
| + return safe_browsing_service_ != NULL;
|
| }
|
|
|
| virtual void SetUpCommandLine(CommandLine* command_line) {
|
| // Makes sure the auto update is not triggered. This test will force the
|
| // update when needed.
|
| command_line->AppendSwitch(switches::kSbDisableAutoUpdate);
|
| +
|
| + // In this test, we fetch SafeBrowsing data and Mac key from the same
|
| + // server. Although in real production, they are served from different
|
| + // servers.
|
| + std::string url_prefix =
|
| + StringPrintf("http://%s:%d/safebrowsing",
|
| + SafeBrowsingTestServer::Host(),
|
| + SafeBrowsingTestServer::Port());
|
| + command_line->AppendSwitchASCII(switches::kSbInfoURLPrefix, url_prefix);
|
| + command_line->AppendSwitchASCII(switches::kSbMacKeyURLPrefix, url_prefix);
|
| }
|
|
|
| + void SetTestStep(int step) {
|
| + std::string test_step = StringPrintf("test_step=%d", step);
|
| + safe_browsing_service_->protocol_manager_->set_additional_query(test_step);
|
| + }
|
| +
|
| private:
|
| SafeBrowsingService* safe_browsing_service_;
|
|
|
| @@ -105,8 +325,11 @@
|
| base::Time last_update_;
|
| bool is_update_scheduled_;
|
| // Indicates if there is a match between a URL's prefix and safebrowsing
|
| - // database (thus potentially it is a phishing url).
|
| - bool is_url_match_in_db_;
|
| + // database (thus potentially it is a phishing URL).
|
| + bool is_checked_url_in_db_;
|
| + // True if last verified URL is not a phishing URL and thus it is safe.
|
| + bool is_checked_url_safe_;
|
| +
|
| DISALLOW_COPY_AND_ASSIGN(SafeBrowsingServiceTest);
|
| };
|
|
|
| @@ -114,41 +337,75 @@
|
| // thread.
|
| class SafeBrowsingServiceTestHelper
|
| : public base::RefCountedThreadSafe<SafeBrowsingServiceTestHelper>,
|
| - public SafeBrowsingService::Client {
|
| + public SafeBrowsingService::Client,
|
| + public URLFetcher::Delegate {
|
| public:
|
| explicit SafeBrowsingServiceTestHelper(
|
| SafeBrowsingServiceTest* safe_browsing_test)
|
| - : safe_browsing_test_(safe_browsing_test) {
|
| + : safe_browsing_test_(safe_browsing_test),
|
| + response_status_(URLRequestStatus::FAILED) {
|
| }
|
|
|
| - // Callbacks for SafeBrowsingService::Client. Not implemented yet.
|
| + // Callbacks for SafeBrowsingService::Client.
|
| virtual void OnUrlCheckResult(const GURL& url,
|
| SafeBrowsingService::UrlCheckResult result) {
|
| - NOTREACHED() << "Not implemented.";
|
| + EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| + EXPECT_TRUE(safe_browsing_test_->is_checked_url_in_db());
|
| + safe_browsing_test_->set_is_checked_url_safe(
|
| + result == SafeBrowsingService::URL_SAFE);
|
| + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
|
| + NewRunnableMethod(this,
|
| + &SafeBrowsingServiceTestHelper::OnCheckUrlDone));
|
| }
|
| virtual void OnBlockingPageComplete(bool proceed) {
|
| NOTREACHED() << "Not implemented.";
|
| }
|
|
|
| - // Functions and callbacks related to CheckUrl. These are used to verify if
|
| - // a URL is a phishing URL.
|
| + // Functions and callbacks to start the safebrowsing database update.
|
| + void ForceUpdate() {
|
| + BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
|
| + NewRunnableMethod(this,
|
| + &SafeBrowsingServiceTestHelper::ForceUpdateInIOThread));
|
| + // Will continue after OnForceUpdateDone().
|
| + ui_test_utils::RunMessageLoop();
|
| + }
|
| + void ForceUpdateInIOThread() {
|
| + EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| + safe_browsing_test_->ForceUpdate();
|
| + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
|
| + NewRunnableMethod(this,
|
| + &SafeBrowsingServiceTestHelper::OnForceUpdateDone));
|
| + }
|
| + void OnForceUpdateDone() {
|
| + StopUILoop();
|
| + }
|
| +
|
| + // Functions and callbacks related to CheckUrl. These are used to verify
|
| + // phishing URLs.
|
| void CheckUrl(const GURL& url) {
|
| BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, NewRunnableMethod(
|
| this, &SafeBrowsingServiceTestHelper::CheckUrlOnIOThread, url));
|
| + ui_test_utils::RunMessageLoop();
|
| }
|
| void CheckUrlOnIOThread(const GURL& url) {
|
| - CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| + EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| safe_browsing_test_->CheckUrl(this, url);
|
| - BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, NewRunnableMethod(
|
| - this, &SafeBrowsingServiceTestHelper::OnCheckUrlOnIOThreadDone));
|
| + if (!safe_browsing_test_->is_checked_url_in_db()) {
|
| + // Ends the checking since this URL's prefix is not in database.
|
| + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, NewRunnableMethod(
|
| + this, &SafeBrowsingServiceTestHelper::OnCheckUrlDone));
|
| + }
|
| + // Otherwise, OnCheckUrlDone is called in OnUrlCheckResult since
|
| + // safebrowsing service further fetches hashes from safebrowsing server.
|
| }
|
| - void OnCheckUrlOnIOThreadDone() {
|
| +
|
| + void OnCheckUrlDone() {
|
| StopUILoop();
|
| }
|
|
|
| // Updates status from IO Thread.
|
| void CheckStatusOnIOThread() {
|
| - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| + EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| safe_browsing_test_->UpdateSafeBrowsingStatus();
|
| safe_browsing_test_->SafeBrowsingMessageLoop()->PostTask(
|
| FROM_HERE, NewRunnableMethod(this,
|
| @@ -157,63 +414,230 @@
|
|
|
| // Checks status in SafeBrowsing Thread.
|
| void CheckIsDatabaseReady() {
|
| - DCHECK_EQ(MessageLoop::current(),
|
| + EXPECT_EQ(MessageLoop::current(),
|
| safe_browsing_test_->SafeBrowsingMessageLoop());
|
| safe_browsing_test_->CheckIsDatabaseReady();
|
| BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, NewRunnableMethod(
|
| - this, &SafeBrowsingServiceTestHelper::OnCheckStatusAfterDelayDone));
|
| + this, &SafeBrowsingServiceTestHelper::OnWaitForStatusUpdateDone));
|
| }
|
|
|
| - void OnCheckStatusAfterDelayDone() {
|
| + void OnWaitForStatusUpdateDone() {
|
| StopUILoop();
|
| }
|
|
|
| - // Checks safebrowsing status after a given latency.
|
| - void CheckStatusAfterDelay(int64 wait_time_sec) {
|
| + // Wait for a given period to get safebrowsing status updated.
|
| + void WaitForStatusUpdate(int64 wait_time_msec) {
|
| BrowserThread::PostDelayedTask(
|
| BrowserThread::IO,
|
| FROM_HERE,
|
| NewRunnableMethod(this,
|
| &SafeBrowsingServiceTestHelper::CheckStatusOnIOThread),
|
| - wait_time_sec * 1000);
|
| + wait_time_msec);
|
| + // Will continue after OnWaitForStatusUpdateDone().
|
| + ui_test_utils::RunMessageLoop();
|
| }
|
|
|
| + void WaitTillServerReady(const char* host, int port) {
|
| + response_status_ = URLRequestStatus::FAILED;
|
| + GURL url(StringPrintf("http://%s:%d%s?test_step=0",
|
| + host, port, kDBResetPath));
|
| + // TODO(lzheng): We should have a way to reliably tell when a server is
|
| + // ready so we could get rid of the Sleep and retry loop.
|
| + while (true) {
|
| + if (FetchUrl(url) == URLRequestStatus::SUCCESS)
|
| + break;
|
| + // Wait and try again if last fetch was failed. The loop will hit the
|
| + // timeout in OutOfProcTestRunner if the fetch can not get success
|
| + // response.
|
| + PlatformThread::Sleep(TestTimeouts::action_timeout_ms());
|
| + }
|
| + }
|
| +
|
| + // Calls test server to fetch database for verification.
|
| + URLRequestStatus::Status FetchDBToVerify(const char* host, int port,
|
| + int test_step) {
|
| + // TODO(lzheng): Remove chunk_type=add once it is not needed by the server.
|
| + GURL url(StringPrintf("http://%s:%d%s?"
|
| + "client=chromium&appver=1.0&pver=2.2&test_step=%d&"
|
| + "chunk_type=add",
|
| + host, port, kDBVerifyPath, test_step));
|
| + return FetchUrl(url);
|
| + }
|
| +
|
| + // Calls test server to fetch URLs for verification.
|
| + URLRequestStatus::Status FetchUrlsToVerify(const char* host, int port,
|
| + int test_step) {
|
| + GURL url(StringPrintf("http://%s:%d%s?"
|
| + "client=chromium&appver=1.0&pver=2.2&test_step=%d",
|
| + host, port, kUrlVerifyPath, test_step));
|
| + return FetchUrl(url);
|
| + }
|
| +
|
| + // Calls test server to check if test data is done. E.g.: if there is a
|
| + // bad URL that server expects test to fetch full hash but the test didn't,
|
| + // this verification will fail.
|
| + URLRequestStatus::Status VerifyTestComplete(const char* host, int port,
|
| + int test_step) {
|
| + GURL url(StringPrintf("http://%s:%d%s?test_step=%d",
|
| + host, port, kTestCompletePath, test_step));
|
| + return FetchUrl(url);
|
| + }
|
| +
|
| + // Callback for URLFetcher.
|
| + virtual void OnURLFetchComplete(const URLFetcher* source,
|
| + const GURL& url,
|
| + const URLRequestStatus& status,
|
| + int response_code,
|
| + const ResponseCookies& cookies,
|
| + const std::string& data) {
|
| + response_data_ = data;
|
| + response_status_ = status.status();
|
| + StopUILoop();
|
| + }
|
| +
|
| + const std::string& response_data() {
|
| + return response_data_;
|
| + }
|
| +
|
| private:
|
| // Stops UI loop after desired status is updated.
|
| void StopUILoop() {
|
| - CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| + EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| MessageLoopForUI::current()->Quit();
|
| }
|
|
|
| + // Fetch a URL. If message_loop_started is true, starts the message loop
|
| + // so the caller could wait till OnURLFetchComplete is called.
|
| + URLRequestStatus::Status FetchUrl(const GURL& url) {
|
| + url_fetcher_.reset(new URLFetcher(url, URLFetcher::GET, this));
|
| + url_fetcher_->set_load_flags(net::LOAD_DISABLE_CACHE);
|
| + url_fetcher_->set_request_context(Profile::GetDefaultRequestContext());
|
| + url_fetcher_->Start();
|
| + ui_test_utils::RunMessageLoop();
|
| + return response_status_;
|
| + }
|
| +
|
| base::OneShotTimer<SafeBrowsingServiceTestHelper> check_update_timer_;
|
| SafeBrowsingServiceTest* safe_browsing_test_;
|
| + scoped_ptr<URLFetcher> url_fetcher_;
|
| + std::string response_data_;
|
| + URLRequestStatus::Status response_status_;
|
| DISALLOW_COPY_AND_ASSIGN(SafeBrowsingServiceTestHelper);
|
| };
|
|
|
| IN_PROC_BROWSER_TEST_F(SafeBrowsingServiceTest, SafeBrowsingSystemTest) {
|
| - InitSafeBrowsingService();
|
| + LOG(INFO) << "Start test";
|
| + const char* server_host = SafeBrowsingTestServer::Host();
|
| + int server_port = SafeBrowsingTestServer::Port();
|
| + ASSERT_TRUE(InitSafeBrowsingService());
|
| +
|
| scoped_refptr<SafeBrowsingServiceTestHelper> safe_browsing_helper =
|
| new SafeBrowsingServiceTestHelper(this);
|
| + int last_step = 0;
|
| + FilePath datafile_path = FilePath(kDataFile);
|
| + SafeBrowsingTestServer test_server(datafile_path);
|
| + ASSERT_TRUE(test_server.Start());
|
|
|
| - // Waits for 1 sec and makes sure safebrowsing update is not happening.
|
| - safe_browsing_helper->CheckStatusAfterDelay(1);
|
| - // Loop will stop once OnCheckStatusOnIOThreadDone in safe_browsing_helper
|
| - // is called and status from safe_browsing_service_ is checked.
|
| - ui_test_utils::RunMessageLoop();
|
| + // Make sure the server is running.
|
| + safe_browsing_helper->WaitTillServerReady(server_host, server_port);
|
| +
|
| + // Waits and makes sure safebrowsing update is not happening.
|
| + // The wait will stop once OnWaitForStatusUpdateDone in
|
| + // safe_browsing_helper is called and status from safe_browsing_service_
|
| + // is checked.
|
| + safe_browsing_helper->WaitForStatusUpdate(0);
|
| EXPECT_TRUE(is_database_ready());
|
| EXPECT_TRUE(is_initial_request());
|
| EXPECT_FALSE(is_update_scheduled());
|
| EXPECT_TRUE(last_update().is_null());
|
| + // Starts updates. After each update, the test will fetch a list of URLs with
|
| + // expected results to verify with safebrowsing service. If there is no error,
|
| + // the test moves on to the next step to get more update chunks.
|
| + // This repeats till there is no update data.
|
| + for (int step = 1;; step++) {
|
| + // Every step should be a fresh start.
|
| + SCOPED_TRACE(StringPrintf("step=%d", step));
|
| + EXPECT_TRUE(is_database_ready());
|
| + EXPECT_FALSE(is_update_scheduled());
|
|
|
| - // Verify URL.
|
| - const char test_url[] = "http://ianfette.org";
|
| - safe_browsing_helper->CheckUrl(GURL(test_url));
|
| - // Loop will stop once OnCheckUrlOnIOThreadDone in safe_browsing_helper
|
| - // is called and url check is done.
|
| - ui_test_utils::RunMessageLoop();
|
| - EXPECT_TRUE(is_url_match_in_db());
|
| + // TODO(lzheng): Remove the following #if and #elif to enable the rest of
|
| + // the test once bot is restarted with change
|
| + // http://codereview.chromium.org/3750002.
|
| +#if defined(OS_WIN)
|
| + break;
|
| +#elif defined(OS_POSIX)
|
| + if (step > 2 ) break;
|
| +#endif
|
|
|
| - // TODO(lzheng): Add tests to launch a testing safebrowsing server
|
| - // and issue requests repeatedly:
|
| - // http://code.google.com/p/google-safe-browsing/wiki/ProtocolTesting
|
| + // Starts safebrowsing update on IO thread. Waits till scheduled
|
| + // update finishes. Stops waiting after kMaxWaitSecPerStep if the update
|
| + // could not finish.
|
| + base::Time now = base::Time::Now();
|
| + SetTestStep(step);
|
| + safe_browsing_helper->ForceUpdate();
|
| +
|
| + do {
|
| + // Periodically pull the status.
|
| + safe_browsing_helper->WaitForStatusUpdate(
|
| + TestTimeouts::action_timeout_ms());
|
| + } while (is_update_scheduled() || is_initial_request() ||
|
| + !is_database_ready());
|
| +
|
| +
|
| + if (last_update() < now) {
|
| + // This means no data available anymore.
|
| + break;
|
| + }
|
| +
|
| + // Fetches URLs to verify and waits till server responses with data.
|
| + EXPECT_EQ(URLRequestStatus::SUCCESS,
|
| + safe_browsing_helper->FetchUrlsToVerify(server_host,
|
| + server_port,
|
| + step));
|
| +
|
| + std::vector<PhishingUrl> phishing_urls;
|
| + EXPECT_TRUE(ParsePhishingUrls(safe_browsing_helper->response_data(),
|
| + &phishing_urls));
|
| + EXPECT_GT(phishing_urls.size(), 0U);
|
| + for (size_t j = 0; j < phishing_urls.size(); ++j) {
|
| + // Verifes with server if a URL is a phishing URL and waits till server
|
| + // responses.
|
| + safe_browsing_helper->CheckUrl(GURL(phishing_urls[j].url));
|
| + if (phishing_urls[j].is_phishing) {
|
| + EXPECT_TRUE(is_checked_url_in_db())
|
| + << phishing_urls[j].url
|
| + << " is_phishing: " << phishing_urls[j].is_phishing
|
| + << " test step: " << step;
|
| + EXPECT_FALSE(is_checked_url_safe())
|
| + << phishing_urls[j].url
|
| + << " is_phishing: " << phishing_urls[j].is_phishing
|
| + << " test step: " << step;
|
| + } else {
|
| + EXPECT_TRUE(is_checked_url_safe())
|
| + << phishing_urls[j].url
|
| + << " is_phishing: " << phishing_urls[j].is_phishing
|
| + << " test step: " << step;
|
| + }
|
| + }
|
| + // TODO(lzheng): We should verify the fetched database with local
|
| + // database to make sure they match.
|
| + EXPECT_EQ(URLRequestStatus::SUCCESS,
|
| + safe_browsing_helper->FetchDBToVerify(server_host,
|
| + server_port,
|
| + step));
|
| + EXPECT_GT(safe_browsing_helper->response_data().size(), 0U);
|
| + last_step = step;
|
| + }
|
| +
|
| + // TODO(lzheng): Enable this check after safebrowsing server updated with
|
| + // the latest data in the next revision.
|
| +
|
| + // Verifies with server if test is done and waits till server responses.
|
| + // EXPECT_EQ(URLRequestStatus::SUCCESS,
|
| + // safe_browsing_helper->VerifyTestComplete(server_host,
|
| + // server_port,
|
| + // last_step));
|
| + // EXPECT_EQ("yes", safe_browsing_helper->response_data());
|
| + test_server.Stop();
|
| }
|
| +
|
|
|