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 27 matching lines...) Expand all Loading... |
83 public: | 83 public: |
84 ~FakeDownloadFeedbackFactory() override {} | 84 ~FakeDownloadFeedbackFactory() override {} |
85 | 85 |
86 std::unique_ptr<DownloadFeedback> CreateDownloadFeedback( | 86 std::unique_ptr<DownloadFeedback> CreateDownloadFeedback( |
87 net::URLRequestContextGetter* request_context_getter, | 87 net::URLRequestContextGetter* request_context_getter, |
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, file_task_runner, file_path, ping_request, |
94 file_task_runner, | |
95 file_path, | |
96 ping_request, | |
97 ping_response, | 94 ping_response, |
98 base::Bind(&FakeDownloadFeedbackFactory::DownloadFeedbackDeleted, | 95 base::Bind(&FakeDownloadFeedbackFactory::DownloadFeedbackSent, |
99 base::Unretained(this), | 96 base::Unretained(this), feedbacks_.size())); |
100 feedbacks_.size())); | |
101 feedbacks_.push_back(feedback); | 97 feedbacks_.push_back(feedback); |
102 return base::WrapUnique(feedback); | 98 return base::WrapUnique(feedback); |
103 } | 99 } |
104 | 100 |
105 void DownloadFeedbackDeleted(size_t n) { feedbacks_[n] = nullptr; } | 101 void DownloadFeedbackSent(size_t n) { feedbacks_[n] = nullptr; } |
106 | 102 |
107 FakeDownloadFeedback* feedback(size_t n) const { | 103 FakeDownloadFeedback* feedback(size_t n) const { |
108 return feedbacks_[n]; | 104 return feedbacks_[n]; |
109 } | 105 } |
110 | 106 |
111 size_t num_feedbacks() const { | 107 size_t num_feedbacks() const { |
112 return feedbacks_.size(); | 108 return feedbacks_.size(); |
113 } | 109 } |
114 | 110 |
115 private: | 111 private: |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
186 | 182 |
187 EXPECT_FALSE(WillStorePings(DownloadProtectionService::SAFE, bad_size)); | 183 EXPECT_FALSE(WillStorePings(DownloadProtectionService::SAFE, bad_size)); |
188 EXPECT_FALSE(WillStorePings(DownloadProtectionService::DANGEROUS, bad_size)); | 184 EXPECT_FALSE(WillStorePings(DownloadProtectionService::DANGEROUS, bad_size)); |
189 EXPECT_FALSE(WillStorePings(DownloadProtectionService::UNCOMMON, bad_size)); | 185 EXPECT_FALSE(WillStorePings(DownloadProtectionService::UNCOMMON, bad_size)); |
190 EXPECT_FALSE( | 186 EXPECT_FALSE( |
191 WillStorePings(DownloadProtectionService::DANGEROUS_HOST, bad_size)); | 187 WillStorePings(DownloadProtectionService::DANGEROUS_HOST, bad_size)); |
192 EXPECT_FALSE(WillStorePings(DownloadProtectionService::POTENTIALLY_UNWANTED, | 188 EXPECT_FALSE(WillStorePings(DownloadProtectionService::POTENTIALLY_UNWANTED, |
193 bad_size)); | 189 bad_size)); |
194 } | 190 } |
195 | 191 |
196 TEST_F(DownloadFeedbackServiceTest, SingleFeedbackComplete) { | 192 TEST_F(DownloadFeedbackServiceTest, SingleFeedbackCompleteAndDiscardDownload) { |
197 const base::FilePath file_path(CreateTestFile(0)); | 193 const base::FilePath file_path(CreateTestFile(0)); |
198 const std::string ping_request = "ping"; | 194 const std::string ping_request = "ping"; |
199 const std::string ping_response = "resp"; | 195 const std::string ping_response = "resp"; |
200 | 196 |
201 content::DownloadItem::AcquireFileCallback download_discarded_callback; | 197 content::DownloadItem::AcquireFileCallback download_discarded_callback; |
202 | 198 |
203 content::MockDownloadItem item; | 199 content::MockDownloadItem item; |
204 EXPECT_CALL(item, GetDangerType()) | 200 EXPECT_CALL(item, GetDangerType()) |
205 .WillRepeatedly(Return(content::DOWNLOAD_DANGER_TYPE_UNCOMMON_CONTENT)); | 201 .WillRepeatedly(Return(content::DOWNLOAD_DANGER_TYPE_UNCOMMON_CONTENT)); |
206 EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(1000)); | 202 EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(1000)); |
207 EXPECT_CALL(item, StealDangerousDownload(_)) | 203 EXPECT_CALL(item, |
208 .WillOnce(SaveArg<0>(&download_discarded_callback)); | 204 StealDangerousDownload(true /*delete_file_after_feedback*/, _)) |
| 205 .WillOnce(SaveArg<1>(&download_discarded_callback)); |
209 | 206 |
210 DownloadFeedbackService service(request_context_getter_.get(), | 207 DownloadFeedbackService service(request_context_getter_.get(), |
211 file_task_runner_.get()); | 208 file_task_runner_.get()); |
212 service.MaybeStorePingsForDownload( | 209 service.MaybeStorePingsForDownload( |
213 DownloadProtectionService::UNCOMMON, &item, ping_request, ping_response); | 210 DownloadProtectionService::UNCOMMON, &item, ping_request, ping_response); |
214 ASSERT_TRUE(DownloadFeedbackService::IsEnabledForDownload(item)); | 211 ASSERT_TRUE(DownloadFeedbackService::IsEnabledForDownload(item)); |
215 service.BeginFeedbackForDownload(&item); | 212 service.BeginFeedbackForDownload(&item, DownloadCommands::DISCARD); |
216 ASSERT_FALSE(download_discarded_callback.is_null()); | 213 ASSERT_FALSE(download_discarded_callback.is_null()); |
217 EXPECT_EQ(0U, num_feedbacks()); | 214 EXPECT_EQ(0U, num_feedbacks()); |
218 | 215 |
| 216 download_discarded_callback.Run(file_path); |
| 217 ASSERT_EQ(1U, num_feedbacks()); |
| 218 ASSERT_TRUE(feedback(0)); |
| 219 EXPECT_TRUE(feedback(0)->start_called()); |
| 220 EXPECT_EQ(ping_request, feedback(0)->GetPingRequestForTesting()); |
| 221 EXPECT_EQ(ping_response, feedback(0)->GetPingResponseForTesting()); |
| 222 |
| 223 feedback(0)->finish_callback().Run(); |
| 224 EXPECT_FALSE(feedback(0)); |
| 225 |
| 226 base::RunLoop().RunUntilIdle(); |
| 227 EXPECT_TRUE(base::PathExists(file_path)); |
| 228 } |
| 229 |
| 230 TEST_F(DownloadFeedbackServiceTest, SingleFeedbackCompleteAndKeepDownload) { |
| 231 const base::FilePath file_path(CreateTestFile(0)); |
| 232 const std::string ping_request = "ping"; |
| 233 const std::string ping_response = "resp"; |
| 234 |
| 235 content::DownloadItem::AcquireFileCallback download_discarded_callback; |
| 236 |
| 237 content::MockDownloadItem item; |
| 238 EXPECT_CALL(item, GetDangerType()) |
| 239 .WillRepeatedly(Return(content::DOWNLOAD_DANGER_TYPE_UNCOMMON_CONTENT)); |
| 240 EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(1000)); |
| 241 EXPECT_CALL(item, |
| 242 StealDangerousDownload(false /*delete_file_after_feedback*/, _)) |
| 243 .WillOnce(SaveArg<1>(&download_discarded_callback)); |
| 244 EXPECT_CALL(item, ValidateDangerousDownload()).Times(1); |
| 245 GURL empty_url; |
| 246 EXPECT_CALL(item, GetURL()).WillOnce(ReturnRef(empty_url)); |
| 247 |
| 248 DownloadFeedbackService service(request_context_getter_.get(), |
| 249 file_task_runner_.get()); |
| 250 service.MaybeStorePingsForDownload(DownloadProtectionService::UNCOMMON, &item, |
| 251 ping_request, ping_response); |
| 252 ASSERT_TRUE(DownloadFeedbackService::IsEnabledForDownload(item)); |
| 253 service.BeginFeedbackForDownload(&item, DownloadCommands::KEEP); |
| 254 ASSERT_FALSE(download_discarded_callback.is_null()); |
| 255 EXPECT_EQ(0U, num_feedbacks()); |
| 256 |
219 download_discarded_callback.Run(file_path); | 257 download_discarded_callback.Run(file_path); |
220 ASSERT_EQ(1U, num_feedbacks()); | 258 ASSERT_EQ(1U, num_feedbacks()); |
221 ASSERT_TRUE(feedback(0)); | 259 ASSERT_TRUE(feedback(0)); |
222 EXPECT_TRUE(feedback(0)->start_called()); | 260 EXPECT_TRUE(feedback(0)->start_called()); |
223 EXPECT_EQ(ping_request, feedback(0)->GetPingRequestForTesting()); | 261 EXPECT_EQ(ping_request, feedback(0)->GetPingRequestForTesting()); |
224 EXPECT_EQ(ping_response, feedback(0)->GetPingResponseForTesting()); | 262 EXPECT_EQ(ping_response, feedback(0)->GetPingResponseForTesting()); |
225 | 263 |
226 feedback(0)->finish_callback().Run(); | 264 feedback(0)->finish_callback().Run(); |
227 EXPECT_FALSE(feedback(0)); | 265 EXPECT_FALSE(feedback(0)); |
228 | 266 |
229 // File should still exist since our FakeDownloadFeedback does not delete it. | |
230 base::RunLoop().RunUntilIdle(); | 267 base::RunLoop().RunUntilIdle(); |
231 EXPECT_TRUE(base::PathExists(file_path)); | 268 EXPECT_TRUE(base::PathExists(file_path)); |
232 } | 269 } |
233 | 270 |
234 TEST_F(DownloadFeedbackServiceTest, MultiplePendingFeedbackComplete) { | 271 TEST_F(DownloadFeedbackServiceTest, MultiplePendingFeedbackComplete) { |
235 const std::string ping_request = "ping"; | 272 const std::string ping_request = "ping"; |
236 const std::string ping_response = "resp"; | 273 const std::string ping_response = "resp"; |
237 const size_t kNumDownloads = 3; | 274 const size_t kNumDownloads = 3; |
238 | 275 |
239 content::DownloadItem::AcquireFileCallback | 276 content::DownloadItem::AcquireFileCallback |
240 download_discarded_callback[kNumDownloads]; | 277 download_discarded_callback[kNumDownloads]; |
241 | 278 |
242 base::FilePath file_path[kNumDownloads]; | 279 base::FilePath file_path[kNumDownloads]; |
243 content::MockDownloadItem item[kNumDownloads]; | 280 content::MockDownloadItem item[kNumDownloads]; |
244 for (size_t i = 0; i < kNumDownloads; ++i) { | 281 for (size_t i = 0; i < kNumDownloads; ++i) { |
245 file_path[i] = CreateTestFile(i); | 282 file_path[i] = CreateTestFile(i); |
246 EXPECT_CALL(item[i], GetDangerType()) | 283 EXPECT_CALL(item[i], GetDangerType()) |
247 .WillRepeatedly(Return(content::DOWNLOAD_DANGER_TYPE_UNCOMMON_CONTENT)); | 284 .WillRepeatedly(Return(content::DOWNLOAD_DANGER_TYPE_UNCOMMON_CONTENT)); |
248 EXPECT_CALL(item[i], GetReceivedBytes()).WillRepeatedly(Return(1000)); | 285 EXPECT_CALL(item[i], GetReceivedBytes()).WillRepeatedly(Return(1000)); |
249 EXPECT_CALL(item[i], StealDangerousDownload(_)) | 286 EXPECT_CALL(item[i], StealDangerousDownload(true, _)) |
250 .WillOnce(SaveArg<0>(&download_discarded_callback[i])); | 287 .WillOnce(SaveArg<1>(&download_discarded_callback[i])); |
251 DownloadFeedbackService::MaybeStorePingsForDownload( | 288 DownloadFeedbackService::MaybeStorePingsForDownload( |
252 DownloadProtectionService::UNCOMMON, &item[i], ping_request, | 289 DownloadProtectionService::UNCOMMON, &item[i], ping_request, |
253 ping_response); | 290 ping_response); |
254 ASSERT_TRUE(DownloadFeedbackService::IsEnabledForDownload(item[i])); | 291 ASSERT_TRUE(DownloadFeedbackService::IsEnabledForDownload(item[i])); |
255 } | 292 } |
256 | 293 |
257 { | 294 { |
258 DownloadFeedbackService service(request_context_getter_.get(), | 295 DownloadFeedbackService service(request_context_getter_.get(), |
259 file_task_runner_.get()); | 296 file_task_runner_.get()); |
260 for (size_t i = 0; i < kNumDownloads; ++i) { | 297 for (size_t i = 0; i < kNumDownloads; ++i) { |
261 SCOPED_TRACE(i); | 298 SCOPED_TRACE(i); |
262 service.BeginFeedbackForDownload(&item[i]); | 299 service.BeginFeedbackForDownload(&item[i], DownloadCommands::DISCARD); |
263 ASSERT_FALSE(download_discarded_callback[i].is_null()); | 300 ASSERT_FALSE(download_discarded_callback[i].is_null()); |
264 } | 301 } |
265 EXPECT_EQ(0U, num_feedbacks()); | 302 EXPECT_EQ(0U, num_feedbacks()); |
266 | 303 |
267 for (size_t i = 0; i < kNumDownloads; ++i) { | 304 for (size_t i = 0; i < kNumDownloads; ++i) { |
268 download_discarded_callback[i].Run(file_path[i]); | 305 download_discarded_callback[i].Run(file_path[i]); |
269 } | 306 } |
270 | 307 |
271 ASSERT_EQ(3U, num_feedbacks()); | 308 ASSERT_EQ(3U, num_feedbacks()); |
272 EXPECT_TRUE(feedback(0)->start_called()); | 309 EXPECT_TRUE(feedback(0)->start_called()); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
308 content::DownloadItem::AcquireFileCallback | 345 content::DownloadItem::AcquireFileCallback |
309 download_discarded_callback[kNumDownloads]; | 346 download_discarded_callback[kNumDownloads]; |
310 | 347 |
311 base::FilePath file_path[kNumDownloads]; | 348 base::FilePath file_path[kNumDownloads]; |
312 content::MockDownloadItem item[kNumDownloads]; | 349 content::MockDownloadItem item[kNumDownloads]; |
313 for (size_t i = 0; i < kNumDownloads; ++i) { | 350 for (size_t i = 0; i < kNumDownloads; ++i) { |
314 file_path[i] = CreateTestFile(i); | 351 file_path[i] = CreateTestFile(i); |
315 EXPECT_CALL(item[i], GetDangerType()) | 352 EXPECT_CALL(item[i], GetDangerType()) |
316 .WillRepeatedly(Return(content::DOWNLOAD_DANGER_TYPE_UNCOMMON_CONTENT)); | 353 .WillRepeatedly(Return(content::DOWNLOAD_DANGER_TYPE_UNCOMMON_CONTENT)); |
317 EXPECT_CALL(item[i], GetReceivedBytes()).WillRepeatedly(Return(1000)); | 354 EXPECT_CALL(item[i], GetReceivedBytes()).WillRepeatedly(Return(1000)); |
318 EXPECT_CALL(item[i], StealDangerousDownload(_)) | 355 EXPECT_CALL(item[i], StealDangerousDownload(true, _)) |
319 .WillOnce(SaveArg<0>(&download_discarded_callback[i])); | 356 .WillOnce(SaveArg<1>(&download_discarded_callback[i])); |
320 DownloadFeedbackService::MaybeStorePingsForDownload( | 357 DownloadFeedbackService::MaybeStorePingsForDownload( |
321 DownloadProtectionService::UNCOMMON, &item[i], ping_request, | 358 DownloadProtectionService::UNCOMMON, &item[i], ping_request, |
322 ping_response); | 359 ping_response); |
323 ASSERT_TRUE(DownloadFeedbackService::IsEnabledForDownload(item[i])); | 360 ASSERT_TRUE(DownloadFeedbackService::IsEnabledForDownload(item[i])); |
324 } | 361 } |
325 | 362 |
326 { | 363 { |
327 DownloadFeedbackService service(request_context_getter_.get(), | 364 DownloadFeedbackService service(request_context_getter_.get(), |
328 file_task_runner_.get()); | 365 file_task_runner_.get()); |
329 for (size_t i = 0; i < kNumDownloads; ++i) { | 366 for (size_t i = 0; i < kNumDownloads; ++i) { |
330 SCOPED_TRACE(i); | 367 SCOPED_TRACE(i); |
331 service.BeginFeedbackForDownload(&item[i]); | 368 service.BeginFeedbackForDownload(&item[i], DownloadCommands::DISCARD); |
332 ASSERT_FALSE(download_discarded_callback[i].is_null()); | 369 ASSERT_FALSE(download_discarded_callback[i].is_null()); |
333 } | 370 } |
334 EXPECT_EQ(0U, num_feedbacks()); | 371 EXPECT_EQ(0U, num_feedbacks()); |
335 | 372 |
336 download_discarded_callback[0].Run(file_path[0]); | 373 download_discarded_callback[0].Run(file_path[0]); |
337 ASSERT_EQ(1U, num_feedbacks()); | 374 ASSERT_EQ(1U, num_feedbacks()); |
338 ASSERT_TRUE(feedback(0)); | 375 ASSERT_TRUE(feedback(0)); |
339 EXPECT_TRUE(feedback(0)->start_called()); | 376 EXPECT_TRUE(feedback(0)->start_called()); |
340 | 377 |
341 download_discarded_callback[1].Run(file_path[1]); | 378 download_discarded_callback[1].Run(file_path[1]); |
(...skipping 25 matching lines...) Expand all Loading... |
367 // was deleted. | 404 // was deleted. |
368 EXPECT_FALSE(base::PathExists(file_path[2])); | 405 EXPECT_FALSE(base::PathExists(file_path[2])); |
369 | 406 |
370 // These files should still exist since the FakeDownloadFeedback does not | 407 // These files should still exist since the FakeDownloadFeedback does not |
371 // delete them. | 408 // delete them. |
372 EXPECT_TRUE(base::PathExists(file_path[0])); | 409 EXPECT_TRUE(base::PathExists(file_path[0])); |
373 EXPECT_TRUE(base::PathExists(file_path[1])); | 410 EXPECT_TRUE(base::PathExists(file_path[1])); |
374 } | 411 } |
375 | 412 |
376 } // namespace safe_browsing | 413 } // namespace safe_browsing |
OLD | NEW |