172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// Use of this source code is governed by a BSD-style license that can be 3bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// found in the LICENSE file. 4731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// 5731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// This test uses the safebrowsing test server published at 6731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// http://code.google.com/p/google-safe-browsing/ to test the safebrowsing 7731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// protocol implemetation. Details of the safebrowsing testing flow is 8731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// documented at 9731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// http://code.google.com/p/google-safe-browsing/wiki/ProtocolTesting 10731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// 11731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// This test launches safebrowsing test server and issues several update 12731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// requests against that server. Each update would get different data and after 13731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// each update, the test will get a list of URLs from the test server to verify 14731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// its repository. The test will succeed only if all updates are performed and 15731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// URLs match what the server expected. 16731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 17731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include <vector> 18bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 19bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "base/command_line.h" 20731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "base/environment.h" 21731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "base/path_service.h" 22731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "base/process_util.h" 23731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "base/string_number_conversions.h" 24731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "base/string_util.h" 25731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "base/string_split.h" 263f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "base/synchronization/lock.h" 273f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "base/threading/platform_thread.h" 28731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "base/time.h" 29731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "base/utf_string_conversions.h" 30bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "chrome/browser/browser_process.h" 3121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/profiles/profile.h" 32bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "chrome/browser/safe_browsing/protocol_manager.h" 33bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "chrome/browser/safe_browsing/safe_browsing_service.h" 34bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "chrome/common/chrome_switches.h" 35731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "chrome/common/url_constants.h" 36bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "chrome/test/in_process_browser_test.h" 37dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/browser_thread.h" 38dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/renderer_host/resource_dispatcher_host.h" 39731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "base/test/test_timeouts.h" 40bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "chrome/test/ui_test_utils.h" 41731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "net/base/host_resolver.h" 42731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "net/base/load_flags.h" 43731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "net/base/net_log.h" 44731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "net/test/python_utils.h" 45bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "testing/gtest/include/gtest/gtest.h" 46bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 47731df977c0511bca2206b5f333555b1205ff1f43Iain Merricknamespace { 48731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 49731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickconst FilePath::CharType kDataFile[] = FILE_PATH_LITERAL("testing_input.dat"); 50731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickconst char kUrlVerifyPath[] = "/safebrowsing/verify_urls"; 51731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickconst char kDBVerifyPath[] = "/safebrowsing/verify_database"; 52731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickconst char kDBResetPath[] = "/reset"; 53731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickconst char kTestCompletePath[] = "/test_complete"; 54731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 55731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickstruct PhishingUrl { 56731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick std::string url; 57731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick std::string list_name; 58731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick bool is_phishing; 59731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}; 60731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 61731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// Parses server response for verify_urls. The expected format is: 62731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// 63731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// first.random.url.com/ internal-test-shavar yes 64731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// second.random.url.com/ internal-test-shavar yes 65731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// ... 66731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickbool ParsePhishingUrls(const std::string& data, 67731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick std::vector<PhishingUrl>* phishing_urls) { 68731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (data.empty()) 69731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return false; 70731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 71731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick std::vector<std::string> urls; 72731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick base::SplitString(data, '\n', &urls); 73731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick for (size_t i = 0; i < urls.size(); ++i) { 74731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (urls[i].empty()) 75731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick continue; 76731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick PhishingUrl phishing_url; 77731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick std::vector<std::string> record_parts; 78731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick base::SplitString(urls[i], '\t', &record_parts); 79731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (record_parts.size() != 3) { 80731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick LOG(ERROR) << "Unexpected URL format in phishing URL list: " 81731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick << urls[i]; 82731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return false; 83731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 84731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick phishing_url.url = std::string(chrome::kHttpScheme) + 85731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick "://" + record_parts[0]; 86731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick phishing_url.list_name = record_parts[1]; 87731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (record_parts[2] == "yes") { 88731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick phishing_url.is_phishing = true; 89731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } else if (record_parts[2] == "no") { 90731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick phishing_url.is_phishing = false; 91731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } else { 92731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick LOG(ERROR) << "Unrecognized expectation in " << urls[i] 93731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick << ": " << record_parts[2]; 94731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return false; 95731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 96731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick phishing_urls->push_back(phishing_url); 97731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 98731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return true; 99731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 100731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 101731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} // namespace 102731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 103731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickclass SafeBrowsingTestServer { 104731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick public: 105731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick explicit SafeBrowsingTestServer(const FilePath& datafile) 106731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick : datafile_(datafile), 107731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick server_handle_(base::kNullProcessHandle) { 108731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 109731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 110731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ~SafeBrowsingTestServer() { 111731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick EXPECT_EQ(base::kNullProcessHandle, server_handle_); 112731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 113731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 114731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Start the python server test suite. 115731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick bool Start() { 116731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Get path to python server script 117731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick FilePath testserver_path; 118731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!PathService::Get(base::DIR_SOURCE_ROOT, &testserver_path)) { 119731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick LOG(ERROR) << "Failed to get DIR_SOURCE_ROOT"; 120731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return false; 121731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 122731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick testserver_path = testserver_path 123731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick .Append(FILE_PATH_LITERAL("third_party")) 124731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick .Append(FILE_PATH_LITERAL("safe_browsing")) 125731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick .Append(FILE_PATH_LITERAL("testing")); 126731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick AppendToPythonPath(testserver_path); 127731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick FilePath testserver = testserver_path.Append( 128731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick FILE_PATH_LITERAL("safebrowsing_test_server.py")); 129731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 130731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick FilePath pyproto_code_dir; 1314a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch if (!GetPyProtoPath(&pyproto_code_dir)) { 1324a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch LOG(ERROR) << "Failed to get generated python protobuf dir"; 133731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return false; 134731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 135731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick AppendToPythonPath(pyproto_code_dir); 136731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick pyproto_code_dir = pyproto_code_dir.Append(FILE_PATH_LITERAL("google")); 137731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick AppendToPythonPath(pyproto_code_dir); 138731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 139731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick FilePath python_runtime; 140731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick EXPECT_TRUE(GetPythonRunTime(&python_runtime)); 141731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick CommandLine cmd_line(python_runtime); 142731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick FilePath datafile = testserver_path.Append(datafile_); 143731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick cmd_line.AppendArgPath(testserver); 144731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick cmd_line.AppendSwitchASCII("port", StringPrintf("%d", kPort_)); 145731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick cmd_line.AppendSwitchPath("datafile", datafile); 146731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 147731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!base::LaunchApp(cmd_line, false, true, &server_handle_)) { 148731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick LOG(ERROR) << "Failed to launch server: " 149731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick << cmd_line.command_line_string(); 150731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return false; 151731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 152731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return true; 153731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 154731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 155731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Stop the python server test suite. 156731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick bool Stop() { 157513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (server_handle_ == base::kNullProcessHandle) 158731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return true; 159731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 160731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // First check if the process has already terminated. 161513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (!base::WaitForSingleProcess(server_handle_, 0) && 162513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch !base::KillProcess(server_handle_, 1, true)) { 163513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch VLOG(1) << "Kill failed?"; 164731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return false; 165731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 166513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 167513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch base::CloseProcessHandle(server_handle_); 168513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch server_handle_ = base::kNullProcessHandle; 169513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch VLOG(1) << "Stopped."; 170731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return true; 171731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 172731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 173731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick static const char* Host() { 174731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return kHost_; 175731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 176731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 177731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick static int Port() { 178731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return kPort_; 179731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 180731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 181731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick private: 182731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick static const char kHost_[]; 183731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick static const int kPort_; 184731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick FilePath datafile_; 185731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick base::ProcessHandle server_handle_; 186731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DISALLOW_COPY_AND_ASSIGN(SafeBrowsingTestServer); 187731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}; 188731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 189731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickconst char SafeBrowsingTestServer::kHost_[] = "localhost"; 190731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickconst int SafeBrowsingTestServer::kPort_ = 40102; 191731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 192bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// This starts the browser and keeps status of states related to SafeBrowsing. 193bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenclass SafeBrowsingServiceTest : public InProcessBrowserTest { 194bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen public: 195bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen SafeBrowsingServiceTest() 196bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen : safe_browsing_service_(NULL), 197bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen is_database_ready_(true), 198bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen is_initial_request_(false), 199bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen is_update_scheduled_(false), 200731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick is_checked_url_in_db_(false), 201731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick is_checked_url_safe_(false) { 202731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 203731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 204731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick virtual ~SafeBrowsingServiceTest() { 205bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } 206bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 207bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen void UpdateSafeBrowsingStatus() { 208731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ASSERT_TRUE(safe_browsing_service_); 2093f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen base::AutoLock lock(update_status_mutex_); 210bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen is_initial_request_ = 211bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen safe_browsing_service_->protocol_manager_->is_initial_request(); 212bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen last_update_ = safe_browsing_service_->protocol_manager_->last_update(); 213bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen is_update_scheduled_ = 214bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen safe_browsing_service_->protocol_manager_->update_timer_.IsRunning(); 215bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } 216bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 217731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick void ForceUpdate() { 218731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ASSERT_TRUE(safe_browsing_service_); 219731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick safe_browsing_service_->protocol_manager_->ForceScheduleNextUpdate(0); 220731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 221731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 222bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen void CheckIsDatabaseReady() { 2233f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen base::AutoLock lock(update_status_mutex_); 224bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen is_database_ready_ = 225bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen !safe_browsing_service_->database_update_in_progress_; 226bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } 227bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 228bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen void CheckUrl(SafeBrowsingService::Client* helper, const GURL& url) { 229731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ASSERT_TRUE(safe_browsing_service_); 2303f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen base::AutoLock lock(update_status_mutex_); 23121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (safe_browsing_service_->CheckBrowseUrl(url, helper)) { 232731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick is_checked_url_in_db_ = false; 233731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick is_checked_url_safe_ = true; 234731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } else { 235731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // In this case, Safebrowsing service will fetch the full hash 236731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // from the server and examine that. Once it is done, 237731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // set_is_checked_url_safe() will be called via callback. 238731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick is_checked_url_in_db_ = true; 239bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } 240bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } 241bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 242731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick bool is_checked_url_in_db() { 2433f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen base::AutoLock l(update_status_mutex_); 244731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return is_checked_url_in_db_; 245731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 246731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 247731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick void set_is_checked_url_safe(bool safe) { 2483f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen base::AutoLock l(update_status_mutex_); 249731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick is_checked_url_safe_ = safe; 250731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 251731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 252731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick bool is_checked_url_safe() { 2533f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen base::AutoLock l(update_status_mutex_); 254731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return is_checked_url_safe_; 255bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } 256bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 257bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen bool is_database_ready() { 2583f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen base::AutoLock l(update_status_mutex_); 259bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen return is_database_ready_; 260bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } 261bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 262bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen bool is_initial_request() { 2633f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen base::AutoLock l(update_status_mutex_); 264bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen return is_initial_request_; 265bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } 266bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 267bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen base::Time last_update() { 2683f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen base::AutoLock l(update_status_mutex_); 269bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen return last_update_; 270bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } 271bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 272bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen bool is_update_scheduled() { 2733f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen base::AutoLock l(update_status_mutex_); 274bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen return is_update_scheduled_; 275bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } 276bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 277bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen MessageLoop* SafeBrowsingMessageLoop() { 278bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen return safe_browsing_service_->safe_browsing_thread_->message_loop(); 279bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } 280bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 281bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen protected: 282731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick bool InitSafeBrowsingService() { 283bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen safe_browsing_service_ = 284bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen g_browser_process->resource_dispatcher_host()->safe_browsing_service(); 285731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return safe_browsing_service_ != NULL; 286bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } 287bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 288bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen virtual void SetUpCommandLine(CommandLine* command_line) { 289bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // Makes sure the auto update is not triggered. This test will force the 290bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // update when needed. 291bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen command_line->AppendSwitch(switches::kSbDisableAutoUpdate); 292ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 2934a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch // This test uses loopback. No need to use IPv6 especially it makes 2944a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch // local requests slow on Windows trybot when ipv6 local address [::1] 2954a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch // is not setup. 2964a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch command_line->AppendSwitch(switches::kDisableIPv6); 297731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 298ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // TODO(lzheng): The test server does not understand download related 299ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // requests. We need to fix the server. 300ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen command_line->AppendSwitch(switches::kSbDisableDownloadProtection); 301ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 302731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // In this test, we fetch SafeBrowsing data and Mac key from the same 303731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // server. Although in real production, they are served from different 304731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // servers. 305731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick std::string url_prefix = 306731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick StringPrintf("http://%s:%d/safebrowsing", 307731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick SafeBrowsingTestServer::Host(), 308731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick SafeBrowsingTestServer::Port()); 309731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick command_line->AppendSwitchASCII(switches::kSbInfoURLPrefix, url_prefix); 310731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick command_line->AppendSwitchASCII(switches::kSbMacKeyURLPrefix, url_prefix); 311731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 312731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 313731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick void SetTestStep(int step) { 314731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick std::string test_step = StringPrintf("test_step=%d", step); 315731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick safe_browsing_service_->protocol_manager_->set_additional_query(test_step); 316bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } 317bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 318bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen private: 319bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen SafeBrowsingService* safe_browsing_service_; 320bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 321bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // Protects all variables below since they are read on UI thread 322bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // but updated on IO thread or safebrowsing thread. 3233f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen base::Lock update_status_mutex_; 324bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 325bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // States associated with safebrowsing service updates. 326bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen bool is_database_ready_; 327bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen bool is_initial_request_; 328bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen base::Time last_update_; 329bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen bool is_update_scheduled_; 330bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // Indicates if there is a match between a URL's prefix and safebrowsing 331731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // database (thus potentially it is a phishing URL). 332731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick bool is_checked_url_in_db_; 333731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // True if last verified URL is not a phishing URL and thus it is safe. 334731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick bool is_checked_url_safe_; 335731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 336bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen DISALLOW_COPY_AND_ASSIGN(SafeBrowsingServiceTest); 337bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}; 338bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 339bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// A ref counted helper class that handles callbacks between IO thread and UI 340bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// thread. 341bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenclass SafeBrowsingServiceTestHelper 342bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen : public base::RefCountedThreadSafe<SafeBrowsingServiceTestHelper>, 343731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick public SafeBrowsingService::Client, 344731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick public URLFetcher::Delegate { 345bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen public: 346bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen explicit SafeBrowsingServiceTestHelper( 347bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen SafeBrowsingServiceTest* safe_browsing_test) 348731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick : safe_browsing_test_(safe_browsing_test), 34972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen response_status_(net::URLRequestStatus::FAILED) { 350bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } 351bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 352731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Callbacks for SafeBrowsingService::Client. 35321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen virtual void OnBrowseUrlCheckResult( 35421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen const GURL& url, SafeBrowsingService::UrlCheckResult result) { 355731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO)); 356731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick EXPECT_TRUE(safe_browsing_test_->is_checked_url_in_db()); 357731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick safe_browsing_test_->set_is_checked_url_safe( 358dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen result == SafeBrowsingService::SAFE); 359731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 360731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick NewRunnableMethod(this, 361731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick &SafeBrowsingServiceTestHelper::OnCheckUrlDone)); 362bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } 36321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen virtual void OnDownloadUrlCheckResult( 364ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const std::vector<GURL>& url_chain, 365ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SafeBrowsingService::UrlCheckResult result) { 36621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // TODO(lzheng): Add test for DownloadUrl. 36721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 36821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 369bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen virtual void OnBlockingPageComplete(bool proceed) { 370bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen NOTREACHED() << "Not implemented."; 371bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } 372bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 373731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Functions and callbacks to start the safebrowsing database update. 374731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick void ForceUpdate() { 375731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, 376731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick NewRunnableMethod(this, 377731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick &SafeBrowsingServiceTestHelper::ForceUpdateInIOThread)); 378731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Will continue after OnForceUpdateDone(). 379731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ui_test_utils::RunMessageLoop(); 380731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 381731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick void ForceUpdateInIOThread() { 382731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO)); 383731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick safe_browsing_test_->ForceUpdate(); 384731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 385731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick NewRunnableMethod(this, 386731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick &SafeBrowsingServiceTestHelper::OnForceUpdateDone)); 387731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 388731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick void OnForceUpdateDone() { 389731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick StopUILoop(); 390731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 391731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 392731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Functions and callbacks related to CheckUrl. These are used to verify 393731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // phishing URLs. 394bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen void CheckUrl(const GURL& url) { 395731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, NewRunnableMethod( 396731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick this, &SafeBrowsingServiceTestHelper::CheckUrlOnIOThread, url)); 397731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ui_test_utils::RunMessageLoop(); 398bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } 399bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen void CheckUrlOnIOThread(const GURL& url) { 400731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO)); 401bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen safe_browsing_test_->CheckUrl(this, url); 402731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!safe_browsing_test_->is_checked_url_in_db()) { 403731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Ends the checking since this URL's prefix is not in database. 404731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, NewRunnableMethod( 405731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick this, &SafeBrowsingServiceTestHelper::OnCheckUrlDone)); 406731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 407731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Otherwise, OnCheckUrlDone is called in OnUrlCheckResult since 408731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // safebrowsing service further fetches hashes from safebrowsing server. 409bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } 410731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 411731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick void OnCheckUrlDone() { 412bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen StopUILoop(); 413bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } 414bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 415bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // Updates status from IO Thread. 416bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen void CheckStatusOnIOThread() { 417731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO)); 418bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen safe_browsing_test_->UpdateSafeBrowsingStatus(); 419bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen safe_browsing_test_->SafeBrowsingMessageLoop()->PostTask( 420bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen FROM_HERE, NewRunnableMethod(this, 421bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen &SafeBrowsingServiceTestHelper::CheckIsDatabaseReady)); 422bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } 423bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 424bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // Checks status in SafeBrowsing Thread. 425bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen void CheckIsDatabaseReady() { 426731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick EXPECT_EQ(MessageLoop::current(), 427bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen safe_browsing_test_->SafeBrowsingMessageLoop()); 428bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen safe_browsing_test_->CheckIsDatabaseReady(); 429731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, NewRunnableMethod( 430731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick this, &SafeBrowsingServiceTestHelper::OnWaitForStatusUpdateDone)); 431bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } 432bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 433731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick void OnWaitForStatusUpdateDone() { 434bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen StopUILoop(); 435bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } 436bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 437731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Wait for a given period to get safebrowsing status updated. 438731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick void WaitForStatusUpdate(int64 wait_time_msec) { 439731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick BrowserThread::PostDelayedTask( 440731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick BrowserThread::IO, 441bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen FROM_HERE, 442bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen NewRunnableMethod(this, 443bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen &SafeBrowsingServiceTestHelper::CheckStatusOnIOThread), 444731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick wait_time_msec); 445731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Will continue after OnWaitForStatusUpdateDone(). 446731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ui_test_utils::RunMessageLoop(); 447731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 448731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 449731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick void WaitTillServerReady(const char* host, int port) { 45072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen response_status_ = net::URLRequestStatus::FAILED; 451731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick GURL url(StringPrintf("http://%s:%d%s?test_step=0", 452731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick host, port, kDBResetPath)); 453731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // TODO(lzheng): We should have a way to reliably tell when a server is 454731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // ready so we could get rid of the Sleep and retry loop. 455731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick while (true) { 45672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (FetchUrl(url) == net::URLRequestStatus::SUCCESS) 457731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick break; 458731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Wait and try again if last fetch was failed. The loop will hit the 459731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // timeout in OutOfProcTestRunner if the fetch can not get success 460731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // response. 4613f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen base::PlatformThread::Sleep(TestTimeouts::action_timeout_ms()); 462731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 463731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 464731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 465731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Calls test server to fetch database for verification. 46672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen net::URLRequestStatus::Status FetchDBToVerify(const char* host, int port, 46772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen int test_step) { 468731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // TODO(lzheng): Remove chunk_type=add once it is not needed by the server. 469731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick GURL url(StringPrintf("http://%s:%d%s?" 470731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick "client=chromium&appver=1.0&pver=2.2&test_step=%d&" 471731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick "chunk_type=add", 472731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick host, port, kDBVerifyPath, test_step)); 473731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return FetchUrl(url); 474731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 475731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 476731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Calls test server to fetch URLs for verification. 47772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen net::URLRequestStatus::Status FetchUrlsToVerify(const char* host, int port, 47872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen int test_step) { 479731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick GURL url(StringPrintf("http://%s:%d%s?" 480731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick "client=chromium&appver=1.0&pver=2.2&test_step=%d", 481731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick host, port, kUrlVerifyPath, test_step)); 482731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return FetchUrl(url); 483731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 484731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 485731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Calls test server to check if test data is done. E.g.: if there is a 486731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // bad URL that server expects test to fetch full hash but the test didn't, 487731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // this verification will fail. 48872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen net::URLRequestStatus::Status VerifyTestComplete(const char* host, int port, 48972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen int test_step) { 490731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick GURL url(StringPrintf("http://%s:%d%s?test_step=%d", 491731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick host, port, kTestCompletePath, test_step)); 492731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return FetchUrl(url); 493731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 494731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 495731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Callback for URLFetcher. 496731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick virtual void OnURLFetchComplete(const URLFetcher* source, 497731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const GURL& url, 49872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const net::URLRequestStatus& status, 499731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick int response_code, 500731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const ResponseCookies& cookies, 501731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const std::string& data) { 502731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick response_data_ = data; 503731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick response_status_ = status.status(); 504731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick StopUILoop(); 505731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 506731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 507731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const std::string& response_data() { 508731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return response_data_; 509bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } 510bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 511bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen private: 512bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // Stops UI loop after desired status is updated. 513bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen void StopUILoop() { 514731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::UI)); 515bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen MessageLoopForUI::current()->Quit(); 516bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } 517bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 518731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Fetch a URL. If message_loop_started is true, starts the message loop 519731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // so the caller could wait till OnURLFetchComplete is called. 52072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen net::URLRequestStatus::Status FetchUrl(const GURL& url) { 521731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick url_fetcher_.reset(new URLFetcher(url, URLFetcher::GET, this)); 522731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick url_fetcher_->set_load_flags(net::LOAD_DISABLE_CACHE); 523731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick url_fetcher_->set_request_context(Profile::GetDefaultRequestContext()); 524731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick url_fetcher_->Start(); 525731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ui_test_utils::RunMessageLoop(); 526731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return response_status_; 527731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 528731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 529bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen base::OneShotTimer<SafeBrowsingServiceTestHelper> check_update_timer_; 530bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen SafeBrowsingServiceTest* safe_browsing_test_; 531731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick scoped_ptr<URLFetcher> url_fetcher_; 532731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick std::string response_data_; 53372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen net::URLRequestStatus::Status response_status_; 534bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen DISALLOW_COPY_AND_ASSIGN(SafeBrowsingServiceTestHelper); 535bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}; 536bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 537bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian MonsenIN_PROC_BROWSER_TEST_F(SafeBrowsingServiceTest, SafeBrowsingSystemTest) { 538731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick LOG(INFO) << "Start test"; 539731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const char* server_host = SafeBrowsingTestServer::Host(); 540731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick int server_port = SafeBrowsingTestServer::Port(); 541731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ASSERT_TRUE(InitSafeBrowsingService()); 542731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 543513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_refptr<SafeBrowsingServiceTestHelper> safe_browsing_helper( 544513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch new SafeBrowsingServiceTestHelper(this)); 545731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick int last_step = 0; 546731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick FilePath datafile_path = FilePath(kDataFile); 547731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick SafeBrowsingTestServer test_server(datafile_path); 548731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ASSERT_TRUE(test_server.Start()); 549731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 550731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Make sure the server is running. 551731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick safe_browsing_helper->WaitTillServerReady(server_host, server_port); 552bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 553731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Waits and makes sure safebrowsing update is not happening. 554731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // The wait will stop once OnWaitForStatusUpdateDone in 555731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // safe_browsing_helper is called and status from safe_browsing_service_ 556731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // is checked. 557731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick safe_browsing_helper->WaitForStatusUpdate(0); 558bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen EXPECT_TRUE(is_database_ready()); 559bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen EXPECT_TRUE(is_initial_request()); 560bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen EXPECT_FALSE(is_update_scheduled()); 561bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen EXPECT_TRUE(last_update().is_null()); 562731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Starts updates. After each update, the test will fetch a list of URLs with 563731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // expected results to verify with safebrowsing service. If there is no error, 564731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // the test moves on to the next step to get more update chunks. 565731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // This repeats till there is no update data. 566731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick for (int step = 1;; step++) { 567731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Every step should be a fresh start. 568731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick SCOPED_TRACE(StringPrintf("step=%d", step)); 569731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick EXPECT_TRUE(is_database_ready()); 570731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick EXPECT_FALSE(is_update_scheduled()); 571731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 572731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Starts safebrowsing update on IO thread. Waits till scheduled 573731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // update finishes. Stops waiting after kMaxWaitSecPerStep if the update 574731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // could not finish. 575731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick base::Time now = base::Time::Now(); 576731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick SetTestStep(step); 577731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick safe_browsing_helper->ForceUpdate(); 578731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 579731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick do { 580731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Periodically pull the status. 581731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick safe_browsing_helper->WaitForStatusUpdate( 582731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick TestTimeouts::action_timeout_ms()); 583731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } while (is_update_scheduled() || is_initial_request() || 584731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick !is_database_ready()); 585731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 586731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 587731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (last_update() < now) { 588731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // This means no data available anymore. 589731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick break; 590731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 591731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 592731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Fetches URLs to verify and waits till server responses with data. 59372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen EXPECT_EQ(net::URLRequestStatus::SUCCESS, 594731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick safe_browsing_helper->FetchUrlsToVerify(server_host, 595731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick server_port, 596731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick step)); 597731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 598731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick std::vector<PhishingUrl> phishing_urls; 599731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick EXPECT_TRUE(ParsePhishingUrls(safe_browsing_helper->response_data(), 600731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick &phishing_urls)); 601731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick EXPECT_GT(phishing_urls.size(), 0U); 602731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick for (size_t j = 0; j < phishing_urls.size(); ++j) { 603731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Verifes with server if a URL is a phishing URL and waits till server 604731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // responses. 605731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick safe_browsing_helper->CheckUrl(GURL(phishing_urls[j].url)); 606731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (phishing_urls[j].is_phishing) { 607731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick EXPECT_TRUE(is_checked_url_in_db()) 608731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick << phishing_urls[j].url 609731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick << " is_phishing: " << phishing_urls[j].is_phishing 610731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick << " test step: " << step; 611731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick EXPECT_FALSE(is_checked_url_safe()) 612731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick << phishing_urls[j].url 613731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick << " is_phishing: " << phishing_urls[j].is_phishing 614731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick << " test step: " << step; 615731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } else { 616731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick EXPECT_TRUE(is_checked_url_safe()) 617731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick << phishing_urls[j].url 618731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick << " is_phishing: " << phishing_urls[j].is_phishing 619731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick << " test step: " << step; 620731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 621731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 622731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // TODO(lzheng): We should verify the fetched database with local 623731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // database to make sure they match. 62472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen EXPECT_EQ(net::URLRequestStatus::SUCCESS, 625731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick safe_browsing_helper->FetchDBToVerify(server_host, 626731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick server_port, 627731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick step)); 628731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick EXPECT_GT(safe_browsing_helper->response_data().size(), 0U); 629731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick last_step = step; 630731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 631731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 632731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Verifies with server if test is done and waits till server responses. 63372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen EXPECT_EQ(net::URLRequestStatus::SUCCESS, 6344a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch safe_browsing_helper->VerifyTestComplete(server_host, 6354a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch server_port, 6364a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch last_step)); 6374a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch EXPECT_EQ("yes", safe_browsing_helper->response_data()); 638731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick test_server.Stop(); 639bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} 640