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/chrome_notification_types.h" | |
16 #include "chrome/browser/prefs/browser_prefs.h" | |
15 #include "chrome/browser/safe_browsing/incident_report_uploader.h" | 17 #include "chrome/browser/safe_browsing/incident_report_uploader.h" |
18 #include "chrome/common/pref_names.h" | |
16 #include "chrome/common/safe_browsing/csd.pb.h" | 19 #include "chrome/common/safe_browsing/csd.pb.h" |
20 #include "chrome/test/base/scoped_testing_local_state.h" | |
21 #include "chrome/test/base/testing_browser_process.h" | |
22 #include "chrome/test/base/testing_pref_service_syncable.h" | |
23 #include "chrome/test/base/testing_profile.h" | |
24 #include "content/public/browser/notification_observer.h" | |
25 #include "content/public/browser/notification_registrar.h" | |
26 #include "content/public/browser/notification_service.h" | |
17 #include "net/url_request/url_request_context_getter.h" | 27 #include "net/url_request/url_request_context_getter.h" |
18 #include "testing/gtest/include/gtest/gtest.h" | 28 #include "testing/gtest/include/gtest/gtest.h" |
19 | 29 |
20 // A test fixture that sets up a test task runner and makes it the thread's | 30 // 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 | 31 // runner. The fixture implements a fake envrionment data collector and a fake |
22 // report uploader. | 32 // report uploader. |
23 class IncidentReportingServiceTest : public testing::Test { | 33 class IncidentReportingServiceTest : public testing::Test { |
24 protected: | 34 protected: |
25 // An IRS class that allows a test harness to provide a fake environment | 35 // An IRS class that allows a test harness to provide a fake environment |
26 // collector and report uploader via callbacks. | 36 // collector and report uploader via callbacks. |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
67 current().collect_environment_callback_.Run(data); | 77 current().collect_environment_callback_.Run(data); |
68 }; | 78 }; |
69 | 79 |
70 static base::LazyInstance<base::ThreadLocalPointer< | 80 static base::LazyInstance<base::ThreadLocalPointer< |
71 TestIncidentReportingService> >::Leaky test_instance_; | 81 TestIncidentReportingService> >::Leaky test_instance_; |
72 | 82 |
73 CollectEnvironmentCallback collect_environment_callback_; | 83 CollectEnvironmentCallback collect_environment_callback_; |
74 StartUploadCallback start_upload_callback_; | 84 StartUploadCallback start_upload_callback_; |
75 }; | 85 }; |
76 | 86 |
87 // A class that registers for PROFILE_CREATED notifications and invokes a | |
88 // callback upon receipt. This is used by the test fixture to provide a means | |
89 // to submit an incident during profile initialization before the reporting | |
90 // service notices that profile creation has completed. | |
mattm
2014/06/18 21:07:18
Is it guaranteed that this observer will be called
grt (UTC plus 2)
2014/06/18 22:47:58
In the current implementation, yes. It's not docum
mattm
2014/06/18 23:05:38
Realistically it's probably fine.. main concern wo
grt (UTC plus 2)
2014/06/19 02:24:39
I've removed the notification service magic in fav
| |
91 class PreProfileInitRegistrar : public content::NotificationObserver { | |
92 public: | |
93 PreProfileInitRegistrar( | |
94 const base::Callback<void(Profile*)>& profile_created_closure) | |
95 : profile_created_closure_(profile_created_closure) { | |
96 notification_registrar_.Add(this, | |
97 chrome::NOTIFICATION_PROFILE_CREATED, | |
98 content::NotificationService::AllSources()); | |
99 } | |
100 | |
101 private: | |
102 virtual void Observe(int type, | |
103 const content::NotificationSource& source, | |
104 const content::NotificationDetails& details) OVERRIDE { | |
105 if (type == chrome::NOTIFICATION_PROFILE_CREATED) { | |
106 Profile* profile = content::Source<Profile>(source).ptr(); | |
107 if (!profile->IsOffTheRecord()) | |
108 profile_created_closure_.Run(profile); | |
109 } | |
110 } | |
111 | |
112 content::NotificationRegistrar notification_registrar_; | |
113 base::Callback<void(Profile*)> profile_created_closure_; | |
114 | |
115 DISALLOW_COPY_AND_ASSIGN(PreProfileInitRegistrar); | |
116 }; | |
117 | |
118 static const int64 kIncidentTimeMsec; | |
77 static const char kFakeOsName[]; | 119 static const char kFakeOsName[]; |
78 | 120 |
79 IncidentReportingServiceTest() | 121 IncidentReportingServiceTest() |
80 : task_runner_(new base::TestSimpleTaskRunner), | 122 : task_runner_(new base::TestSimpleTaskRunner), |
81 thread_task_runner_handle_(task_runner_), | 123 thread_task_runner_handle_(task_runner_), |
124 local_state_(TestingBrowserProcess::GetGlobal()), | |
125 pre_profile_init_registrar_( | |
126 base::Bind(&IncidentReportingServiceTest::PreProfileInit, | |
127 base::Unretained(this))), | |
82 instance_(new TestIncidentReportingService( | 128 instance_(new TestIncidentReportingService( |
83 task_runner_, | 129 task_runner_, |
84 base::Bind(&IncidentReportingServiceTest::CollectEnvironmentData, | 130 base::Bind(&IncidentReportingServiceTest::CollectEnvironmentData, |
85 base::Unretained(this)), | 131 base::Unretained(this)), |
86 base::Bind(&IncidentReportingServiceTest::StartUpload, | 132 base::Bind(&IncidentReportingServiceTest::StartUpload, |
87 base::Unretained(this)))), | 133 base::Unretained(this)))), |
88 upload_result_(safe_browsing::IncidentReportUploader::UPLOAD_SUCCESS), | 134 upload_result_(safe_browsing::IncidentReportUploader::UPLOAD_SUCCESS), |
89 environment_collected_(), | 135 environment_collected_(), |
90 uploader_destroyed_() { | 136 uploader_destroyed_() {} |
91 instance_->SetEnabled(true); | 137 |
138 // Begins the test by creating a profile. An incident will be created within | |
139 // PreProfileInit. Tasks are run to allow the service to operate to | |
140 // completion. | |
141 void CreateProfileAndRunTest(bool safe_browsing_enabled) { | |
142 // Create prefs for the profile with safe browsing enabled or not. | |
143 scoped_ptr<TestingPrefServiceSyncable> prefs( | |
144 new TestingPrefServiceSyncable); | |
145 chrome::RegisterUserProfilePrefs(prefs->registry()); | |
146 prefs->SetBoolean(prefs::kSafeBrowsingEnabled, safe_browsing_enabled); | |
147 | |
148 // Build the test profile (PreProfileInit will be called). | |
149 TestingProfile::Builder builder; | |
150 builder.SetPrefService(prefs.PassAs<PrefServiceSyncable>()); | |
151 testing_profile_ = builder.Build().Pass(); | |
152 | |
153 // Let all tasks run. | |
154 task_runner_->RunUntilIdle(); | |
mattm
2014/06/18 21:07:18
I didn't notice before, but how does this work? Sh
grt (UTC plus 2)
2014/06/18 22:47:58
I had the same "huh?" moment. TestSimpleTaskRunner
mattm
2014/06/18 23:05:38
Ah ha, thanks.
| |
92 } | 155 } |
93 | 156 |
157 // Returns an incident suitable for testing. | |
158 scoped_ptr<safe_browsing::ClientIncidentReport_IncidentData> | |
159 MakeTestIncident() { | |
160 scoped_ptr<safe_browsing::ClientIncidentReport_IncidentData> incident( | |
161 new safe_browsing::ClientIncidentReport_IncidentData()); | |
162 incident->set_incident_time_msec(kIncidentTimeMsec); | |
163 incident->mutable_tracked_preference(); | |
164 return incident.Pass(); | |
165 } | |
166 | |
167 // Confirms that the test incident was uploaded by the service. | |
168 void ExpectTestIncidentUploaded() { | |
169 ASSERT_TRUE(uploaded_report_); | |
170 ASSERT_EQ(1, uploaded_report_->incident_size()); | |
171 ASSERT_TRUE(uploaded_report_->incident(0).has_incident_time_msec()); | |
172 ASSERT_EQ(kIncidentTimeMsec, | |
173 uploaded_report_->incident(0).incident_time_msec()); | |
174 ASSERT_TRUE(uploaded_report_->has_environment()); | |
175 ASSERT_TRUE(uploaded_report_->environment().has_os()); | |
176 ASSERT_TRUE(uploaded_report_->environment().os().has_os_name()); | |
177 ASSERT_EQ(std::string(kFakeOsName), | |
178 uploaded_report_->environment().os().os_name()); | |
179 } | |
180 | |
181 void ExpectNoUpload() { ASSERT_FALSE(uploaded_report_); } | |
182 | |
94 bool HasCollectedEnvironmentData() const { return environment_collected_; } | 183 bool HasCollectedEnvironmentData() const { return environment_collected_; } |
95 bool UploaderDestroyed() const { return uploader_destroyed_; } | 184 bool UploaderDestroyed() const { return uploader_destroyed_; } |
96 | 185 |
97 scoped_refptr<base::TestSimpleTaskRunner> task_runner_; | 186 scoped_refptr<base::TestSimpleTaskRunner> task_runner_; |
98 base::ThreadTaskRunnerHandle thread_task_runner_handle_; | 187 base::ThreadTaskRunnerHandle thread_task_runner_handle_; |
188 ScopedTestingLocalState local_state_; | |
189 | |
190 // This registrar must be constructed before the service instance below. | |
191 PreProfileInitRegistrar pre_profile_init_registrar_; | |
192 | |
193 // This service instance must be constructed after the registrar above. | |
99 scoped_ptr<safe_browsing::IncidentReportingService> instance_; | 194 scoped_ptr<safe_browsing::IncidentReportingService> instance_; |
100 safe_browsing::IncidentReportUploader::Result upload_result_; | 195 safe_browsing::IncidentReportUploader::Result upload_result_; |
101 bool environment_collected_; | 196 bool environment_collected_; |
102 scoped_ptr<safe_browsing::ClientIncidentReport> uploaded_report_; | 197 scoped_ptr<safe_browsing::ClientIncidentReport> uploaded_report_; |
103 bool uploader_destroyed_; | 198 bool uploader_destroyed_; |
199 scoped_ptr<TestingProfile> testing_profile_; | |
104 | 200 |
105 private: | 201 private: |
106 // A fake IncidentReportUploader that posts a task to provide a given response | 202 // 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 | 203 // 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. | 204 // harness via a closure when it is deleted by the incident reporting service. |
109 class FakeUploader : public safe_browsing::IncidentReportUploader { | 205 class FakeUploader : public safe_browsing::IncidentReportUploader { |
110 public: | 206 public: |
111 FakeUploader( | 207 FakeUploader( |
112 const base::Closure& on_deleted, | 208 const base::Closure& on_deleted, |
113 const safe_browsing::IncidentReportUploader::OnResultCallback& callback, | 209 const safe_browsing::IncidentReportUploader::OnResultCallback& callback, |
(...skipping 15 matching lines...) Expand all Loading... | |
129 callback_.Run(result_, | 225 callback_.Run(result_, |
130 scoped_ptr<safe_browsing::ClientIncidentResponse>()); | 226 scoped_ptr<safe_browsing::ClientIncidentResponse>()); |
131 } | 227 } |
132 | 228 |
133 base::Closure on_deleted_; | 229 base::Closure on_deleted_; |
134 safe_browsing::IncidentReportUploader::Result result_; | 230 safe_browsing::IncidentReportUploader::Result result_; |
135 | 231 |
136 DISALLOW_COPY_AND_ASSIGN(FakeUploader); | 232 DISALLOW_COPY_AND_ASSIGN(FakeUploader); |
137 }; | 233 }; |
138 | 234 |
235 // A callback run by the test fixture when a profile is created. An incident | |
236 // is added. | |
237 void PreProfileInit(Profile* profile) { | |
238 // The instance must have already been created. | |
239 ASSERT_TRUE(instance_); | |
240 // Add a test incident to the service. | |
241 instance_->GetAddIncidentCallback(profile).Run(MakeTestIncident().Pass()); | |
242 } | |
243 | |
244 // A fake CollectEnvironmentData implementation invoked by the service during | |
245 // operation. | |
139 void CollectEnvironmentData( | 246 void CollectEnvironmentData( |
140 safe_browsing::ClientIncidentReport_EnvironmentData* data) { | 247 safe_browsing::ClientIncidentReport_EnvironmentData* data) { |
141 ASSERT_NE( | 248 ASSERT_NE( |
142 static_cast<safe_browsing::ClientIncidentReport_EnvironmentData*>(NULL), | 249 static_cast<safe_browsing::ClientIncidentReport_EnvironmentData*>(NULL), |
143 data); | 250 data); |
144 data->mutable_os()->set_os_name(kFakeOsName); | 251 data->mutable_os()->set_os_name(kFakeOsName); |
145 environment_collected_ = true; | 252 environment_collected_ = true; |
146 } | 253 } |
147 | 254 |
255 // A fake StartUpload implementation invoked by the service during operation. | |
148 scoped_ptr<safe_browsing::IncidentReportUploader> StartUpload( | 256 scoped_ptr<safe_browsing::IncidentReportUploader> StartUpload( |
149 const safe_browsing::IncidentReportUploader::OnResultCallback& callback, | 257 const safe_browsing::IncidentReportUploader::OnResultCallback& callback, |
150 const safe_browsing::ClientIncidentReport& report) { | 258 const safe_browsing::ClientIncidentReport& report) { |
151 // Remember the report that is being uploaded. | 259 // Remember the report that is being uploaded. |
152 uploaded_report_.reset(new safe_browsing::ClientIncidentReport(report)); | 260 uploaded_report_.reset(new safe_browsing::ClientIncidentReport(report)); |
153 return scoped_ptr<safe_browsing::IncidentReportUploader>(new FakeUploader( | 261 return scoped_ptr<safe_browsing::IncidentReportUploader>(new FakeUploader( |
154 base::Bind(&IncidentReportingServiceTest::OnUploaderDestroyed, | 262 base::Bind(&IncidentReportingServiceTest::OnUploaderDestroyed, |
155 base::Unretained(this)), | 263 base::Unretained(this)), |
156 callback, | 264 callback, |
157 upload_result_)); | 265 upload_result_)); |
158 } | 266 } |
159 | 267 |
160 void OnUploaderDestroyed() { uploader_destroyed_ = true; } | 268 void OnUploaderDestroyed() { uploader_destroyed_ = true; } |
161 }; | 269 }; |
162 | 270 |
163 // static | 271 // static |
164 base::LazyInstance<base::ThreadLocalPointer< | 272 base::LazyInstance<base::ThreadLocalPointer< |
165 IncidentReportingServiceTest::TestIncidentReportingService> >::Leaky | 273 IncidentReportingServiceTest::TestIncidentReportingService> >::Leaky |
166 IncidentReportingServiceTest::TestIncidentReportingService::test_instance_ = | 274 IncidentReportingServiceTest::TestIncidentReportingService::test_instance_ = |
167 LAZY_INSTANCE_INITIALIZER; | 275 LAZY_INSTANCE_INITIALIZER; |
168 | 276 |
169 // static | 277 // static |
278 const int64 IncidentReportingServiceTest::kIncidentTimeMsec = 47LL; | |
170 const char IncidentReportingServiceTest::kFakeOsName[] = "fakedows"; | 279 const char IncidentReportingServiceTest::kFakeOsName[] = "fakedows"; |
171 | 280 |
281 // Tests that an incident added during profile initialization when safe browsing | |
282 // is on is uploaded. | |
172 TEST_F(IncidentReportingServiceTest, AddIncident) { | 283 TEST_F(IncidentReportingServiceTest, AddIncident) { |
173 // Make up a dummy incident. | 284 // Create the profile, thereby causing the test to begin. |
174 const int64 kIncidentTimeMsec = 47LL; | 285 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 | 286 |
185 // Verify that environment collection took place. | 287 // Verify that environment collection took place. |
186 EXPECT_TRUE(HasCollectedEnvironmentData()); | 288 EXPECT_TRUE(HasCollectedEnvironmentData()); |
187 | 289 |
188 // Verify that report upload took place and contained the incident and | 290 // Verify that report upload took place and contained the incident and |
189 // environment data. | 291 // environment data. |
190 ASSERT_TRUE(uploaded_report_); | 292 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 | 293 |
201 // Verify that the uploader was destroyed. | 294 // Verify that the uploader was destroyed. |
202 ASSERT_TRUE(UploaderDestroyed()); | 295 ASSERT_TRUE(UploaderDestroyed()); |
203 } | 296 } |
204 | 297 |
205 // Nothing happens when disabled | 298 // Tests that an incident added during profile initialization when safe browsing |
206 // Nothing is sent when disabled before/after environment collection | 299 // is off is not uploaded. |
300 TEST_F(IncidentReportingServiceTest, NoSafeBrowsing) { | |
301 // Create the profile, thereby causing the test to begin. | |
302 CreateProfileAndRunTest(false); | |
303 | |
304 // Verify that no report upload took place. | |
305 ExpectNoUpload(); | |
306 } | |
307 | |
207 // Duplicate incidents are stripped | 308 // Duplicate incidents are stripped |
208 // Parallel uploads | 309 // Parallel uploads |
209 // Shutdown during processing | 310 // Shutdown during processing |
210 // environment colection taking longer than incident delay timer | 311 // environment colection taking longer than incident delay timer |
211 // environment colection taking longer than incident delay timer, and then | 312 // environment colection taking longer than incident delay timer, and then |
212 // another incident arriving | 313 // another incident arriving |
OLD | NEW |