| Index: chrome/browser/safe_browsing/incident_reporting_service_unittest.cc
|
| diff --git a/chrome/browser/safe_browsing/incident_reporting_service_unittest.cc b/chrome/browser/safe_browsing/incident_reporting_service_unittest.cc
|
| index 40dd948937885663ff6a2bc2cbb7ecc27fd57340..1496486e105ffb1c0758a1f37714647dc3678202 100644
|
| --- a/chrome/browser/safe_browsing/incident_reporting_service_unittest.cc
|
| +++ b/chrome/browser/safe_browsing/incident_reporting_service_unittest.cc
|
| @@ -4,11 +4,13 @@
|
|
|
| #include "chrome/browser/safe_browsing/incident_reporting_service.h"
|
|
|
| +#include <map>
|
| #include <string>
|
|
|
| #include "base/bind.h"
|
| #include "base/callback.h"
|
| #include "base/lazy_instance.h"
|
| +#include "base/strings/utf_string_conversions.h"
|
| #include "base/test/test_simple_task_runner.h"
|
| #include "base/thread_task_runner_handle.h"
|
| #include "base/threading/thread_local.h"
|
| @@ -16,10 +18,10 @@
|
| #include "chrome/browser/safe_browsing/incident_report_uploader.h"
|
| #include "chrome/common/pref_names.h"
|
| #include "chrome/common/safe_browsing/csd.pb.h"
|
| -#include "chrome/test/base/scoped_testing_local_state.h"
|
| #include "chrome/test/base/testing_browser_process.h"
|
| #include "chrome/test/base/testing_pref_service_syncable.h"
|
| #include "chrome/test/base/testing_profile.h"
|
| +#include "chrome/test/base/testing_profile_manager.h"
|
| #include "net/url_request/url_request_context_getter.h"
|
| #include "testing/gtest/include/gtest/gtest.h"
|
|
|
| @@ -90,13 +92,27 @@ class IncidentReportingServiceTest : public testing::Test {
|
| StartUploadCallback start_upload_callback_;
|
| };
|
|
|
| + // A type for specifying whether or not a profile created by CreateProfile
|
| + // participates in safe browsing.
|
| + enum SafeBrowsingDisposition {
|
| + SAFE_BROWSING_OPT_OUT,
|
| + SAFE_BROWSING_OPT_IN,
|
| + };
|
| +
|
| + // A type for specifying the action to be taken by the test fixture during
|
| + // profile initialization (before NOTIFICATION_PROFILE_CREATED is sent).
|
| + enum OnProfileCreationAction {
|
| + ON_PROFILE_CREATION_NO_ACTION,
|
| + ON_PROFILE_CREATION_ADD_INCIDENT, // Add an incident to the service.
|
| + };
|
| +
|
| static const int64 kIncidentTimeMsec;
|
| static const char kFakeOsName[];
|
|
|
| IncidentReportingServiceTest()
|
| : task_runner_(new base::TestSimpleTaskRunner),
|
| thread_task_runner_handle_(task_runner_),
|
| - local_state_(TestingBrowserProcess::GetGlobal()),
|
| + profile_manager_(TestingBrowserProcess::GetGlobal()),
|
| instance_(new TestIncidentReportingService(
|
| task_runner_,
|
| base::Bind(&IncidentReportingServiceTest::PreProfileCreate,
|
| @@ -109,23 +125,46 @@ class IncidentReportingServiceTest : public testing::Test {
|
| environment_collected_(),
|
| uploader_destroyed_() {}
|
|
|
| - // Begins the test by creating a profile. An incident will be created within
|
| - // PreProfileCreate. Tasks are run to allow the service to operate to
|
| - // completion.
|
| - void CreateProfileAndRunTest(bool safe_browsing_enabled) {
|
| + virtual void SetUp() OVERRIDE {
|
| + testing::Test::SetUp();
|
| + ASSERT_TRUE(profile_manager_.SetUp());
|
| + }
|
| +
|
| + // Creates and returns a profile (owned by the profile manager) with or
|
| + // without safe browsing enabled. An incident will be created within
|
| + // PreProfileCreate if requested.
|
| + TestingProfile* CreateProfile(const std::string& profile_name,
|
| + SafeBrowsingDisposition safe_browsing_opt_in,
|
| + OnProfileCreationAction on_creation_action) {
|
| // Create prefs for the profile with safe browsing enabled or not.
|
| scoped_ptr<TestingPrefServiceSyncable> prefs(
|
| new TestingPrefServiceSyncable);
|
| chrome::RegisterUserProfilePrefs(prefs->registry());
|
| - prefs->SetBoolean(prefs::kSafeBrowsingEnabled, safe_browsing_enabled);
|
| -
|
| - // Build the test profile (PreProfileCreate will be called).
|
| - TestingProfile::Builder builder;
|
| - builder.SetPrefService(prefs.PassAs<PrefServiceSyncable>());
|
| - testing_profile_ = builder.Build().Pass();
|
| + prefs->SetBoolean(prefs::kSafeBrowsingEnabled,
|
| + safe_browsing_opt_in == SAFE_BROWSING_OPT_IN);
|
| +
|
| + // Remember whether or not to create an incident.
|
| + profile_properties_[profile_name].on_creation_action = on_creation_action;
|
| +
|
| + // Boom (or fizzle).
|
| + return profile_manager_.CreateTestingProfile(
|
| + profile_name,
|
| + prefs.PassAs<PrefServiceSyncable>(),
|
| + base::ASCIIToUTF16(profile_name),
|
| + 0, // avatar_id (unused)
|
| + std::string(), // supervised_user_id (unused)
|
| + TestingProfile::TestingFactories());
|
| + }
|
|
|
| - // Let all tasks run.
|
| - task_runner_->RunUntilIdle();
|
| + // Configures a callback to run when the next upload is started that will post
|
| + // a task to delete the profile. This task will run before the upload
|
| + // finishes.
|
| + void DeleteProfileOnUpload(Profile* profile) {
|
| + ASSERT_TRUE(on_start_upload_callback_.is_null());
|
| + on_start_upload_callback_ =
|
| + base::Bind(&IncidentReportingServiceTest::DelayedDeleteProfile,
|
| + base::Unretained(this),
|
| + profile);
|
| }
|
|
|
| // Returns an incident suitable for testing.
|
| @@ -138,7 +177,13 @@ class IncidentReportingServiceTest : public testing::Test {
|
| return incident.Pass();
|
| }
|
|
|
| - // Confirms that the test incident was uploaded by the service.
|
| + // Adds a test incident to the service.
|
| + void AddTestIncident(Profile* profile) {
|
| + instance_->GetAddIncidentCallback(profile).Run(MakeTestIncident().Pass());
|
| + }
|
| +
|
| + // Confirms that the test incident was uploaded by the service, then clears
|
| + // the instance for subsequent incidents.
|
| void ExpectTestIncidentUploaded() {
|
| ASSERT_TRUE(uploaded_report_);
|
| ASSERT_EQ(1, uploaded_report_->incident_size());
|
| @@ -150,6 +195,8 @@ class IncidentReportingServiceTest : public testing::Test {
|
| ASSERT_TRUE(uploaded_report_->environment().os().has_os_name());
|
| ASSERT_EQ(std::string(kFakeOsName),
|
| uploaded_report_->environment().os().os_name());
|
| +
|
| + uploaded_report_.reset();
|
| }
|
|
|
| void ExpectNoUpload() { ASSERT_FALSE(uploaded_report_); }
|
| @@ -159,13 +206,13 @@ class IncidentReportingServiceTest : public testing::Test {
|
|
|
| scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
|
| base::ThreadTaskRunnerHandle thread_task_runner_handle_;
|
| - ScopedTestingLocalState local_state_;
|
| + TestingProfileManager profile_manager_;
|
| scoped_ptr<safe_browsing::IncidentReportingService> instance_;
|
| + base::Closure on_start_upload_callback_;
|
| safe_browsing::IncidentReportUploader::Result upload_result_;
|
| bool environment_collected_;
|
| scoped_ptr<safe_browsing::ClientIncidentReport> uploaded_report_;
|
| bool uploader_destroyed_;
|
| - scoped_ptr<TestingProfile> testing_profile_;
|
|
|
| private:
|
| // A fake IncidentReportUploader that posts a task to provide a given response
|
| @@ -201,13 +248,48 @@ class IncidentReportingServiceTest : public testing::Test {
|
| DISALLOW_COPY_AND_ASSIGN(FakeUploader);
|
| };
|
|
|
| + // Properties for a profile that impact the behavior of the test.
|
| + struct ProfileProperties {
|
| + ProfileProperties() : on_creation_action(ON_PROFILE_CREATION_NO_ACTION) {}
|
| +
|
| + // The action taken by the test fixture during profile initialization
|
| + // (before NOTIFICATION_PROFILE_CREATED is sent).
|
| + OnProfileCreationAction on_creation_action;
|
| + };
|
| +
|
| + // Returns the name of a profile as provided to CreateProfile.
|
| + static std::string GetProfileName(Profile* profile) {
|
| + // Cannot reliably use profile->GetProfileName() since the test needs the
|
| + // name before the profile manager sets it (which happens after profile
|
| + // creation).
|
| + return profile->GetPath().BaseName().AsUTF8Unsafe();
|
| + }
|
| +
|
| + // Posts a task to delete the profile.
|
| + void DelayedDeleteProfile(Profile* profile) {
|
| + base::ThreadTaskRunnerHandle::Get()->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(&TestingProfileManager::DeleteTestingProfile,
|
| + base::Unretained(&profile_manager_),
|
| + GetProfileName(profile)));
|
| + }
|
| +
|
| // A callback run by the test fixture when a profile is created. An incident
|
| // is added.
|
| void PreProfileCreate(Profile* profile) {
|
| // The instance must have already been created.
|
| ASSERT_TRUE(instance_);
|
| - // Add a test incident to the service.
|
| - instance_->GetAddIncidentCallback(profile).Run(MakeTestIncident().Pass());
|
| + // Add a test incident to the service if requested.
|
| + switch (profile_properties_[GetProfileName(profile)].on_creation_action) {
|
| + case ON_PROFILE_CREATION_ADD_INCIDENT:
|
| + AddTestIncident(profile);
|
| + break;
|
| + default:
|
| + ASSERT_EQ(
|
| + ON_PROFILE_CREATION_NO_ACTION,
|
| + profile_properties_[GetProfileName(profile)].on_creation_action);
|
| + break;
|
| + }
|
| }
|
|
|
| // A fake CollectEnvironmentData implementation invoked by the service during
|
| @@ -227,6 +309,11 @@ class IncidentReportingServiceTest : public testing::Test {
|
| const safe_browsing::ClientIncidentReport& report) {
|
| // Remember the report that is being uploaded.
|
| uploaded_report_.reset(new safe_browsing::ClientIncidentReport(report));
|
| + // Run and clear the OnStartUpload callback, if provided.
|
| + if (!on_start_upload_callback_.is_null()) {
|
| + on_start_upload_callback_.Run();
|
| + on_start_upload_callback_ = base::Closure();
|
| + }
|
| return scoped_ptr<safe_browsing::IncidentReportUploader>(new FakeUploader(
|
| base::Bind(&IncidentReportingServiceTest::OnUploaderDestroyed,
|
| base::Unretained(this)),
|
| @@ -235,6 +322,9 @@ class IncidentReportingServiceTest : public testing::Test {
|
| }
|
|
|
| void OnUploaderDestroyed() { uploader_destroyed_ = true; }
|
| +
|
| + // A mapping of profile name to its corresponding properties.
|
| + std::map<std::string, ProfileProperties> profile_properties_;
|
| };
|
|
|
| // static
|
| @@ -243,15 +333,17 @@ base::LazyInstance<base::ThreadLocalPointer<
|
| IncidentReportingServiceTest::TestIncidentReportingService::test_instance_ =
|
| LAZY_INSTANCE_INITIALIZER;
|
|
|
| -// static
|
| const int64 IncidentReportingServiceTest::kIncidentTimeMsec = 47LL;
|
| const char IncidentReportingServiceTest::kFakeOsName[] = "fakedows";
|
|
|
| // Tests that an incident added during profile initialization when safe browsing
|
| // is on is uploaded.
|
| TEST_F(IncidentReportingServiceTest, AddIncident) {
|
| - // Create the profile, thereby causing the test to begin.
|
| - CreateProfileAndRunTest(true);
|
| + CreateProfile(
|
| + "profile1", SAFE_BROWSING_OPT_IN, ON_PROFILE_CREATION_ADD_INCIDENT);
|
| +
|
| + // Let all tasks run.
|
| + task_runner_->RunUntilIdle();
|
|
|
| // Verify that environment collection took place.
|
| EXPECT_TRUE(HasCollectedEnvironmentData());
|
| @@ -268,12 +360,86 @@ TEST_F(IncidentReportingServiceTest, AddIncident) {
|
| // is off is not uploaded.
|
| TEST_F(IncidentReportingServiceTest, NoSafeBrowsing) {
|
| // Create the profile, thereby causing the test to begin.
|
| - CreateProfileAndRunTest(false);
|
| + CreateProfile(
|
| + "profile1", SAFE_BROWSING_OPT_OUT, ON_PROFILE_CREATION_ADD_INCIDENT);
|
| +
|
| + // Let all tasks run.
|
| + task_runner_->RunUntilIdle();
|
|
|
| // Verify that no report upload took place.
|
| ExpectNoUpload();
|
| }
|
|
|
| +// Tests that an incident added after upload is not uploaded again.
|
| +TEST_F(IncidentReportingServiceTest, OnlyOneUpload) {
|
| + // Create the profile, thereby causing the test to begin.
|
| + Profile* profile = CreateProfile(
|
| + "profile1", SAFE_BROWSING_OPT_IN, ON_PROFILE_CREATION_ADD_INCIDENT);
|
| +
|
| + // Let all tasks run.
|
| + task_runner_->RunUntilIdle();
|
| +
|
| + // Verify that report upload took place and contained the incident and
|
| + // environment data.
|
| + ExpectTestIncidentUploaded();
|
| +
|
| + // Add the incident to the service again.
|
| + AddTestIncident(profile);
|
| +
|
| + // Let all tasks run.
|
| + task_runner_->RunUntilIdle();
|
| +
|
| + // Verify that no additional report upload took place.
|
| + ExpectNoUpload();
|
| +}
|
| +
|
| +// Tests that the same incident added for two different profiles in sequence
|
| +// results in two uploads.
|
| +TEST_F(IncidentReportingServiceTest, TwoProfilesTwoUploads) {
|
| + // Create the profile, thereby causing the test to begin.
|
| + CreateProfile(
|
| + "profile1", SAFE_BROWSING_OPT_IN, ON_PROFILE_CREATION_ADD_INCIDENT);
|
| +
|
| + // Let all tasks run.
|
| + task_runner_->RunUntilIdle();
|
| +
|
| + // Verify that report upload took place and contained the incident and
|
| + // environment data.
|
| + ExpectTestIncidentUploaded();
|
| +
|
| + // Create a second profile with its own incident on creation.
|
| + CreateProfile(
|
| + "profile2", SAFE_BROWSING_OPT_IN, ON_PROFILE_CREATION_ADD_INCIDENT);
|
| +
|
| + // Let all tasks run.
|
| + task_runner_->RunUntilIdle();
|
| +
|
| + // Verify that a second report upload took place.
|
| + ExpectTestIncidentUploaded();
|
| +}
|
| +
|
| +// Tests that an upload succeeds if the profile is destroyed while it is
|
| +// pending.
|
| +TEST_F(IncidentReportingServiceTest, ProfileDestroyedDuringUpload) {
|
| + // Create a profile for which an incident will be added.
|
| + Profile* profile = CreateProfile(
|
| + "profile1", SAFE_BROWSING_OPT_IN, ON_PROFILE_CREATION_ADD_INCIDENT);
|
| +
|
| + // Hook up a callback to run when the upload is started that will post a task
|
| + // to delete the profile. This task will run before the upload finishes.
|
| + DeleteProfileOnUpload(profile);
|
| +
|
| + // Let all tasks run.
|
| + task_runner_->RunUntilIdle();
|
| +
|
| + // Verify that report upload took place and contained the incident and
|
| + // environment data.
|
| + ExpectTestIncidentUploaded();
|
| +
|
| + // The lack of a crash indicates that the deleted profile was not accessed by
|
| + // the service while handling the upload response.
|
| +}
|
| +
|
| // Parallel uploads
|
| // Shutdown during processing
|
| // environment colection taking longer than incident delay timer
|
|
|