Home | History | Annotate | Download | only in incident_reporting
      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