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

Side by Side Diff: chrome/renderer/safe_browsing/phishing_dom_feature_extractor_browsertest.cc

Issue 3130039: Limit the time spent on a single iteration of PhishingDOMFeatureExtractor. (Closed) Base URL: http://src.chromium.org/git/chromium.git
Patch Set: tiny comment fix Created 10 years, 4 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
« no previous file with comments | « chrome/renderer/safe_browsing/phishing_dom_feature_extractor.cc ('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 // 4 //
5 // Note that although this is not a "browser" test, it runs as part of 5 // Note that although this is not a "browser" test, it runs as part of
6 // browser_tests. This is because WebKit does not work properly if it is 6 // browser_tests. This is because WebKit does not work properly if it is
7 // shutdown and re-initialized. Since browser_tests runs each test in a 7 // shutdown and re-initialized. Since browser_tests runs each test in a
8 // new process, this avoids the problem. 8 // new process, this avoids the problem.
9 9
10 #include "chrome/renderer/safe_browsing/phishing_dom_feature_extractor.h" 10 #include "chrome/renderer/safe_browsing/phishing_dom_feature_extractor.h"
11 11
12 #include <string.h> // for memcpy() 12 #include <string.h> // for memcpy()
13 #include <map> 13 #include <map>
14 #include <string> 14 #include <string>
15 15
16 #include "base/callback.h" 16 #include "base/callback.h"
17 #include "base/command_line.h" 17 #include "base/command_line.h"
18 #include "base/message_loop.h" 18 #include "base/message_loop.h"
19 #include "base/process.h" 19 #include "base/process.h"
20 #include "base/string_util.h" 20 #include "base/string_util.h"
21 #include "base/time.h"
21 #include "chrome/common/main_function_params.h" 22 #include "chrome/common/main_function_params.h"
22 #include "chrome/common/render_messages.h" 23 #include "chrome/common/render_messages.h"
23 #include "chrome/common/sandbox_init_wrapper.h" 24 #include "chrome/common/sandbox_init_wrapper.h"
24 #include "chrome/renderer/mock_render_process.h" 25 #include "chrome/renderer/mock_render_process.h"
25 #include "chrome/renderer/render_thread.h" 26 #include "chrome/renderer/render_thread.h"
26 #include "chrome/renderer/render_view.h" 27 #include "chrome/renderer/render_view.h"
27 #include "chrome/renderer/render_view_visitor.h" 28 #include "chrome/renderer/render_view_visitor.h"
28 #include "chrome/renderer/renderer_main_platform_delegate.h" 29 #include "chrome/renderer/renderer_main_platform_delegate.h"
30 #include "chrome/renderer/safe_browsing/feature_extractor_clock.h"
29 #include "chrome/renderer/safe_browsing/features.h" 31 #include "chrome/renderer/safe_browsing/features.h"
30 #include "googleurl/src/gurl.h" 32 #include "googleurl/src/gurl.h"
31 #include "ipc/ipc_channel.h" 33 #include "ipc/ipc_channel.h"
32 #include "net/http/http_response_headers.h" 34 #include "net/http/http_response_headers.h"
33 #include "testing/gmock/include/gmock/gmock.h" 35 #include "testing/gmock/include/gmock/gmock.h"
34 #include "testing/gtest/include/gtest/gtest.h" 36 #include "testing/gtest/include/gtest/gtest.h"
35 #include "third_party/WebKit/WebKit/chromium/public/WebFrame.h" 37 #include "third_party/WebKit/WebKit/chromium/public/WebFrame.h"
36 #include "third_party/WebKit/WebKit/chromium/public/WebURLRequest.h" 38 #include "third_party/WebKit/WebKit/chromium/public/WebURLRequest.h"
37 #include "third_party/WebKit/WebKit/chromium/public/WebView.h" 39 #include "third_party/WebKit/WebKit/chromium/public/WebView.h"
38 #include "webkit/glue/webkit_glue.h" 40 #include "webkit/glue/webkit_glue.h"
39 41
40 using ::testing::ContainerEq; 42 using ::testing::ContainerEq;
43 using ::testing::Return;
41 44
42 namespace safe_browsing { 45 namespace safe_browsing {
43 46
44 class PhishingDOMFeatureExtractorTest : public ::testing::Test, 47 class PhishingDOMFeatureExtractorTest : public ::testing::Test,
45 public IPC::Channel::Listener, 48 public IPC::Channel::Listener,
46 public RenderViewVisitor { 49 public RenderViewVisitor {
47 public: 50 public:
48 // IPC::Channel::Listener implementation. 51 // IPC::Channel::Listener implementation.
49 virtual void OnMessageReceived(const IPC::Message& message) { 52 virtual void OnMessageReceived(const IPC::Message& message) {
50 IPC_BEGIN_MESSAGE_MAP(PhishingDOMFeatureExtractorTest, message) 53 IPC_BEGIN_MESSAGE_MAP(PhishingDOMFeatureExtractorTest, message)
51 IPC_MESSAGE_HANDLER(ViewHostMsg_RenderViewReady, OnRenderViewReady) 54 IPC_MESSAGE_HANDLER(ViewHostMsg_RenderViewReady, OnRenderViewReady)
52 IPC_MESSAGE_HANDLER(ViewHostMsg_DidStopLoading, OnDidStopLoading) 55 IPC_MESSAGE_HANDLER(ViewHostMsg_DidStopLoading, OnDidStopLoading)
53 IPC_MESSAGE_HANDLER(ViewHostMsg_RequestResource, OnRequestResource) 56 IPC_MESSAGE_HANDLER(ViewHostMsg_RequestResource, OnRequestResource)
54 IPC_END_MESSAGE_MAP() 57 IPC_END_MESSAGE_MAP()
55 } 58 }
56 59
57 // RenderViewVisitor implementation. 60 // RenderViewVisitor implementation.
58 virtual bool Visit(RenderView* render_view) { 61 virtual bool Visit(RenderView* render_view) {
59 view_ = render_view; 62 view_ = render_view;
60 return false; 63 return false;
61 } 64 }
62 65
63 protected: 66 protected:
67 class MockClock : public FeatureExtractorClock {
68 public:
69 MOCK_METHOD0(Now, base::TimeTicks());
70 };
71
64 virtual void SetUp() { 72 virtual void SetUp() {
65 // Set up the renderer. This code is largely adapted from 73 // Set up the renderer. This code is largely adapted from
66 // render_view_test.cc and renderer_main.cc. Note that we use a 74 // render_view_test.cc and renderer_main.cc. Note that we use a
67 // MockRenderProcess (because we don't need to use IPC for painting), 75 // MockRenderProcess (because we don't need to use IPC for painting),
68 // but we use a real RenderThread so that we can use the ResourceDispatcher 76 // but we use a real RenderThread so that we can use the ResourceDispatcher
69 // to fetch network resources. These are then served canned content 77 // to fetch network resources. These are then served canned content
70 // in OnRequestResource(). 78 // in OnRequestResource().
71 sandbox_init_wrapper_.reset(new SandboxInitWrapper); 79 sandbox_init_wrapper_.reset(new SandboxInitWrapper);
72 command_line_.reset(new CommandLine(CommandLine::ARGUMENTS_ONLY)); 80 command_line_.reset(new CommandLine(CommandLine::ARGUMENTS_ONLY));
73 params_.reset(new MainFunctionParams(*command_line_, 81 params_.reset(new MainFunctionParams(*command_line_,
(...skipping 15 matching lines...) Expand all
89 // We can't call View::Create() directly here or else we won't get 97 // We can't call View::Create() directly here or else we won't get
90 // RenderProcess's lazy initialization of WebKit. 98 // RenderProcess's lazy initialization of WebKit.
91 view_ = NULL; 99 view_ = NULL;
92 ViewMsg_New_Params params; 100 ViewMsg_New_Params params;
93 params.parent_window = 0; 101 params.parent_window = 0;
94 params.view_id = kViewId; 102 params.view_id = kViewId;
95 params.session_storage_namespace_id = kInvalidSessionStorageNamespaceId; 103 params.session_storage_namespace_id = kInvalidSessionStorageNamespaceId;
96 ASSERT_TRUE(channel_->Send(new ViewMsg_New(params))); 104 ASSERT_TRUE(channel_->Send(new ViewMsg_New(params)));
97 msg_loop_.Run(); 105 msg_loop_.Run();
98 106
99 extractor_.reset(new PhishingDOMFeatureExtractor(view_)); 107 clock_ = new MockClock();
108 extractor_.reset(new PhishingDOMFeatureExtractor(view_, clock_));
100 } 109 }
101 110
102 virtual void TearDown() { 111 virtual void TearDown() {
103 // Try very hard to collect garbage before shutting down. 112 // Try very hard to collect garbage before shutting down.
104 GetMainFrame()->collectGarbage(); 113 GetMainFrame()->collectGarbage();
105 GetMainFrame()->collectGarbage(); 114 GetMainFrame()->collectGarbage();
106 115
107 ASSERT_TRUE(channel_->Send(new ViewMsg_Close(kViewId))); 116 ASSERT_TRUE(channel_->Send(new ViewMsg_Close(kViewId)));
108 do { 117 do {
109 msg_loop_.RunAllPending(); 118 msg_loop_.RunAllPending();
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
225 scoped_ptr<IPC::Channel> channel_; 234 scoped_ptr<IPC::Channel> channel_;
226 RenderThread* render_thread_; // owned by mock_process_ 235 RenderThread* render_thread_; // owned by mock_process_
227 scoped_ptr<MockRenderProcess> mock_process_; 236 scoped_ptr<MockRenderProcess> mock_process_;
228 RenderView* view_; // not owned, deletes itself on close 237 RenderView* view_; // not owned, deletes itself on close
229 scoped_ptr<RendererMainPlatformDelegate> platform_; 238 scoped_ptr<RendererMainPlatformDelegate> platform_;
230 scoped_ptr<MainFunctionParams> params_; 239 scoped_ptr<MainFunctionParams> params_;
231 scoped_ptr<CommandLine> command_line_; 240 scoped_ptr<CommandLine> command_line_;
232 scoped_ptr<SandboxInitWrapper> sandbox_init_wrapper_; 241 scoped_ptr<SandboxInitWrapper> sandbox_init_wrapper_;
233 242
234 scoped_ptr<PhishingDOMFeatureExtractor> extractor_; 243 scoped_ptr<PhishingDOMFeatureExtractor> extractor_;
244 MockClock* clock_; // owned by extractor_
235 // Map of URL -> response body for network requests from the renderer. 245 // Map of URL -> response body for network requests from the renderer.
236 // Any URLs not in this map are served a 404 error. 246 // Any URLs not in this map are served a 404 error.
237 std::map<std::string, std::string> responses_; 247 std::map<std::string, std::string> responses_;
238 bool success_; // holds the success value from ExtractFeatures 248 bool success_; // holds the success value from ExtractFeatures
239 }; 249 };
240 250
241 int PhishingDOMFeatureExtractorTest::next_thread_id_ = 0; 251 int PhishingDOMFeatureExtractorTest::next_thread_id_ = 0;
242 252
243 TEST_F(PhishingDOMFeatureExtractorTest, FormFeatures) { 253 TEST_F(PhishingDOMFeatureExtractorTest, FormFeatures) {
254 // This test doesn't exercise the extraction timing.
255 EXPECT_CALL(*clock_, Now()).WillRepeatedly(Return(base::TimeTicks::Now()));
244 responses_["http://host.com/"] = 256 responses_["http://host.com/"] =
245 "<html><head><body>" 257 "<html><head><body>"
246 "<form action=\"query\"><input type=text><input type=checkbox></form>" 258 "<form action=\"query\"><input type=text><input type=checkbox></form>"
247 "<form action=\"http://cgi.host.com/submit\"></form>" 259 "<form action=\"http://cgi.host.com/submit\"></form>"
248 "<form action=\"http://other.com/\"></form>" 260 "<form action=\"http://other.com/\"></form>"
249 "<form action=\"query\"></form>" 261 "<form action=\"query\"></form>"
250 "<form></form></body></html>"; 262 "<form></form></body></html>";
251 263
252 FeatureMap expected_features; 264 FeatureMap expected_features;
253 expected_features.AddBooleanFeature(features::kPageHasForms); 265 expected_features.AddBooleanFeature(features::kPageHasForms);
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
290 expected_features.Clear(); 302 expected_features.Clear();
291 expected_features.AddBooleanFeature(features::kPageHasTextInputs); 303 expected_features.AddBooleanFeature(features::kPageHasTextInputs);
292 304
293 features.Clear(); 305 features.Clear();
294 LoadURL("http://host.com/"); 306 LoadURL("http://host.com/");
295 ASSERT_TRUE(ExtractFeatures(&features)); 307 ASSERT_TRUE(ExtractFeatures(&features));
296 EXPECT_THAT(features.features(), ContainerEq(expected_features.features())); 308 EXPECT_THAT(features.features(), ContainerEq(expected_features.features()));
297 } 309 }
298 310
299 TEST_F(PhishingDOMFeatureExtractorTest, LinkFeatures) { 311 TEST_F(PhishingDOMFeatureExtractorTest, LinkFeatures) {
312 // This test doesn't exercise the extraction timing.
313 EXPECT_CALL(*clock_, Now()).WillRepeatedly(Return(base::TimeTicks::Now()));
300 responses_["http://www.host.com/"] = 314 responses_["http://www.host.com/"] =
301 "<html><head><body>" 315 "<html><head><body>"
302 "<a href=\"http://www2.host.com/abc\">link</a>" 316 "<a href=\"http://www2.host.com/abc\">link</a>"
303 "<a name=page_anchor></a>" 317 "<a name=page_anchor></a>"
304 "<a href=\"http://www.chromium.org/\">chromium</a>" 318 "<a href=\"http://www.chromium.org/\">chromium</a>"
305 "</body></html"; 319 "</body></html";
306 320
307 FeatureMap expected_features; 321 FeatureMap expected_features;
308 expected_features.AddRealFeature(features::kPageExternalLinksFreq, 0.5); 322 expected_features.AddRealFeature(features::kPageExternalLinksFreq, 0.5);
309 expected_features.AddRealFeature(features::kPageSecureLinksFreq, 0.0); 323 expected_features.AddRealFeature(features::kPageSecureLinksFreq, 0.0);
(...skipping 20 matching lines...) Expand all
330 expected_features.AddBooleanFeature(features::kPageLinkDomain + 344 expected_features.AddBooleanFeature(features::kPageLinkDomain +
331 std::string("chromium.org")); 345 std::string("chromium.org"));
332 346
333 features.Clear(); 347 features.Clear();
334 LoadURL("https://www.host.com/"); 348 LoadURL("https://www.host.com/");
335 ASSERT_TRUE(ExtractFeatures(&features)); 349 ASSERT_TRUE(ExtractFeatures(&features));
336 EXPECT_THAT(features.features(), ContainerEq(expected_features.features())); 350 EXPECT_THAT(features.features(), ContainerEq(expected_features.features()));
337 } 351 }
338 352
339 TEST_F(PhishingDOMFeatureExtractorTest, ScriptAndImageFeatures) { 353 TEST_F(PhishingDOMFeatureExtractorTest, ScriptAndImageFeatures) {
354 // This test doesn't exercise the extraction timing.
355 EXPECT_CALL(*clock_, Now()).WillRepeatedly(Return(base::TimeTicks::Now()));
340 responses_["http://host.com/"] = 356 responses_["http://host.com/"] =
341 "<html><head><script></script><script></script></head></html>"; 357 "<html><head><script></script><script></script></head></html>";
342 358
343 FeatureMap expected_features; 359 FeatureMap expected_features;
344 expected_features.AddBooleanFeature(features::kPageNumScriptTagsGTOne); 360 expected_features.AddBooleanFeature(features::kPageNumScriptTagsGTOne);
345 361
346 FeatureMap features; 362 FeatureMap features;
347 LoadURL("http://host.com/"); 363 LoadURL("http://host.com/");
348 ASSERT_TRUE(ExtractFeatures(&features)); 364 ASSERT_TRUE(ExtractFeatures(&features));
349 EXPECT_THAT(features.features(), ContainerEq(expected_features.features())); 365 EXPECT_THAT(features.features(), ContainerEq(expected_features.features()));
350 366
351 responses_["http://host.com/"] = 367 responses_["http://host.com/"] =
352 "<html><head><script></script><script></script><script></script>" 368 "<html><head><script></script><script></script><script></script>"
353 "<script></script><script></script><script></script><script></script>" 369 "<script></script><script></script><script></script><script></script>"
354 "</head><body><img src=\"blah.gif\">" 370 "</head><body><img src=\"blah.gif\">"
355 "<img src=\"http://host2.com/blah.gif\"></body></html>"; 371 "<img src=\"http://host2.com/blah.gif\"></body></html>";
356 372
357 expected_features.Clear(); 373 expected_features.Clear();
358 expected_features.AddBooleanFeature(features::kPageNumScriptTagsGTOne); 374 expected_features.AddBooleanFeature(features::kPageNumScriptTagsGTOne);
359 expected_features.AddBooleanFeature(features::kPageNumScriptTagsGTSix); 375 expected_features.AddBooleanFeature(features::kPageNumScriptTagsGTSix);
360 expected_features.AddRealFeature(features::kPageImgOtherDomainFreq, 0.5); 376 expected_features.AddRealFeature(features::kPageImgOtherDomainFreq, 0.5);
361 377
362 features.Clear(); 378 features.Clear();
363 LoadURL("http://host.com/"); 379 LoadURL("http://host.com/");
364 ASSERT_TRUE(ExtractFeatures(&features)); 380 ASSERT_TRUE(ExtractFeatures(&features));
365 EXPECT_THAT(features.features(), ContainerEq(expected_features.features())); 381 EXPECT_THAT(features.features(), ContainerEq(expected_features.features()));
366 } 382 }
367 383
368 TEST_F(PhishingDOMFeatureExtractorTest, SubFrames) { 384 TEST_F(PhishingDOMFeatureExtractorTest, SubFrames) {
385 // This test doesn't exercise the extraction timing.
386 EXPECT_CALL(*clock_, Now()).WillRepeatedly(Return(base::TimeTicks::Now()));
387
369 // Test that features are aggregated across all frames. 388 // Test that features are aggregated across all frames.
370 responses_["http://host.com/"] = 389 responses_["http://host.com/"] =
371 "<html><body><input type=text><a href=\"info.html\">link</a>" 390 "<html><body><input type=text><a href=\"info.html\">link</a>"
372 "<iframe src=\"http://host2.com/\"></iframe>" 391 "<iframe src=\"http://host2.com/\"></iframe>"
373 "<iframe src=\"http://host3.com/\"></iframe>" 392 "<iframe src=\"http://host3.com/\"></iframe>"
374 "</body></html>"; 393 "</body></html>";
375 394
376 responses_["http://host2.com/"] = 395 responses_["http://host2.com/"] =
377 "<html><head><script></script><body>" 396 "<html><head><script></script><body>"
378 "<form action=\"http://host4.com/\"><input type=checkbox></form>" 397 "<form action=\"http://host4.com/\"><input type=checkbox></form>"
(...skipping 28 matching lines...) Expand all
407 expected_features.AddRealFeature(features::kPageSecureLinksFreq, 0.25); 426 expected_features.AddRealFeature(features::kPageSecureLinksFreq, 0.25);
408 expected_features.AddBooleanFeature(features::kPageNumScriptTagsGTOne); 427 expected_features.AddBooleanFeature(features::kPageNumScriptTagsGTOne);
409 expected_features.AddRealFeature(features::kPageImgOtherDomainFreq, 1.0); 428 expected_features.AddRealFeature(features::kPageImgOtherDomainFreq, 1.0);
410 429
411 FeatureMap features; 430 FeatureMap features;
412 LoadURL("http://host.com/"); 431 LoadURL("http://host.com/");
413 ASSERT_TRUE(ExtractFeatures(&features)); 432 ASSERT_TRUE(ExtractFeatures(&features));
414 EXPECT_THAT(features.features(), ContainerEq(expected_features.features())); 433 EXPECT_THAT(features.features(), ContainerEq(expected_features.features()));
415 } 434 }
416 435
417 // TODO(bryner): Test extraction with multiple passes, including the case where 436 TEST_F(PhishingDOMFeatureExtractorTest, Continuation) {
418 // the node we stopped on is removed from the document. 437 // For this test, we'll cause the feature extraction to run multiple
438 // iterations by incrementing the clock.
439
440 // This page has a total of 50 elements. For the external forms feature to
441 // be computed correctly, the extractor has to examine the whole document.
442 // Note: the empty HEAD is important -- WebKit will synthesize a HEAD if
443 // there isn't one present, which can be confusing for the element counts.
444 std::string response = "<html><head></head><body>"
445 "<form action=\"ondomain\"></form>";
446 for (int i = 0; i < 45; ++i) {
447 response.append("<p>");
448 }
449 response.append("<form action=\"http://host2.com/\"></form></body></html>");
450 responses_["http://host.com/"] = response;
451
452 // Advance the clock 30 ms every 10 elements processed, 10 ms between chunks.
453 // Note that this assumes kClockCheckGranularity = 10 and
454 // kMaxTimePerChunkMs = 50.
455 base::TimeTicks now = base::TimeTicks::Now();
456 EXPECT_CALL(*clock_, Now())
457 // Time check at the start of extraction.
458 .WillOnce(Return(now))
459 // Time check at the start of the first chunk of work.
460 .WillOnce(Return(now))
461 // Time check after the first 10 elements.
462 .WillOnce(Return(now + base::TimeDelta::FromMilliseconds(30)))
463 // Time check after the next 10 elements. This is over the chunk
464 // time limit, so a continuation task will be posted.
465 .WillOnce(Return(now + base::TimeDelta::FromMilliseconds(60)))
466 // Time check at the start of the second chunk of work.
467 .WillOnce(Return(now + base::TimeDelta::FromMilliseconds(70)))
468 // Time check after resuming iteration for the second chunk.
469 .WillOnce(Return(now + base::TimeDelta::FromMilliseconds(72)))
470 // Time check after the next 10 elements.
471 .WillOnce(Return(now + base::TimeDelta::FromMilliseconds(100)))
472 // Time check after the next 10 elements. This will trigger another
473 // continuation task.
474 .WillOnce(Return(now + base::TimeDelta::FromMilliseconds(130)))
475 // Time check at the start of the third chunk of work.
476 .WillOnce(Return(now + base::TimeDelta::FromMilliseconds(140)))
477 // Time check after resuming iteration for the third chunk.
478 .WillOnce(Return(now + base::TimeDelta::FromMilliseconds(142)))
479 // Time check after the last 10 elements.
480 .WillOnce(Return(now + base::TimeDelta::FromMilliseconds(170)))
481 // A final time check for the histograms.
482 .WillOnce(Return(now + base::TimeDelta::FromMilliseconds(180)));
483
484 FeatureMap expected_features;
485 expected_features.AddBooleanFeature(features::kPageHasForms);
486 expected_features.AddRealFeature(features::kPageActionOtherDomainFreq, 0.5);
487
488 FeatureMap features;
489 LoadURL("http://host.com/");
490 ASSERT_TRUE(ExtractFeatures(&features));
491 EXPECT_THAT(features.features(), ContainerEq(expected_features.features()));
492 // Make sure none of the mock expectations carry over to the next test.
493 ::testing::Mock::VerifyAndClearExpectations(clock_);
494
495 // Now repeat the test with the same page, but advance the clock faster so
496 // that the extraction time exceeds the maximum total time for the feature
497 // extractor. Extraction should fail. Note that this assumes
498 // kMaxTotalTimeMs = 500.
499 EXPECT_CALL(*clock_, Now())
500 // Time check at the start of extraction.
501 .WillOnce(Return(now))
502 // Time check at the start of the first chunk of work.
503 .WillOnce(Return(now))
504 // Time check after the first 10 elements.
505 .WillOnce(Return(now + base::TimeDelta::FromMilliseconds(300)))
506 // Time check at the start of the second chunk of work.
507 .WillOnce(Return(now + base::TimeDelta::FromMilliseconds(350)))
508 // Time check after resuming iteration for the second chunk.
509 .WillOnce(Return(now + base::TimeDelta::FromMilliseconds(360)))
510 // Time check after the next 10 elements. This is over the limit.
511 .WillOnce(Return(now + base::TimeDelta::FromMilliseconds(600)))
512 // A final time check for the histograms.
513 .WillOnce(Return(now + base::TimeDelta::FromMilliseconds(620)));
514
515 features.Clear();
516 EXPECT_FALSE(ExtractFeatures(&features));
517 }
419 518
420 } // namespace safe_browsing 519 } // namespace safe_browsing
OLDNEW
« no previous file with comments | « chrome/renderer/safe_browsing/phishing_dom_feature_extractor.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698