OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "base/file_util.h" | 5 #include "base/file_util.h" |
6 #include "base/message_loop.h" | 6 #include "base/message_loop.h" |
7 #include "base/string_number_conversions.h" | 7 #include "base/string_number_conversions.h" |
8 #include "base/test/test_file_util.h" | |
8 #include "content/browser/browser_thread_impl.h" | 9 #include "content/browser/browser_thread_impl.h" |
9 #include "content/browser/download/byte_stream.h" | 10 #include "content/browser/download/byte_stream.h" |
10 #include "content/browser/download/download_create_info.h" | 11 #include "content/browser/download/download_create_info.h" |
11 #include "content/browser/download/download_file_impl.h" | 12 #include "content/browser/download/download_file_impl.h" |
12 #include "content/browser/download/download_request_handle.h" | 13 #include "content/browser/download/download_request_handle.h" |
13 #include "content/browser/power_save_blocker.h" | 14 #include "content/browser/power_save_blocker.h" |
14 #include "content/public/browser/download_interrupt_reasons.h" | 15 #include "content/public/browser/download_interrupt_reasons.h" |
15 #include "content/public/browser/download_manager.h" | 16 #include "content/public/browser/download_manager.h" |
16 #include "content/public/test/mock_download_manager.h" | 17 #include "content/public/test/mock_download_manager.h" |
17 #include "net/base/file_stream.h" | 18 #include "net/base/file_stream.h" |
19 #include "net/base/mock_file_stream.h" | |
18 #include "net/base/net_errors.h" | 20 #include "net/base/net_errors.h" |
19 #include "testing/gmock/include/gmock/gmock.h" | 21 #include "testing/gmock/include/gmock/gmock.h" |
20 #include "testing/gtest/include/gtest/gtest.h" | 22 #include "testing/gtest/include/gtest/gtest.h" |
21 | 23 |
22 using content::BrowserThread; | 24 using content::BrowserThread; |
23 using content::BrowserThreadImpl; | 25 using content::BrowserThreadImpl; |
24 using content::DownloadFile; | 26 using content::DownloadFile; |
25 using content::DownloadId; | 27 using content::DownloadId; |
26 using content::DownloadManager; | 28 using content::DownloadManager; |
27 using ::testing::_; | 29 using ::testing::_; |
28 using ::testing::AnyNumber; | 30 using ::testing::AnyNumber; |
29 using ::testing::DoAll; | 31 using ::testing::DoAll; |
32 using ::testing::InSequence; | |
30 using ::testing::Return; | 33 using ::testing::Return; |
31 using ::testing::SetArgPointee; | 34 using ::testing::SetArgPointee; |
32 using ::testing::StrictMock; | 35 using ::testing::StrictMock; |
33 | 36 |
34 namespace { | 37 namespace { |
35 | 38 |
36 class MockByteStreamReader : public content::ByteStreamReader { | 39 class MockByteStreamReader : public content::ByteStreamReader { |
37 public: | 40 public: |
38 MockByteStreamReader() {} | 41 MockByteStreamReader() {} |
39 ~MockByteStreamReader() {} | 42 ~MockByteStreamReader() {} |
40 | 43 |
41 // ByteStream functions | 44 // ByteStream functions |
42 MOCK_METHOD2(Read, content::ByteStreamReader::StreamState( | 45 MOCK_METHOD2(Read, content::ByteStreamReader::StreamState( |
43 scoped_refptr<net::IOBuffer>*, size_t*)); | 46 scoped_refptr<net::IOBuffer>*, size_t*)); |
44 MOCK_CONST_METHOD0(GetStatus, content::DownloadInterruptReason()); | 47 MOCK_CONST_METHOD0(GetStatus, content::DownloadInterruptReason()); |
45 MOCK_METHOD1(RegisterCallback, void(const base::Closure&)); | 48 MOCK_METHOD1(RegisterCallback, void(const base::Closure&)); |
46 }; | 49 }; |
47 | 50 |
51 class LocalMockDownloadManager : public content::MockDownloadManager { | |
52 public: | |
53 MOCK_METHOD4(CurrentUpdateStatus, | |
54 void(int32, int64, int64, const std::string&)); | |
55 }; | |
56 | |
48 } // namespace | 57 } // namespace |
49 | 58 |
50 DownloadId::Domain kValidIdDomain = "valid DownloadId::Domain"; | 59 DownloadId::Domain kValidIdDomain = "valid DownloadId::Domain"; |
51 | 60 |
52 class DownloadFileTest : public testing::Test { | 61 class DownloadFileTest : public testing::Test { |
53 public: | 62 public: |
54 | 63 |
55 static const char* kTestData1; | 64 static const char* kTestData1; |
56 static const char* kTestData2; | 65 static const char* kTestData2; |
57 static const char* kTestData3; | 66 static const char* kTestData3; |
58 static const char* kDataHash; | 67 static const char* kDataHash; |
59 static const int32 kDummyDownloadId; | 68 static const int32 kDummyDownloadId; |
60 static const int kDummyChildId; | 69 static const int kDummyChildId; |
61 static const int kDummyRequestId; | 70 static const int kDummyRequestId; |
62 | 71 |
63 // We need a UI |BrowserThread| in order to destruct |download_manager_|, | 72 // We need a UI |BrowserThread| in order to destruct |download_manager_|, |
64 // which has trait |BrowserThread::DeleteOnUIThread|. Without this, | 73 // which has trait |BrowserThread::DeleteOnUIThread|. Without this, |
65 // calling Release() on |download_manager_| won't ever result in its | 74 // calling Release() on |download_manager_| won't ever result in its |
66 // destructor being called and we get a leak. | 75 // destructor being called and we get a leak. |
67 DownloadFileTest() : | 76 DownloadFileTest() : |
77 update_download_id_(-1), | |
78 bytes_(-1), | |
79 bytes_per_sec_(-1), | |
80 hash_state_("xyzzy"), | |
68 ui_thread_(BrowserThread::UI, &loop_), | 81 ui_thread_(BrowserThread::UI, &loop_), |
69 file_thread_(BrowserThread::FILE, &loop_) { | 82 file_thread_(BrowserThread::FILE, &loop_) { |
70 } | 83 } |
71 | 84 |
72 ~DownloadFileTest() { | 85 ~DownloadFileTest() { |
73 } | 86 } |
74 | 87 |
75 void SetUpdateDownloadInfo(int32 id, int64 bytes, int64 bytes_per_sec, | 88 void SetUpdateDownloadInfo(int32 id, int64 bytes, int64 bytes_per_sec, |
76 const std::string& hash_state) { | 89 const std::string& hash_state) { |
90 update_download_id_ = id; | |
77 bytes_ = bytes; | 91 bytes_ = bytes; |
78 bytes_per_sec_ = bytes_per_sec; | 92 bytes_per_sec_ = bytes_per_sec; |
79 hash_state_ = hash_state; | 93 hash_state_ = hash_state; |
80 } | 94 } |
81 | 95 |
96 void ConfirmUpdateDownloadInfo() { | |
97 download_manager_->CurrentUpdateStatus( | |
98 update_download_id_, bytes_, bytes_per_sec_, hash_state_); | |
99 } | |
100 | |
82 virtual void SetUp() { | 101 virtual void SetUp() { |
83 download_manager_ = new StrictMock<content::MockDownloadManager>; | 102 download_manager_ = new StrictMock<LocalMockDownloadManager>; |
84 EXPECT_CALL(*(download_manager_.get()), | 103 EXPECT_CALL(*(download_manager_.get()), |
85 UpdateDownload( | 104 UpdateDownload( |
86 DownloadId(kValidIdDomain, kDummyDownloadId + 0).local(), | 105 DownloadId(kValidIdDomain, kDummyDownloadId + 0).local(), |
87 _, _, _)) | 106 _, _, _)) |
88 .Times(AnyNumber()) | 107 .Times(AnyNumber()) |
89 .WillRepeatedly(Invoke(this, &DownloadFileTest::SetUpdateDownloadInfo)); | 108 .WillRepeatedly(Invoke(this, &DownloadFileTest::SetUpdateDownloadInfo)); |
90 } | 109 } |
91 | 110 |
92 virtual void TearDown() { | 111 virtual void TearDown() { |
93 // When a DownloadManager's reference count drops to 0, it is not | 112 // When a DownloadManager's reference count drops to 0, it is not |
(...skipping 16 matching lines...) Expand all Loading... | |
110 | 129 |
111 input_stream_ = new StrictMock<MockByteStreamReader>(); | 130 input_stream_ = new StrictMock<MockByteStreamReader>(); |
112 | 131 |
113 // TODO: Need to actually create a function that'll set the variables | 132 // TODO: Need to actually create a function that'll set the variables |
114 // based on the inputs from the callback. | 133 // based on the inputs from the callback. |
115 EXPECT_CALL(*input_stream_, RegisterCallback(_)) | 134 EXPECT_CALL(*input_stream_, RegisterCallback(_)) |
116 .WillOnce(Invoke(this, &DownloadFileTest::RegisterCallback)) | 135 .WillOnce(Invoke(this, &DownloadFileTest::RegisterCallback)) |
117 .RetiresOnSaturation(); | 136 .RetiresOnSaturation(); |
118 | 137 |
119 DownloadCreateInfo info; | 138 DownloadCreateInfo info; |
139 // info.request_handle default constructed to null. | |
120 info.download_id = DownloadId(kValidIdDomain, kDummyDownloadId + offset); | 140 info.download_id = DownloadId(kValidIdDomain, kDummyDownloadId + offset); |
121 // info.request_handle default constructed to null. | |
122 info.save_info.file_stream = file_stream_; | 141 info.save_info.file_stream = file_stream_; |
123 download_file_.reset( | 142 download_file_.reset( |
124 new DownloadFileImpl( | 143 new DownloadFileImpl( |
125 &info, | 144 &info, |
126 scoped_ptr<content::ByteStreamReader>(input_stream_).Pass(), | 145 scoped_ptr<content::ByteStreamReader>(input_stream_).Pass(), |
127 new DownloadRequestHandle(), | 146 new DownloadRequestHandle(), |
128 download_manager_, calculate_hash, | 147 download_manager_, calculate_hash, |
129 scoped_ptr<content::PowerSaveBlocker>(NULL).Pass(), | 148 scoped_ptr<content::PowerSaveBlocker>(NULL).Pass(), |
130 net::BoundNetLog())); | 149 net::BoundNetLog())); |
131 | 150 |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
221 EXPECT_CALL(*(download_manager_.get()), | 240 EXPECT_CALL(*(download_manager_.get()), |
222 UpdateDownload( | 241 UpdateDownload( |
223 DownloadId(kValidIdDomain, kDummyDownloadId + 0).local(), | 242 DownloadId(kValidIdDomain, kDummyDownloadId + 0).local(), |
224 _, _, _)) | 243 _, _, _)) |
225 .Times(AnyNumber()) | 244 .Times(AnyNumber()) |
226 .WillRepeatedly(Invoke(this, | 245 .WillRepeatedly(Invoke(this, |
227 &DownloadFileTest::SetUpdateDownloadInfo)); | 246 &DownloadFileTest::SetUpdateDownloadInfo)); |
228 } | 247 } |
229 } | 248 } |
230 | 249 |
250 content::DownloadInterruptReason Rename( | |
251 const FilePath& full_path, bool overwrite_existing_file, | |
252 FilePath* result_path_p) { | |
253 base::WeakPtrFactory<DownloadFileTest> weak_ptr_factory(this); | |
254 content::DownloadInterruptReason result_reason( | |
255 content::DOWNLOAD_INTERRUPT_REASON_NONE); | |
256 bool callback_was_called(false); | |
257 FilePath result_path; | |
258 | |
259 download_file_->Rename(full_path, overwrite_existing_file, | |
260 base::Bind(&DownloadFileTest::SetRenameResult, | |
261 weak_ptr_factory.GetWeakPtr(), | |
262 &callback_was_called, | |
263 &result_reason, result_path_p)); | |
264 loop_.RunAllPending(); | |
265 | |
266 EXPECT_TRUE(callback_was_called); | |
267 return result_reason; | |
268 } | |
269 | |
231 protected: | 270 protected: |
232 scoped_refptr<StrictMock<content::MockDownloadManager> > download_manager_; | 271 scoped_refptr<StrictMock<LocalMockDownloadManager> > download_manager_; |
233 | 272 |
234 linked_ptr<net::FileStream> file_stream_; | 273 linked_ptr<net::FileStream> file_stream_; |
235 | 274 |
236 // DownloadFile instance we are testing. | 275 // DownloadFile instance we are testing. |
237 scoped_ptr<DownloadFile> download_file_; | 276 scoped_ptr<DownloadFile> download_file_; |
238 | 277 |
239 // Stream for sending data into the download file. | 278 // Stream for sending data into the download file. |
240 // Owned by download_file_; will be alive for lifetime of download_file_. | 279 // Owned by download_file_; will be alive for lifetime of download_file_. |
241 StrictMock<MockByteStreamReader>* input_stream_; | 280 StrictMock<MockByteStreamReader>* input_stream_; |
242 | 281 |
243 // Sink callback data for stream. | 282 // Sink callback data for stream. |
244 base::Closure sink_callback_; | 283 base::Closure sink_callback_; |
245 | 284 |
246 // Latest update sent to the download manager. | 285 // Latest update sent to the download manager. |
286 int32 update_download_id_; | |
247 int64 bytes_; | 287 int64 bytes_; |
248 int64 bytes_per_sec_; | 288 int64 bytes_per_sec_; |
249 std::string hash_state_; | 289 std::string hash_state_; |
250 | 290 |
251 MessageLoop loop_; | 291 MessageLoop loop_; |
252 | 292 |
253 private: | 293 private: |
294 void SetRenameResult(bool* called_p, | |
295 content::DownloadInterruptReason* reason_p, | |
296 FilePath* result_path_p, | |
297 content::DownloadInterruptReason reason, | |
298 const FilePath& result_path) { | |
299 if (called_p) | |
300 *called_p = true; | |
301 if (reason_p) | |
302 *reason_p = reason; | |
303 if (result_path_p) | |
304 *result_path_p = result_path; | |
305 } | |
306 | |
254 // UI thread. | 307 // UI thread. |
255 BrowserThreadImpl ui_thread_; | 308 BrowserThreadImpl ui_thread_; |
256 // File thread to satisfy debug checks in DownloadFile. | 309 // File thread to satisfy debug checks in DownloadFile. |
257 BrowserThreadImpl file_thread_; | 310 BrowserThreadImpl file_thread_; |
258 | 311 |
259 // Keep track of what data should be saved to the disk file. | 312 // Keep track of what data should be saved to the disk file. |
260 std::string expected_data_; | 313 std::string expected_data_; |
261 }; | 314 }; |
262 | 315 |
263 const char* DownloadFileTest::kTestData1 = | 316 const char* DownloadFileTest::kTestData1 = |
(...skipping 10 matching lines...) Expand all Loading... | |
274 // Rename the file before any data is downloaded, after some has, after it all | 327 // Rename the file before any data is downloaded, after some has, after it all |
275 // has, and after it's closed. | 328 // has, and after it's closed. |
276 TEST_F(DownloadFileTest, RenameFileFinal) { | 329 TEST_F(DownloadFileTest, RenameFileFinal) { |
277 ASSERT_TRUE(CreateDownloadFile(0, true)); | 330 ASSERT_TRUE(CreateDownloadFile(0, true)); |
278 FilePath initial_path(download_file_->FullPath()); | 331 FilePath initial_path(download_file_->FullPath()); |
279 EXPECT_TRUE(file_util::PathExists(initial_path)); | 332 EXPECT_TRUE(file_util::PathExists(initial_path)); |
280 FilePath path_1(initial_path.InsertBeforeExtensionASCII("_1")); | 333 FilePath path_1(initial_path.InsertBeforeExtensionASCII("_1")); |
281 FilePath path_2(initial_path.InsertBeforeExtensionASCII("_2")); | 334 FilePath path_2(initial_path.InsertBeforeExtensionASCII("_2")); |
282 FilePath path_3(initial_path.InsertBeforeExtensionASCII("_3")); | 335 FilePath path_3(initial_path.InsertBeforeExtensionASCII("_3")); |
283 FilePath path_4(initial_path.InsertBeforeExtensionASCII("_4")); | 336 FilePath path_4(initial_path.InsertBeforeExtensionASCII("_4")); |
337 FilePath path_5(initial_path.InsertBeforeExtensionASCII("_5")); | |
338 FilePath output_path; | |
284 | 339 |
285 // Rename the file before downloading any data. | 340 // Rename the file before downloading any data. |
286 EXPECT_EQ(content::DOWNLOAD_INTERRUPT_REASON_NONE, | 341 EXPECT_EQ(content::DOWNLOAD_INTERRUPT_REASON_NONE, |
287 download_file_->Rename(path_1)); | 342 Rename(path_1, false, &output_path)); |
288 FilePath renamed_path = download_file_->FullPath(); | 343 FilePath renamed_path = download_file_->FullPath(); |
289 EXPECT_EQ(path_1, renamed_path); | 344 EXPECT_EQ(path_1, renamed_path); |
345 EXPECT_EQ(path_1, output_path); | |
290 | 346 |
291 // Check the files. | 347 // Check the files. |
292 EXPECT_FALSE(file_util::PathExists(initial_path)); | 348 EXPECT_FALSE(file_util::PathExists(initial_path)); |
293 EXPECT_TRUE(file_util::PathExists(path_1)); | 349 EXPECT_TRUE(file_util::PathExists(path_1)); |
294 | 350 |
295 // Download the data. | 351 // Download the data. |
296 const char* chunks1[] = { kTestData1, kTestData2 }; | 352 const char* chunks1[] = { kTestData1, kTestData2 }; |
297 AppendDataToFile(chunks1, 2); | 353 AppendDataToFile(chunks1, 2); |
298 | 354 |
299 // Rename the file after downloading some data. | 355 // Rename the file after downloading some data. |
300 EXPECT_EQ(content::DOWNLOAD_INTERRUPT_REASON_NONE, | 356 EXPECT_EQ(content::DOWNLOAD_INTERRUPT_REASON_NONE, |
301 download_file_->Rename(path_2)); | 357 Rename(path_2, false, &output_path)); |
302 renamed_path = download_file_->FullPath(); | 358 renamed_path = download_file_->FullPath(); |
303 EXPECT_EQ(path_2, renamed_path); | 359 EXPECT_EQ(path_2, renamed_path); |
360 EXPECT_EQ(path_2, output_path); | |
304 | 361 |
305 // Check the files. | 362 // Check the files. |
306 EXPECT_FALSE(file_util::PathExists(path_1)); | 363 EXPECT_FALSE(file_util::PathExists(path_1)); |
307 EXPECT_TRUE(file_util::PathExists(path_2)); | 364 EXPECT_TRUE(file_util::PathExists(path_2)); |
308 | 365 |
309 const char* chunks2[] = { kTestData3 }; | 366 const char* chunks2[] = { kTestData3 }; |
310 AppendDataToFile(chunks2, 1); | 367 AppendDataToFile(chunks2, 1); |
311 | 368 |
312 // Rename the file after downloading all the data. | 369 // Rename the file after downloading all the data. |
313 EXPECT_EQ(content::DOWNLOAD_INTERRUPT_REASON_NONE, | 370 EXPECT_EQ(content::DOWNLOAD_INTERRUPT_REASON_NONE, |
314 download_file_->Rename(path_3)); | 371 Rename(path_3, false, &output_path)); |
315 renamed_path = download_file_->FullPath(); | 372 renamed_path = download_file_->FullPath(); |
316 EXPECT_EQ(path_3, renamed_path); | 373 EXPECT_EQ(path_3, renamed_path); |
374 EXPECT_EQ(path_3, output_path); | |
317 | 375 |
318 // Check the files. | 376 // Check the files. |
319 EXPECT_FALSE(file_util::PathExists(path_2)); | 377 EXPECT_FALSE(file_util::PathExists(path_2)); |
320 EXPECT_TRUE(file_util::PathExists(path_3)); | 378 EXPECT_TRUE(file_util::PathExists(path_3)); |
321 | 379 |
322 // Should not be able to get the hash until the file is closed. | 380 // Should not be able to get the hash until the file is closed. |
323 std::string hash; | 381 std::string hash; |
324 EXPECT_FALSE(download_file_->GetHash(&hash)); | 382 EXPECT_FALSE(download_file_->GetHash(&hash)); |
325 FinishStream(content::DOWNLOAD_INTERRUPT_REASON_NONE, true); | 383 FinishStream(content::DOWNLOAD_INTERRUPT_REASON_NONE, true); |
326 loop_.RunAllPending(); | 384 loop_.RunAllPending(); |
327 | 385 |
328 // Rename the file after downloading all the data and closing the file. | 386 // Rename the file after downloading all the data and closing the file. |
329 EXPECT_EQ(content::DOWNLOAD_INTERRUPT_REASON_NONE, | 387 EXPECT_EQ(content::DOWNLOAD_INTERRUPT_REASON_NONE, |
330 download_file_->Rename(path_4)); | 388 Rename(path_4, false, &output_path)); |
331 renamed_path = download_file_->FullPath(); | 389 renamed_path = download_file_->FullPath(); |
332 EXPECT_EQ(path_4, renamed_path); | 390 EXPECT_EQ(path_4, renamed_path); |
391 EXPECT_EQ(path_4, output_path); | |
333 | 392 |
334 // Check the files. | 393 // Check the files. |
335 EXPECT_FALSE(file_util::PathExists(path_3)); | 394 EXPECT_FALSE(file_util::PathExists(path_3)); |
336 EXPECT_TRUE(file_util::PathExists(path_4)); | 395 EXPECT_TRUE(file_util::PathExists(path_4)); |
337 | 396 |
338 // Check the hash. | 397 // Check the hash. |
339 EXPECT_TRUE(download_file_->GetHash(&hash)); | 398 EXPECT_TRUE(download_file_->GetHash(&hash)); |
340 EXPECT_EQ(kDataHash, base::HexEncode(hash.data(), hash.size())); | 399 EXPECT_EQ(kDataHash, base::HexEncode(hash.data(), hash.size())); |
341 | 400 |
401 // Check that a rename with overwrite to an existing file succeeds. | |
402 std::string file_contents; | |
403 ASSERT_FALSE(file_util::PathExists(path_5)); | |
404 static const char file_data[] = "xyzzy"; | |
405 ASSERT_EQ(static_cast<int>(sizeof(file_data) - 1), | |
406 file_util::WriteFile(path_5, file_data, sizeof(file_data) - 1)); | |
407 ASSERT_TRUE(file_util::PathExists(path_5)); | |
408 EXPECT_TRUE(file_util::ReadFileToString(path_5, &file_contents)); | |
409 EXPECT_EQ(std::string(file_data), file_contents); | |
410 | |
411 EXPECT_EQ(content::DOWNLOAD_INTERRUPT_REASON_NONE, | |
412 Rename(path_5, true, &output_path)); | |
413 EXPECT_EQ(path_5, output_path); | |
414 | |
415 file_contents = ""; | |
416 EXPECT_TRUE(file_util::ReadFileToString(path_5, &file_contents)); | |
417 EXPECT_NE(std::string(file_data), file_contents); | |
418 | |
342 DestroyDownloadFile(0); | 419 DestroyDownloadFile(0); |
343 } | 420 } |
344 | 421 |
422 // Test to make sure the rename uniquifies if we aren't overwriting | |
423 // and there's a file where we're aiming. | |
424 TEST_F(DownloadFileTest, RenameUniquifies) { | |
425 ASSERT_TRUE(CreateDownloadFile(0, true)); | |
426 FilePath initial_path(download_file_->FullPath()); | |
427 EXPECT_TRUE(file_util::PathExists(initial_path)); | |
428 FilePath path_1(initial_path.InsertBeforeExtensionASCII("_1")); | |
429 FilePath path_1_suffixed(path_1.InsertBeforeExtensionASCII(" (1)")); | |
430 | |
431 ASSERT_FALSE(file_util::PathExists(path_1)); | |
432 static const char file_data[] = "xyzzy"; | |
433 ASSERT_EQ(static_cast<int>(sizeof(file_data)), | |
434 file_util::WriteFile(path_1, file_data, sizeof(file_data))); | |
435 ASSERT_TRUE(file_util::PathExists(path_1)); | |
436 | |
437 EXPECT_EQ(content::DOWNLOAD_INTERRUPT_REASON_NONE, | |
438 Rename(path_1, false, NULL)); | |
439 EXPECT_TRUE(file_util::PathExists(path_1_suffixed)); | |
440 | |
441 FinishStream(content::DOWNLOAD_INTERRUPT_REASON_NONE, true); | |
442 loop_.RunAllPending(); | |
443 DestroyDownloadFile(0); | |
444 } | |
445 | |
446 // Test to make sure we get the proper error on failure. | |
447 TEST_F(DownloadFileTest, RenameError) { | |
448 ASSERT_TRUE(CreateDownloadFile(0, true)); | |
449 FilePath initial_path(download_file_->FullPath()); | |
450 EXPECT_TRUE(file_util::PathExists(initial_path)); | |
451 FilePath path_1(initial_path.InsertBeforeExtensionASCII("_1")); | |
452 FilePath path_1_suffixed(path_1.InsertBeforeExtensionASCII(" (1)")); | |
453 ASSERT_FALSE(file_util::PathExists(path_1_suffixed)); | |
454 | |
455 ASSERT_FALSE(file_util::PathExists(path_1)); | |
456 static const char file_data[] = "xyzzy"; | |
457 ASSERT_EQ(static_cast<int>(sizeof(file_data)), | |
458 file_util::WriteFile(path_1, file_data, sizeof(file_data))); | |
459 ASSERT_TRUE(file_util::PathExists(path_1)); | |
460 | |
461 { | |
462 file_util::PermissionRestorer restorer(path_1); | |
463 ASSERT_TRUE(file_util::MakeFileUnwritable(path_1)); | |
asanka
2012/07/10 18:11:45
Apparently this isn't enough. See http://coderevie
| |
464 | |
465 EXPECT_EQ(content::DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED, | |
466 Rename(path_1, true, NULL)); | |
467 EXPECT_FALSE(file_util::PathExists(path_1_suffixed)); | |
468 } | |
469 | |
470 FinishStream(content::DOWNLOAD_INTERRUPT_REASON_NONE, true); | |
471 loop_.RunAllPending(); | |
472 DestroyDownloadFile(0); | |
473 } | |
474 | |
345 // Various tests of the StreamActive method. | 475 // Various tests of the StreamActive method. |
346 TEST_F(DownloadFileTest, StreamEmptySuccess) { | 476 TEST_F(DownloadFileTest, StreamEmptySuccess) { |
347 ASSERT_TRUE(CreateDownloadFile(0, true)); | 477 ASSERT_TRUE(CreateDownloadFile(0, true)); |
348 FilePath initial_path(download_file_->FullPath()); | 478 FilePath initial_path(download_file_->FullPath()); |
349 EXPECT_TRUE(file_util::PathExists(initial_path)); | 479 EXPECT_TRUE(file_util::PathExists(initial_path)); |
350 | 480 |
351 // Test that calling the sink_callback_ on an empty stream shouldn't | 481 // Test that calling the sink_callback_ on an empty stream shouldn't |
352 // do anything. | 482 // do anything. |
353 AppendDataToFile(NULL, 0); | 483 AppendDataToFile(NULL, 0); |
354 ::testing::Mock::VerifyAndClearExpectations(download_manager_.get()); | 484 ::testing::Mock::VerifyAndClearExpectations(download_manager_.get()); |
(...skipping 18 matching lines...) Expand all Loading... | |
373 TEST_F(DownloadFileTest, StreamEmptyError) { | 503 TEST_F(DownloadFileTest, StreamEmptyError) { |
374 ASSERT_TRUE(CreateDownloadFile(0, true)); | 504 ASSERT_TRUE(CreateDownloadFile(0, true)); |
375 FilePath initial_path(download_file_->FullPath()); | 505 FilePath initial_path(download_file_->FullPath()); |
376 EXPECT_TRUE(file_util::PathExists(initial_path)); | 506 EXPECT_TRUE(file_util::PathExists(initial_path)); |
377 | 507 |
378 // Finish the download in error and make sure we see it on the | 508 // Finish the download in error and make sure we see it on the |
379 // DownloadManager. | 509 // DownloadManager. |
380 EXPECT_CALL(*(download_manager_.get()), | 510 EXPECT_CALL(*(download_manager_.get()), |
381 OnDownloadInterrupted( | 511 OnDownloadInterrupted( |
382 DownloadId(kValidIdDomain, kDummyDownloadId + 0).local(), | 512 DownloadId(kValidIdDomain, kDummyDownloadId + 0).local(), |
383 0, _, | 513 content::DOWNLOAD_INTERRUPT_REASON_NETWORK_DISCONNECTED)) |
384 content::DOWNLOAD_INTERRUPT_REASON_NETWORK_DISCONNECTED)); | 514 .WillOnce(InvokeWithoutArgs( |
515 this, &DownloadFileTest::ConfirmUpdateDownloadInfo)); | |
516 | |
517 // If this next EXPECT_CALL fails flakily, it's probably a real failure. | |
518 // We'll be getting a stream of UpdateDownload calls from the timer, and | |
519 // the last one may have the correct information even if the failure | |
520 // doesn't produce an update, as the timer update may have triggered at the | |
521 // same time. | |
522 EXPECT_CALL(*(download_manager_.get()), | |
523 CurrentUpdateStatus(kDummyDownloadId + 0, 0, _, _)); | |
524 | |
385 FinishStream(content::DOWNLOAD_INTERRUPT_REASON_NETWORK_DISCONNECTED, false); | 525 FinishStream(content::DOWNLOAD_INTERRUPT_REASON_NETWORK_DISCONNECTED, false); |
386 | 526 |
527 loop_.RunAllPending(); | |
528 | |
387 DestroyDownloadFile(0); | 529 DestroyDownloadFile(0); |
388 } | 530 } |
389 | 531 |
390 TEST_F(DownloadFileTest, StreamNonEmptySuccess) { | 532 TEST_F(DownloadFileTest, StreamNonEmptySuccess) { |
391 ASSERT_TRUE(CreateDownloadFile(0, true)); | 533 ASSERT_TRUE(CreateDownloadFile(0, true)); |
392 FilePath initial_path(download_file_->FullPath()); | 534 FilePath initial_path(download_file_->FullPath()); |
393 EXPECT_TRUE(file_util::PathExists(initial_path)); | 535 EXPECT_TRUE(file_util::PathExists(initial_path)); |
394 | 536 |
395 const char* chunks1[] = { kTestData1, kTestData2 }; | 537 const char* chunks1[] = { kTestData1, kTestData2 }; |
396 ::testing::Sequence s1; | 538 ::testing::Sequence s1; |
(...skipping 12 matching lines...) Expand all Loading... | |
409 TEST_F(DownloadFileTest, StreamNonEmptyError) { | 551 TEST_F(DownloadFileTest, StreamNonEmptyError) { |
410 ASSERT_TRUE(CreateDownloadFile(0, true)); | 552 ASSERT_TRUE(CreateDownloadFile(0, true)); |
411 FilePath initial_path(download_file_->FullPath()); | 553 FilePath initial_path(download_file_->FullPath()); |
412 EXPECT_TRUE(file_util::PathExists(initial_path)); | 554 EXPECT_TRUE(file_util::PathExists(initial_path)); |
413 | 555 |
414 const char* chunks1[] = { kTestData1, kTestData2 }; | 556 const char* chunks1[] = { kTestData1, kTestData2 }; |
415 ::testing::Sequence s1; | 557 ::testing::Sequence s1; |
416 SetupDataAppend(chunks1, 2, s1); | 558 SetupDataAppend(chunks1, 2, s1); |
417 SetupFinishStream(content::DOWNLOAD_INTERRUPT_REASON_NETWORK_DISCONNECTED, | 559 SetupFinishStream(content::DOWNLOAD_INTERRUPT_REASON_NETWORK_DISCONNECTED, |
418 s1); | 560 s1); |
561 | |
419 EXPECT_CALL(*(download_manager_.get()), | 562 EXPECT_CALL(*(download_manager_.get()), |
420 OnDownloadInterrupted( | 563 OnDownloadInterrupted( |
421 DownloadId(kValidIdDomain, kDummyDownloadId + 0).local(), | 564 DownloadId(kValidIdDomain, kDummyDownloadId + 0).local(), |
422 strlen(kTestData1) + strlen(kTestData2), _, | 565 content::DOWNLOAD_INTERRUPT_REASON_NETWORK_DISCONNECTED)) |
423 content::DOWNLOAD_INTERRUPT_REASON_NETWORK_DISCONNECTED)); | 566 .WillOnce(InvokeWithoutArgs( |
567 this, &DownloadFileTest::ConfirmUpdateDownloadInfo)); | |
568 | |
569 // If this next EXPECT_CALL fails flakily, it's probably a real failure. | |
570 // We'll be getting a stream of UpdateDownload calls from the timer, and | |
571 // the last one may have the correct information even if the failure | |
572 // doesn't produce an update, as the timer update may have triggered at the | |
573 // same time. | |
574 EXPECT_CALL(*(download_manager_.get()), | |
575 CurrentUpdateStatus(kDummyDownloadId + 0, | |
576 strlen(kTestData1) + strlen(kTestData2), | |
577 _, _)); | |
578 | |
424 sink_callback_.Run(); | 579 sink_callback_.Run(); |
580 loop_.RunAllPending(); | |
425 VerifyStreamAndSize(); | 581 VerifyStreamAndSize(); |
426 DestroyDownloadFile(0); | 582 DestroyDownloadFile(0); |
427 } | 583 } |
428 | 584 |
429 // Send some data, wait 3/4s of a second, run the message loop, and | 585 // Send some data, wait 3/4s of a second, run the message loop, and |
430 // confirm the values the DownloadManager received are correct. | 586 // confirm the values the DownloadManager received are correct. |
431 TEST_F(DownloadFileTest, ConfirmUpdate) { | 587 TEST_F(DownloadFileTest, ConfirmUpdate) { |
432 CreateDownloadFile(0, true); | 588 CreateDownloadFile(0, true); |
433 | 589 |
434 const char* chunks1[] = { kTestData1, kTestData2 }; | 590 const char* chunks1[] = { kTestData1, kTestData2 }; |
435 AppendDataToFile(chunks1, 2); | 591 AppendDataToFile(chunks1, 2); |
436 | 592 |
437 // Run the message loops for 750ms and check for results. | 593 // Run the message loops for 750ms and check for results. |
438 loop_.PostDelayedTask(FROM_HERE, MessageLoop::QuitClosure(), | 594 loop_.PostDelayedTask(FROM_HERE, MessageLoop::QuitClosure(), |
439 base::TimeDelta::FromMilliseconds(750)); | 595 base::TimeDelta::FromMilliseconds(750)); |
440 loop_.Run(); | 596 loop_.Run(); |
441 | 597 |
442 EXPECT_EQ(static_cast<int64>(strlen(kTestData1) + strlen(kTestData2)), | 598 EXPECT_EQ(static_cast<int64>(strlen(kTestData1) + strlen(kTestData2)), |
443 bytes_); | 599 bytes_); |
444 EXPECT_EQ(download_file_->GetHashState(), hash_state_); | 600 EXPECT_EQ(download_file_->GetHashState(), hash_state_); |
445 | 601 |
446 FinishStream(content::DOWNLOAD_INTERRUPT_REASON_NONE, true); | 602 FinishStream(content::DOWNLOAD_INTERRUPT_REASON_NONE, true); |
447 DestroyDownloadFile(0); | 603 DestroyDownloadFile(0); |
448 } | 604 } |
OLD | NEW |