OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/download_feedback_service.h" | 5 #include "chrome/browser/safe_browsing/download_feedback_service.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 #include <stdint.h> | 8 #include <stdint.h> |
9 | 9 |
10 #include <vector> | 10 #include <vector> |
11 | 11 |
12 #include "base/files/file_util.h" | 12 #include "base/files/file_util.h" |
13 #include "base/files/scoped_temp_dir.h" | 13 #include "base/files/scoped_temp_dir.h" |
14 #include "base/memory/ptr_util.h" | 14 #include "base/memory/ptr_util.h" |
15 #include "base/run_loop.h" | 15 #include "base/run_loop.h" |
16 #include "base/strings/string_number_conversions.h" | 16 #include "base/strings/string_number_conversions.h" |
17 #include "chrome/browser/safe_browsing/download_feedback.h" | 17 #include "chrome/browser/safe_browsing/download_feedback.h" |
18 #include "content/public/browser/browser_thread.h" | 18 #include "content/public/browser/browser_thread.h" |
19 #include "content/public/test/mock_download_item.h" | 19 #include "content/public/test/mock_download_item.h" |
20 #include "content/public/test/test_browser_thread_bundle.h" | 20 #include "content/public/test/test_browser_thread_bundle.h" |
21 #include "net/url_request/url_request_test_util.h" | 21 #include "net/url_request/url_request_test_util.h" |
22 #include "testing/gmock/include/gmock/gmock.h" | 22 #include "testing/gmock/include/gmock/gmock.h" |
23 #include "testing/gtest/include/gtest/gtest.h" | 23 #include "testing/gtest/include/gtest/gtest.h" |
24 | 24 |
25 using ::testing::_; | 25 using ::testing::_; |
26 using ::testing::Return; | 26 using ::testing::Return; |
| 27 using ::testing::ReturnRef; |
27 using ::testing::SaveArg; | 28 using ::testing::SaveArg; |
28 | 29 |
29 namespace safe_browsing { | 30 namespace safe_browsing { |
30 | 31 |
31 namespace { | 32 namespace { |
32 | 33 |
33 class FakeDownloadFeedback : public DownloadFeedback { | 34 class FakeDownloadFeedback : public DownloadFeedback { |
34 public: | 35 public: |
35 FakeDownloadFeedback(net::URLRequestContextGetter* request_context_getter, | 36 FakeDownloadFeedback(net::URLRequestContextGetter* request_context_getter, |
36 base::TaskRunner* file_task_runner, | 37 base::TaskRunner* file_task_runner, |
37 const base::FilePath& file_path, | 38 const base::FilePath& file_path, |
38 const std::string& ping_request, | 39 const std::string& ping_request, |
39 const std::string& ping_response, | 40 const std::string& ping_response, |
40 base::Closure deletion_callback) | 41 base::Closure deletion_callback) |
41 : ping_request_(ping_request), | 42 : ping_request_(ping_request), |
42 ping_response_(ping_response), | 43 ping_response_(ping_response), |
43 deletion_callback_(deletion_callback), | 44 deletion_callback_(deletion_callback), |
44 start_called_(false) { | 45 start_called_(false) {} |
45 } | |
46 | 46 |
47 ~FakeDownloadFeedback() override { deletion_callback_.Run(); } | 47 ~FakeDownloadFeedback() override { deletion_callback_.Run(); } |
48 | 48 |
49 void Start(const base::Closure& finish_callback) override { | 49 void Start(const base::Closure& finish_callback) override { |
50 start_called_ = true; | 50 start_called_ = true; |
51 finish_callback_ = finish_callback; | 51 finish_callback_ = finish_callback; |
52 } | 52 } |
53 | 53 |
54 const std::string& GetPingRequestForTesting() const override { | 54 const std::string& GetPingRequestForTesting() const override { |
55 return ping_request_; | 55 return ping_request_; |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
88 base::TaskRunner* file_task_runner, | 88 base::TaskRunner* file_task_runner, |
89 const base::FilePath& file_path, | 89 const base::FilePath& file_path, |
90 const std::string& ping_request, | 90 const std::string& ping_request, |
91 const std::string& ping_response) override { | 91 const std::string& ping_response) override { |
92 FakeDownloadFeedback* feedback = new FakeDownloadFeedback( | 92 FakeDownloadFeedback* feedback = new FakeDownloadFeedback( |
93 request_context_getter, | 93 request_context_getter, |
94 file_task_runner, | 94 file_task_runner, |
95 file_path, | 95 file_path, |
96 ping_request, | 96 ping_request, |
97 ping_response, | 97 ping_response, |
98 base::Bind(&FakeDownloadFeedbackFactory::DownloadFeedbackDeleted, | 98 base::Bind(&FakeDownloadFeedbackFactory::DownloadFeedbackSent, |
99 base::Unretained(this), | 99 base::Unretained(this), |
100 feedbacks_.size())); | 100 feedbacks_.size())); |
101 feedbacks_.push_back(feedback); | 101 feedbacks_.push_back(feedback); |
102 return base::WrapUnique(feedback); | 102 return base::WrapUnique(feedback); |
103 } | 103 } |
104 | 104 |
105 void DownloadFeedbackDeleted(size_t n) { feedbacks_[n] = nullptr; } | 105 void DownloadFeedbackSent(size_t n) { |
| 106 feedbacks_[n] = nullptr; |
| 107 } |
106 | 108 |
107 FakeDownloadFeedback* feedback(size_t n) const { | 109 FakeDownloadFeedback* feedback(size_t n) const { |
108 return feedbacks_[n]; | 110 return feedbacks_[n]; |
109 } | 111 } |
110 | 112 |
111 size_t num_feedbacks() const { | 113 size_t num_feedbacks() const { |
112 return feedbacks_.size(); | 114 return feedbacks_.size(); |
113 } | 115 } |
114 | 116 |
115 private: | 117 private: |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
186 | 188 |
187 EXPECT_FALSE(WillStorePings(DownloadProtectionService::SAFE, bad_size)); | 189 EXPECT_FALSE(WillStorePings(DownloadProtectionService::SAFE, bad_size)); |
188 EXPECT_FALSE(WillStorePings(DownloadProtectionService::DANGEROUS, bad_size)); | 190 EXPECT_FALSE(WillStorePings(DownloadProtectionService::DANGEROUS, bad_size)); |
189 EXPECT_FALSE(WillStorePings(DownloadProtectionService::UNCOMMON, bad_size)); | 191 EXPECT_FALSE(WillStorePings(DownloadProtectionService::UNCOMMON, bad_size)); |
190 EXPECT_FALSE( | 192 EXPECT_FALSE( |
191 WillStorePings(DownloadProtectionService::DANGEROUS_HOST, bad_size)); | 193 WillStorePings(DownloadProtectionService::DANGEROUS_HOST, bad_size)); |
192 EXPECT_FALSE(WillStorePings(DownloadProtectionService::POTENTIALLY_UNWANTED, | 194 EXPECT_FALSE(WillStorePings(DownloadProtectionService::POTENTIALLY_UNWANTED, |
193 bad_size)); | 195 bad_size)); |
194 } | 196 } |
195 | 197 |
196 TEST_F(DownloadFeedbackServiceTest, SingleFeedbackComplete) { | 198 TEST_F(DownloadFeedbackServiceTest, SingleFeedbackCompleteAndDiscardDownload) { |
197 const base::FilePath file_path(CreateTestFile(0)); | 199 const base::FilePath file_path(CreateTestFile(0)); |
198 const std::string ping_request = "ping"; | 200 const std::string ping_request = "ping"; |
199 const std::string ping_response = "resp"; | 201 const std::string ping_response = "resp"; |
200 | 202 |
201 content::DownloadItem::AcquireFileCallback download_discarded_callback; | 203 content::DownloadItem::AcquireFileCallback download_discarded_callback; |
202 | 204 |
203 content::MockDownloadItem item; | 205 content::MockDownloadItem item; |
204 EXPECT_CALL(item, GetDangerType()) | 206 EXPECT_CALL(item, GetDangerType()) |
205 .WillRepeatedly(Return(content::DOWNLOAD_DANGER_TYPE_UNCOMMON_CONTENT)); | 207 .WillRepeatedly(Return(content::DOWNLOAD_DANGER_TYPE_UNCOMMON_CONTENT)); |
206 EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(1000)); | 208 EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(1000)); |
207 EXPECT_CALL(item, StealDangerousDownload(_)) | 209 EXPECT_CALL(item, |
208 .WillOnce(SaveArg<0>(&download_discarded_callback)); | 210 StealDangerousDownload(true /*delete_file_after_feedback*/, _)) |
| 211 .WillOnce(SaveArg<1>(&download_discarded_callback)); |
209 | 212 |
210 DownloadFeedbackService service(request_context_getter_.get(), | 213 DownloadFeedbackService service(request_context_getter_.get(), |
211 file_task_runner_.get()); | 214 file_task_runner_.get()); |
212 service.MaybeStorePingsForDownload( | 215 service.MaybeStorePingsForDownload( |
213 DownloadProtectionService::UNCOMMON, &item, ping_request, ping_response); | 216 DownloadProtectionService::UNCOMMON, &item, ping_request, ping_response); |
214 ASSERT_TRUE(DownloadFeedbackService::IsEnabledForDownload(item)); | 217 ASSERT_TRUE(DownloadFeedbackService::IsEnabledForDownload(item)); |
215 service.BeginFeedbackForDownload(&item); | 218 service.BeginFeedbackForDownload(&item, DownloadCommands::DISCARD); |
216 ASSERT_FALSE(download_discarded_callback.is_null()); | 219 ASSERT_FALSE(download_discarded_callback.is_null()); |
217 EXPECT_EQ(0U, num_feedbacks()); | 220 EXPECT_EQ(0U, num_feedbacks()); |
218 | 221 |
| 222 download_discarded_callback.Run(file_path); |
| 223 ASSERT_EQ(1U, num_feedbacks()); |
| 224 ASSERT_TRUE(feedback(0)); |
| 225 EXPECT_TRUE(feedback(0)->start_called()); |
| 226 EXPECT_EQ(ping_request, feedback(0)->GetPingRequestForTesting()); |
| 227 EXPECT_EQ(ping_response, feedback(0)->GetPingResponseForTesting()); |
| 228 |
| 229 feedback(0)->finish_callback().Run(); |
| 230 EXPECT_FALSE(feedback(0)); |
| 231 |
| 232 base::RunLoop().RunUntilIdle(); |
| 233 EXPECT_TRUE(base::PathExists(file_path)); |
| 234 } |
| 235 |
| 236 TEST_F(DownloadFeedbackServiceTest, SingleFeedbackCompleteAndKeepDownload) { |
| 237 const base::FilePath file_path(CreateTestFile(0)); |
| 238 const std::string ping_request = "ping"; |
| 239 const std::string ping_response = "resp"; |
| 240 |
| 241 content::DownloadItem::AcquireFileCallback download_discarded_callback; |
| 242 |
| 243 content::MockDownloadItem item; |
| 244 EXPECT_CALL(item, GetDangerType()) |
| 245 .WillRepeatedly(Return(content::DOWNLOAD_DANGER_TYPE_UNCOMMON_CONTENT)); |
| 246 EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(1000)); |
| 247 EXPECT_CALL(item, |
| 248 StealDangerousDownload(false /*delete_file_after_feedback*/, _)) |
| 249 .WillOnce(SaveArg<1>(&download_discarded_callback)); |
| 250 EXPECT_CALL(item, ValidateDangerousDownload()).Times(1); |
| 251 GURL empty_url; |
| 252 EXPECT_CALL(item, GetURL()).WillOnce(ReturnRef(empty_url)); |
| 253 |
| 254 DownloadFeedbackService service(request_context_getter_.get(), |
| 255 file_task_runner_.get()); |
| 256 service.MaybeStorePingsForDownload(DownloadProtectionService::UNCOMMON, &item, |
| 257 ping_request, ping_response); |
| 258 ASSERT_TRUE(DownloadFeedbackService::IsEnabledForDownload(item)); |
| 259 service.BeginFeedbackForDownload(&item, DownloadCommands::KEEP); |
| 260 ASSERT_FALSE(download_discarded_callback.is_null()); |
| 261 EXPECT_EQ(0U, num_feedbacks()); |
| 262 |
219 download_discarded_callback.Run(file_path); | 263 download_discarded_callback.Run(file_path); |
220 ASSERT_EQ(1U, num_feedbacks()); | 264 ASSERT_EQ(1U, num_feedbacks()); |
221 ASSERT_TRUE(feedback(0)); | 265 ASSERT_TRUE(feedback(0)); |
222 EXPECT_TRUE(feedback(0)->start_called()); | 266 EXPECT_TRUE(feedback(0)->start_called()); |
223 EXPECT_EQ(ping_request, feedback(0)->GetPingRequestForTesting()); | 267 EXPECT_EQ(ping_request, feedback(0)->GetPingRequestForTesting()); |
224 EXPECT_EQ(ping_response, feedback(0)->GetPingResponseForTesting()); | 268 EXPECT_EQ(ping_response, feedback(0)->GetPingResponseForTesting()); |
225 | 269 |
226 feedback(0)->finish_callback().Run(); | 270 feedback(0)->finish_callback().Run(); |
227 EXPECT_FALSE(feedback(0)); | 271 EXPECT_FALSE(feedback(0)); |
228 | 272 |
229 // File should still exist since our FakeDownloadFeedback does not delete it. | |
230 base::RunLoop().RunUntilIdle(); | 273 base::RunLoop().RunUntilIdle(); |
231 EXPECT_TRUE(base::PathExists(file_path)); | 274 EXPECT_TRUE(base::PathExists(file_path)); |
232 } | 275 } |
233 | 276 |
234 TEST_F(DownloadFeedbackServiceTest, MultiplePendingFeedbackComplete) { | 277 TEST_F(DownloadFeedbackServiceTest, MultiplePendingFeedbackComplete) { |
235 const std::string ping_request = "ping"; | 278 const std::string ping_request = "ping"; |
236 const std::string ping_response = "resp"; | 279 const std::string ping_response = "resp"; |
237 const size_t kNumDownloads = 3; | 280 const size_t kNumDownloads = 3; |
238 | 281 |
239 content::DownloadItem::AcquireFileCallback | 282 content::DownloadItem::AcquireFileCallback |
240 download_discarded_callback[kNumDownloads]; | 283 download_discarded_callback[kNumDownloads]; |
241 | 284 |
242 base::FilePath file_path[kNumDownloads]; | 285 base::FilePath file_path[kNumDownloads]; |
243 content::MockDownloadItem item[kNumDownloads]; | 286 content::MockDownloadItem item[kNumDownloads]; |
244 for (size_t i = 0; i < kNumDownloads; ++i) { | 287 for (size_t i = 0; i < kNumDownloads; ++i) { |
245 file_path[i] = CreateTestFile(i); | 288 file_path[i] = CreateTestFile(i); |
246 EXPECT_CALL(item[i], GetDangerType()) | 289 EXPECT_CALL(item[i], GetDangerType()) |
247 .WillRepeatedly(Return(content::DOWNLOAD_DANGER_TYPE_UNCOMMON_CONTENT)); | 290 .WillRepeatedly(Return(content::DOWNLOAD_DANGER_TYPE_UNCOMMON_CONTENT)); |
248 EXPECT_CALL(item[i], GetReceivedBytes()).WillRepeatedly(Return(1000)); | 291 EXPECT_CALL(item[i], GetReceivedBytes()).WillRepeatedly(Return(1000)); |
249 EXPECT_CALL(item[i], StealDangerousDownload(_)) | 292 EXPECT_CALL(item[i], StealDangerousDownload(true, _)) |
250 .WillOnce(SaveArg<0>(&download_discarded_callback[i])); | 293 .WillOnce(SaveArg<1>(&download_discarded_callback[i])); |
251 DownloadFeedbackService::MaybeStorePingsForDownload( | 294 DownloadFeedbackService::MaybeStorePingsForDownload( |
252 DownloadProtectionService::UNCOMMON, &item[i], ping_request, | 295 DownloadProtectionService::UNCOMMON, &item[i], ping_request, |
253 ping_response); | 296 ping_response); |
254 ASSERT_TRUE(DownloadFeedbackService::IsEnabledForDownload(item[i])); | 297 ASSERT_TRUE(DownloadFeedbackService::IsEnabledForDownload(item[i])); |
255 } | 298 } |
256 | 299 |
257 { | 300 { |
258 DownloadFeedbackService service(request_context_getter_.get(), | 301 DownloadFeedbackService service(request_context_getter_.get(), |
259 file_task_runner_.get()); | 302 file_task_runner_.get()); |
260 for (size_t i = 0; i < kNumDownloads; ++i) { | 303 for (size_t i = 0; i < kNumDownloads; ++i) { |
261 SCOPED_TRACE(i); | 304 SCOPED_TRACE(i); |
262 service.BeginFeedbackForDownload(&item[i]); | 305 service.BeginFeedbackForDownload(&item[i], DownloadCommands::DISCARD); |
263 ASSERT_FALSE(download_discarded_callback[i].is_null()); | 306 ASSERT_FALSE(download_discarded_callback[i].is_null()); |
264 } | 307 } |
265 EXPECT_EQ(0U, num_feedbacks()); | 308 EXPECT_EQ(0U, num_feedbacks()); |
266 | 309 |
267 for (size_t i = 0; i < kNumDownloads; ++i) { | 310 for (size_t i = 0; i < kNumDownloads; ++i) { |
268 download_discarded_callback[i].Run(file_path[i]); | 311 download_discarded_callback[i].Run(file_path[i]); |
269 } | 312 } |
270 | 313 |
271 ASSERT_EQ(3U, num_feedbacks()); | 314 ASSERT_EQ(3U, num_feedbacks()); |
272 EXPECT_TRUE(feedback(0)->start_called()); | 315 EXPECT_TRUE(feedback(0)->start_called()); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
308 content::DownloadItem::AcquireFileCallback | 351 content::DownloadItem::AcquireFileCallback |
309 download_discarded_callback[kNumDownloads]; | 352 download_discarded_callback[kNumDownloads]; |
310 | 353 |
311 base::FilePath file_path[kNumDownloads]; | 354 base::FilePath file_path[kNumDownloads]; |
312 content::MockDownloadItem item[kNumDownloads]; | 355 content::MockDownloadItem item[kNumDownloads]; |
313 for (size_t i = 0; i < kNumDownloads; ++i) { | 356 for (size_t i = 0; i < kNumDownloads; ++i) { |
314 file_path[i] = CreateTestFile(i); | 357 file_path[i] = CreateTestFile(i); |
315 EXPECT_CALL(item[i], GetDangerType()) | 358 EXPECT_CALL(item[i], GetDangerType()) |
316 .WillRepeatedly(Return(content::DOWNLOAD_DANGER_TYPE_UNCOMMON_CONTENT)); | 359 .WillRepeatedly(Return(content::DOWNLOAD_DANGER_TYPE_UNCOMMON_CONTENT)); |
317 EXPECT_CALL(item[i], GetReceivedBytes()).WillRepeatedly(Return(1000)); | 360 EXPECT_CALL(item[i], GetReceivedBytes()).WillRepeatedly(Return(1000)); |
318 EXPECT_CALL(item[i], StealDangerousDownload(_)) | 361 EXPECT_CALL(item[i], StealDangerousDownload(true, _)) |
319 .WillOnce(SaveArg<0>(&download_discarded_callback[i])); | 362 .WillOnce(SaveArg<1>(&download_discarded_callback[i])); |
320 DownloadFeedbackService::MaybeStorePingsForDownload( | 363 DownloadFeedbackService::MaybeStorePingsForDownload( |
321 DownloadProtectionService::UNCOMMON, &item[i], ping_request, | 364 DownloadProtectionService::UNCOMMON, &item[i], ping_request, |
322 ping_response); | 365 ping_response); |
323 ASSERT_TRUE(DownloadFeedbackService::IsEnabledForDownload(item[i])); | 366 ASSERT_TRUE(DownloadFeedbackService::IsEnabledForDownload(item[i])); |
324 } | 367 } |
325 | 368 |
326 { | 369 { |
327 DownloadFeedbackService service(request_context_getter_.get(), | 370 DownloadFeedbackService service(request_context_getter_.get(), |
328 file_task_runner_.get()); | 371 file_task_runner_.get()); |
329 for (size_t i = 0; i < kNumDownloads; ++i) { | 372 for (size_t i = 0; i < kNumDownloads; ++i) { |
330 SCOPED_TRACE(i); | 373 SCOPED_TRACE(i); |
331 service.BeginFeedbackForDownload(&item[i]); | 374 service.BeginFeedbackForDownload(&item[i], DownloadCommands::DISCARD); |
332 ASSERT_FALSE(download_discarded_callback[i].is_null()); | 375 ASSERT_FALSE(download_discarded_callback[i].is_null()); |
333 } | 376 } |
334 EXPECT_EQ(0U, num_feedbacks()); | 377 EXPECT_EQ(0U, num_feedbacks()); |
335 | 378 |
336 download_discarded_callback[0].Run(file_path[0]); | 379 download_discarded_callback[0].Run(file_path[0]); |
337 ASSERT_EQ(1U, num_feedbacks()); | 380 ASSERT_EQ(1U, num_feedbacks()); |
338 ASSERT_TRUE(feedback(0)); | 381 ASSERT_TRUE(feedback(0)); |
339 EXPECT_TRUE(feedback(0)->start_called()); | 382 EXPECT_TRUE(feedback(0)->start_called()); |
340 | 383 |
341 download_discarded_callback[1].Run(file_path[1]); | 384 download_discarded_callback[1].Run(file_path[1]); |
(...skipping 25 matching lines...) Expand all Loading... |
367 // was deleted. | 410 // was deleted. |
368 EXPECT_FALSE(base::PathExists(file_path[2])); | 411 EXPECT_FALSE(base::PathExists(file_path[2])); |
369 | 412 |
370 // These files should still exist since the FakeDownloadFeedback does not | 413 // These files should still exist since the FakeDownloadFeedback does not |
371 // delete them. | 414 // delete them. |
372 EXPECT_TRUE(base::PathExists(file_path[0])); | 415 EXPECT_TRUE(base::PathExists(file_path[0])); |
373 EXPECT_TRUE(base::PathExists(file_path[1])); | 416 EXPECT_TRUE(base::PathExists(file_path[1])); |
374 } | 417 } |
375 | 418 |
376 } // namespace safe_browsing | 419 } // namespace safe_browsing |
OLD | NEW |