OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/safe_browsing/incident_reporting_service.h" | 5 #include "chrome/browser/safe_browsing/incident_reporting_service.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/callback.h" | 10 #include "base/callback.h" |
11 #include "base/lazy_instance.h" | 11 #include "base/lazy_instance.h" |
12 #include "base/test/test_simple_task_runner.h" | 12 #include "base/test/test_simple_task_runner.h" |
13 #include "base/thread_task_runner_handle.h" | 13 #include "base/thread_task_runner_handle.h" |
14 #include "base/threading/thread_local.h" | 14 #include "base/threading/thread_local.h" |
| 15 #include "chrome/browser/prefs/browser_prefs.h" |
15 #include "chrome/browser/safe_browsing/incident_report_uploader.h" | 16 #include "chrome/browser/safe_browsing/incident_report_uploader.h" |
| 17 #include "chrome/common/pref_names.h" |
16 #include "chrome/common/safe_browsing/csd.pb.h" | 18 #include "chrome/common/safe_browsing/csd.pb.h" |
| 19 #include "chrome/test/base/scoped_testing_local_state.h" |
| 20 #include "chrome/test/base/testing_browser_process.h" |
| 21 #include "chrome/test/base/testing_pref_service_syncable.h" |
| 22 #include "chrome/test/base/testing_profile.h" |
17 #include "net/url_request/url_request_context_getter.h" | 23 #include "net/url_request/url_request_context_getter.h" |
18 #include "testing/gtest/include/gtest/gtest.h" | 24 #include "testing/gtest/include/gtest/gtest.h" |
19 | 25 |
20 // A test fixture that sets up a test task runner and makes it the thread's | 26 // A test fixture that sets up a test task runner and makes it the thread's |
21 // runner. The fixture implements a fake envrionment data collector and a fake | 27 // runner. The fixture implements a fake envrionment data collector and a fake |
22 // report uploader. | 28 // report uploader. |
23 class IncidentReportingServiceTest : public testing::Test { | 29 class IncidentReportingServiceTest : public testing::Test { |
24 protected: | 30 protected: |
25 // An IRS class that allows a test harness to provide a fake environment | 31 // An IRS class that allows a test harness to provide a fake environment |
26 // collector and report uploader via callbacks. | 32 // collector and report uploader via callbacks. |
27 class TestIncidentReportingService | 33 class TestIncidentReportingService |
28 : public safe_browsing::IncidentReportingService { | 34 : public safe_browsing::IncidentReportingService { |
29 public: | 35 public: |
| 36 typedef base::Callback<void(Profile*)> PreProfileCreateCallback; |
| 37 |
30 typedef base::Callback< | 38 typedef base::Callback< |
31 void(safe_browsing::ClientIncidentReport_EnvironmentData*)> | 39 void(safe_browsing::ClientIncidentReport_EnvironmentData*)> |
32 CollectEnvironmentCallback; | 40 CollectEnvironmentCallback; |
33 | 41 |
34 typedef base::Callback<scoped_ptr<safe_browsing::IncidentReportUploader>( | 42 typedef base::Callback<scoped_ptr<safe_browsing::IncidentReportUploader>( |
35 const safe_browsing::IncidentReportUploader::OnResultCallback&, | 43 const safe_browsing::IncidentReportUploader::OnResultCallback&, |
36 const safe_browsing::ClientIncidentReport& report)> StartUploadCallback; | 44 const safe_browsing::ClientIncidentReport& report)> StartUploadCallback; |
37 | 45 |
38 TestIncidentReportingService( | 46 TestIncidentReportingService( |
39 const scoped_refptr<base::TaskRunner>& task_runner, | 47 const scoped_refptr<base::TaskRunner>& task_runner, |
| 48 const PreProfileCreateCallback& pre_profile_create_callback, |
40 const CollectEnvironmentCallback& collect_environment_callback, | 49 const CollectEnvironmentCallback& collect_environment_callback, |
41 const StartUploadCallback& start_upload_callback) | 50 const StartUploadCallback& start_upload_callback) |
42 : IncidentReportingService(NULL, NULL), | 51 : IncidentReportingService(NULL, NULL), |
| 52 pre_profile_create_callback_(pre_profile_create_callback), |
43 collect_environment_callback_(collect_environment_callback), | 53 collect_environment_callback_(collect_environment_callback), |
44 start_upload_callback_(start_upload_callback) { | 54 start_upload_callback_(start_upload_callback) { |
45 SetCollectEnvironmentHook(&CollectEnvironmentData, task_runner); | 55 SetCollectEnvironmentHook(&CollectEnvironmentData, task_runner); |
46 test_instance_.Get().Set(this); | 56 test_instance_.Get().Set(this); |
47 } | 57 } |
48 | 58 |
49 virtual ~TestIncidentReportingService() { test_instance_.Get().Set(NULL); } | 59 virtual ~TestIncidentReportingService() { test_instance_.Get().Set(NULL); } |
50 | 60 |
51 protected: | 61 protected: |
| 62 virtual void OnProfileCreated(Profile* profile) OVERRIDE { |
| 63 pre_profile_create_callback_.Run(profile); |
| 64 safe_browsing::IncidentReportingService::OnProfileCreated(profile); |
| 65 } |
| 66 |
52 virtual scoped_ptr<safe_browsing::IncidentReportUploader> StartReportUpload( | 67 virtual scoped_ptr<safe_browsing::IncidentReportUploader> StartReportUpload( |
53 const safe_browsing::IncidentReportUploader::OnResultCallback& callback, | 68 const safe_browsing::IncidentReportUploader::OnResultCallback& callback, |
54 const scoped_refptr<net::URLRequestContextGetter>& | 69 const scoped_refptr<net::URLRequestContextGetter>& |
55 request_context_getter, | 70 request_context_getter, |
56 const safe_browsing::ClientIncidentReport& report) OVERRIDE { | 71 const safe_browsing::ClientIncidentReport& report) OVERRIDE { |
57 return start_upload_callback_.Run(callback, report); | 72 return start_upload_callback_.Run(callback, report); |
58 } | 73 } |
59 | 74 |
60 private: | 75 private: |
61 static TestIncidentReportingService& current() { | 76 static TestIncidentReportingService& current() { |
62 return *test_instance_.Get().Get(); | 77 return *test_instance_.Get().Get(); |
63 } | 78 } |
64 | 79 |
65 static void CollectEnvironmentData( | 80 static void CollectEnvironmentData( |
66 safe_browsing::ClientIncidentReport_EnvironmentData* data) { | 81 safe_browsing::ClientIncidentReport_EnvironmentData* data) { |
67 current().collect_environment_callback_.Run(data); | 82 current().collect_environment_callback_.Run(data); |
68 }; | 83 }; |
69 | 84 |
70 static base::LazyInstance<base::ThreadLocalPointer< | 85 static base::LazyInstance<base::ThreadLocalPointer< |
71 TestIncidentReportingService> >::Leaky test_instance_; | 86 TestIncidentReportingService> >::Leaky test_instance_; |
72 | 87 |
| 88 PreProfileCreateCallback pre_profile_create_callback_; |
73 CollectEnvironmentCallback collect_environment_callback_; | 89 CollectEnvironmentCallback collect_environment_callback_; |
74 StartUploadCallback start_upload_callback_; | 90 StartUploadCallback start_upload_callback_; |
75 }; | 91 }; |
76 | 92 |
| 93 static const int64 kIncidentTimeMsec; |
77 static const char kFakeOsName[]; | 94 static const char kFakeOsName[]; |
78 | 95 |
79 IncidentReportingServiceTest() | 96 IncidentReportingServiceTest() |
80 : task_runner_(new base::TestSimpleTaskRunner), | 97 : task_runner_(new base::TestSimpleTaskRunner), |
81 thread_task_runner_handle_(task_runner_), | 98 thread_task_runner_handle_(task_runner_), |
| 99 local_state_(TestingBrowserProcess::GetGlobal()), |
82 instance_(new TestIncidentReportingService( | 100 instance_(new TestIncidentReportingService( |
83 task_runner_, | 101 task_runner_, |
| 102 base::Bind(&IncidentReportingServiceTest::PreProfileCreate, |
| 103 base::Unretained(this)), |
84 base::Bind(&IncidentReportingServiceTest::CollectEnvironmentData, | 104 base::Bind(&IncidentReportingServiceTest::CollectEnvironmentData, |
85 base::Unretained(this)), | 105 base::Unretained(this)), |
86 base::Bind(&IncidentReportingServiceTest::StartUpload, | 106 base::Bind(&IncidentReportingServiceTest::StartUpload, |
87 base::Unretained(this)))), | 107 base::Unretained(this)))), |
88 upload_result_(safe_browsing::IncidentReportUploader::UPLOAD_SUCCESS), | 108 upload_result_(safe_browsing::IncidentReportUploader::UPLOAD_SUCCESS), |
89 environment_collected_(), | 109 environment_collected_(), |
90 uploader_destroyed_() { | 110 uploader_destroyed_() {} |
91 instance_->SetEnabled(true); | 111 |
| 112 // Begins the test by creating a profile. An incident will be created within |
| 113 // PreProfileCreate. Tasks are run to allow the service to operate to |
| 114 // completion. |
| 115 void CreateProfileAndRunTest(bool safe_browsing_enabled) { |
| 116 // Create prefs for the profile with safe browsing enabled or not. |
| 117 scoped_ptr<TestingPrefServiceSyncable> prefs( |
| 118 new TestingPrefServiceSyncable); |
| 119 chrome::RegisterUserProfilePrefs(prefs->registry()); |
| 120 prefs->SetBoolean(prefs::kSafeBrowsingEnabled, safe_browsing_enabled); |
| 121 |
| 122 // Build the test profile (PreProfileCreate will be called). |
| 123 TestingProfile::Builder builder; |
| 124 builder.SetPrefService(prefs.PassAs<PrefServiceSyncable>()); |
| 125 testing_profile_ = builder.Build().Pass(); |
| 126 |
| 127 // Let all tasks run. |
| 128 task_runner_->RunUntilIdle(); |
92 } | 129 } |
93 | 130 |
| 131 // Returns an incident suitable for testing. |
| 132 scoped_ptr<safe_browsing::ClientIncidentReport_IncidentData> |
| 133 MakeTestIncident() { |
| 134 scoped_ptr<safe_browsing::ClientIncidentReport_IncidentData> incident( |
| 135 new safe_browsing::ClientIncidentReport_IncidentData()); |
| 136 incident->set_incident_time_msec(kIncidentTimeMsec); |
| 137 incident->mutable_tracked_preference(); |
| 138 return incident.Pass(); |
| 139 } |
| 140 |
| 141 // Confirms that the test incident was uploaded by the service. |
| 142 void ExpectTestIncidentUploaded() { |
| 143 ASSERT_TRUE(uploaded_report_); |
| 144 ASSERT_EQ(1, uploaded_report_->incident_size()); |
| 145 ASSERT_TRUE(uploaded_report_->incident(0).has_incident_time_msec()); |
| 146 ASSERT_EQ(kIncidentTimeMsec, |
| 147 uploaded_report_->incident(0).incident_time_msec()); |
| 148 ASSERT_TRUE(uploaded_report_->has_environment()); |
| 149 ASSERT_TRUE(uploaded_report_->environment().has_os()); |
| 150 ASSERT_TRUE(uploaded_report_->environment().os().has_os_name()); |
| 151 ASSERT_EQ(std::string(kFakeOsName), |
| 152 uploaded_report_->environment().os().os_name()); |
| 153 } |
| 154 |
| 155 void ExpectNoUpload() { ASSERT_FALSE(uploaded_report_); } |
| 156 |
94 bool HasCollectedEnvironmentData() const { return environment_collected_; } | 157 bool HasCollectedEnvironmentData() const { return environment_collected_; } |
95 bool UploaderDestroyed() const { return uploader_destroyed_; } | 158 bool UploaderDestroyed() const { return uploader_destroyed_; } |
96 | 159 |
97 scoped_refptr<base::TestSimpleTaskRunner> task_runner_; | 160 scoped_refptr<base::TestSimpleTaskRunner> task_runner_; |
98 base::ThreadTaskRunnerHandle thread_task_runner_handle_; | 161 base::ThreadTaskRunnerHandle thread_task_runner_handle_; |
| 162 ScopedTestingLocalState local_state_; |
99 scoped_ptr<safe_browsing::IncidentReportingService> instance_; | 163 scoped_ptr<safe_browsing::IncidentReportingService> instance_; |
100 safe_browsing::IncidentReportUploader::Result upload_result_; | 164 safe_browsing::IncidentReportUploader::Result upload_result_; |
101 bool environment_collected_; | 165 bool environment_collected_; |
102 scoped_ptr<safe_browsing::ClientIncidentReport> uploaded_report_; | 166 scoped_ptr<safe_browsing::ClientIncidentReport> uploaded_report_; |
103 bool uploader_destroyed_; | 167 bool uploader_destroyed_; |
| 168 scoped_ptr<TestingProfile> testing_profile_; |
104 | 169 |
105 private: | 170 private: |
106 // A fake IncidentReportUploader that posts a task to provide a given response | 171 // A fake IncidentReportUploader that posts a task to provide a given response |
107 // back to the incident reporting service. It also reports back to the test | 172 // back to the incident reporting service. It also reports back to the test |
108 // harness via a closure when it is deleted by the incident reporting service. | 173 // harness via a closure when it is deleted by the incident reporting service. |
109 class FakeUploader : public safe_browsing::IncidentReportUploader { | 174 class FakeUploader : public safe_browsing::IncidentReportUploader { |
110 public: | 175 public: |
111 FakeUploader( | 176 FakeUploader( |
112 const base::Closure& on_deleted, | 177 const base::Closure& on_deleted, |
113 const safe_browsing::IncidentReportUploader::OnResultCallback& callback, | 178 const safe_browsing::IncidentReportUploader::OnResultCallback& callback, |
(...skipping 15 matching lines...) Expand all Loading... |
129 callback_.Run(result_, | 194 callback_.Run(result_, |
130 scoped_ptr<safe_browsing::ClientIncidentResponse>()); | 195 scoped_ptr<safe_browsing::ClientIncidentResponse>()); |
131 } | 196 } |
132 | 197 |
133 base::Closure on_deleted_; | 198 base::Closure on_deleted_; |
134 safe_browsing::IncidentReportUploader::Result result_; | 199 safe_browsing::IncidentReportUploader::Result result_; |
135 | 200 |
136 DISALLOW_COPY_AND_ASSIGN(FakeUploader); | 201 DISALLOW_COPY_AND_ASSIGN(FakeUploader); |
137 }; | 202 }; |
138 | 203 |
| 204 // A callback run by the test fixture when a profile is created. An incident |
| 205 // is added. |
| 206 void PreProfileCreate(Profile* profile) { |
| 207 // The instance must have already been created. |
| 208 ASSERT_TRUE(instance_); |
| 209 // Add a test incident to the service. |
| 210 instance_->GetAddIncidentCallback(profile).Run(MakeTestIncident().Pass()); |
| 211 } |
| 212 |
| 213 // A fake CollectEnvironmentData implementation invoked by the service during |
| 214 // operation. |
139 void CollectEnvironmentData( | 215 void CollectEnvironmentData( |
140 safe_browsing::ClientIncidentReport_EnvironmentData* data) { | 216 safe_browsing::ClientIncidentReport_EnvironmentData* data) { |
141 ASSERT_NE( | 217 ASSERT_NE( |
142 static_cast<safe_browsing::ClientIncidentReport_EnvironmentData*>(NULL), | 218 static_cast<safe_browsing::ClientIncidentReport_EnvironmentData*>(NULL), |
143 data); | 219 data); |
144 data->mutable_os()->set_os_name(kFakeOsName); | 220 data->mutable_os()->set_os_name(kFakeOsName); |
145 environment_collected_ = true; | 221 environment_collected_ = true; |
146 } | 222 } |
147 | 223 |
| 224 // A fake StartUpload implementation invoked by the service during operation. |
148 scoped_ptr<safe_browsing::IncidentReportUploader> StartUpload( | 225 scoped_ptr<safe_browsing::IncidentReportUploader> StartUpload( |
149 const safe_browsing::IncidentReportUploader::OnResultCallback& callback, | 226 const safe_browsing::IncidentReportUploader::OnResultCallback& callback, |
150 const safe_browsing::ClientIncidentReport& report) { | 227 const safe_browsing::ClientIncidentReport& report) { |
151 // Remember the report that is being uploaded. | 228 // Remember the report that is being uploaded. |
152 uploaded_report_.reset(new safe_browsing::ClientIncidentReport(report)); | 229 uploaded_report_.reset(new safe_browsing::ClientIncidentReport(report)); |
153 return scoped_ptr<safe_browsing::IncidentReportUploader>(new FakeUploader( | 230 return scoped_ptr<safe_browsing::IncidentReportUploader>(new FakeUploader( |
154 base::Bind(&IncidentReportingServiceTest::OnUploaderDestroyed, | 231 base::Bind(&IncidentReportingServiceTest::OnUploaderDestroyed, |
155 base::Unretained(this)), | 232 base::Unretained(this)), |
156 callback, | 233 callback, |
157 upload_result_)); | 234 upload_result_)); |
158 } | 235 } |
159 | 236 |
160 void OnUploaderDestroyed() { uploader_destroyed_ = true; } | 237 void OnUploaderDestroyed() { uploader_destroyed_ = true; } |
161 }; | 238 }; |
162 | 239 |
163 // static | 240 // static |
164 base::LazyInstance<base::ThreadLocalPointer< | 241 base::LazyInstance<base::ThreadLocalPointer< |
165 IncidentReportingServiceTest::TestIncidentReportingService> >::Leaky | 242 IncidentReportingServiceTest::TestIncidentReportingService> >::Leaky |
166 IncidentReportingServiceTest::TestIncidentReportingService::test_instance_ = | 243 IncidentReportingServiceTest::TestIncidentReportingService::test_instance_ = |
167 LAZY_INSTANCE_INITIALIZER; | 244 LAZY_INSTANCE_INITIALIZER; |
168 | 245 |
169 // static | 246 // static |
| 247 const int64 IncidentReportingServiceTest::kIncidentTimeMsec = 47LL; |
170 const char IncidentReportingServiceTest::kFakeOsName[] = "fakedows"; | 248 const char IncidentReportingServiceTest::kFakeOsName[] = "fakedows"; |
171 | 249 |
| 250 // Tests that an incident added during profile initialization when safe browsing |
| 251 // is on is uploaded. |
172 TEST_F(IncidentReportingServiceTest, AddIncident) { | 252 TEST_F(IncidentReportingServiceTest, AddIncident) { |
173 // Make up a dummy incident. | 253 // Create the profile, thereby causing the test to begin. |
174 const int64 kIncidentTimeMsec = 47LL; | 254 CreateProfileAndRunTest(true); |
175 scoped_ptr<safe_browsing::ClientIncidentReport_IncidentData> incident( | |
176 new safe_browsing::ClientIncidentReport_IncidentData()); | |
177 incident->set_incident_time_msec(kIncidentTimeMsec); | |
178 | |
179 // Add it to the service. | |
180 instance_->GetAddIncidentCallback().Run(incident.Pass()); | |
181 | |
182 // Let all tasks run. | |
183 task_runner_->RunUntilIdle(); | |
184 | 255 |
185 // Verify that environment collection took place. | 256 // Verify that environment collection took place. |
186 EXPECT_TRUE(HasCollectedEnvironmentData()); | 257 EXPECT_TRUE(HasCollectedEnvironmentData()); |
187 | 258 |
188 // Verify that report upload took place and contained the incident and | 259 // Verify that report upload took place and contained the incident and |
189 // environment data. | 260 // environment data. |
190 ASSERT_TRUE(uploaded_report_); | 261 ExpectTestIncidentUploaded(); |
191 ASSERT_EQ(1, uploaded_report_->incident_size()); | |
192 ASSERT_TRUE(uploaded_report_->incident(0).has_incident_time_msec()); | |
193 ASSERT_EQ(kIncidentTimeMsec, | |
194 uploaded_report_->incident(0).incident_time_msec()); | |
195 ASSERT_TRUE(uploaded_report_->has_environment()); | |
196 ASSERT_TRUE(uploaded_report_->environment().has_os()); | |
197 ASSERT_TRUE(uploaded_report_->environment().os().has_os_name()); | |
198 ASSERT_EQ(std::string(kFakeOsName), | |
199 uploaded_report_->environment().os().os_name()); | |
200 | 262 |
201 // Verify that the uploader was destroyed. | 263 // Verify that the uploader was destroyed. |
202 ASSERT_TRUE(UploaderDestroyed()); | 264 ASSERT_TRUE(UploaderDestroyed()); |
203 } | 265 } |
204 | 266 |
205 // Nothing happens when disabled | 267 // Tests that an incident added during profile initialization when safe browsing |
206 // Nothing is sent when disabled before/after environment collection | 268 // is off is not uploaded. |
207 // Duplicate incidents are stripped | 269 TEST_F(IncidentReportingServiceTest, NoSafeBrowsing) { |
| 270 // Create the profile, thereby causing the test to begin. |
| 271 CreateProfileAndRunTest(false); |
| 272 |
| 273 // Verify that no report upload took place. |
| 274 ExpectNoUpload(); |
| 275 } |
| 276 |
208 // Parallel uploads | 277 // Parallel uploads |
209 // Shutdown during processing | 278 // Shutdown during processing |
210 // environment colection taking longer than incident delay timer | 279 // environment colection taking longer than incident delay timer |
211 // environment colection taking longer than incident delay timer, and then | 280 // environment colection taking longer than incident delay timer, and then |
212 // another incident arriving | 281 // another incident arriving |
OLD | NEW |