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