Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(226)

Side by Side Diff: chrome/browser/safe_browsing/safe_browsing_test.cc

Issue 3277008: add safebrowsing testserver (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: resync before submitting Created 10 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « DEPS ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 //
5 // This test uses the safebrowsing test server published at
6 // http://code.google.com/p/google-safe-browsing/ to test the safebrowsing
7 // protocol implemetation. Details of the safebrowsing testing flow is
8 // documented at
9 // http://code.google.com/p/google-safe-browsing/wiki/ProtocolTesting
10 //
11 // This test launches safebrowsing test server and issues several update
12 // requests against that server. Each update would get different data and after
13 // each update, the test will get a list of URLs from the test server to verify
14 // its repository. The test will succeed only if all updates are performed and
15 // URLs match what the server expected.
16
17 #include <vector>
4 18
5 #include "base/command_line.h" 19 #include "base/command_line.h"
20 #include "base/condition_variable.h"
21 #include "base/environment.h"
6 #include "base/lock.h" 22 #include "base/lock.h"
23 #include "base/path_service.h"
24 #include "base/process_util.h"
25 #include "base/string_number_conversions.h"
26 #include "base/string_util.h"
27 #include "base/string_split.h"
28 #include "base/time.h"
29 #include "base/utf_string_conversions.h"
7 #include "chrome/browser/browser_process.h" 30 #include "chrome/browser/browser_process.h"
8 #include "chrome/browser/browser_thread.h" 31 #include "chrome/browser/browser_thread.h"
32 #include "chrome/browser/profile.h"
9 #include "chrome/browser/renderer_host/resource_dispatcher_host.h" 33 #include "chrome/browser/renderer_host/resource_dispatcher_host.h"
10 #include "chrome/browser/safe_browsing/protocol_manager.h" 34 #include "chrome/browser/safe_browsing/protocol_manager.h"
11 #include "chrome/browser/safe_browsing/safe_browsing_service.h" 35 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
12 #include "chrome/common/chrome_switches.h" 36 #include "chrome/common/chrome_switches.h"
37 #include "chrome/common/url_constants.h"
13 #include "chrome/test/in_process_browser_test.h" 38 #include "chrome/test/in_process_browser_test.h"
39 #include "base/test/test_timeouts.h"
14 #include "chrome/test/ui_test_utils.h" 40 #include "chrome/test/ui_test_utils.h"
41 #include "net/base/host_resolver.h"
42 #include "net/base/load_flags.h"
43 #include "net/base/net_log.h"
44 #include "net/test/python_utils.h"
15 #include "testing/gtest/include/gtest/gtest.h" 45 #include "testing/gtest/include/gtest/gtest.h"
16 46
47 namespace {
48
49 const FilePath::CharType kDataFile[] = FILE_PATH_LITERAL("testing_input.dat");
50 const char kUrlVerifyPath[] = "/safebrowsing/verify_urls";
51 const char kDBVerifyPath[] = "/safebrowsing/verify_database";
52 const char kDBResetPath[] = "/reset";
53 const char kTestCompletePath[] = "/test_complete";
54
55 struct PhishingUrl {
56 std::string url;
57 std::string list_name;
58 bool is_phishing;
59 };
60
61 // Parses server response for verify_urls. The expected format is:
62 //
63 // first.random.url.com/ internal-test-shavar yes
64 // second.random.url.com/ internal-test-shavar yes
65 // ...
66 bool ParsePhishingUrls(const std::string& data,
67 std::vector<PhishingUrl>* phishing_urls) {
68 if (data.empty())
69 return false;
70
71 std::vector<std::string> urls;
72 base::SplitString(data, '\n', &urls);
73 for (size_t i = 0; i < urls.size(); ++i) {
74 if (urls[i].empty())
75 continue;
76 PhishingUrl phishing_url;
77 std::vector<std::string> record_parts;
78 base::SplitString(urls[i], '\t', &record_parts);
79 if (record_parts.size() != 3) {
80 LOG(ERROR) << "Unexpected URL format in phishing URL list: "
81 << urls[i];
82 return false;
83 }
84 phishing_url.url = std::string(chrome::kHttpScheme) +
85 "://" + record_parts[0];
86 phishing_url.list_name = record_parts[1];
87 if (record_parts[2] == "yes") {
88 phishing_url.is_phishing = true;
89 } else if (record_parts[2] == "no") {
90 phishing_url.is_phishing = false;
91 } else {
92 LOG(ERROR) << "Unrecognized expectation in " << urls[i]
93 << ": " << record_parts[2];
94 return false;
95 }
96 phishing_urls->push_back(phishing_url);
97 }
98 return true;
99 }
100
101 } // namespace
102
103 class SafeBrowsingTestServer {
104 public:
105 explicit SafeBrowsingTestServer(const FilePath& datafile)
106 : datafile_(datafile),
107 server_handle_(base::kNullProcessHandle) {
108 }
109
110 ~SafeBrowsingTestServer() {
111 EXPECT_EQ(base::kNullProcessHandle, server_handle_);
112 }
113
114 // Start the python server test suite.
115 bool Start() {
116 // Get path to python server script
117 FilePath testserver_path;
118 if (!PathService::Get(base::DIR_SOURCE_ROOT, &testserver_path)) {
119 LOG(ERROR) << "Failed to get DIR_SOURCE_ROOT";
120 return false;
121 }
122 testserver_path = testserver_path
123 .Append(FILE_PATH_LITERAL("third_party"))
124 .Append(FILE_PATH_LITERAL("safe_browsing"))
125 .Append(FILE_PATH_LITERAL("testing"));
126 AppendToPythonPath(testserver_path);
127 FilePath testserver = testserver_path.Append(
128 FILE_PATH_LITERAL("safebrowsing_test_server.py"));
129
130 FilePath pyproto_code_dir;
131 if (!PathService::Get(base::DIR_EXE, &pyproto_code_dir)) {
132 LOG(ERROR) << "Failed to get DIR_EXE";
133 return false;
134 }
135 pyproto_code_dir = pyproto_code_dir.Append(FILE_PATH_LITERAL("pyproto"));
136 AppendToPythonPath(pyproto_code_dir);
137 pyproto_code_dir = pyproto_code_dir.Append(FILE_PATH_LITERAL("google"));
138 AppendToPythonPath(pyproto_code_dir);
139
140 FilePath python_runtime;
141 EXPECT_TRUE(GetPythonRunTime(&python_runtime));
142 CommandLine cmd_line(python_runtime);
143 FilePath datafile = testserver_path.Append(datafile_);
144 cmd_line.AppendArgPath(testserver);
145 cmd_line.AppendSwitchASCII("port", StringPrintf("%d", kPort_));
146 cmd_line.AppendSwitchPath("datafile", datafile);
147
148 if (!base::LaunchApp(cmd_line, false, true, &server_handle_)) {
149 LOG(ERROR) << "Failed to launch server: "
150 << cmd_line.command_line_string();
151 return false;
152 }
153 return true;
154 }
155
156 // Stop the python server test suite.
157 bool Stop() {
158 if (server_handle_ == base::kNullProcessHandle) {
159 return true;
160 }
161
162 // First check if the process has already terminated.
163 bool ret = base::WaitForSingleProcess(server_handle_, 0);
164 if (!ret) {
165 ret = base::KillProcess(server_handle_, 1, true);
166 }
167
168 if (ret) {
169 base::CloseProcessHandle(server_handle_);
170 server_handle_ = base::kNullProcessHandle;
171 LOG(INFO) << "Stopped.";
172 } else {
173 LOG(INFO) << "Kill failed?";
174 return false;
175 }
176 return true;
177 }
178
179 static const char* Host() {
180 return kHost_;
181 }
182
183 static int Port() {
184 return kPort_;
185 }
186
187 private:
188 static const char kHost_[];
189 static const int kPort_;
190 FilePath datafile_;
191 base::ProcessHandle server_handle_;
192 DISALLOW_COPY_AND_ASSIGN(SafeBrowsingTestServer);
193 };
194
195 const char SafeBrowsingTestServer::kHost_[] = "localhost";
196 const int SafeBrowsingTestServer::kPort_ = 40102;
197
17 // This starts the browser and keeps status of states related to SafeBrowsing. 198 // This starts the browser and keeps status of states related to SafeBrowsing.
18 class SafeBrowsingServiceTest : public InProcessBrowserTest { 199 class SafeBrowsingServiceTest : public InProcessBrowserTest {
19 public: 200 public:
20 SafeBrowsingServiceTest() 201 SafeBrowsingServiceTest()
21 : safe_browsing_service_(NULL), 202 : safe_browsing_service_(NULL),
22 is_database_ready_(true), 203 is_database_ready_(true),
23 is_initial_request_(false), 204 is_initial_request_(false),
24 is_update_scheduled_(false), 205 is_update_scheduled_(false),
25 is_url_match_in_db_(false) { 206 is_checked_url_in_db_(false),
207 is_checked_url_safe_(false) {
208 }
209
210 virtual ~SafeBrowsingServiceTest() {
26 } 211 }
27 212
28 void UpdateSafeBrowsingStatus() { 213 void UpdateSafeBrowsingStatus() {
29 CHECK(safe_browsing_service_); 214 ASSERT_TRUE(safe_browsing_service_);
30 AutoLock lock(update_status_mutex_); 215 AutoLock lock(update_status_mutex_);
31 is_initial_request_ = 216 is_initial_request_ =
32 safe_browsing_service_->protocol_manager_->is_initial_request(); 217 safe_browsing_service_->protocol_manager_->is_initial_request();
33 last_update_ = safe_browsing_service_->protocol_manager_->last_update(); 218 last_update_ = safe_browsing_service_->protocol_manager_->last_update();
34 is_update_scheduled_ = 219 is_update_scheduled_ =
35 safe_browsing_service_->protocol_manager_->update_timer_.IsRunning(); 220 safe_browsing_service_->protocol_manager_->update_timer_.IsRunning();
36 } 221 }
37 222
223 void ForceUpdate() {
224 ASSERT_TRUE(safe_browsing_service_);
225 safe_browsing_service_->protocol_manager_->ForceScheduleNextUpdate(0);
226 }
227
38 void CheckIsDatabaseReady() { 228 void CheckIsDatabaseReady() {
39 AutoLock lock(update_status_mutex_); 229 AutoLock lock(update_status_mutex_);
40 is_database_ready_ = 230 is_database_ready_ =
41 !safe_browsing_service_->database_update_in_progress_; 231 !safe_browsing_service_->database_update_in_progress_;
42 } 232 }
43 233
44 void CheckUrl(SafeBrowsingService::Client* helper, const GURL& url) { 234 void CheckUrl(SafeBrowsingService::Client* helper, const GURL& url) {
45 CHECK(safe_browsing_service_); 235 ASSERT_TRUE(safe_browsing_service_);
46 AutoLock lock(update_status_mutex_); 236 AutoLock lock(update_status_mutex_);
47 if (!safe_browsing_service_->CheckUrl(url, helper)) { 237 if (safe_browsing_service_->CheckUrl(url, helper)) {
48 safe_browsing_service_->CancelCheck(helper); 238 is_checked_url_in_db_ = false;
49 is_url_match_in_db_ = false; 239 is_checked_url_safe_ = true;
240 } else {
241 // In this case, Safebrowsing service will fetch the full hash
242 // from the server and examine that. Once it is done,
243 // set_is_checked_url_safe() will be called via callback.
244 is_checked_url_in_db_ = true;
50 } 245 }
51 is_url_match_in_db_ = true;
52 } 246 }
53 247
54 bool is_url_match_in_db() { 248 bool is_checked_url_in_db() {
55 AutoLock l(update_status_mutex_); 249 AutoLock l(update_status_mutex_);
56 return is_url_match_in_db_; 250 return is_checked_url_in_db_;
251 }
252
253 void set_is_checked_url_safe(bool safe) {
254 AutoLock l(update_status_mutex_);
255 is_checked_url_safe_ = safe;
256 }
257
258 bool is_checked_url_safe() {
259 AutoLock l(update_status_mutex_);
260 return is_checked_url_safe_;
57 } 261 }
58 262
59 bool is_database_ready() { 263 bool is_database_ready() {
60 AutoLock l(update_status_mutex_); 264 AutoLock l(update_status_mutex_);
61 return is_database_ready_; 265 return is_database_ready_;
62 } 266 }
63 267
64 bool is_initial_request() { 268 bool is_initial_request() {
65 AutoLock l(update_status_mutex_); 269 AutoLock l(update_status_mutex_);
66 return is_initial_request_; 270 return is_initial_request_;
67 } 271 }
68 272
69 base::Time last_update() { 273 base::Time last_update() {
70 AutoLock l(update_status_mutex_); 274 AutoLock l(update_status_mutex_);
71 return last_update_; 275 return last_update_;
72 } 276 }
73 277
74 bool is_update_scheduled() { 278 bool is_update_scheduled() {
75 AutoLock l(update_status_mutex_); 279 AutoLock l(update_status_mutex_);
76 return is_update_scheduled_; 280 return is_update_scheduled_;
77 } 281 }
78 282
79 MessageLoop* SafeBrowsingMessageLoop() { 283 MessageLoop* SafeBrowsingMessageLoop() {
80 return safe_browsing_service_->safe_browsing_thread_->message_loop(); 284 return safe_browsing_service_->safe_browsing_thread_->message_loop();
81 } 285 }
82 286
83 protected: 287 protected:
84 void InitSafeBrowsingService() { 288 bool InitSafeBrowsingService() {
85 safe_browsing_service_ = 289 safe_browsing_service_ =
86 g_browser_process->resource_dispatcher_host()->safe_browsing_service(); 290 g_browser_process->resource_dispatcher_host()->safe_browsing_service();
291 return safe_browsing_service_ != NULL;
87 } 292 }
88 293
89 virtual void SetUpCommandLine(CommandLine* command_line) { 294 virtual void SetUpCommandLine(CommandLine* command_line) {
90 // Makes sure the auto update is not triggered. This test will force the 295 // Makes sure the auto update is not triggered. This test will force the
91 // update when needed. 296 // update when needed.
92 command_line->AppendSwitch(switches::kSbDisableAutoUpdate); 297 command_line->AppendSwitch(switches::kSbDisableAutoUpdate);
298
299 // In this test, we fetch SafeBrowsing data and Mac key from the same
300 // server. Although in real production, they are served from different
301 // servers.
302 std::string url_prefix =
303 StringPrintf("http://%s:%d/safebrowsing",
304 SafeBrowsingTestServer::Host(),
305 SafeBrowsingTestServer::Port());
306 command_line->AppendSwitchASCII(switches::kSbInfoURLPrefix, url_prefix);
307 command_line->AppendSwitchASCII(switches::kSbMacKeyURLPrefix, url_prefix);
308 }
309
310 void SetTestStep(int step) {
311 std::string test_step = StringPrintf("test_step=%d", step);
312 safe_browsing_service_->protocol_manager_->set_additional_query(test_step);
93 } 313 }
94 314
95 private: 315 private:
96 SafeBrowsingService* safe_browsing_service_; 316 SafeBrowsingService* safe_browsing_service_;
97 317
98 // Protects all variables below since they are read on UI thread 318 // Protects all variables below since they are read on UI thread
99 // but updated on IO thread or safebrowsing thread. 319 // but updated on IO thread or safebrowsing thread.
100 Lock update_status_mutex_; 320 Lock update_status_mutex_;
101 321
102 // States associated with safebrowsing service updates. 322 // States associated with safebrowsing service updates.
103 bool is_database_ready_; 323 bool is_database_ready_;
104 bool is_initial_request_; 324 bool is_initial_request_;
105 base::Time last_update_; 325 base::Time last_update_;
106 bool is_update_scheduled_; 326 bool is_update_scheduled_;
107 // Indicates if there is a match between a URL's prefix and safebrowsing 327 // Indicates if there is a match between a URL's prefix and safebrowsing
108 // database (thus potentially it is a phishing url). 328 // database (thus potentially it is a phishing URL).
109 bool is_url_match_in_db_; 329 bool is_checked_url_in_db_;
330 // True if last verified URL is not a phishing URL and thus it is safe.
331 bool is_checked_url_safe_;
332
110 DISALLOW_COPY_AND_ASSIGN(SafeBrowsingServiceTest); 333 DISALLOW_COPY_AND_ASSIGN(SafeBrowsingServiceTest);
111 }; 334 };
112 335
113 // A ref counted helper class that handles callbacks between IO thread and UI 336 // A ref counted helper class that handles callbacks between IO thread and UI
114 // thread. 337 // thread.
115 class SafeBrowsingServiceTestHelper 338 class SafeBrowsingServiceTestHelper
116 : public base::RefCountedThreadSafe<SafeBrowsingServiceTestHelper>, 339 : public base::RefCountedThreadSafe<SafeBrowsingServiceTestHelper>,
117 public SafeBrowsingService::Client { 340 public SafeBrowsingService::Client,
341 public URLFetcher::Delegate {
118 public: 342 public:
119 explicit SafeBrowsingServiceTestHelper( 343 explicit SafeBrowsingServiceTestHelper(
120 SafeBrowsingServiceTest* safe_browsing_test) 344 SafeBrowsingServiceTest* safe_browsing_test)
121 : safe_browsing_test_(safe_browsing_test) { 345 : safe_browsing_test_(safe_browsing_test),
346 response_status_(URLRequestStatus::FAILED) {
122 } 347 }
123 348
124 // Callbacks for SafeBrowsingService::Client. Not implemented yet. 349 // Callbacks for SafeBrowsingService::Client.
125 virtual void OnUrlCheckResult(const GURL& url, 350 virtual void OnUrlCheckResult(const GURL& url,
126 SafeBrowsingService::UrlCheckResult result) { 351 SafeBrowsingService::UrlCheckResult result) {
127 NOTREACHED() << "Not implemented."; 352 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
353 EXPECT_TRUE(safe_browsing_test_->is_checked_url_in_db());
354 safe_browsing_test_->set_is_checked_url_safe(
355 result == SafeBrowsingService::URL_SAFE);
356 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
357 NewRunnableMethod(this,
358 &SafeBrowsingServiceTestHelper::OnCheckUrlDone));
128 } 359 }
129 virtual void OnBlockingPageComplete(bool proceed) { 360 virtual void OnBlockingPageComplete(bool proceed) {
130 NOTREACHED() << "Not implemented."; 361 NOTREACHED() << "Not implemented.";
131 } 362 }
132 363
133 // Functions and callbacks related to CheckUrl. These are used to verify if 364 // Functions and callbacks to start the safebrowsing database update.
134 // a URL is a phishing URL. 365 void ForceUpdate() {
366 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
367 NewRunnableMethod(this,
368 &SafeBrowsingServiceTestHelper::ForceUpdateInIOThread));
369 // Will continue after OnForceUpdateDone().
370 ui_test_utils::RunMessageLoop();
371 }
372 void ForceUpdateInIOThread() {
373 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
374 safe_browsing_test_->ForceUpdate();
375 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
376 NewRunnableMethod(this,
377 &SafeBrowsingServiceTestHelper::OnForceUpdateDone));
378 }
379 void OnForceUpdateDone() {
380 StopUILoop();
381 }
382
383 // Functions and callbacks related to CheckUrl. These are used to verify
384 // phishing URLs.
135 void CheckUrl(const GURL& url) { 385 void CheckUrl(const GURL& url) {
136 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, NewRunnableMethod( 386 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, NewRunnableMethod(
137 this, &SafeBrowsingServiceTestHelper::CheckUrlOnIOThread, url)); 387 this, &SafeBrowsingServiceTestHelper::CheckUrlOnIOThread, url));
388 ui_test_utils::RunMessageLoop();
138 } 389 }
139 void CheckUrlOnIOThread(const GURL& url) { 390 void CheckUrlOnIOThread(const GURL& url) {
140 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 391 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
141 safe_browsing_test_->CheckUrl(this, url); 392 safe_browsing_test_->CheckUrl(this, url);
142 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, NewRunnableMethod( 393 if (!safe_browsing_test_->is_checked_url_in_db()) {
143 this, &SafeBrowsingServiceTestHelper::OnCheckUrlOnIOThreadDone)); 394 // Ends the checking since this URL's prefix is not in database.
395 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, NewRunnableMethod(
396 this, &SafeBrowsingServiceTestHelper::OnCheckUrlDone));
397 }
398 // Otherwise, OnCheckUrlDone is called in OnUrlCheckResult since
399 // safebrowsing service further fetches hashes from safebrowsing server.
144 } 400 }
145 void OnCheckUrlOnIOThreadDone() { 401
402 void OnCheckUrlDone() {
146 StopUILoop(); 403 StopUILoop();
147 } 404 }
148 405
149 // Updates status from IO Thread. 406 // Updates status from IO Thread.
150 void CheckStatusOnIOThread() { 407 void CheckStatusOnIOThread() {
151 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 408 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
152 safe_browsing_test_->UpdateSafeBrowsingStatus(); 409 safe_browsing_test_->UpdateSafeBrowsingStatus();
153 safe_browsing_test_->SafeBrowsingMessageLoop()->PostTask( 410 safe_browsing_test_->SafeBrowsingMessageLoop()->PostTask(
154 FROM_HERE, NewRunnableMethod(this, 411 FROM_HERE, NewRunnableMethod(this,
155 &SafeBrowsingServiceTestHelper::CheckIsDatabaseReady)); 412 &SafeBrowsingServiceTestHelper::CheckIsDatabaseReady));
156 } 413 }
157 414
158 // Checks status in SafeBrowsing Thread. 415 // Checks status in SafeBrowsing Thread.
159 void CheckIsDatabaseReady() { 416 void CheckIsDatabaseReady() {
160 DCHECK_EQ(MessageLoop::current(), 417 EXPECT_EQ(MessageLoop::current(),
161 safe_browsing_test_->SafeBrowsingMessageLoop()); 418 safe_browsing_test_->SafeBrowsingMessageLoop());
162 safe_browsing_test_->CheckIsDatabaseReady(); 419 safe_browsing_test_->CheckIsDatabaseReady();
163 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, NewRunnableMethod( 420 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, NewRunnableMethod(
164 this, &SafeBrowsingServiceTestHelper::OnCheckStatusAfterDelayDone)); 421 this, &SafeBrowsingServiceTestHelper::OnWaitForStatusUpdateDone));
165 } 422 }
166 423
167 void OnCheckStatusAfterDelayDone() { 424 void OnWaitForStatusUpdateDone() {
168 StopUILoop(); 425 StopUILoop();
169 } 426 }
170 427
171 // Checks safebrowsing status after a given latency. 428 // Wait for a given period to get safebrowsing status updated.
172 void CheckStatusAfterDelay(int64 wait_time_sec) { 429 void WaitForStatusUpdate(int64 wait_time_msec) {
173 BrowserThread::PostDelayedTask( 430 BrowserThread::PostDelayedTask(
174 BrowserThread::IO, 431 BrowserThread::IO,
175 FROM_HERE, 432 FROM_HERE,
176 NewRunnableMethod(this, 433 NewRunnableMethod(this,
177 &SafeBrowsingServiceTestHelper::CheckStatusOnIOThread), 434 &SafeBrowsingServiceTestHelper::CheckStatusOnIOThread),
178 wait_time_sec * 1000); 435 wait_time_msec);
436 // Will continue after OnWaitForStatusUpdateDone().
437 ui_test_utils::RunMessageLoop();
438 }
439
440 void WaitTillServerReady(const char* host, int port) {
441 response_status_ = URLRequestStatus::FAILED;
442 GURL url(StringPrintf("http://%s:%d%s?test_step=0",
443 host, port, kDBResetPath));
444 // TODO(lzheng): We should have a way to reliably tell when a server is
445 // ready so we could get rid of the Sleep and retry loop.
446 while (true) {
447 if (FetchUrl(url) == URLRequestStatus::SUCCESS)
448 break;
449 // Wait and try again if last fetch was failed. The loop will hit the
450 // timeout in OutOfProcTestRunner if the fetch can not get success
451 // response.
452 PlatformThread::Sleep(TestTimeouts::action_timeout_ms());
453 }
454 }
455
456 // Calls test server to fetch database for verification.
457 URLRequestStatus::Status FetchDBToVerify(const char* host, int port,
458 int test_step) {
459 // TODO(lzheng): Remove chunk_type=add once it is not needed by the server.
460 GURL url(StringPrintf("http://%s:%d%s?"
461 "client=chromium&appver=1.0&pver=2.2&test_step=%d&"
462 "chunk_type=add",
463 host, port, kDBVerifyPath, test_step));
464 return FetchUrl(url);
465 }
466
467 // Calls test server to fetch URLs for verification.
468 URLRequestStatus::Status FetchUrlsToVerify(const char* host, int port,
469 int test_step) {
470 GURL url(StringPrintf("http://%s:%d%s?"
471 "client=chromium&appver=1.0&pver=2.2&test_step=%d",
472 host, port, kUrlVerifyPath, test_step));
473 return FetchUrl(url);
474 }
475
476 // Calls test server to check if test data is done. E.g.: if there is a
477 // bad URL that server expects test to fetch full hash but the test didn't,
478 // this verification will fail.
479 URLRequestStatus::Status VerifyTestComplete(const char* host, int port,
480 int test_step) {
481 GURL url(StringPrintf("http://%s:%d%s?test_step=%d",
482 host, port, kTestCompletePath, test_step));
483 return FetchUrl(url);
484 }
485
486 // Callback for URLFetcher.
487 virtual void OnURLFetchComplete(const URLFetcher* source,
488 const GURL& url,
489 const URLRequestStatus& status,
490 int response_code,
491 const ResponseCookies& cookies,
492 const std::string& data) {
493 response_data_ = data;
494 response_status_ = status.status();
495 StopUILoop();
496 }
497
498 const std::string& response_data() {
499 return response_data_;
179 } 500 }
180 501
181 private: 502 private:
182 // Stops UI loop after desired status is updated. 503 // Stops UI loop after desired status is updated.
183 void StopUILoop() { 504 void StopUILoop() {
184 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 505 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::UI));
185 MessageLoopForUI::current()->Quit(); 506 MessageLoopForUI::current()->Quit();
186 } 507 }
187 508
509 // Fetch a URL. If message_loop_started is true, starts the message loop
510 // so the caller could wait till OnURLFetchComplete is called.
511 URLRequestStatus::Status FetchUrl(const GURL& url) {
512 url_fetcher_.reset(new URLFetcher(url, URLFetcher::GET, this));
513 url_fetcher_->set_load_flags(net::LOAD_DISABLE_CACHE);
514 url_fetcher_->set_request_context(Profile::GetDefaultRequestContext());
515 url_fetcher_->Start();
516 ui_test_utils::RunMessageLoop();
517 return response_status_;
518 }
519
188 base::OneShotTimer<SafeBrowsingServiceTestHelper> check_update_timer_; 520 base::OneShotTimer<SafeBrowsingServiceTestHelper> check_update_timer_;
189 SafeBrowsingServiceTest* safe_browsing_test_; 521 SafeBrowsingServiceTest* safe_browsing_test_;
522 scoped_ptr<URLFetcher> url_fetcher_;
523 std::string response_data_;
524 URLRequestStatus::Status response_status_;
190 DISALLOW_COPY_AND_ASSIGN(SafeBrowsingServiceTestHelper); 525 DISALLOW_COPY_AND_ASSIGN(SafeBrowsingServiceTestHelper);
191 }; 526 };
192 527
193 IN_PROC_BROWSER_TEST_F(SafeBrowsingServiceTest, SafeBrowsingSystemTest) { 528 IN_PROC_BROWSER_TEST_F(SafeBrowsingServiceTest, SafeBrowsingSystemTest) {
194 InitSafeBrowsingService(); 529 LOG(INFO) << "Start test";
530 const char* server_host = SafeBrowsingTestServer::Host();
531 int server_port = SafeBrowsingTestServer::Port();
532 ASSERT_TRUE(InitSafeBrowsingService());
533
195 scoped_refptr<SafeBrowsingServiceTestHelper> safe_browsing_helper = 534 scoped_refptr<SafeBrowsingServiceTestHelper> safe_browsing_helper =
196 new SafeBrowsingServiceTestHelper(this); 535 new SafeBrowsingServiceTestHelper(this);
197 536 int last_step = 0;
198 // Waits for 1 sec and makes sure safebrowsing update is not happening. 537 FilePath datafile_path = FilePath(kDataFile);
199 safe_browsing_helper->CheckStatusAfterDelay(1); 538 SafeBrowsingTestServer test_server(datafile_path);
200 // Loop will stop once OnCheckStatusOnIOThreadDone in safe_browsing_helper 539 ASSERT_TRUE(test_server.Start());
201 // is called and status from safe_browsing_service_ is checked. 540
202 ui_test_utils::RunMessageLoop(); 541 // Make sure the server is running.
542 safe_browsing_helper->WaitTillServerReady(server_host, server_port);
543
544 // Waits and makes sure safebrowsing update is not happening.
545 // The wait will stop once OnWaitForStatusUpdateDone in
546 // safe_browsing_helper is called and status from safe_browsing_service_
547 // is checked.
548 safe_browsing_helper->WaitForStatusUpdate(0);
203 EXPECT_TRUE(is_database_ready()); 549 EXPECT_TRUE(is_database_ready());
204 EXPECT_TRUE(is_initial_request()); 550 EXPECT_TRUE(is_initial_request());
205 EXPECT_FALSE(is_update_scheduled()); 551 EXPECT_FALSE(is_update_scheduled());
206 EXPECT_TRUE(last_update().is_null()); 552 EXPECT_TRUE(last_update().is_null());
207 553 // Starts updates. After each update, the test will fetch a list of URLs with
208 // Verify URL. 554 // expected results to verify with safebrowsing service. If there is no error,
209 const char test_url[] = "http://ianfette.org"; 555 // the test moves on to the next step to get more update chunks.
210 safe_browsing_helper->CheckUrl(GURL(test_url)); 556 // This repeats till there is no update data.
211 // Loop will stop once OnCheckUrlOnIOThreadDone in safe_browsing_helper 557 for (int step = 1;; step++) {
212 // is called and url check is done. 558 // Every step should be a fresh start.
213 ui_test_utils::RunMessageLoop(); 559 SCOPED_TRACE(StringPrintf("step=%d", step));
214 EXPECT_TRUE(is_url_match_in_db()); 560 EXPECT_TRUE(is_database_ready());
215 561 EXPECT_FALSE(is_update_scheduled());
216 // TODO(lzheng): Add tests to launch a testing safebrowsing server 562
217 // and issue requests repeatedly: 563 // TODO(lzheng): Remove the following #if and #elif to enable the rest of
218 // http://code.google.com/p/google-safe-browsing/wiki/ProtocolTesting 564 // the test once bot is restarted with change
565 // http://codereview.chromium.org/3750002.
566 #if defined(OS_WIN)
567 break;
568 #elif defined(OS_POSIX)
569 if (step > 2 ) break;
570 #endif
571
572 // Starts safebrowsing update on IO thread. Waits till scheduled
573 // update finishes. Stops waiting after kMaxWaitSecPerStep if the update
574 // could not finish.
575 base::Time now = base::Time::Now();
576 SetTestStep(step);
577 safe_browsing_helper->ForceUpdate();
578
579 do {
580 // Periodically pull the status.
581 safe_browsing_helper->WaitForStatusUpdate(
582 TestTimeouts::action_timeout_ms());
583 } while (is_update_scheduled() || is_initial_request() ||
584 !is_database_ready());
585
586
587 if (last_update() < now) {
588 // This means no data available anymore.
589 break;
590 }
591
592 // Fetches URLs to verify and waits till server responses with data.
593 EXPECT_EQ(URLRequestStatus::SUCCESS,
594 safe_browsing_helper->FetchUrlsToVerify(server_host,
595 server_port,
596 step));
597
598 std::vector<PhishingUrl> phishing_urls;
599 EXPECT_TRUE(ParsePhishingUrls(safe_browsing_helper->response_data(),
600 &phishing_urls));
601 EXPECT_GT(phishing_urls.size(), 0U);
602 for (size_t j = 0; j < phishing_urls.size(); ++j) {
603 // Verifes with server if a URL is a phishing URL and waits till server
604 // responses.
605 safe_browsing_helper->CheckUrl(GURL(phishing_urls[j].url));
606 if (phishing_urls[j].is_phishing) {
607 EXPECT_TRUE(is_checked_url_in_db())
608 << phishing_urls[j].url
609 << " is_phishing: " << phishing_urls[j].is_phishing
610 << " test step: " << step;
611 EXPECT_FALSE(is_checked_url_safe())
612 << phishing_urls[j].url
613 << " is_phishing: " << phishing_urls[j].is_phishing
614 << " test step: " << step;
615 } else {
616 EXPECT_TRUE(is_checked_url_safe())
617 << phishing_urls[j].url
618 << " is_phishing: " << phishing_urls[j].is_phishing
619 << " test step: " << step;
620 }
621 }
622 // TODO(lzheng): We should verify the fetched database with local
623 // database to make sure they match.
624 EXPECT_EQ(URLRequestStatus::SUCCESS,
625 safe_browsing_helper->FetchDBToVerify(server_host,
626 server_port,
627 step));
628 EXPECT_GT(safe_browsing_helper->response_data().size(), 0U);
629 last_step = step;
630 }
631
632 // TODO(lzheng): Enable this check after safebrowsing server updated with
633 // the latest data in the next revision.
634
635 // Verifies with server if test is done and waits till server responses.
636 // EXPECT_EQ(URLRequestStatus::SUCCESS,
637 // safe_browsing_helper->VerifyTestComplete(server_host,
638 // server_port,
639 // last_step));
640 // EXPECT_EQ("yes", safe_browsing_helper->response_data());
641 test_server.Stop();
219 } 642 }
643
OLDNEW
« no previous file with comments | « DEPS ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698