Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(51)

Side by Side Diff: content/browser/download/download_file_unittest.cc

Issue 1751603002: [Downloads] Rework how hashes are calculated for download files. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Address first round of comments Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 <stddef.h> 5 #include <stddef.h>
6 #include <stdint.h> 6 #include <stdint.h>
7
7 #include <utility> 8 #include <utility>
9 #include <vector>
8 10
9 #include "base/files/file.h" 11 #include "base/files/file.h"
10 #include "base/files/file_util.h" 12 #include "base/files/file_util.h"
11 #include "base/location.h" 13 #include "base/location.h"
12 #include "base/run_loop.h" 14 #include "base/run_loop.h"
13 #include "base/single_thread_task_runner.h" 15 #include "base/single_thread_task_runner.h"
14 #include "base/strings/string_number_conversions.h" 16 #include "base/strings/string_number_conversions.h"
15 #include "base/test/test_file_util.h" 17 #include "base/test/test_file_util.h"
16 #include "base/thread_task_runner_handle.h" 18 #include "base/thread_task_runner_handle.h"
17 #include "build/build_config.h" 19 #include "build/build_config.h"
18 #include "content/browser/browser_thread_impl.h" 20 #include "content/browser/browser_thread_impl.h"
19 #include "content/browser/byte_stream.h" 21 #include "content/browser/byte_stream.h"
20 #include "content/browser/download/download_create_info.h" 22 #include "content/browser/download/download_create_info.h"
23 #include "content/browser/download/download_destination_observer.h"
21 #include "content/browser/download/download_file_impl.h" 24 #include "content/browser/download/download_file_impl.h"
22 #include "content/browser/download/download_request_handle.h" 25 #include "content/browser/download/download_request_handle.h"
23 #include "content/public/browser/download_destination_observer.h"
24 #include "content/public/browser/download_interrupt_reasons.h" 26 #include "content/public/browser/download_interrupt_reasons.h"
25 #include "content/public/browser/download_manager.h" 27 #include "content/public/browser/download_manager.h"
26 #include "content/public/test/mock_download_manager.h" 28 #include "content/public/test/mock_download_manager.h"
27 #include "net/base/file_stream.h" 29 #include "net/base/file_stream.h"
28 #include "net/base/mock_file_stream.h" 30 #include "net/base/mock_file_stream.h"
29 #include "net/base/net_errors.h" 31 #include "net/base/net_errors.h"
30 #include "testing/gmock/include/gmock/gmock.h" 32 #include "testing/gmock/include/gmock/gmock.h"
31 #include "testing/gtest/include/gtest/gtest.h" 33 #include "testing/gtest/include/gtest/gtest.h"
32 34
33 using ::testing::_; 35 using ::testing::_;
34 using ::testing::AnyNumber; 36 using ::testing::AnyNumber;
35 using ::testing::DoAll; 37 using ::testing::DoAll;
36 using ::testing::InSequence; 38 using ::testing::InSequence;
37 using ::testing::Return; 39 using ::testing::Return;
38 using ::testing::SetArgPointee; 40 using ::testing::SetArgPointee;
39 using ::testing::StrictMock; 41 using ::testing::StrictMock;
40 42
41 namespace content { 43 namespace content {
42 namespace { 44 namespace {
43 45
46 std::string GetHexEncodedHashValue(crypto::SecureHash* hash_state) {
47 if (!hash_state)
48 return std::string();
49 std::vector<char> hash_value(hash_state->GetHashLength());
50 hash_state->Finish(&hash_value.front(), hash_value.size());
51 return base::HexEncode(&hash_value.front(), hash_value.size());
52 }
53
44 class MockByteStreamReader : public ByteStreamReader { 54 class MockByteStreamReader : public ByteStreamReader {
45 public: 55 public:
46 MockByteStreamReader() {} 56 MockByteStreamReader() {}
47 ~MockByteStreamReader() {} 57 ~MockByteStreamReader() {}
48 58
49 // ByteStream functions 59 // ByteStream functions
50 MOCK_METHOD2(Read, ByteStreamReader::StreamState( 60 MOCK_METHOD2(Read, ByteStreamReader::StreamState(
51 scoped_refptr<net::IOBuffer>*, size_t*)); 61 scoped_refptr<net::IOBuffer>*, size_t*));
52 MOCK_CONST_METHOD0(GetStatus, int()); 62 MOCK_CONST_METHOD0(GetStatus, int());
53 MOCK_METHOD1(RegisterCallback, void(const base::Closure&)); 63 MOCK_METHOD1(RegisterCallback, void(const base::Closure&));
54 }; 64 };
55 65
56 class MockDownloadDestinationObserver : public DownloadDestinationObserver { 66 class MockDownloadDestinationObserver : public DownloadDestinationObserver {
57 public: 67 public:
58 MOCK_METHOD3(DestinationUpdate, void(int64_t, int64_t, const std::string&)); 68 MOCK_METHOD2(DestinationUpdate, void(int64_t, int64_t));
59 MOCK_METHOD1(DestinationError, void(DownloadInterruptReason)); 69 void DestinationError(DownloadInterruptReason reason,
60 MOCK_METHOD1(DestinationCompleted, void(const std::string&)); 70 int64_t bytes_so_far,
71 scoped_ptr<crypto::SecureHash> hash_state) override {
72 MockDestinationError(reason, bytes_so_far,
73 GetHexEncodedHashValue(hash_state.get()));
74 }
75 void DestinationCompleted(
76 int64_t total_bytes,
77 scoped_ptr<crypto::SecureHash> hash_state) override {
78 MockDestinationCompleted(total_bytes,
79 GetHexEncodedHashValue(hash_state.get()));
80 }
81
82 MOCK_METHOD3(MockDestinationError,
83 void(DownloadInterruptReason, int64_t, const std::string&));
84 MOCK_METHOD2(MockDestinationCompleted, void(int64_t, const std::string&));
61 85
62 // Doesn't override any methods in the base class. Used to make sure 86 // Doesn't override any methods in the base class. Used to make sure
63 // that the last DestinationUpdate before a Destination{Completed,Error} 87 // that the last DestinationUpdate before a Destination{Completed,Error}
64 // had the right values. 88 // had the right values.
65 MOCK_METHOD3(CurrentUpdateStatus, void(int64_t, int64_t, const std::string&)); 89 MOCK_METHOD2(CurrentUpdateStatus, void(int64_t, int64_t));
66 }; 90 };
67 91
68 MATCHER(IsNullCallback, "") { return (arg.is_null()); } 92 MATCHER(IsNullCallback, "") { return (arg.is_null()); }
69 93
70 typedef void (DownloadFile::*DownloadFileRenameMethodType)( 94 enum DownloadFileRenameMethodType { RENAME_AND_UNIQUIFY, RENAME_AND_ANNOTATE };
71 const base::FilePath&,
72 const DownloadFile::RenameCompletionCallback&);
73 95
74 // This is a test DownloadFileImpl that has no retry delay and, on Posix, 96 // This is a test DownloadFileImpl that has no retry delay and, on Posix,
75 // retries renames failed due to ACCESS_DENIED. 97 // retries renames failed due to ACCESS_DENIED.
76 class TestDownloadFileImpl : public DownloadFileImpl { 98 class TestDownloadFileImpl : public DownloadFileImpl {
77 public: 99 public:
78 TestDownloadFileImpl(const DownloadSaveInfo& save_info, 100 TestDownloadFileImpl(scoped_ptr<DownloadSaveInfo> save_info,
79 const base::FilePath& default_downloads_directory, 101 const base::FilePath& default_downloads_directory,
80 const GURL& url,
81 const GURL& referrer_url,
82 bool calculate_hash,
83 base::File file,
84 scoped_ptr<ByteStreamReader> stream, 102 scoped_ptr<ByteStreamReader> stream,
85 const net::BoundNetLog& bound_net_log, 103 const net::BoundNetLog& bound_net_log,
86 base::WeakPtr<DownloadDestinationObserver> observer) 104 base::WeakPtr<DownloadDestinationObserver> observer)
87 : DownloadFileImpl(save_info, 105 : DownloadFileImpl(std::move(save_info),
88 default_downloads_directory, 106 default_downloads_directory,
89 url,
90 referrer_url,
91 calculate_hash,
92 std::move(file),
93 std::move(stream), 107 std::move(stream),
94 bound_net_log, 108 bound_net_log,
95 observer) {} 109 observer) {}
96 110
97 protected: 111 protected:
98 base::TimeDelta GetRetryDelayForFailedRename(int attempt_count) override { 112 base::TimeDelta GetRetryDelayForFailedRename(int attempt_count) override {
99 return base::TimeDelta::FromMilliseconds(0); 113 return base::TimeDelta::FromMilliseconds(0);
100 } 114 }
101 115
102 #if !defined(OS_WIN) 116 #if !defined(OS_WIN)
103 // On Posix, we don't encounter transient errors during renames, except 117 // On Posix, we don't encounter transient errors during renames, except
104 // possibly EAGAIN, which is difficult to replicate reliably. So we resort to 118 // possibly EAGAIN, which is difficult to replicate reliably. So we resort to
105 // simulating a transient error using ACCESS_DENIED instead. 119 // simulating a transient error using ACCESS_DENIED instead.
106 bool ShouldRetryFailedRename(DownloadInterruptReason reason) override { 120 bool ShouldRetryFailedRename(DownloadInterruptReason reason) override {
107 return reason == DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED; 121 return reason == DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED;
108 } 122 }
109 #endif 123 #endif
110 }; 124 };
111 125
112 } // namespace 126 } // namespace
113 127
114 class DownloadFileTest : public testing::Test { 128 class DownloadFileTest : public testing::Test {
115 public: 129 public:
116 130 static const char kTestData1[];
117 static const char* kTestData1; 131 static const char kTestData2[];
118 static const char* kTestData2; 132 static const char kTestData3[];
119 static const char* kTestData3; 133 static const char kDataHash[];
120 static const char* kDataHash; 134 static const char kEmptyHash[];
121 static const uint32_t kDummyDownloadId; 135 static const uint32_t kDummyDownloadId;
122 static const int kDummyChildId; 136 static const int kDummyChildId;
123 static const int kDummyRequestId; 137 static const int kDummyRequestId;
124 138
125 DownloadFileTest() : 139 DownloadFileTest() :
126 observer_(new StrictMock<MockDownloadDestinationObserver>), 140 observer_(new StrictMock<MockDownloadDestinationObserver>),
127 observer_factory_(observer_.get()), 141 observer_factory_(observer_.get()),
128 input_stream_(NULL), 142 input_stream_(NULL),
129 bytes_(-1), 143 bytes_(-1),
130 bytes_per_sec_(-1), 144 bytes_per_sec_(-1),
131 hash_state_("xyzzy"),
132 ui_thread_(BrowserThread::UI, &loop_), 145 ui_thread_(BrowserThread::UI, &loop_),
133 file_thread_(BrowserThread::FILE, &loop_) { 146 file_thread_(BrowserThread::FILE, &loop_) {
134 } 147 }
135 148
136 ~DownloadFileTest() override {} 149 ~DownloadFileTest() override {}
137 150
138 void SetUpdateDownloadInfo(int64_t bytes, 151 void SetUpdateDownloadInfo(int64_t bytes, int64_t bytes_per_sec) {
139 int64_t bytes_per_sec,
140 const std::string& hash_state) {
141 bytes_ = bytes; 152 bytes_ = bytes;
142 bytes_per_sec_ = bytes_per_sec; 153 bytes_per_sec_ = bytes_per_sec;
143 hash_state_ = hash_state;
144 } 154 }
145 155
146 void ConfirmUpdateDownloadInfo() { 156 void ConfirmUpdateDownloadInfo() {
147 observer_->CurrentUpdateStatus(bytes_, bytes_per_sec_, hash_state_); 157 observer_->CurrentUpdateStatus(bytes_, bytes_per_sec_);
148 } 158 }
149 159
150 void SetUp() override { 160 void SetUp() override {
151 EXPECT_CALL(*(observer_.get()), DestinationUpdate(_, _, _)) 161 EXPECT_CALL(*(observer_.get()), DestinationUpdate(_, _))
152 .Times(AnyNumber()) 162 .Times(AnyNumber())
153 .WillRepeatedly(Invoke(this, &DownloadFileTest::SetUpdateDownloadInfo)); 163 .WillRepeatedly(Invoke(this, &DownloadFileTest::SetUpdateDownloadInfo));
154 } 164 }
155 165
156 // Mock calls to this function are forwarded here. 166 // Mock calls to this function are forwarded here.
157 void RegisterCallback(const base::Closure& sink_callback) { 167 void RegisterCallback(const base::Closure& sink_callback) {
158 sink_callback_ = sink_callback; 168 sink_callback_ = sink_callback;
159 } 169 }
160 170
161 void SetInterruptReasonCallback(const base::Closure& closure, 171 void SetInterruptReasonCallback(const base::Closure& closure,
(...skipping 10 matching lines...) Expand all
172 input_stream_ = new StrictMock<MockByteStreamReader>(); 182 input_stream_ = new StrictMock<MockByteStreamReader>();
173 183
174 // TODO: Need to actually create a function that'll set the variables 184 // TODO: Need to actually create a function that'll set the variables
175 // based on the inputs from the callback. 185 // based on the inputs from the callback.
176 EXPECT_CALL(*input_stream_, RegisterCallback(_)) 186 EXPECT_CALL(*input_stream_, RegisterCallback(_))
177 .WillOnce(Invoke(this, &DownloadFileTest::RegisterCallback)) 187 .WillOnce(Invoke(this, &DownloadFileTest::RegisterCallback))
178 .RetiresOnSaturation(); 188 .RetiresOnSaturation();
179 189
180 scoped_ptr<DownloadSaveInfo> save_info(new DownloadSaveInfo()); 190 scoped_ptr<DownloadSaveInfo> save_info(new DownloadSaveInfo());
181 download_file_.reset(new TestDownloadFileImpl( 191 download_file_.reset(new TestDownloadFileImpl(
182 *save_info, base::FilePath(), 192 std::move(save_info), base::FilePath(),
183 GURL(), // Source
184 GURL(), // Referrer
185 calculate_hash, std::move(save_info->file),
186 scoped_ptr<ByteStreamReader>(input_stream_), net::BoundNetLog(), 193 scoped_ptr<ByteStreamReader>(input_stream_), net::BoundNetLog(),
187 observer_factory_.GetWeakPtr())); 194 observer_factory_.GetWeakPtr()));
188 download_file_->SetClientGuid("12345678-ABCD-1234-DCBA-123456789ABC");
189 195
190 EXPECT_CALL(*input_stream_, Read(_, _)) 196 EXPECT_CALL(*input_stream_, Read(_, _))
191 .WillOnce(Return(ByteStreamReader::STREAM_EMPTY)) 197 .WillOnce(Return(ByteStreamReader::STREAM_EMPTY))
192 .RetiresOnSaturation(); 198 .RetiresOnSaturation();
193 199
194 base::WeakPtrFactory<DownloadFileTest> weak_ptr_factory(this); 200 base::WeakPtrFactory<DownloadFileTest> weak_ptr_factory(this);
195 DownloadInterruptReason result = DOWNLOAD_INTERRUPT_REASON_NONE; 201 DownloadInterruptReason result = DOWNLOAD_INTERRUPT_REASON_NONE;
196 base::RunLoop loop_runner; 202 base::RunLoop loop_runner;
197 download_file_->Initialize(base::Bind( 203 download_file_->Initialize(base::Bind(
198 &DownloadFileTest::SetInterruptReasonCallback, 204 &DownloadFileTest::SetInterruptReasonCallback,
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
263 .RetiresOnSaturation(); 269 .RetiresOnSaturation();
264 EXPECT_CALL(*input_stream_, GetStatus()) 270 EXPECT_CALL(*input_stream_, GetStatus())
265 .InSequence(s) 271 .InSequence(s)
266 .WillOnce(Return(interrupt_reason)) 272 .WillOnce(Return(interrupt_reason))
267 .RetiresOnSaturation(); 273 .RetiresOnSaturation();
268 EXPECT_CALL(*input_stream_, RegisterCallback(_)) 274 EXPECT_CALL(*input_stream_, RegisterCallback(_))
269 .RetiresOnSaturation(); 275 .RetiresOnSaturation();
270 } 276 }
271 277
272 void FinishStream(DownloadInterruptReason interrupt_reason, 278 void FinishStream(DownloadInterruptReason interrupt_reason,
273 bool check_observer) { 279 bool check_observer,
280 const std::string& expected_hash) {
274 ::testing::Sequence s1; 281 ::testing::Sequence s1;
275 SetupFinishStream(interrupt_reason, s1); 282 SetupFinishStream(interrupt_reason, s1);
276 sink_callback_.Run(); 283 sink_callback_.Run();
277 VerifyStreamAndSize(); 284 VerifyStreamAndSize();
278 if (check_observer) { 285 if (check_observer) {
279 EXPECT_CALL(*(observer_.get()), DestinationCompleted(_)); 286 EXPECT_CALL(*(observer_.get()),
287 MockDestinationCompleted(_, expected_hash));
280 loop_.RunUntilIdle(); 288 loop_.RunUntilIdle();
281 ::testing::Mock::VerifyAndClearExpectations(observer_.get()); 289 ::testing::Mock::VerifyAndClearExpectations(observer_.get());
282 EXPECT_CALL(*(observer_.get()), DestinationUpdate(_, _, _)) 290 EXPECT_CALL(*(observer_.get()), DestinationUpdate(_, _))
283 .Times(AnyNumber()) 291 .Times(AnyNumber())
284 .WillRepeatedly(Invoke(this, 292 .WillRepeatedly(
285 &DownloadFileTest::SetUpdateDownloadInfo)); 293 Invoke(this, &DownloadFileTest::SetUpdateDownloadInfo));
286 } 294 }
287 } 295 }
288 296
289 DownloadInterruptReason RenameAndUniquify( 297 DownloadInterruptReason RenameAndUniquify(
290 const base::FilePath& full_path, 298 const base::FilePath& full_path,
291 base::FilePath* result_path_p) { 299 base::FilePath* result_path_p) {
292 return InvokeRenameMethodAndWaitForCallback( 300 return InvokeRenameMethodAndWaitForCallback(RENAME_AND_UNIQUIFY, full_path,
293 &DownloadFile::RenameAndUniquify, full_path, result_path_p); 301 result_path_p);
294 } 302 }
295 303
296 DownloadInterruptReason RenameAndAnnotate( 304 DownloadInterruptReason RenameAndAnnotate(
297 const base::FilePath& full_path, 305 const base::FilePath& full_path,
298 base::FilePath* result_path_p) { 306 base::FilePath* result_path_p) {
299 return InvokeRenameMethodAndWaitForCallback( 307 return InvokeRenameMethodAndWaitForCallback(RENAME_AND_ANNOTATE, full_path,
300 &DownloadFile::RenameAndAnnotate, full_path, result_path_p); 308 result_path_p);
301 } 309 }
302 310
303 void ExpectPermissionError(DownloadInterruptReason err) { 311 void ExpectPermissionError(DownloadInterruptReason err) {
304 EXPECT_TRUE(err == DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR || 312 EXPECT_TRUE(err == DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR ||
305 err == DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED) 313 err == DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED)
306 << "Interrupt reason = " << err; 314 << "Interrupt reason = " << err;
307 } 315 }
308 316
309 protected: 317 protected:
318 void InvokeRenameMethod(
319 DownloadFileRenameMethodType method,
320 const base::FilePath& full_path,
321 const DownloadFile::RenameCompletionCallback& completion_callback) {
322 switch (method) {
323 case RENAME_AND_UNIQUIFY:
324 download_file_->RenameAndUniquify(full_path, completion_callback);
325 break;
326
327 case RENAME_AND_ANNOTATE:
328 download_file_->RenameAndAnnotate(
329 full_path, "12345678-ABCD-1234-DCBA-123456789ABC", GURL(), GURL(),
330 completion_callback);
331 break;
332 }
333 }
334
310 DownloadInterruptReason InvokeRenameMethodAndWaitForCallback( 335 DownloadInterruptReason InvokeRenameMethodAndWaitForCallback(
311 DownloadFileRenameMethodType method, 336 DownloadFileRenameMethodType method,
312 const base::FilePath& full_path, 337 const base::FilePath& full_path,
313 base::FilePath* result_path_p) { 338 base::FilePath* result_path_p) {
314 DownloadInterruptReason result_reason(DOWNLOAD_INTERRUPT_REASON_NONE); 339 DownloadInterruptReason result_reason(DOWNLOAD_INTERRUPT_REASON_NONE);
315 base::FilePath result_path; 340 base::FilePath result_path;
316
317 base::RunLoop loop_runner; 341 base::RunLoop loop_runner;
318 ((*download_file_).*method)(full_path, 342 DownloadFile::RenameCompletionCallback completion_callback =
319 base::Bind(&DownloadFileTest::SetRenameResult, 343 base::Bind(&DownloadFileTest::SetRenameResult, base::Unretained(this),
320 base::Unretained(this), 344 loop_runner.QuitClosure(), &result_reason, result_path_p);
321 loop_runner.QuitClosure(), 345 InvokeRenameMethod(method, full_path, completion_callback);
322 &result_reason,
323 result_path_p));
324 loop_runner.Run(); 346 loop_runner.Run();
325 return result_reason; 347 return result_reason;
326 } 348 }
327 349
328 scoped_ptr<StrictMock<MockDownloadDestinationObserver> > observer_; 350 scoped_ptr<StrictMock<MockDownloadDestinationObserver> > observer_;
329 base::WeakPtrFactory<DownloadDestinationObserver> observer_factory_; 351 base::WeakPtrFactory<DownloadDestinationObserver> observer_factory_;
330 352
331 // DownloadFile instance we are testing. 353 // DownloadFile instance we are testing.
332 scoped_ptr<DownloadFile> download_file_; 354 scoped_ptr<DownloadFile> download_file_;
333 355
334 // Stream for sending data into the download file. 356 // Stream for sending data into the download file.
335 // Owned by download_file_; will be alive for lifetime of download_file_. 357 // Owned by download_file_; will be alive for lifetime of download_file_.
336 StrictMock<MockByteStreamReader>* input_stream_; 358 StrictMock<MockByteStreamReader>* input_stream_;
337 359
338 // Sink callback data for stream. 360 // Sink callback data for stream.
339 base::Closure sink_callback_; 361 base::Closure sink_callback_;
340 362
341 // Latest update sent to the observer. 363 // Latest update sent to the observer.
342 int64_t bytes_; 364 int64_t bytes_;
343 int64_t bytes_per_sec_; 365 int64_t bytes_per_sec_;
344 std::string hash_state_;
345 366
346 base::MessageLoop loop_; 367 base::MessageLoop loop_;
347 368
348 private: 369 private:
349 void SetRenameResult(const base::Closure& closure, 370 void SetRenameResult(const base::Closure& closure,
350 DownloadInterruptReason* reason_p, 371 DownloadInterruptReason* reason_p,
351 base::FilePath* result_path_p, 372 base::FilePath* result_path_p,
352 DownloadInterruptReason reason, 373 DownloadInterruptReason reason,
353 const base::FilePath& result_path) { 374 const base::FilePath& result_path) {
354 if (reason_p) 375 if (reason_p)
(...skipping 29 matching lines...) Expand all
384 } 405 }
385 }; 406 };
386 407
387 // And now instantiate all DownloadFileTestWithRename tests using both 408 // And now instantiate all DownloadFileTestWithRename tests using both
388 // DownloadFile rename methods. Each test of the form 409 // DownloadFile rename methods. Each test of the form
389 // DownloadFileTestWithRename.<FooTest> will be instantiated once with 410 // DownloadFileTestWithRename.<FooTest> will be instantiated once with
390 // RenameAndAnnotate as the value parameter and once with RenameAndUniquify as 411 // RenameAndAnnotate as the value parameter and once with RenameAndUniquify as
391 // the value parameter. 412 // the value parameter.
392 INSTANTIATE_TEST_CASE_P(DownloadFile, 413 INSTANTIATE_TEST_CASE_P(DownloadFile,
393 DownloadFileTestWithRename, 414 DownloadFileTestWithRename,
394 ::testing::Values(&DownloadFile::RenameAndAnnotate, 415 ::testing::Values(RENAME_AND_ANNOTATE,
395 &DownloadFile::RenameAndUniquify)); 416 RENAME_AND_UNIQUIFY));
396 417
397 const char* DownloadFileTest::kTestData1 = 418 const char DownloadFileTest::kTestData1[] =
398 "Let's write some data to the file!\n"; 419 "Let's write some data to the file!\n";
399 const char* DownloadFileTest::kTestData2 = "Writing more data.\n"; 420 const char DownloadFileTest::kTestData2[] = "Writing more data.\n";
400 const char* DownloadFileTest::kTestData3 = "Final line."; 421 const char DownloadFileTest::kTestData3[] = "Final line.";
401 const char* DownloadFileTest::kDataHash = 422 const char DownloadFileTest::kDataHash[] =
402 "CBF68BF10F8003DB86B31343AFAC8C7175BD03FB5FC905650F8C80AF087443A8"; 423 "CBF68BF10F8003DB86B31343AFAC8C7175BD03FB5FC905650F8C80AF087443A8";
424 const char DownloadFileTest::kEmptyHash[] =
425 "E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855";
403 426
404 const uint32_t DownloadFileTest::kDummyDownloadId = 23; 427 const uint32_t DownloadFileTest::kDummyDownloadId = 23;
405 const int DownloadFileTest::kDummyChildId = 3; 428 const int DownloadFileTest::kDummyChildId = 3;
406 const int DownloadFileTest::kDummyRequestId = 67; 429 const int DownloadFileTest::kDummyRequestId = 67;
407 430
408 // Rename the file before any data is downloaded, after some has, after it all 431 // Rename the file before any data is downloaded, after some has, after it all
409 // has, and after it's closed. 432 // has, and after it's closed.
410 TEST_P(DownloadFileTestWithRename, RenameFileFinal) { 433 TEST_P(DownloadFileTestWithRename, RenameFileFinal) {
411 ASSERT_TRUE(CreateDownloadFile(0, true)); 434 ASSERT_TRUE(CreateDownloadFile(0, true));
412 base::FilePath initial_path(download_file_->FullPath()); 435 base::FilePath initial_path(download_file_->FullPath());
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
450 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, 473 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE,
451 InvokeSelectedRenameMethod(path_3, &output_path)); 474 InvokeSelectedRenameMethod(path_3, &output_path));
452 renamed_path = download_file_->FullPath(); 475 renamed_path = download_file_->FullPath();
453 EXPECT_EQ(path_3, renamed_path); 476 EXPECT_EQ(path_3, renamed_path);
454 EXPECT_EQ(path_3, output_path); 477 EXPECT_EQ(path_3, output_path);
455 478
456 // Check the files. 479 // Check the files.
457 EXPECT_FALSE(base::PathExists(path_2)); 480 EXPECT_FALSE(base::PathExists(path_2));
458 EXPECT_TRUE(base::PathExists(path_3)); 481 EXPECT_TRUE(base::PathExists(path_3));
459 482
460 // Should not be able to get the hash until the file is closed. 483 FinishStream(DOWNLOAD_INTERRUPT_REASON_NONE, true, kDataHash);
461 std::string hash;
462 EXPECT_FALSE(download_file_->GetHash(&hash));
463 FinishStream(DOWNLOAD_INTERRUPT_REASON_NONE, true);
464 loop_.RunUntilIdle(); 484 loop_.RunUntilIdle();
465 485
466 // Rename the file after downloading all the data and closing the file. 486 // Rename the file after downloading all the data and closing the file.
467 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, 487 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE,
468 InvokeSelectedRenameMethod(path_4, &output_path)); 488 InvokeSelectedRenameMethod(path_4, &output_path));
469 renamed_path = download_file_->FullPath(); 489 renamed_path = download_file_->FullPath();
470 EXPECT_EQ(path_4, renamed_path); 490 EXPECT_EQ(path_4, renamed_path);
471 EXPECT_EQ(path_4, output_path); 491 EXPECT_EQ(path_4, output_path);
472 492
473 // Check the files. 493 // Check the files.
474 EXPECT_FALSE(base::PathExists(path_3)); 494 EXPECT_FALSE(base::PathExists(path_3));
475 EXPECT_TRUE(base::PathExists(path_4)); 495 EXPECT_TRUE(base::PathExists(path_4));
476 496
477 // Check the hash.
478 EXPECT_TRUE(download_file_->GetHash(&hash));
479 EXPECT_EQ(kDataHash, base::HexEncode(hash.data(), hash.size()));
480
481 DestroyDownloadFile(0); 497 DestroyDownloadFile(0);
482 } 498 }
483 499
484 // Test to make sure the rename overwrites when requested. This is separate from 500 // Test to make sure the rename overwrites when requested. This is separate from
485 // the above test because it only applies to RenameAndAnnotate(). 501 // the above test because it only applies to RenameAndAnnotate().
486 // RenameAndUniquify() doesn't overwrite by design. 502 // RenameAndUniquify() doesn't overwrite by design.
487 TEST_F(DownloadFileTest, RenameOverwrites) { 503 TEST_F(DownloadFileTest, RenameOverwrites) {
488 ASSERT_TRUE(CreateDownloadFile(0, true)); 504 ASSERT_TRUE(CreateDownloadFile(0, true));
489 base::FilePath initial_path(download_file_->FullPath()); 505 base::FilePath initial_path(download_file_->FullPath());
490 EXPECT_TRUE(base::PathExists(initial_path)); 506 EXPECT_TRUE(base::PathExists(initial_path));
491 base::FilePath path_1(initial_path.InsertBeforeExtensionASCII("_1")); 507 base::FilePath path_1(initial_path.InsertBeforeExtensionASCII("_1"));
492 508
493 ASSERT_FALSE(base::PathExists(path_1)); 509 ASSERT_FALSE(base::PathExists(path_1));
494 static const char file_data[] = "xyzzy"; 510 static const char file_data[] = "xyzzy";
495 ASSERT_EQ(static_cast<int>(sizeof(file_data)), 511 ASSERT_EQ(static_cast<int>(sizeof(file_data)),
496 base::WriteFile(path_1, file_data, sizeof(file_data))); 512 base::WriteFile(path_1, file_data, sizeof(file_data)));
497 ASSERT_TRUE(base::PathExists(path_1)); 513 ASSERT_TRUE(base::PathExists(path_1));
498 514
499 base::FilePath new_path; 515 base::FilePath new_path;
500 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, 516 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE,
501 RenameAndAnnotate(path_1, &new_path)); 517 RenameAndAnnotate(path_1, &new_path));
502 EXPECT_EQ(path_1.value(), new_path.value()); 518 EXPECT_EQ(path_1.value(), new_path.value());
503 519
504 std::string file_contents; 520 std::string file_contents;
505 ASSERT_TRUE(base::ReadFileToString(new_path, &file_contents)); 521 ASSERT_TRUE(base::ReadFileToString(new_path, &file_contents));
506 EXPECT_NE(std::string(file_data), file_contents); 522 EXPECT_NE(std::string(file_data), file_contents);
507 523
508 FinishStream(DOWNLOAD_INTERRUPT_REASON_NONE, true); 524 FinishStream(DOWNLOAD_INTERRUPT_REASON_NONE, true, kEmptyHash);
509 loop_.RunUntilIdle(); 525 loop_.RunUntilIdle();
510 DestroyDownloadFile(0); 526 DestroyDownloadFile(0);
511 } 527 }
512 528
513 // Test to make sure the rename uniquifies if we aren't overwriting 529 // Test to make sure the rename uniquifies if we aren't overwriting
514 // and there's a file where we're aiming. As above, not a 530 // and there's a file where we're aiming. As above, not a
515 // DownloadFileTestWithRename test because this only applies to 531 // DownloadFileTestWithRename test because this only applies to
516 // RenameAndUniquify(). 532 // RenameAndUniquify().
517 TEST_F(DownloadFileTest, RenameUniquifies) { 533 TEST_F(DownloadFileTest, RenameUniquifies) {
518 ASSERT_TRUE(CreateDownloadFile(0, true)); 534 ASSERT_TRUE(CreateDownloadFile(0, true));
519 base::FilePath initial_path(download_file_->FullPath()); 535 base::FilePath initial_path(download_file_->FullPath());
520 EXPECT_TRUE(base::PathExists(initial_path)); 536 EXPECT_TRUE(base::PathExists(initial_path));
521 base::FilePath path_1(initial_path.InsertBeforeExtensionASCII("_1")); 537 base::FilePath path_1(initial_path.InsertBeforeExtensionASCII("_1"));
522 base::FilePath path_1_suffixed(path_1.InsertBeforeExtensionASCII(" (1)")); 538 base::FilePath path_1_suffixed(path_1.InsertBeforeExtensionASCII(" (1)"));
523 539
524 ASSERT_FALSE(base::PathExists(path_1)); 540 ASSERT_FALSE(base::PathExists(path_1));
525 static const char file_data[] = "xyzzy"; 541 static const char file_data[] = "xyzzy";
526 ASSERT_EQ(static_cast<int>(sizeof(file_data)), 542 ASSERT_EQ(static_cast<int>(sizeof(file_data)),
527 base::WriteFile(path_1, file_data, sizeof(file_data))); 543 base::WriteFile(path_1, file_data, sizeof(file_data)));
528 ASSERT_TRUE(base::PathExists(path_1)); 544 ASSERT_TRUE(base::PathExists(path_1));
529 545
530 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, RenameAndUniquify(path_1, NULL)); 546 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, RenameAndUniquify(path_1, NULL));
531 EXPECT_TRUE(base::PathExists(path_1_suffixed)); 547 EXPECT_TRUE(base::PathExists(path_1_suffixed));
532 548
533 FinishStream(DOWNLOAD_INTERRUPT_REASON_NONE, true); 549 FinishStream(DOWNLOAD_INTERRUPT_REASON_NONE, true, kEmptyHash);
534 loop_.RunUntilIdle(); 550 loop_.RunUntilIdle();
535 DestroyDownloadFile(0); 551 DestroyDownloadFile(0);
536 } 552 }
537 553
538 // Test that RenameAndUniquify doesn't try to uniquify in the case where the 554 // Test that RenameAndUniquify doesn't try to uniquify in the case where the
539 // target filename is the same as the current filename. 555 // target filename is the same as the current filename.
540 TEST_F(DownloadFileTest, RenameRecognizesSelfConflict) { 556 TEST_F(DownloadFileTest, RenameRecognizesSelfConflict) {
541 ASSERT_TRUE(CreateDownloadFile(0, true)); 557 ASSERT_TRUE(CreateDownloadFile(0, true));
542 base::FilePath initial_path(download_file_->FullPath()); 558 base::FilePath initial_path(download_file_->FullPath());
543 EXPECT_TRUE(base::PathExists(initial_path)); 559 EXPECT_TRUE(base::PathExists(initial_path));
544 560
545 base::FilePath new_path; 561 base::FilePath new_path;
546 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, 562 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE,
547 RenameAndUniquify(initial_path, &new_path)); 563 RenameAndUniquify(initial_path, &new_path));
548 EXPECT_TRUE(base::PathExists(initial_path)); 564 EXPECT_TRUE(base::PathExists(initial_path));
549 565
550 FinishStream(DOWNLOAD_INTERRUPT_REASON_NONE, true); 566 FinishStream(DOWNLOAD_INTERRUPT_REASON_NONE, true, kEmptyHash);
551 loop_.RunUntilIdle(); 567 loop_.RunUntilIdle();
552 DestroyDownloadFile(0); 568 DestroyDownloadFile(0);
553 EXPECT_EQ(initial_path.value(), new_path.value()); 569 EXPECT_EQ(initial_path.value(), new_path.value());
554 } 570 }
555 571
556 // Test to make sure we get the proper error on failure. 572 // Test to make sure we get the proper error on failure.
557 TEST_P(DownloadFileTestWithRename, RenameError) { 573 TEST_P(DownloadFileTestWithRename, RenameError) {
558 ASSERT_TRUE(CreateDownloadFile(0, true)); 574 ASSERT_TRUE(CreateDownloadFile(0, true));
559 base::FilePath initial_path(download_file_->FullPath()); 575 base::FilePath initial_path(download_file_->FullPath());
560 576
(...skipping 14 matching lines...) Expand all
575 { 591 {
576 base::FilePermissionRestorer restorer(target_dir); 592 base::FilePermissionRestorer restorer(target_dir);
577 ASSERT_TRUE(base::MakeFileUnwritable(target_dir)); 593 ASSERT_TRUE(base::MakeFileUnwritable(target_dir));
578 594
579 // Expect nulling out of further processing. 595 // Expect nulling out of further processing.
580 EXPECT_CALL(*input_stream_, RegisterCallback(IsNullCallback())); 596 EXPECT_CALL(*input_stream_, RegisterCallback(IsNullCallback()));
581 ExpectPermissionError(InvokeSelectedRenameMethod(target_path, NULL)); 597 ExpectPermissionError(InvokeSelectedRenameMethod(target_path, NULL));
582 EXPECT_FALSE(base::PathExists(target_path_suffixed)); 598 EXPECT_FALSE(base::PathExists(target_path_suffixed));
583 } 599 }
584 600
585 FinishStream(DOWNLOAD_INTERRUPT_REASON_NONE, true); 601 FinishStream(DOWNLOAD_INTERRUPT_REASON_NONE, true, kEmptyHash);
586 loop_.RunUntilIdle(); 602 loop_.RunUntilIdle();
587 DestroyDownloadFile(0); 603 DestroyDownloadFile(0);
588 } 604 }
589 605
590 namespace { 606 namespace {
591 607
592 void TestRenameCompletionCallback(const base::Closure& closure, 608 void TestRenameCompletionCallback(const base::Closure& closure,
593 bool* did_run_callback, 609 bool* did_run_callback,
594 DownloadInterruptReason interrupt_reason, 610 DownloadInterruptReason interrupt_reason,
595 const base::FilePath& new_path) { 611 const base::FilePath& new_path) {
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
638 #else 654 #else
639 // Simulate a transient failure by revoking write permission for target_dir. 655 // Simulate a transient failure by revoking write permission for target_dir.
640 // The TestDownloadFileImpl class treats this error as transient even though 656 // The TestDownloadFileImpl class treats this error as transient even though
641 // DownloadFileImpl itself doesn't. 657 // DownloadFileImpl itself doesn't.
642 base::FilePermissionRestorer restore_permissions_for(target_dir); 658 base::FilePermissionRestorer restore_permissions_for(target_dir);
643 ASSERT_TRUE(base::MakeFileUnwritable(target_dir)); 659 ASSERT_TRUE(base::MakeFileUnwritable(target_dir));
644 #endif 660 #endif
645 661
646 // The Rename() should fail here and enqueue a retry task without invoking 662 // The Rename() should fail here and enqueue a retry task without invoking
647 // the completion callback. 663 // the completion callback.
648 ((*download_file_).*GetParam())(target_path, 664 InvokeRenameMethod(
649 base::Bind(&TestRenameCompletionCallback, 665 GetParam(), target_path,
650 succeeding_run.QuitClosure(), 666 base::Bind(&TestRenameCompletionCallback, succeeding_run.QuitClosure(),
651 &did_run_callback)); 667 &did_run_callback));
652 EXPECT_FALSE(did_run_callback); 668 EXPECT_FALSE(did_run_callback);
653 669
654 base::RunLoop first_failing_run; 670 base::RunLoop first_failing_run;
655 // Queue the QuitClosure() on the MessageLoop now. Any tasks queued by the 671 // Queue the QuitClosure() on the MessageLoop now. Any tasks queued by the
656 // Rename() will be in front of the QuitClosure(). Running the message loop 672 // Rename() will be in front of the QuitClosure(). Running the message loop
657 // now causes the just the first retry task to be run. The rename still 673 // now causes the just the first retry task to be run. The rename still
658 // fails, so another retry task would get queued behind the QuitClosure(). 674 // fails, so another retry task would get queued behind the QuitClosure().
659 base::ThreadTaskRunnerHandle::Get()->PostTask( 675 base::ThreadTaskRunnerHandle::Get()->PostTask(
660 FROM_HERE, first_failing_run.QuitClosure()); 676 FROM_HERE, first_failing_run.QuitClosure());
661 first_failing_run.Run(); 677 first_failing_run.Run();
662 EXPECT_FALSE(did_run_callback); 678 EXPECT_FALSE(did_run_callback);
663 679
664 // Running another loop should have the same effect as the above as long as 680 // Running another loop should have the same effect as the above as long as
665 // kMaxRenameRetries is greater than 2. 681 // kMaxRenameRetries is greater than 2.
666 base::RunLoop second_failing_run; 682 base::RunLoop second_failing_run;
667 base::ThreadTaskRunnerHandle::Get()->PostTask( 683 base::ThreadTaskRunnerHandle::Get()->PostTask(
668 FROM_HERE, second_failing_run.QuitClosure()); 684 FROM_HERE, second_failing_run.QuitClosure());
669 second_failing_run.Run(); 685 second_failing_run.Run();
670 EXPECT_FALSE(did_run_callback); 686 EXPECT_FALSE(did_run_callback);
671 } 687 }
672 688
673 // This time the QuitClosure from succeeding_run should get executed. 689 // This time the QuitClosure from succeeding_run should get executed.
674 succeeding_run.Run(); 690 succeeding_run.Run();
675 EXPECT_TRUE(did_run_callback); 691 EXPECT_TRUE(did_run_callback);
676 692
677 FinishStream(DOWNLOAD_INTERRUPT_REASON_NONE, true); 693 FinishStream(DOWNLOAD_INTERRUPT_REASON_NONE, true, kEmptyHash);
678 loop_.RunUntilIdle(); 694 loop_.RunUntilIdle();
679 DestroyDownloadFile(0); 695 DestroyDownloadFile(0);
680 } 696 }
681 697
682 // Various tests of the StreamActive method. 698 // Various tests of the StreamActive method.
683 TEST_F(DownloadFileTest, StreamEmptySuccess) { 699 TEST_F(DownloadFileTest, StreamEmptySuccess) {
684 ASSERT_TRUE(CreateDownloadFile(0, true)); 700 ASSERT_TRUE(CreateDownloadFile(0, true));
685 base::FilePath initial_path(download_file_->FullPath()); 701 base::FilePath initial_path(download_file_->FullPath());
686 EXPECT_TRUE(base::PathExists(initial_path)); 702 EXPECT_TRUE(base::PathExists(initial_path));
687 703
688 // Test that calling the sink_callback_ on an empty stream shouldn't 704 // Test that calling the sink_callback_ on an empty stream shouldn't
689 // do anything. 705 // do anything.
690 AppendDataToFile(NULL, 0); 706 AppendDataToFile(NULL, 0);
691 707
692 // Finish the download this way and make sure we see it on the 708 // Finish the download this way and make sure we see it on the observer.
693 // observer. 709 FinishStream(DOWNLOAD_INTERRUPT_REASON_NONE, true, kEmptyHash);
694 EXPECT_CALL(*(observer_.get()), DestinationCompleted(_));
695 FinishStream(DOWNLOAD_INTERRUPT_REASON_NONE, false);
696 loop_.RunUntilIdle(); 710 loop_.RunUntilIdle();
697 711
698 DestroyDownloadFile(0); 712 DestroyDownloadFile(0);
699 } 713 }
700 714
701 TEST_F(DownloadFileTest, StreamEmptyError) { 715 TEST_F(DownloadFileTest, StreamEmptyError) {
702 ASSERT_TRUE(CreateDownloadFile(0, true)); 716 ASSERT_TRUE(CreateDownloadFile(0, true));
703 base::FilePath initial_path(download_file_->FullPath()); 717 base::FilePath initial_path(download_file_->FullPath());
704 EXPECT_TRUE(base::PathExists(initial_path)); 718 EXPECT_TRUE(base::PathExists(initial_path));
705 719
706 // Finish the download in error and make sure we see it on the 720 // Finish the download in error and make sure we see it on the
707 // observer. 721 // observer.
708 EXPECT_CALL(*(observer_.get()), 722 EXPECT_CALL(
709 DestinationError( 723 *(observer_.get()),
710 DOWNLOAD_INTERRUPT_REASON_NETWORK_DISCONNECTED)) 724 MockDestinationError(DOWNLOAD_INTERRUPT_REASON_NETWORK_DISCONNECTED, 0,
725 kEmptyHash))
711 .WillOnce(InvokeWithoutArgs( 726 .WillOnce(InvokeWithoutArgs(
712 this, &DownloadFileTest::ConfirmUpdateDownloadInfo)); 727 this, &DownloadFileTest::ConfirmUpdateDownloadInfo));
713 728
714 // If this next EXPECT_CALL fails flakily, it's probably a real failure. 729 // If this next EXPECT_CALL fails flakily, it's probably a real failure.
715 // We'll be getting a stream of UpdateDownload calls from the timer, and 730 // We'll be getting a stream of UpdateDownload calls from the timer, and
716 // the last one may have the correct information even if the failure 731 // the last one may have the correct information even if the failure
717 // doesn't produce an update, as the timer update may have triggered at the 732 // doesn't produce an update, as the timer update may have triggered at the
718 // same time. 733 // same time.
719 EXPECT_CALL(*(observer_.get()), CurrentUpdateStatus(0, _, _)); 734 EXPECT_CALL(*(observer_.get()), CurrentUpdateStatus(0, _));
720 735
721 FinishStream(DOWNLOAD_INTERRUPT_REASON_NETWORK_DISCONNECTED, false); 736 FinishStream(DOWNLOAD_INTERRUPT_REASON_NETWORK_DISCONNECTED, false,
737 kEmptyHash);
722 738
723 loop_.RunUntilIdle(); 739 loop_.RunUntilIdle();
724 740
725 DestroyDownloadFile(0); 741 DestroyDownloadFile(0);
726 } 742 }
727 743
728 TEST_F(DownloadFileTest, StreamNonEmptySuccess) { 744 TEST_F(DownloadFileTest, StreamNonEmptySuccess) {
729 ASSERT_TRUE(CreateDownloadFile(0, true)); 745 ASSERT_TRUE(CreateDownloadFile(0, true));
730 base::FilePath initial_path(download_file_->FullPath()); 746 base::FilePath initial_path(download_file_->FullPath());
731 EXPECT_TRUE(base::PathExists(initial_path)); 747 EXPECT_TRUE(base::PathExists(initial_path));
732 748
733 const char* chunks1[] = { kTestData1, kTestData2 }; 749 const char* chunks1[] = { kTestData1, kTestData2 };
734 ::testing::Sequence s1; 750 ::testing::Sequence s1;
735 SetupDataAppend(chunks1, 2, s1); 751 SetupDataAppend(chunks1, 2, s1);
736 SetupFinishStream(DOWNLOAD_INTERRUPT_REASON_NONE, s1); 752 SetupFinishStream(DOWNLOAD_INTERRUPT_REASON_NONE, s1);
737 EXPECT_CALL(*(observer_.get()), DestinationCompleted(_)); 753 EXPECT_CALL(*(observer_.get()), MockDestinationCompleted(_, _));
738 sink_callback_.Run(); 754 sink_callback_.Run();
739 VerifyStreamAndSize(); 755 VerifyStreamAndSize();
740 loop_.RunUntilIdle(); 756 loop_.RunUntilIdle();
741 DestroyDownloadFile(0); 757 DestroyDownloadFile(0);
742 } 758 }
743 759
744 TEST_F(DownloadFileTest, StreamNonEmptyError) { 760 TEST_F(DownloadFileTest, StreamNonEmptyError) {
745 ASSERT_TRUE(CreateDownloadFile(0, true)); 761 ASSERT_TRUE(CreateDownloadFile(0, true));
746 base::FilePath initial_path(download_file_->FullPath()); 762 base::FilePath initial_path(download_file_->FullPath());
747 EXPECT_TRUE(base::PathExists(initial_path)); 763 EXPECT_TRUE(base::PathExists(initial_path));
748 764
749 const char* chunks1[] = { kTestData1, kTestData2 }; 765 const char* chunks1[] = { kTestData1, kTestData2 };
750 ::testing::Sequence s1; 766 ::testing::Sequence s1;
751 SetupDataAppend(chunks1, 2, s1); 767 SetupDataAppend(chunks1, 2, s1);
752 SetupFinishStream(DOWNLOAD_INTERRUPT_REASON_NETWORK_DISCONNECTED, s1); 768 SetupFinishStream(DOWNLOAD_INTERRUPT_REASON_NETWORK_DISCONNECTED, s1);
753 769
754 EXPECT_CALL(*(observer_.get()), 770 EXPECT_CALL(*(observer_.get()),
755 DestinationError( 771 MockDestinationError(
756 DOWNLOAD_INTERRUPT_REASON_NETWORK_DISCONNECTED)) 772 DOWNLOAD_INTERRUPT_REASON_NETWORK_DISCONNECTED, _, _))
757 .WillOnce(InvokeWithoutArgs( 773 .WillOnce(InvokeWithoutArgs(
758 this, &DownloadFileTest::ConfirmUpdateDownloadInfo)); 774 this, &DownloadFileTest::ConfirmUpdateDownloadInfo));
759 775
760 // If this next EXPECT_CALL fails flakily, it's probably a real failure. 776 // If this next EXPECT_CALL fails flakily, it's probably a real failure.
761 // We'll be getting a stream of UpdateDownload calls from the timer, and 777 // We'll be getting a stream of UpdateDownload calls from the timer, and
762 // the last one may have the correct information even if the failure 778 // the last one may have the correct information even if the failure
763 // doesn't produce an update, as the timer update may have triggered at the 779 // doesn't produce an update, as the timer update may have triggered at the
764 // same time. 780 // same time.
765 EXPECT_CALL(*(observer_.get()), 781 EXPECT_CALL(*(observer_.get()),
766 CurrentUpdateStatus(strlen(kTestData1) + strlen(kTestData2), 782 CurrentUpdateStatus(strlen(kTestData1) + strlen(kTestData2), _));
767 _, _));
768 783
769 sink_callback_.Run(); 784 sink_callback_.Run();
770 loop_.RunUntilIdle(); 785 loop_.RunUntilIdle();
771 VerifyStreamAndSize(); 786 VerifyStreamAndSize();
772 DestroyDownloadFile(0); 787 DestroyDownloadFile(0);
773 } 788 }
774 789
775 // Send some data, wait 3/4s of a second, run the message loop, and
776 // confirm the values the observer received are correct.
777 TEST_F(DownloadFileTest, ConfirmUpdate) {
778 CreateDownloadFile(0, true);
779
780 const char* chunks1[] = { kTestData1, kTestData2 };
781 AppendDataToFile(chunks1, 2);
782
783 // Run the message loops for 750ms and check for results.
784 loop_.task_runner()->PostDelayedTask(FROM_HERE,
785 base::MessageLoop::QuitWhenIdleClosure(),
786 base::TimeDelta::FromMilliseconds(750));
787 loop_.Run();
788
789 EXPECT_EQ(static_cast<int64_t>(strlen(kTestData1) + strlen(kTestData2)),
790 bytes_);
791 EXPECT_EQ(download_file_->GetHashState(), hash_state_);
792
793 FinishStream(DOWNLOAD_INTERRUPT_REASON_NONE, true);
794 DestroyDownloadFile(0);
795 }
796
797 } // namespace content 790 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698