1 // Copyright 2014 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "chrome/browser/safe_browsing/incident_reporting/incident_reporting_service.h" 6 7 #include <map> 8 #include <string> 9 10 #include "base/bind.h" 11 #include "base/callback.h" 12 #include "base/lazy_instance.h" 13 #include "base/strings/utf_string_conversions.h" 14 #include "base/test/test_simple_task_runner.h" 15 #include "base/thread_task_runner_handle.h" 16 #include "base/threading/thread_local.h" 17 #include "chrome/browser/prefs/browser_prefs.h" 18 #include "chrome/browser/safe_browsing/incident_reporting/incident_report_uploader.h" 19 #include "chrome/browser/safe_browsing/incident_reporting/last_download_finder.h" 20 #include "chrome/common/pref_names.h" 21 #include "chrome/common/safe_browsing/csd.pb.h" 22 #include "chrome/test/base/testing_browser_process.h" 23 #include "chrome/test/base/testing_pref_service_syncable.h" 24 #include "chrome/test/base/testing_profile.h" 25 #include "chrome/test/base/testing_profile_manager.h" 26 #include "net/url_request/url_request_context_getter.h" 27 #include "testing/gtest/include/gtest/gtest.h" 28 29 // A test fixture that sets up a test task runner and makes it the thread's 30 // runner. The fixture implements a fake envrionment data collector and a fake 31 // report uploader. 32 class IncidentReportingServiceTest : public testing::Test { 33 protected: 34 // An IRS class that allows a test harness to provide a fake environment 35 // collector and report uploader via callbacks. 36 class TestIncidentReportingService 37 : public safe_browsing::IncidentReportingService { 38 public: 39 typedef base::Callback<void(Profile*)> PreProfileAddCallback; 40 41 typedef base::Callback< 42 void(safe_browsing::ClientIncidentReport_EnvironmentData*)> 43 CollectEnvironmentCallback; 44 45 typedef base::Callback<scoped_ptr<safe_browsing::LastDownloadFinder>( 46 const safe_browsing::LastDownloadFinder::LastDownloadCallback& 47 callback)> CreateDownloadFinderCallback; 48 49 typedef base::Callback<scoped_ptr<safe_browsing::IncidentReportUploader>( 50 const safe_browsing::IncidentReportUploader::OnResultCallback&, 51 const safe_browsing::ClientIncidentReport& report)> StartUploadCallback; 52 53 TestIncidentReportingService( 54 const scoped_refptr<base::TaskRunner>& task_runner, 55 const PreProfileAddCallback& pre_profile_add_callback, 56 const CollectEnvironmentCallback& collect_environment_callback, 57 const CreateDownloadFinderCallback& create_download_finder_callback, 58 const StartUploadCallback& start_upload_callback) 59 : IncidentReportingService(NULL, 60 NULL, 61 base::TimeDelta::FromMilliseconds(5), 62 task_runner), 63 pre_profile_add_callback_(pre_profile_add_callback), 64 collect_environment_callback_(collect_environment_callback), 65 create_download_finder_callback_(create_download_finder_callback), 66 start_upload_callback_(start_upload_callback) { 67 SetCollectEnvironmentHook(&CollectEnvironmentData, task_runner); 68 test_instance_.Get().Set(this); 69 } 70 71 virtual ~TestIncidentReportingService() { test_instance_.Get().Set(NULL); } 72 73 bool IsProcessingReport() const { 74 return IncidentReportingService::IsProcessingReport(); 75 } 76 77 protected: 78 virtual void OnProfileAdded(Profile* profile) OVERRIDE { 79 pre_profile_add_callback_.Run(profile); 80 safe_browsing::IncidentReportingService::OnProfileAdded(profile); 81 } 82 83 virtual scoped_ptr<safe_browsing::LastDownloadFinder> CreateDownloadFinder( 84 const safe_browsing::LastDownloadFinder::LastDownloadCallback& callback) 85 OVERRIDE { 86 return create_download_finder_callback_.Run(callback); 87 } 88 89 virtual scoped_ptr<safe_browsing::IncidentReportUploader> StartReportUpload( 90 const safe_browsing::IncidentReportUploader::OnResultCallback& callback, 91 const scoped_refptr<net::URLRequestContextGetter>& 92 request_context_getter, 93 const safe_browsing::ClientIncidentReport& report) OVERRIDE { 94 return start_upload_callback_.Run(callback, report); 95 } 96 97 private: 98 static TestIncidentReportingService& current() { 99 return *test_instance_.Get().Get(); 100 } 101 102 static void CollectEnvironmentData( 103 safe_browsing::ClientIncidentReport_EnvironmentData* data) { 104 current().collect_environment_callback_.Run(data); 105 }; 106 107 static base::LazyInstance<base::ThreadLocalPointer< 108 TestIncidentReportingService> >::Leaky test_instance_; 109 110 PreProfileAddCallback pre_profile_add_callback_; 111 CollectEnvironmentCallback collect_environment_callback_; 112 CreateDownloadFinderCallback create_download_finder_callback_; 113 StartUploadCallback start_upload_callback_; 114 }; 115 116 // A type for specifying whether or not a profile created by CreateProfile 117 // participates in safe browsing. 118 enum SafeBrowsingDisposition { 119 SAFE_BROWSING_OPT_OUT, 120 SAFE_BROWSING_OPT_IN, 121 }; 122 123 // A type for specifying the action to be taken by the test fixture during 124 // profile initialization (before NOTIFICATION_PROFILE_ADDED is sent). 125 enum OnProfileAdditionAction { 126 ON_PROFILE_ADDITION_NO_ACTION, 127 ON_PROFILE_ADDITION_ADD_INCIDENT, // Add an incident to the service. 128 ON_PROFILE_ADDITION_ADD_TWO_INCIDENTS, // Add two incidents to the service. 129 }; 130 131 // A type for specifying the action to be taken by the test fixture when the 132 // service creates a LastDownloadFinder. 133 enum OnCreateDownloadFinderAction { 134 // Post a task that reports a download. 135 ON_CREATE_DOWNLOAD_FINDER_DOWNLOAD_FOUND, 136 // Post a task that reports no downloads found. 137 ON_CREATE_DOWNLOAD_FINDER_NO_DOWNLOADS, 138 // Immediately return due to a lack of eligible profiles. 139 ON_CREATE_DOWNLOAD_FINDER_NO_PROFILES, 140 }; 141 142 // A type for specifying the action to be taken by the test fixture when its 143 // delayed analysis callback is run. 144 enum OnDelayedAnalysisAction { 145 ON_DELAYED_ANALYSIS_NO_ACTION, 146 ON_DELAYED_ANALYSIS_ADD_INCIDENT, // Add an incident to the service. 147 }; 148 149 static const int64 kIncidentTimeMsec; 150 static const char kFakeOsName[]; 151 static const char kFakeDownloadToken[]; 152 static const char kTestTrackedPrefPath[]; 153 154 IncidentReportingServiceTest() 155 : task_runner_(new base::TestSimpleTaskRunner), 156 thread_task_runner_handle_(task_runner_), 157 profile_manager_(TestingBrowserProcess::GetGlobal()), 158 instance_(new TestIncidentReportingService( 159 task_runner_, 160 base::Bind(&IncidentReportingServiceTest::PreProfileAdd, 161 base::Unretained(this)), 162 base::Bind(&IncidentReportingServiceTest::CollectEnvironmentData, 163 base::Unretained(this)), 164 base::Bind(&IncidentReportingServiceTest::CreateDownloadFinder, 165 base::Unretained(this)), 166 base::Bind(&IncidentReportingServiceTest::StartUpload, 167 base::Unretained(this)))), 168 on_create_download_finder_action_( 169 ON_CREATE_DOWNLOAD_FINDER_DOWNLOAD_FOUND), 170 on_delayed_analysis_action_(ON_DELAYED_ANALYSIS_NO_ACTION), 171 upload_result_(safe_browsing::IncidentReportUploader::UPLOAD_SUCCESS), 172 environment_collected_(), 173 download_finder_created_(), 174 download_finder_destroyed_(), 175 uploader_destroyed_(), 176 delayed_analysis_ran_() {} 177 178 virtual void SetUp() OVERRIDE { 179 testing::Test::SetUp(); 180 ASSERT_TRUE(profile_manager_.SetUp()); 181 } 182 183 // Sets the action to be taken by the test fixture when the service creates a 184 // LastDownloadFinder. 185 void SetCreateDownloadFinderAction(OnCreateDownloadFinderAction action) { 186 on_create_download_finder_action_ = action; 187 } 188 189 // Creates and returns a profile (owned by the profile manager) with or 190 // without safe browsing enabled. An incident will be created within 191 // PreProfileAdd if requested. 192 TestingProfile* CreateProfile(const std::string& profile_name, 193 SafeBrowsingDisposition safe_browsing_opt_in, 194 OnProfileAdditionAction on_addition_action) { 195 // Create prefs for the profile with safe browsing enabled or not. 196 scoped_ptr<TestingPrefServiceSyncable> prefs( 197 new TestingPrefServiceSyncable); 198 chrome::RegisterUserProfilePrefs(prefs->registry()); 199 prefs->SetBoolean(prefs::kSafeBrowsingEnabled, 200 safe_browsing_opt_in == SAFE_BROWSING_OPT_IN); 201 202 // Remember whether or not to create an incident. 203 profile_properties_[profile_name].on_addition_action = on_addition_action; 204 205 // Boom (or fizzle). 206 return profile_manager_.CreateTestingProfile( 207 profile_name, 208 prefs.PassAs<PrefServiceSyncable>(), 209 base::ASCIIToUTF16(profile_name), 210 0, // avatar_id (unused) 211 std::string(), // supervised_user_id (unused) 212 TestingProfile::TestingFactories()); 213 } 214 215 // Configures a callback to run when the next upload is started that will post 216 // a task to delete the profile. This task will run before the upload 217 // finishes. 218 void DeleteProfileOnUpload(Profile* profile) { 219 ASSERT_TRUE(on_start_upload_callback_.is_null()); 220 on_start_upload_callback_ = 221 base::Bind(&IncidentReportingServiceTest::DelayedDeleteProfile, 222 base::Unretained(this), 223 profile); 224 } 225 226 // Returns an incident suitable for testing. 227 scoped_ptr<safe_browsing::ClientIncidentReport_IncidentData> 228 MakeTestIncident() { 229 scoped_ptr<safe_browsing::ClientIncidentReport_IncidentData> incident( 230 new safe_browsing::ClientIncidentReport_IncidentData()); 231 incident->set_incident_time_msec(kIncidentTimeMsec); 232 safe_browsing::ClientIncidentReport_IncidentData_TrackedPreferenceIncident* 233 tp_incident = incident->mutable_tracked_preference(); 234 tp_incident->set_path(kTestTrackedPrefPath); 235 return incident.Pass(); 236 } 237 238 // Adds a test incident to the service. 239 void AddTestIncident(Profile* profile) { 240 instance_->GetAddIncidentCallback(profile).Run(MakeTestIncident().Pass()); 241 } 242 243 // Registers the callback to be run for delayed analysis. 244 void RegisterAnalysis(OnDelayedAnalysisAction on_delayed_analysis_action) { 245 on_delayed_analysis_action_ = on_delayed_analysis_action; 246 instance_->RegisterDelayedAnalysisCallback( 247 base::Bind(&IncidentReportingServiceTest::OnDelayedAnalysis, 248 base::Unretained(this))); 249 } 250 251 // Confirms that the test incident(s) was/were uploaded by the service, then 252 // clears the instance for subsequent incidents. 253 void ExpectTestIncidentUploaded(int incident_count) { 254 ASSERT_TRUE(uploaded_report_); 255 ASSERT_EQ(incident_count, uploaded_report_->incident_size()); 256 for (int i = 0; i < incident_count; ++i) { 257 ASSERT_TRUE(uploaded_report_->incident(i).has_incident_time_msec()); 258 ASSERT_EQ(kIncidentTimeMsec, 259 uploaded_report_->incident(i).incident_time_msec()); 260 ASSERT_TRUE(uploaded_report_->incident(i).has_tracked_preference()); 261 ASSERT_TRUE( 262 uploaded_report_->incident(i).tracked_preference().has_path()); 263 ASSERT_EQ(std::string(kTestTrackedPrefPath), 264 uploaded_report_->incident(i).tracked_preference().path()); 265 } 266 ASSERT_TRUE(uploaded_report_->has_environment()); 267 ASSERT_TRUE(uploaded_report_->environment().has_os()); 268 ASSERT_TRUE(uploaded_report_->environment().os().has_os_name()); 269 ASSERT_EQ(std::string(kFakeOsName), 270 uploaded_report_->environment().os().os_name()); 271 ASSERT_EQ(std::string(kFakeDownloadToken), 272 uploaded_report_->download().token()); 273 274 uploaded_report_.reset(); 275 } 276 277 void AssertNoUpload() { ASSERT_FALSE(uploaded_report_); } 278 279 bool HasCollectedEnvironmentData() const { return environment_collected_; } 280 bool HasCreatedDownloadFinder() const { return download_finder_created_; } 281 bool DownloadFinderDestroyed() const { return download_finder_destroyed_; } 282 bool UploaderDestroyed() const { return uploader_destroyed_; } 283 bool DelayedAnalysisRan() const { return delayed_analysis_ran_; } 284 285 scoped_refptr<base::TestSimpleTaskRunner> task_runner_; 286 base::ThreadTaskRunnerHandle thread_task_runner_handle_; 287 TestingProfileManager profile_manager_; 288 scoped_ptr<TestIncidentReportingService> instance_; 289 base::Closure on_start_upload_callback_; 290 OnCreateDownloadFinderAction on_create_download_finder_action_; 291 OnDelayedAnalysisAction on_delayed_analysis_action_; 292 safe_browsing::IncidentReportUploader::Result upload_result_; 293 bool environment_collected_; 294 bool download_finder_created_; 295 scoped_ptr<safe_browsing::ClientIncidentReport> uploaded_report_; 296 bool download_finder_destroyed_; 297 bool uploader_destroyed_; 298 bool delayed_analysis_ran_; 299 300 private: 301 // A fake IncidentReportUploader that posts a task to provide a given response 302 // back to the incident reporting service. It also reports back to the test 303 // harness via a closure when it is deleted by the incident reporting service. 304 class FakeUploader : public safe_browsing::IncidentReportUploader { 305 public: 306 FakeUploader( 307 const base::Closure& on_deleted, 308 const safe_browsing::IncidentReportUploader::OnResultCallback& callback, 309 safe_browsing::IncidentReportUploader::Result result) 310 : safe_browsing::IncidentReportUploader(callback), 311 on_deleted_(on_deleted), 312 result_(result) { 313 // Post a task that will provide the response. 314 base::ThreadTaskRunnerHandle::Get()->PostTask( 315 FROM_HERE, 316 base::Bind(&FakeUploader::FinishUpload, base::Unretained(this))); 317 } 318 virtual ~FakeUploader() { on_deleted_.Run(); } 319 320 private: 321 void FinishUpload() { 322 // Callbacks have a tendency to delete the uploader, so no touching 323 // anything after this. 324 callback_.Run(result_, 325 scoped_ptr<safe_browsing::ClientIncidentResponse>()); 326 } 327 328 base::Closure on_deleted_; 329 safe_browsing::IncidentReportUploader::Result result_; 330 331 DISALLOW_COPY_AND_ASSIGN(FakeUploader); 332 }; 333 334 class FakeDownloadFinder : public safe_browsing::LastDownloadFinder { 335 public: 336 static scoped_ptr<safe_browsing::LastDownloadFinder> Create( 337 const base::Closure& on_deleted, 338 scoped_ptr<safe_browsing::ClientIncidentReport_DownloadDetails> 339 download, 340 const safe_browsing::LastDownloadFinder::LastDownloadCallback& 341 callback) { 342 // Post a task to run the callback. 343 base::ThreadTaskRunnerHandle::Get()->PostTask( 344 FROM_HERE, base::Bind(callback, base::Passed(&download))); 345 return scoped_ptr<safe_browsing::LastDownloadFinder>( 346 new FakeDownloadFinder(on_deleted)); 347 } 348 349 virtual ~FakeDownloadFinder() { on_deleted_.Run(); } 350 351 private: 352 explicit FakeDownloadFinder(const base::Closure& on_deleted) 353 : on_deleted_(on_deleted) {} 354 355 base::Closure on_deleted_; 356 357 DISALLOW_COPY_AND_ASSIGN(FakeDownloadFinder); 358 }; 359 360 // Properties for a profile that impact the behavior of the test. 361 struct ProfileProperties { 362 ProfileProperties() : on_addition_action(ON_PROFILE_ADDITION_NO_ACTION) {} 363 364 // The action taken by the test fixture during profile initialization 365 // (before NOTIFICATION_PROFILE_ADDED is sent). 366 OnProfileAdditionAction on_addition_action; 367 }; 368 369 // Posts a task to delete the profile. 370 void DelayedDeleteProfile(Profile* profile) { 371 base::ThreadTaskRunnerHandle::Get()->PostTask( 372 FROM_HERE, 373 base::Bind(&TestingProfileManager::DeleteTestingProfile, 374 base::Unretained(&profile_manager_), 375 profile->GetProfileName())); 376 } 377 378 // A callback run by the test fixture when a profile is added. An incident 379 // is added. 380 void PreProfileAdd(Profile* profile) { 381 // The instance must have already been created. 382 ASSERT_TRUE(instance_); 383 // Add a test incident to the service if requested. 384 switch (profile_properties_[profile->GetProfileName()].on_addition_action) { 385 case ON_PROFILE_ADDITION_ADD_INCIDENT: 386 AddTestIncident(profile); 387 break; 388 case ON_PROFILE_ADDITION_ADD_TWO_INCIDENTS: 389 AddTestIncident(profile); 390 AddTestIncident(profile); 391 break; 392 default: 393 ASSERT_EQ( 394 ON_PROFILE_ADDITION_NO_ACTION, 395 profile_properties_[profile->GetProfileName()].on_addition_action); 396 break; 397 } 398 } 399 400 // A fake CollectEnvironmentData implementation invoked by the service during 401 // operation. 402 void CollectEnvironmentData( 403 safe_browsing::ClientIncidentReport_EnvironmentData* data) { 404 ASSERT_NE( 405 static_cast<safe_browsing::ClientIncidentReport_EnvironmentData*>(NULL), 406 data); 407 data->mutable_os()->set_os_name(kFakeOsName); 408 environment_collected_ = true; 409 } 410 411 // A fake CreateDownloadFinder implementation invoked by the service during 412 // operation. 413 scoped_ptr<safe_browsing::LastDownloadFinder> CreateDownloadFinder( 414 const safe_browsing::LastDownloadFinder::LastDownloadCallback& callback) { 415 download_finder_created_ = true; 416 scoped_ptr<safe_browsing::ClientIncidentReport_DownloadDetails> download; 417 if (on_create_download_finder_action_ == 418 ON_CREATE_DOWNLOAD_FINDER_NO_PROFILES) { 419 return scoped_ptr<safe_browsing::LastDownloadFinder>(); 420 } 421 if (on_create_download_finder_action_ == 422 ON_CREATE_DOWNLOAD_FINDER_DOWNLOAD_FOUND) { 423 download.reset(new safe_browsing::ClientIncidentReport_DownloadDetails); 424 download->set_token(kFakeDownloadToken); 425 } 426 return scoped_ptr<safe_browsing::LastDownloadFinder>( 427 FakeDownloadFinder::Create( 428 base::Bind(&IncidentReportingServiceTest::OnDownloadFinderDestroyed, 429 base::Unretained(this)), 430 download.Pass(), 431 callback)); 432 } 433 434 // A fake StartUpload implementation invoked by the service during operation. 435 scoped_ptr<safe_browsing::IncidentReportUploader> StartUpload( 436 const safe_browsing::IncidentReportUploader::OnResultCallback& callback, 437 const safe_browsing::ClientIncidentReport& report) { 438 // Remember the report that is being uploaded. 439 uploaded_report_.reset(new safe_browsing::ClientIncidentReport(report)); 440 // Run and clear the OnStartUpload callback, if provided. 441 if (!on_start_upload_callback_.is_null()) { 442 on_start_upload_callback_.Run(); 443 on_start_upload_callback_ = base::Closure(); 444 } 445 return scoped_ptr<safe_browsing::IncidentReportUploader>( 446 new FakeUploader( 447 base::Bind( 448 &IncidentReportingServiceTest::OnUploaderDestroyed, 449 base::Unretained(this)), 450 callback, 451 upload_result_)).Pass(); 452 } 453 454 void OnDownloadFinderDestroyed() { download_finder_destroyed_ = true; } 455 void OnUploaderDestroyed() { uploader_destroyed_ = true; } 456 457 void OnDelayedAnalysis(const safe_browsing::AddIncidentCallback& callback) { 458 delayed_analysis_ran_ = true; 459 if (on_delayed_analysis_action_ == ON_DELAYED_ANALYSIS_ADD_INCIDENT) 460 callback.Run(MakeTestIncident().Pass()); 461 } 462 463 // A mapping of profile name to its corresponding properties. 464 std::map<std::string, ProfileProperties> profile_properties_; 465 }; 466 467 // static 468 base::LazyInstance<base::ThreadLocalPointer< 469 IncidentReportingServiceTest::TestIncidentReportingService> >::Leaky 470 IncidentReportingServiceTest::TestIncidentReportingService::test_instance_ = 471 LAZY_INSTANCE_INITIALIZER; 472 473 const int64 IncidentReportingServiceTest::kIncidentTimeMsec = 47LL; 474 const char IncidentReportingServiceTest::kFakeOsName[] = "fakedows"; 475 const char IncidentReportingServiceTest::kFakeDownloadToken[] = "fakedlt"; 476 const char IncidentReportingServiceTest::kTestTrackedPrefPath[] = "some_pref"; 477 478 // Tests that an incident added during profile initialization when safe browsing 479 // is on is uploaded. 480 TEST_F(IncidentReportingServiceTest, AddIncident) { 481 CreateProfile( 482 "profile1", SAFE_BROWSING_OPT_IN, ON_PROFILE_ADDITION_ADD_INCIDENT); 483 484 // Let all tasks run. 485 task_runner_->RunUntilIdle(); 486 487 // Verify that environment collection took place. 488 EXPECT_TRUE(HasCollectedEnvironmentData()); 489 490 // Verify that the most recent download was looked for. 491 EXPECT_TRUE(HasCreatedDownloadFinder()); 492 493 // Verify that report upload took place and contained the incident, 494 // environment data, and download details. 495 ExpectTestIncidentUploaded(1); 496 497 // Verify that the download finder and the uploader were destroyed. 498 ASSERT_TRUE(DownloadFinderDestroyed()); 499 ASSERT_TRUE(UploaderDestroyed()); 500 501 // Ensure that no report processing remains. 502 ASSERT_FALSE(instance_->IsProcessingReport()); 503 } 504 505 // Tests that multiple incidents are coalesced into the same report. 506 TEST_F(IncidentReportingServiceTest, CoalesceIncidents) { 507 CreateProfile( 508 "profile1", SAFE_BROWSING_OPT_IN, ON_PROFILE_ADDITION_ADD_TWO_INCIDENTS); 509 510 // Let all tasks run. 511 task_runner_->RunUntilIdle(); 512 513 // Verify that environment collection took place. 514 EXPECT_TRUE(HasCollectedEnvironmentData()); 515 516 // Verify that the most recent download was looked for. 517 EXPECT_TRUE(HasCreatedDownloadFinder()); 518 519 // Verify that report upload took place and contained the incident, 520 // environment data, and download details. 521 ExpectTestIncidentUploaded(2); 522 523 // Verify that the download finder and the uploader were destroyed. 524 ASSERT_TRUE(DownloadFinderDestroyed()); 525 ASSERT_TRUE(UploaderDestroyed()); 526 527 // Ensure that no report processing remains. 528 ASSERT_FALSE(instance_->IsProcessingReport()); 529 } 530 531 // Tests that an incident added during profile initialization when safe browsing 532 // is off is not uploaded. 533 TEST_F(IncidentReportingServiceTest, NoSafeBrowsing) { 534 // Create the profile, thereby causing the test to begin. 535 CreateProfile( 536 "profile1", SAFE_BROWSING_OPT_OUT, ON_PROFILE_ADDITION_ADD_INCIDENT); 537 538 // Let all tasks run. 539 task_runner_->RunUntilIdle(); 540 541 // Verify that no report upload took place. 542 AssertNoUpload(); 543 544 // Ensure that no report processing remains. 545 ASSERT_FALSE(instance_->IsProcessingReport()); 546 } 547 548 // Tests that no incident report is uploaded if there is no recent download. 549 TEST_F(IncidentReportingServiceTest, NoDownloadNoUpload) { 550 // Tell the fixture to return no downloads found. 551 SetCreateDownloadFinderAction(ON_CREATE_DOWNLOAD_FINDER_NO_DOWNLOADS); 552 553 // Create the profile, thereby causing the test to begin. 554 CreateProfile( 555 "profile1", SAFE_BROWSING_OPT_IN, ON_PROFILE_ADDITION_ADD_INCIDENT); 556 557 // Let all tasks run. 558 task_runner_->RunUntilIdle(); 559 560 // Verify that the download finder was run but that no report upload took 561 // place. 562 EXPECT_TRUE(HasCreatedDownloadFinder()); 563 AssertNoUpload(); 564 EXPECT_TRUE(DownloadFinderDestroyed()); 565 566 // Ensure that no report processing remains. 567 ASSERT_FALSE(instance_->IsProcessingReport()); 568 } 569 570 // Tests that no incident report is uploaded if there is no recent download. 571 TEST_F(IncidentReportingServiceTest, NoProfilesNoUpload) { 572 // Tell the fixture to pretend there are no profiles eligible for finding 573 // downloads. 574 SetCreateDownloadFinderAction(ON_CREATE_DOWNLOAD_FINDER_NO_PROFILES); 575 576 // Create the profile, thereby causing the test to begin. 577 CreateProfile( 578 "profile1", SAFE_BROWSING_OPT_IN, ON_PROFILE_ADDITION_ADD_INCIDENT); 579 580 // Let all tasks run. 581 task_runner_->RunUntilIdle(); 582 583 // Verify that the download finder was run but that no report upload took 584 // place. 585 EXPECT_TRUE(HasCreatedDownloadFinder()); 586 AssertNoUpload(); 587 // Although CreateDownloadFinder was called, no instance was returned so there 588 // is nothing to have been destroyed. 589 EXPECT_FALSE(DownloadFinderDestroyed()); 590 591 // Ensure that no report processing remains. 592 ASSERT_FALSE(instance_->IsProcessingReport()); 593 } 594 595 // Tests that an identical incident added after upload is not uploaded again. 596 TEST_F(IncidentReportingServiceTest, OneIncidentOneUpload) { 597 // Create the profile, thereby causing the test to begin. 598 Profile* profile = CreateProfile( 599 "profile1", SAFE_BROWSING_OPT_IN, ON_PROFILE_ADDITION_ADD_INCIDENT); 600 601 // Let all tasks run. 602 task_runner_->RunUntilIdle(); 603 604 // Verify that report upload took place and contained the incident and 605 // environment data. 606 ExpectTestIncidentUploaded(1); 607 608 // Add the incident to the service again. 609 AddTestIncident(profile); 610 611 // Let all tasks run. 612 task_runner_->RunUntilIdle(); 613 614 // Verify that no additional report upload took place. 615 AssertNoUpload(); 616 617 // Ensure that no report processing remains. 618 ASSERT_FALSE(instance_->IsProcessingReport()); 619 } 620 621 // Tests that two incidents of the same type with different payloads lead to two 622 // uploads. 623 TEST_F(IncidentReportingServiceTest, TwoIncidentsTwoUploads) { 624 // Create the profile, thereby causing the test to begin. 625 Profile* profile = CreateProfile( 626 "profile1", SAFE_BROWSING_OPT_IN, ON_PROFILE_ADDITION_ADD_INCIDENT); 627 628 // Let all tasks run. 629 task_runner_->RunUntilIdle(); 630 631 // Verify that report upload took place and contained the incident and 632 // environment data. 633 ExpectTestIncidentUploaded(1); 634 635 // Add a variation on the incident to the service. 636 scoped_ptr<safe_browsing::ClientIncidentReport_IncidentData> incident( 637 MakeTestIncident()); 638 incident->mutable_tracked_preference()->set_atomic_value("leeches"); 639 instance_->GetAddIncidentCallback(profile).Run(incident.Pass()); 640 641 // Let all tasks run. 642 task_runner_->RunUntilIdle(); 643 644 // Verify that an additional report upload took place. 645 ExpectTestIncidentUploaded(1); 646 647 // Ensure that no report processing remains. 648 ASSERT_FALSE(instance_->IsProcessingReport()); 649 } 650 651 // Tests that the same incident added for two different profiles in sequence 652 // results in two uploads. 653 TEST_F(IncidentReportingServiceTest, TwoProfilesTwoUploads) { 654 // Create the profile, thereby causing the test to begin. 655 CreateProfile( 656 "profile1", SAFE_BROWSING_OPT_IN, ON_PROFILE_ADDITION_ADD_INCIDENT); 657 658 // Let all tasks run. 659 task_runner_->RunUntilIdle(); 660 661 // Verify that report upload took place and contained the incident and 662 // environment data. 663 ExpectTestIncidentUploaded(1); 664 665 // Create a second profile with its own incident on addition. 666 CreateProfile( 667 "profile2", SAFE_BROWSING_OPT_IN, ON_PROFILE_ADDITION_ADD_INCIDENT); 668 669 // Let all tasks run. 670 task_runner_->RunUntilIdle(); 671 672 // Verify that a second report upload took place. 673 ExpectTestIncidentUploaded(1); 674 675 // Ensure that no report processing remains. 676 ASSERT_FALSE(instance_->IsProcessingReport()); 677 } 678 679 // Tests that an upload succeeds if the profile is destroyed while it is 680 // pending. 681 TEST_F(IncidentReportingServiceTest, ProfileDestroyedDuringUpload) { 682 // Create a profile for which an incident will be added. 683 Profile* profile = CreateProfile( 684 "profile1", SAFE_BROWSING_OPT_IN, ON_PROFILE_ADDITION_ADD_INCIDENT); 685 686 // Hook up a callback to run when the upload is started that will post a task 687 // to delete the profile. This task will run before the upload finishes. 688 DeleteProfileOnUpload(profile); 689 690 // Let all tasks run. 691 task_runner_->RunUntilIdle(); 692 693 // Verify that report upload took place and contained the incident and 694 // environment data. 695 ExpectTestIncidentUploaded(1); 696 697 // Ensure that no report processing remains. 698 ASSERT_FALSE(instance_->IsProcessingReport()); 699 700 // The lack of a crash indicates that the deleted profile was not accessed by 701 // the service while handling the upload response. 702 } 703 704 // Tests that no upload takes place if the old pref was present. 705 TEST_F(IncidentReportingServiceTest, MigrateOldPref) { 706 Profile* profile = CreateProfile( 707 "profile1", SAFE_BROWSING_OPT_IN, ON_PROFILE_ADDITION_NO_ACTION); 708 709 // This is a legacy profile. 710 profile->GetPrefs()->SetBoolean(prefs::kSafeBrowsingIncidentReportSent, true); 711 712 // Add the test incident. 713 AddTestIncident(profile); 714 715 // Let all tasks run. 716 task_runner_->RunUntilIdle(); 717 718 // No upload should have taken place. 719 AssertNoUpload(); 720 721 // The legacy pref should have been cleared. 722 ASSERT_FALSE( 723 profile->GetPrefs()->GetBoolean(prefs::kSafeBrowsingIncidentReportSent)); 724 725 // Adding the same incident again should still result in no upload. 726 AddTestIncident(profile); 727 728 // Let all tasks run. 729 task_runner_->RunUntilIdle(); 730 731 // No upload should have taken place. 732 AssertNoUpload(); 733 734 // Ensure that no report processing remains. 735 ASSERT_FALSE(instance_->IsProcessingReport()); 736 } 737 738 // Tests that no upload results from adding an incident that is not affiliated 739 // with a profile. 740 TEST_F(IncidentReportingServiceTest, ProcessWideNoProfileNoUpload) { 741 // Add the test incident. 742 AddTestIncident(NULL); 743 744 // Let all tasks run. 745 task_runner_->RunUntilIdle(); 746 747 // No upload should have taken place. 748 AssertNoUpload(); 749 750 // Ensure that no report processing remains. 751 ASSERT_FALSE(instance_->IsProcessingReport()); 752 } 753 754 // Tests that there is an upload when a profile is present for a proc-wide 755 // incident and that pruning works. 756 TEST_F(IncidentReportingServiceTest, ProcessWideOneUpload) { 757 // Add a profile that participates in safe browsing. 758 CreateProfile( 759 "profile1", SAFE_BROWSING_OPT_IN, ON_PROFILE_ADDITION_NO_ACTION); 760 761 // Add the test incident. 762 AddTestIncident(NULL); 763 764 // Let all tasks run. 765 task_runner_->RunUntilIdle(); 766 767 // An upload should have taken place. 768 ExpectTestIncidentUploaded(1); 769 770 // Add the incident to the service again. 771 AddTestIncident(NULL); 772 773 // Let all tasks run. 774 task_runner_->RunUntilIdle(); 775 776 // Verify that no additional report upload took place. 777 AssertNoUpload(); 778 779 // Ensure that no report processing remains. 780 ASSERT_FALSE(instance_->IsProcessingReport()); 781 } 782 783 // Tests that two process-wide incidents of the same type with different 784 // payloads added via the same callback lead to two uploads. 785 TEST_F(IncidentReportingServiceTest, ProcessWideTwoUploads) { 786 // Add a profile that participates in safe browsing. 787 CreateProfile( 788 "profile1", SAFE_BROWSING_OPT_IN, ON_PROFILE_ADDITION_NO_ACTION); 789 790 // Add the test incident. 791 safe_browsing::AddIncidentCallback add_incident( 792 instance_->GetAddIncidentCallback(NULL)); 793 add_incident.Run(MakeTestIncident().Pass()); 794 795 // Let all tasks run. 796 task_runner_->RunUntilIdle(); 797 798 // An upload should have taken place. 799 ExpectTestIncidentUploaded(1); 800 801 // Add a variation on the incident to the service. 802 scoped_ptr<safe_browsing::ClientIncidentReport_IncidentData> incident( 803 MakeTestIncident()); 804 incident->mutable_tracked_preference()->set_atomic_value("leeches"); 805 add_incident.Run(incident.Pass()); 806 807 // Let all tasks run. 808 task_runner_->RunUntilIdle(); 809 810 // Verify that an additional report upload took place. 811 ExpectTestIncidentUploaded(1); 812 813 // Ensure that no report processing remains. 814 ASSERT_FALSE(instance_->IsProcessingReport()); 815 } 816 817 // Tests that there is an upload when a profile appears after a proc-wide 818 // incident. 819 TEST_F(IncidentReportingServiceTest, ProcessWideOneUploadAfterProfile) { 820 // Add the test incident. 821 AddTestIncident(NULL); 822 823 // Let all tasks run. 824 task_runner_->RunUntilIdle(); 825 826 // Verify that no report upload took place. 827 AssertNoUpload(); 828 829 // Add a profile that participates in safe browsing. 830 CreateProfile( 831 "profile1", SAFE_BROWSING_OPT_IN, ON_PROFILE_ADDITION_NO_ACTION); 832 833 // Let all tasks run. 834 task_runner_->RunUntilIdle(); 835 836 // An upload should have taken place. 837 ExpectTestIncidentUploaded(1); 838 839 // Ensure that no report processing remains. 840 ASSERT_FALSE(instance_->IsProcessingReport()); 841 } 842 843 TEST_F(IncidentReportingServiceTest, NoCollectionWithoutIncident) { 844 // Register a callback. 845 RegisterAnalysis(ON_DELAYED_ANALYSIS_NO_ACTION); 846 847 // Let all tasks run. 848 task_runner_->RunUntilIdle(); 849 850 // Confirm that the callback was not run. 851 ASSERT_FALSE(DelayedAnalysisRan()); 852 853 // No collection should have taken place. 854 ASSERT_FALSE(HasCollectedEnvironmentData()); 855 856 // Add a profile that participates in safe browsing. 857 CreateProfile( 858 "profile1", SAFE_BROWSING_OPT_IN, ON_PROFILE_ADDITION_NO_ACTION); 859 860 // Let all tasks run. 861 task_runner_->RunUntilIdle(); 862 863 // Confirm that the callback was run. 864 ASSERT_TRUE(DelayedAnalysisRan()); 865 866 // Still no collection should have taken place. 867 ASSERT_FALSE(HasCollectedEnvironmentData()); 868 869 // Ensure that no report processing remains. 870 ASSERT_FALSE(instance_->IsProcessingReport()); 871 } 872 873 // Tests that delayed analysis callbacks are called following the addition of a 874 // profile that participates in safe browsing. 875 TEST_F(IncidentReportingServiceTest, AnalysisAfterProfile) { 876 // Register a callback. 877 RegisterAnalysis(ON_DELAYED_ANALYSIS_NO_ACTION); 878 879 // Let all tasks run. 880 task_runner_->RunUntilIdle(); 881 882 // Not run yet. 883 ASSERT_FALSE(DelayedAnalysisRan()); 884 885 // Add a profile that participates in safe browsing. 886 CreateProfile( 887 "profile1", SAFE_BROWSING_OPT_IN, ON_PROFILE_ADDITION_NO_ACTION); 888 889 // Let all tasks run. 890 task_runner_->RunUntilIdle(); 891 892 // And now they have. 893 ASSERT_TRUE(DelayedAnalysisRan()); 894 895 // Ensure that no report processing remains. 896 ASSERT_FALSE(instance_->IsProcessingReport()); 897 } 898 899 // Tests that delayed analysis callbacks are called following their registration 900 // when a profile that participates in safe browsing is already present. 901 TEST_F(IncidentReportingServiceTest, AnalysisWhenRegisteredWithProfile) { 902 // Add a profile that participates in safe browsing. 903 CreateProfile( 904 "profile1", SAFE_BROWSING_OPT_IN, ON_PROFILE_ADDITION_NO_ACTION); 905 906 // Register a callback. 907 RegisterAnalysis(ON_DELAYED_ANALYSIS_NO_ACTION); 908 909 // Let all tasks run. 910 task_runner_->RunUntilIdle(); 911 912 // Confirm that the callbacks were run. 913 ASSERT_TRUE(DelayedAnalysisRan()); 914 915 // Ensure that no report processing remains. 916 ASSERT_FALSE(instance_->IsProcessingReport()); 917 } 918 919 // Tests that no upload results from a delayed analysis incident when no 920 // safe browsing profile is present. 921 TEST_F(IncidentReportingServiceTest, DelayedAnalysisNoProfileNoUpload) { 922 // Register a callback that will add an incident. 923 RegisterAnalysis(ON_DELAYED_ANALYSIS_ADD_INCIDENT); 924 925 // Add a profile that does not participate in safe browsing. 926 CreateProfile( 927 "profile1", SAFE_BROWSING_OPT_OUT, ON_PROFILE_ADDITION_NO_ACTION); 928 929 // Let all tasks run. 930 task_runner_->RunUntilIdle(); 931 932 // The callback should not have been run. 933 ASSERT_FALSE(DelayedAnalysisRan()); 934 935 // No upload should have taken place. 936 AssertNoUpload(); 937 938 // Ensure that no report processing remains. 939 ASSERT_FALSE(instance_->IsProcessingReport()); 940 } 941 942 // Tests that there is an upload when a profile is present for a delayed 943 // analysis incident and that pruning works. 944 TEST_F(IncidentReportingServiceTest, DelayedAnalysisOneUpload) { 945 // Register a callback that will add an incident. 946 RegisterAnalysis(ON_DELAYED_ANALYSIS_ADD_INCIDENT); 947 948 // Add a profile that participates in safe browsing. 949 CreateProfile( 950 "profile1", SAFE_BROWSING_OPT_IN, ON_PROFILE_ADDITION_NO_ACTION); 951 952 // Let all tasks run. 953 task_runner_->RunUntilIdle(); 954 955 // The callback should have been run. 956 ASSERT_TRUE(DelayedAnalysisRan()); 957 958 // An upload should have taken place. 959 ExpectTestIncidentUploaded(1); 960 961 // Add the incident to the service again. 962 AddTestIncident(NULL); 963 964 // Let all tasks run. 965 task_runner_->RunUntilIdle(); 966 967 // Verify that no additional report upload took place. 968 AssertNoUpload(); 969 970 // Ensure that no report processing remains. 971 ASSERT_FALSE(instance_->IsProcessingReport()); 972 } 973 974 // Tests that the service stops processing when no download is found. 975 TEST_F(IncidentReportingServiceTest, NoDownloadNoWaiting) { 976 // Tell the fixture to return no downloads found. 977 SetCreateDownloadFinderAction(ON_CREATE_DOWNLOAD_FINDER_NO_DOWNLOADS); 978 979 // Register a callback. 980 RegisterAnalysis(ON_DELAYED_ANALYSIS_NO_ACTION); 981 982 // Add a profile that participates in safe browsing. 983 Profile* profile = CreateProfile( 984 "profile1", SAFE_BROWSING_OPT_IN, ON_PROFILE_ADDITION_NO_ACTION); 985 986 // Add an incident. 987 AddTestIncident(profile); 988 989 // Let all tasks run. 990 task_runner_->RunUntilIdle(); 991 992 // Verify that the download finder was run but that no report upload took 993 // place. 994 EXPECT_TRUE(HasCreatedDownloadFinder()); 995 AssertNoUpload(); 996 EXPECT_TRUE(DownloadFinderDestroyed()); 997 998 // Ensure that the report is dropped. 999 ASSERT_FALSE(instance_->IsProcessingReport()); 1000 } 1001 1002 // Parallel uploads 1003 // Shutdown during processing 1004 // environment colection taking longer than incident delay timer 1005 // environment colection taking longer than incident delay timer, and then 1006 // another incident arriving 1007