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

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: Rebase on top of https://codereview.chromium.org/1781983002 since that's going in first. 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(
73 reason, bytes_so_far, 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,
162 DownloadInterruptReason* reason_p, 172 DownloadInterruptReason* reason_p,
163 DownloadInterruptReason reason) { 173 DownloadInterruptReason reason) {
164 *reason_p = reason; 174 *reason_p = reason;
165 closure.Run(); 175 closure.Run();
166 } 176 }
167 177
168 bool CreateDownloadFile(int offset, bool calculate_hash) { 178 bool CreateDownloadFile(int offset, bool calculate_hash) {
169 // There can be only one. 179 // There can be only one.
170 DCHECK(!download_file_.get()); 180 DCHECK(!download_file_.get());
171 181
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(
182 *save_info, base::FilePath(), 192 new TestDownloadFileImpl(std::move(save_info),
183 GURL(), // Source 193 base::FilePath(),
184 GURL(), // Referrer 194 scoped_ptr<ByteStreamReader>(input_stream_),
185 calculate_hash, std::move(save_info->file), 195 net::BoundNetLog(),
186 scoped_ptr<ByteStreamReader>(input_stream_), net::BoundNetLog(), 196 observer_factory_.GetWeakPtr()));
187 observer_factory_.GetWeakPtr()));
188 download_file_->SetClientGuid("12345678-ABCD-1234-DCBA-123456789ABC");
189 197
190 EXPECT_CALL(*input_stream_, Read(_, _)) 198 EXPECT_CALL(*input_stream_, Read(_, _))
191 .WillOnce(Return(ByteStreamReader::STREAM_EMPTY)) 199 .WillOnce(Return(ByteStreamReader::STREAM_EMPTY))
192 .RetiresOnSaturation(); 200 .RetiresOnSaturation();
193 201
194 base::WeakPtrFactory<DownloadFileTest> weak_ptr_factory(this); 202 base::WeakPtrFactory<DownloadFileTest> weak_ptr_factory(this);
195 DownloadInterruptReason result = DOWNLOAD_INTERRUPT_REASON_NONE; 203 DownloadInterruptReason result = DOWNLOAD_INTERRUPT_REASON_NONE;
196 base::RunLoop loop_runner; 204 base::RunLoop loop_runner;
197 download_file_->Initialize(base::Bind( 205 download_file_->Initialize(base::Bind(
198 &DownloadFileTest::SetInterruptReasonCallback, 206 &DownloadFileTest::SetInterruptReasonCallback,
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
263 .RetiresOnSaturation(); 271 .RetiresOnSaturation();
264 EXPECT_CALL(*input_stream_, GetStatus()) 272 EXPECT_CALL(*input_stream_, GetStatus())
265 .InSequence(s) 273 .InSequence(s)
266 .WillOnce(Return(interrupt_reason)) 274 .WillOnce(Return(interrupt_reason))
267 .RetiresOnSaturation(); 275 .RetiresOnSaturation();
268 EXPECT_CALL(*input_stream_, RegisterCallback(_)) 276 EXPECT_CALL(*input_stream_, RegisterCallback(_))
269 .RetiresOnSaturation(); 277 .RetiresOnSaturation();
270 } 278 }
271 279
272 void FinishStream(DownloadInterruptReason interrupt_reason, 280 void FinishStream(DownloadInterruptReason interrupt_reason,
273 bool check_observer) { 281 bool check_observer,
282 const std::string& expected_hash) {
274 ::testing::Sequence s1; 283 ::testing::Sequence s1;
275 SetupFinishStream(interrupt_reason, s1); 284 SetupFinishStream(interrupt_reason, s1);
276 sink_callback_.Run(); 285 sink_callback_.Run();
277 VerifyStreamAndSize(); 286 VerifyStreamAndSize();
278 if (check_observer) { 287 if (check_observer) {
279 EXPECT_CALL(*(observer_.get()), DestinationCompleted(_)); 288 EXPECT_CALL(*(observer_.get()),
289 MockDestinationCompleted(_, expected_hash));
280 loop_.RunUntilIdle(); 290 loop_.RunUntilIdle();
281 ::testing::Mock::VerifyAndClearExpectations(observer_.get()); 291 ::testing::Mock::VerifyAndClearExpectations(observer_.get());
282 EXPECT_CALL(*(observer_.get()), DestinationUpdate(_, _, _)) 292 EXPECT_CALL(*(observer_.get()), DestinationUpdate(_, _))
283 .Times(AnyNumber()) 293 .Times(AnyNumber())
284 .WillRepeatedly(Invoke(this, 294 .WillRepeatedly(
285 &DownloadFileTest::SetUpdateDownloadInfo)); 295 Invoke(this, &DownloadFileTest::SetUpdateDownloadInfo));
286 } 296 }
287 } 297 }
288 298
289 DownloadInterruptReason RenameAndUniquify( 299 DownloadInterruptReason RenameAndUniquify(
290 const base::FilePath& full_path, 300 const base::FilePath& full_path,
291 base::FilePath* result_path_p) { 301 base::FilePath* result_path_p) {
292 return InvokeRenameMethodAndWaitForCallback( 302 return InvokeRenameMethodAndWaitForCallback(
293 &DownloadFile::RenameAndUniquify, full_path, result_path_p); 303 RENAME_AND_UNIQUIFY, full_path, result_path_p);
294 } 304 }
295 305
296 DownloadInterruptReason RenameAndAnnotate( 306 DownloadInterruptReason RenameAndAnnotate(
297 const base::FilePath& full_path, 307 const base::FilePath& full_path,
298 base::FilePath* result_path_p) { 308 base::FilePath* result_path_p) {
299 return InvokeRenameMethodAndWaitForCallback( 309 return InvokeRenameMethodAndWaitForCallback(
300 &DownloadFile::RenameAndAnnotate, full_path, result_path_p); 310 RENAME_AND_ANNOTATE, full_path, result_path_p);
301 } 311 }
302 312
303 void ExpectPermissionError(DownloadInterruptReason err) { 313 void ExpectPermissionError(DownloadInterruptReason err) {
304 EXPECT_TRUE(err == DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR || 314 EXPECT_TRUE(err == DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR ||
305 err == DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED) 315 err == DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED)
306 << "Interrupt reason = " << err; 316 << "Interrupt reason = " << err;
307 } 317 }
308 318
309 protected: 319 protected:
320 void InvokeRenameMethod(
321 DownloadFileRenameMethodType method,
322 const base::FilePath& full_path,
323 const DownloadFile::RenameCompletionCallback& completion_callback) {
324 switch (method) {
325 case RENAME_AND_UNIQUIFY:
326 download_file_->RenameAndUniquify(full_path, completion_callback);
327 break;
328
329 case RENAME_AND_ANNOTATE:
330 download_file_->RenameAndAnnotate(
331 full_path,
332 "12345678-ABCD-1234-DCBA-123456789ABC",
333 GURL(),
334 GURL(),
335 completion_callback);
336 break;
337 }
338 }
339
310 DownloadInterruptReason InvokeRenameMethodAndWaitForCallback( 340 DownloadInterruptReason InvokeRenameMethodAndWaitForCallback(
311 DownloadFileRenameMethodType method, 341 DownloadFileRenameMethodType method,
312 const base::FilePath& full_path, 342 const base::FilePath& full_path,
313 base::FilePath* result_path_p) { 343 base::FilePath* result_path_p) {
314 DownloadInterruptReason result_reason(DOWNLOAD_INTERRUPT_REASON_NONE); 344 DownloadInterruptReason result_reason(DOWNLOAD_INTERRUPT_REASON_NONE);
315 base::FilePath result_path; 345 base::FilePath result_path;
316
317 base::RunLoop loop_runner; 346 base::RunLoop loop_runner;
318 ((*download_file_).*method)(full_path, 347 DownloadFile::RenameCompletionCallback completion_callback =
319 base::Bind(&DownloadFileTest::SetRenameResult, 348 base::Bind(&DownloadFileTest::SetRenameResult,
320 base::Unretained(this), 349 base::Unretained(this),
321 loop_runner.QuitClosure(), 350 loop_runner.QuitClosure(),
322 &result_reason, 351 &result_reason,
323 result_path_p)); 352 result_path_p);
353 InvokeRenameMethod(method, full_path, completion_callback);
324 loop_runner.Run(); 354 loop_runner.Run();
325 return result_reason; 355 return result_reason;
326 } 356 }
327 357
328 scoped_ptr<StrictMock<MockDownloadDestinationObserver> > observer_; 358 scoped_ptr<StrictMock<MockDownloadDestinationObserver> > observer_;
329 base::WeakPtrFactory<DownloadDestinationObserver> observer_factory_; 359 base::WeakPtrFactory<DownloadDestinationObserver> observer_factory_;
330 360
331 // DownloadFile instance we are testing. 361 // DownloadFile instance we are testing.
332 scoped_ptr<DownloadFile> download_file_; 362 scoped_ptr<DownloadFile> download_file_;
333 363
334 // Stream for sending data into the download file. 364 // Stream for sending data into the download file.
335 // Owned by download_file_; will be alive for lifetime of download_file_. 365 // Owned by download_file_; will be alive for lifetime of download_file_.
336 StrictMock<MockByteStreamReader>* input_stream_; 366 StrictMock<MockByteStreamReader>* input_stream_;
337 367
338 // Sink callback data for stream. 368 // Sink callback data for stream.
339 base::Closure sink_callback_; 369 base::Closure sink_callback_;
340 370
341 // Latest update sent to the observer. 371 // Latest update sent to the observer.
342 int64_t bytes_; 372 int64_t bytes_;
343 int64_t bytes_per_sec_; 373 int64_t bytes_per_sec_;
344 std::string hash_state_;
345 374
346 base::MessageLoop loop_; 375 base::MessageLoop loop_;
347 376
348 private: 377 private:
349 void SetRenameResult(const base::Closure& closure, 378 void SetRenameResult(const base::Closure& closure,
350 DownloadInterruptReason* reason_p, 379 DownloadInterruptReason* reason_p,
351 base::FilePath* result_path_p, 380 base::FilePath* result_path_p,
352 DownloadInterruptReason reason, 381 DownloadInterruptReason reason,
353 const base::FilePath& result_path) { 382 const base::FilePath& result_path) {
354 if (reason_p) 383 if (reason_p)
(...skipping 29 matching lines...) Expand all
384 } 413 }
385 }; 414 };
386 415
387 // And now instantiate all DownloadFileTestWithRename tests using both 416 // And now instantiate all DownloadFileTestWithRename tests using both
388 // DownloadFile rename methods. Each test of the form 417 // DownloadFile rename methods. Each test of the form
389 // DownloadFileTestWithRename.<FooTest> will be instantiated once with 418 // DownloadFileTestWithRename.<FooTest> will be instantiated once with
390 // RenameAndAnnotate as the value parameter and once with RenameAndUniquify as 419 // RenameAndAnnotate as the value parameter and once with RenameAndUniquify as
391 // the value parameter. 420 // the value parameter.
392 INSTANTIATE_TEST_CASE_P(DownloadFile, 421 INSTANTIATE_TEST_CASE_P(DownloadFile,
393 DownloadFileTestWithRename, 422 DownloadFileTestWithRename,
394 ::testing::Values(&DownloadFile::RenameAndAnnotate, 423 ::testing::Values(RENAME_AND_ANNOTATE,
395 &DownloadFile::RenameAndUniquify)); 424 RENAME_AND_UNIQUIFY));
396 425
397 const char* DownloadFileTest::kTestData1 = 426 const char DownloadFileTest::kTestData1[] =
398 "Let's write some data to the file!\n"; 427 "Let's write some data to the file!\n";
399 const char* DownloadFileTest::kTestData2 = "Writing more data.\n"; 428 const char DownloadFileTest::kTestData2[] = "Writing more data.\n";
400 const char* DownloadFileTest::kTestData3 = "Final line."; 429 const char DownloadFileTest::kTestData3[] = "Final line.";
401 const char* DownloadFileTest::kDataHash = 430 const char DownloadFileTest::kDataHash[] =
402 "CBF68BF10F8003DB86B31343AFAC8C7175BD03FB5FC905650F8C80AF087443A8"; 431 "CBF68BF10F8003DB86B31343AFAC8C7175BD03FB5FC905650F8C80AF087443A8";
432 const char DownloadFileTest::kEmptyHash[] =
433 "E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855";
403 434
404 const uint32_t DownloadFileTest::kDummyDownloadId = 23; 435 const uint32_t DownloadFileTest::kDummyDownloadId = 23;
405 const int DownloadFileTest::kDummyChildId = 3; 436 const int DownloadFileTest::kDummyChildId = 3;
406 const int DownloadFileTest::kDummyRequestId = 67; 437 const int DownloadFileTest::kDummyRequestId = 67;
407 438
408 // Rename the file before any data is downloaded, after some has, after it all 439 // Rename the file before any data is downloaded, after some has, after it all
409 // has, and after it's closed. 440 // has, and after it's closed.
410 TEST_P(DownloadFileTestWithRename, RenameFileFinal) { 441 TEST_P(DownloadFileTestWithRename, RenameFileFinal) {
411 ASSERT_TRUE(CreateDownloadFile(0, true)); 442 ASSERT_TRUE(CreateDownloadFile(0, true));
412 base::FilePath initial_path(download_file_->FullPath()); 443 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, 481 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE,
451 InvokeSelectedRenameMethod(path_3, &output_path)); 482 InvokeSelectedRenameMethod(path_3, &output_path));
452 renamed_path = download_file_->FullPath(); 483 renamed_path = download_file_->FullPath();
453 EXPECT_EQ(path_3, renamed_path); 484 EXPECT_EQ(path_3, renamed_path);
454 EXPECT_EQ(path_3, output_path); 485 EXPECT_EQ(path_3, output_path);
455 486
456 // Check the files. 487 // Check the files.
457 EXPECT_FALSE(base::PathExists(path_2)); 488 EXPECT_FALSE(base::PathExists(path_2));
458 EXPECT_TRUE(base::PathExists(path_3)); 489 EXPECT_TRUE(base::PathExists(path_3));
459 490
460 // Should not be able to get the hash until the file is closed. 491 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(); 492 loop_.RunUntilIdle();
465 493
466 // Rename the file after downloading all the data and closing the file. 494 // Rename the file after downloading all the data and closing the file.
467 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, 495 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE,
468 InvokeSelectedRenameMethod(path_4, &output_path)); 496 InvokeSelectedRenameMethod(path_4, &output_path));
469 renamed_path = download_file_->FullPath(); 497 renamed_path = download_file_->FullPath();
470 EXPECT_EQ(path_4, renamed_path); 498 EXPECT_EQ(path_4, renamed_path);
471 EXPECT_EQ(path_4, output_path); 499 EXPECT_EQ(path_4, output_path);
472 500
473 // Check the files. 501 // Check the files.
474 EXPECT_FALSE(base::PathExists(path_3)); 502 EXPECT_FALSE(base::PathExists(path_3));
475 EXPECT_TRUE(base::PathExists(path_4)); 503 EXPECT_TRUE(base::PathExists(path_4));
476 504
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); 505 DestroyDownloadFile(0);
482 } 506 }
483 507
484 // Test to make sure the rename overwrites when requested. This is separate from 508 // Test to make sure the rename overwrites when requested. This is separate from
485 // the above test because it only applies to RenameAndAnnotate(). 509 // the above test because it only applies to RenameAndAnnotate().
486 // RenameAndUniquify() doesn't overwrite by design. 510 // RenameAndUniquify() doesn't overwrite by design.
487 TEST_F(DownloadFileTest, RenameOverwrites) { 511 TEST_F(DownloadFileTest, RenameOverwrites) {
488 ASSERT_TRUE(CreateDownloadFile(0, true)); 512 ASSERT_TRUE(CreateDownloadFile(0, true));
489 base::FilePath initial_path(download_file_->FullPath()); 513 base::FilePath initial_path(download_file_->FullPath());
490 EXPECT_TRUE(base::PathExists(initial_path)); 514 EXPECT_TRUE(base::PathExists(initial_path));
491 base::FilePath path_1(initial_path.InsertBeforeExtensionASCII("_1")); 515 base::FilePath path_1(initial_path.InsertBeforeExtensionASCII("_1"));
492 516
493 ASSERT_FALSE(base::PathExists(path_1)); 517 ASSERT_FALSE(base::PathExists(path_1));
494 static const char file_data[] = "xyzzy"; 518 static const char file_data[] = "xyzzy";
495 ASSERT_EQ(static_cast<int>(sizeof(file_data)), 519 ASSERT_EQ(static_cast<int>(sizeof(file_data)),
496 base::WriteFile(path_1, file_data, sizeof(file_data))); 520 base::WriteFile(path_1, file_data, sizeof(file_data)));
497 ASSERT_TRUE(base::PathExists(path_1)); 521 ASSERT_TRUE(base::PathExists(path_1));
498 522
499 base::FilePath new_path; 523 base::FilePath new_path;
500 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, 524 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE,
501 RenameAndAnnotate(path_1, &new_path)); 525 RenameAndAnnotate(path_1, &new_path));
502 EXPECT_EQ(path_1.value(), new_path.value()); 526 EXPECT_EQ(path_1.value(), new_path.value());
503 527
504 std::string file_contents; 528 std::string file_contents;
505 ASSERT_TRUE(base::ReadFileToString(new_path, &file_contents)); 529 ASSERT_TRUE(base::ReadFileToString(new_path, &file_contents));
506 EXPECT_NE(std::string(file_data), file_contents); 530 EXPECT_NE(std::string(file_data), file_contents);
507 531
508 FinishStream(DOWNLOAD_INTERRUPT_REASON_NONE, true); 532 FinishStream(DOWNLOAD_INTERRUPT_REASON_NONE, true, kEmptyHash);
509 loop_.RunUntilIdle(); 533 loop_.RunUntilIdle();
510 DestroyDownloadFile(0); 534 DestroyDownloadFile(0);
511 } 535 }
512 536
513 // Test to make sure the rename uniquifies if we aren't overwriting 537 // 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 538 // and there's a file where we're aiming. As above, not a
515 // DownloadFileTestWithRename test because this only applies to 539 // DownloadFileTestWithRename test because this only applies to
516 // RenameAndUniquify(). 540 // RenameAndUniquify().
517 TEST_F(DownloadFileTest, RenameUniquifies) { 541 TEST_F(DownloadFileTest, RenameUniquifies) {
518 ASSERT_TRUE(CreateDownloadFile(0, true)); 542 ASSERT_TRUE(CreateDownloadFile(0, true));
519 base::FilePath initial_path(download_file_->FullPath()); 543 base::FilePath initial_path(download_file_->FullPath());
520 EXPECT_TRUE(base::PathExists(initial_path)); 544 EXPECT_TRUE(base::PathExists(initial_path));
521 base::FilePath path_1(initial_path.InsertBeforeExtensionASCII("_1")); 545 base::FilePath path_1(initial_path.InsertBeforeExtensionASCII("_1"));
522 base::FilePath path_1_suffixed(path_1.InsertBeforeExtensionASCII(" (1)")); 546 base::FilePath path_1_suffixed(path_1.InsertBeforeExtensionASCII(" (1)"));
523 547
524 ASSERT_FALSE(base::PathExists(path_1)); 548 ASSERT_FALSE(base::PathExists(path_1));
525 static const char file_data[] = "xyzzy"; 549 static const char file_data[] = "xyzzy";
526 ASSERT_EQ(static_cast<int>(sizeof(file_data)), 550 ASSERT_EQ(static_cast<int>(sizeof(file_data)),
527 base::WriteFile(path_1, file_data, sizeof(file_data))); 551 base::WriteFile(path_1, file_data, sizeof(file_data)));
528 ASSERT_TRUE(base::PathExists(path_1)); 552 ASSERT_TRUE(base::PathExists(path_1));
529 553
530 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, RenameAndUniquify(path_1, NULL)); 554 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, RenameAndUniquify(path_1, NULL));
531 EXPECT_TRUE(base::PathExists(path_1_suffixed)); 555 EXPECT_TRUE(base::PathExists(path_1_suffixed));
532 556
533 FinishStream(DOWNLOAD_INTERRUPT_REASON_NONE, true); 557 FinishStream(DOWNLOAD_INTERRUPT_REASON_NONE, true, kEmptyHash);
534 loop_.RunUntilIdle(); 558 loop_.RunUntilIdle();
535 DestroyDownloadFile(0); 559 DestroyDownloadFile(0);
536 } 560 }
537 561
538 // Test that RenameAndUniquify doesn't try to uniquify in the case where the 562 // Test that RenameAndUniquify doesn't try to uniquify in the case where the
539 // target filename is the same as the current filename. 563 // target filename is the same as the current filename.
540 TEST_F(DownloadFileTest, RenameRecognizesSelfConflict) { 564 TEST_F(DownloadFileTest, RenameRecognizesSelfConflict) {
541 ASSERT_TRUE(CreateDownloadFile(0, true)); 565 ASSERT_TRUE(CreateDownloadFile(0, true));
542 base::FilePath initial_path(download_file_->FullPath()); 566 base::FilePath initial_path(download_file_->FullPath());
543 EXPECT_TRUE(base::PathExists(initial_path)); 567 EXPECT_TRUE(base::PathExists(initial_path));
544 568
545 base::FilePath new_path; 569 base::FilePath new_path;
546 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, 570 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE,
547 RenameAndUniquify(initial_path, &new_path)); 571 RenameAndUniquify(initial_path, &new_path));
548 EXPECT_TRUE(base::PathExists(initial_path)); 572 EXPECT_TRUE(base::PathExists(initial_path));
549 573
550 FinishStream(DOWNLOAD_INTERRUPT_REASON_NONE, true); 574 FinishStream(DOWNLOAD_INTERRUPT_REASON_NONE, true, kEmptyHash);
551 loop_.RunUntilIdle(); 575 loop_.RunUntilIdle();
552 DestroyDownloadFile(0); 576 DestroyDownloadFile(0);
553 EXPECT_EQ(initial_path.value(), new_path.value()); 577 EXPECT_EQ(initial_path.value(), new_path.value());
554 } 578 }
555 579
556 // Test to make sure we get the proper error on failure. 580 // Test to make sure we get the proper error on failure.
557 TEST_P(DownloadFileTestWithRename, RenameError) { 581 TEST_P(DownloadFileTestWithRename, RenameError) {
558 ASSERT_TRUE(CreateDownloadFile(0, true)); 582 ASSERT_TRUE(CreateDownloadFile(0, true));
559 base::FilePath initial_path(download_file_->FullPath()); 583 base::FilePath initial_path(download_file_->FullPath());
560 584
(...skipping 14 matching lines...) Expand all
575 { 599 {
576 base::FilePermissionRestorer restorer(target_dir); 600 base::FilePermissionRestorer restorer(target_dir);
577 ASSERT_TRUE(base::MakeFileUnwritable(target_dir)); 601 ASSERT_TRUE(base::MakeFileUnwritable(target_dir));
578 602
579 // Expect nulling out of further processing. 603 // Expect nulling out of further processing.
580 EXPECT_CALL(*input_stream_, RegisterCallback(IsNullCallback())); 604 EXPECT_CALL(*input_stream_, RegisterCallback(IsNullCallback()));
581 ExpectPermissionError(InvokeSelectedRenameMethod(target_path, NULL)); 605 ExpectPermissionError(InvokeSelectedRenameMethod(target_path, NULL));
582 EXPECT_FALSE(base::PathExists(target_path_suffixed)); 606 EXPECT_FALSE(base::PathExists(target_path_suffixed));
583 } 607 }
584 608
585 FinishStream(DOWNLOAD_INTERRUPT_REASON_NONE, true); 609 FinishStream(DOWNLOAD_INTERRUPT_REASON_NONE, true, kEmptyHash);
586 loop_.RunUntilIdle(); 610 loop_.RunUntilIdle();
587 DestroyDownloadFile(0); 611 DestroyDownloadFile(0);
588 } 612 }
589 613
590 namespace { 614 namespace {
591 615
592 void TestRenameCompletionCallback(const base::Closure& closure, 616 void TestRenameCompletionCallback(const base::Closure& closure,
593 bool* did_run_callback, 617 bool* did_run_callback,
594 DownloadInterruptReason interrupt_reason, 618 DownloadInterruptReason interrupt_reason,
595 const base::FilePath& new_path) { 619 const base::FilePath& new_path) {
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
638 #else 662 #else
639 // Simulate a transient failure by revoking write permission for target_dir. 663 // Simulate a transient failure by revoking write permission for target_dir.
640 // The TestDownloadFileImpl class treats this error as transient even though 664 // The TestDownloadFileImpl class treats this error as transient even though
641 // DownloadFileImpl itself doesn't. 665 // DownloadFileImpl itself doesn't.
642 base::FilePermissionRestorer restore_permissions_for(target_dir); 666 base::FilePermissionRestorer restore_permissions_for(target_dir);
643 ASSERT_TRUE(base::MakeFileUnwritable(target_dir)); 667 ASSERT_TRUE(base::MakeFileUnwritable(target_dir));
644 #endif 668 #endif
645 669
646 // The Rename() should fail here and enqueue a retry task without invoking 670 // The Rename() should fail here and enqueue a retry task without invoking
647 // the completion callback. 671 // the completion callback.
648 ((*download_file_).*GetParam())(target_path, 672 InvokeRenameMethod(GetParam(),
649 base::Bind(&TestRenameCompletionCallback, 673 target_path,
650 succeeding_run.QuitClosure(), 674 base::Bind(&TestRenameCompletionCallback,
651 &did_run_callback)); 675 succeeding_run.QuitClosure(),
676 &did_run_callback));
652 EXPECT_FALSE(did_run_callback); 677 EXPECT_FALSE(did_run_callback);
653 678
654 base::RunLoop first_failing_run; 679 base::RunLoop first_failing_run;
655 // Queue the QuitClosure() on the MessageLoop now. Any tasks queued by the 680 // 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 681 // 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 682 // 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(). 683 // fails, so another retry task would get queued behind the QuitClosure().
659 base::ThreadTaskRunnerHandle::Get()->PostTask( 684 base::ThreadTaskRunnerHandle::Get()->PostTask(
660 FROM_HERE, first_failing_run.QuitClosure()); 685 FROM_HERE, first_failing_run.QuitClosure());
661 first_failing_run.Run(); 686 first_failing_run.Run();
662 EXPECT_FALSE(did_run_callback); 687 EXPECT_FALSE(did_run_callback);
663 688
664 // Running another loop should have the same effect as the above as long as 689 // Running another loop should have the same effect as the above as long as
665 // kMaxRenameRetries is greater than 2. 690 // kMaxRenameRetries is greater than 2.
666 base::RunLoop second_failing_run; 691 base::RunLoop second_failing_run;
667 base::ThreadTaskRunnerHandle::Get()->PostTask( 692 base::ThreadTaskRunnerHandle::Get()->PostTask(
668 FROM_HERE, second_failing_run.QuitClosure()); 693 FROM_HERE, second_failing_run.QuitClosure());
669 second_failing_run.Run(); 694 second_failing_run.Run();
670 EXPECT_FALSE(did_run_callback); 695 EXPECT_FALSE(did_run_callback);
671 } 696 }
672 697
673 // This time the QuitClosure from succeeding_run should get executed. 698 // This time the QuitClosure from succeeding_run should get executed.
674 succeeding_run.Run(); 699 succeeding_run.Run();
675 EXPECT_TRUE(did_run_callback); 700 EXPECT_TRUE(did_run_callback);
676 701
677 FinishStream(DOWNLOAD_INTERRUPT_REASON_NONE, true); 702 FinishStream(DOWNLOAD_INTERRUPT_REASON_NONE, true, kEmptyHash);
678 loop_.RunUntilIdle(); 703 loop_.RunUntilIdle();
679 DestroyDownloadFile(0); 704 DestroyDownloadFile(0);
680 } 705 }
681 706
682 // Various tests of the StreamActive method. 707 // Various tests of the StreamActive method.
683 TEST_F(DownloadFileTest, StreamEmptySuccess) { 708 TEST_F(DownloadFileTest, StreamEmptySuccess) {
684 ASSERT_TRUE(CreateDownloadFile(0, true)); 709 ASSERT_TRUE(CreateDownloadFile(0, true));
685 base::FilePath initial_path(download_file_->FullPath()); 710 base::FilePath initial_path(download_file_->FullPath());
686 EXPECT_TRUE(base::PathExists(initial_path)); 711 EXPECT_TRUE(base::PathExists(initial_path));
687 712
688 // Test that calling the sink_callback_ on an empty stream shouldn't 713 // Test that calling the sink_callback_ on an empty stream shouldn't
689 // do anything. 714 // do anything.
690 AppendDataToFile(NULL, 0); 715 AppendDataToFile(NULL, 0);
691 716
692 // Finish the download this way and make sure we see it on the 717 // Finish the download this way and make sure we see it on the observer.
693 // observer. 718 FinishStream(DOWNLOAD_INTERRUPT_REASON_NONE, true, kEmptyHash);
694 EXPECT_CALL(*(observer_.get()), DestinationCompleted(_));
695 FinishStream(DOWNLOAD_INTERRUPT_REASON_NONE, false);
696 loop_.RunUntilIdle(); 719 loop_.RunUntilIdle();
697 720
698 DestroyDownloadFile(0); 721 DestroyDownloadFile(0);
699 } 722 }
700 723
701 TEST_F(DownloadFileTest, StreamEmptyError) { 724 TEST_F(DownloadFileTest, StreamEmptyError) {
702 ASSERT_TRUE(CreateDownloadFile(0, true)); 725 ASSERT_TRUE(CreateDownloadFile(0, true));
703 base::FilePath initial_path(download_file_->FullPath()); 726 base::FilePath initial_path(download_file_->FullPath());
704 EXPECT_TRUE(base::PathExists(initial_path)); 727 EXPECT_TRUE(base::PathExists(initial_path));
705 728
706 // Finish the download in error and make sure we see it on the 729 // Finish the download in error and make sure we see it on the
707 // observer. 730 // observer.
708 EXPECT_CALL(*(observer_.get()), 731 EXPECT_CALL(
709 DestinationError( 732 *(observer_.get()),
710 DOWNLOAD_INTERRUPT_REASON_NETWORK_DISCONNECTED)) 733 MockDestinationError(
734 DOWNLOAD_INTERRUPT_REASON_NETWORK_DISCONNECTED, 0, kEmptyHash))
711 .WillOnce(InvokeWithoutArgs( 735 .WillOnce(InvokeWithoutArgs(
712 this, &DownloadFileTest::ConfirmUpdateDownloadInfo)); 736 this, &DownloadFileTest::ConfirmUpdateDownloadInfo));
713 737
714 // If this next EXPECT_CALL fails flakily, it's probably a real failure. 738 // 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 739 // 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 740 // 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 741 // doesn't produce an update, as the timer update may have triggered at the
718 // same time. 742 // same time.
719 EXPECT_CALL(*(observer_.get()), CurrentUpdateStatus(0, _, _)); 743 EXPECT_CALL(*(observer_.get()), CurrentUpdateStatus(0, _));
720 744
721 FinishStream(DOWNLOAD_INTERRUPT_REASON_NETWORK_DISCONNECTED, false); 745 FinishStream(
746 DOWNLOAD_INTERRUPT_REASON_NETWORK_DISCONNECTED, false, kEmptyHash);
722 747
723 loop_.RunUntilIdle(); 748 loop_.RunUntilIdle();
724 749
725 DestroyDownloadFile(0); 750 DestroyDownloadFile(0);
726 } 751 }
727 752
728 TEST_F(DownloadFileTest, StreamNonEmptySuccess) { 753 TEST_F(DownloadFileTest, StreamNonEmptySuccess) {
729 ASSERT_TRUE(CreateDownloadFile(0, true)); 754 ASSERT_TRUE(CreateDownloadFile(0, true));
730 base::FilePath initial_path(download_file_->FullPath()); 755 base::FilePath initial_path(download_file_->FullPath());
731 EXPECT_TRUE(base::PathExists(initial_path)); 756 EXPECT_TRUE(base::PathExists(initial_path));
732 757
733 const char* chunks1[] = { kTestData1, kTestData2 }; 758 const char* chunks1[] = { kTestData1, kTestData2 };
734 ::testing::Sequence s1; 759 ::testing::Sequence s1;
735 SetupDataAppend(chunks1, 2, s1); 760 SetupDataAppend(chunks1, 2, s1);
736 SetupFinishStream(DOWNLOAD_INTERRUPT_REASON_NONE, s1); 761 SetupFinishStream(DOWNLOAD_INTERRUPT_REASON_NONE, s1);
737 EXPECT_CALL(*(observer_.get()), DestinationCompleted(_)); 762 EXPECT_CALL(*(observer_.get()), MockDestinationCompleted(_, _));
738 sink_callback_.Run(); 763 sink_callback_.Run();
739 VerifyStreamAndSize(); 764 VerifyStreamAndSize();
740 loop_.RunUntilIdle(); 765 loop_.RunUntilIdle();
741 DestroyDownloadFile(0); 766 DestroyDownloadFile(0);
742 } 767 }
743 768
744 TEST_F(DownloadFileTest, StreamNonEmptyError) { 769 TEST_F(DownloadFileTest, StreamNonEmptyError) {
745 ASSERT_TRUE(CreateDownloadFile(0, true)); 770 ASSERT_TRUE(CreateDownloadFile(0, true));
746 base::FilePath initial_path(download_file_->FullPath()); 771 base::FilePath initial_path(download_file_->FullPath());
747 EXPECT_TRUE(base::PathExists(initial_path)); 772 EXPECT_TRUE(base::PathExists(initial_path));
748 773
749 const char* chunks1[] = { kTestData1, kTestData2 }; 774 const char* chunks1[] = { kTestData1, kTestData2 };
750 ::testing::Sequence s1; 775 ::testing::Sequence s1;
751 SetupDataAppend(chunks1, 2, s1); 776 SetupDataAppend(chunks1, 2, s1);
752 SetupFinishStream(DOWNLOAD_INTERRUPT_REASON_NETWORK_DISCONNECTED, s1); 777 SetupFinishStream(DOWNLOAD_INTERRUPT_REASON_NETWORK_DISCONNECTED, s1);
753 778
754 EXPECT_CALL(*(observer_.get()), 779 EXPECT_CALL(*(observer_.get()),
755 DestinationError( 780 MockDestinationError(
756 DOWNLOAD_INTERRUPT_REASON_NETWORK_DISCONNECTED)) 781 DOWNLOAD_INTERRUPT_REASON_NETWORK_DISCONNECTED, _, _))
757 .WillOnce(InvokeWithoutArgs( 782 .WillOnce(InvokeWithoutArgs(
758 this, &DownloadFileTest::ConfirmUpdateDownloadInfo)); 783 this, &DownloadFileTest::ConfirmUpdateDownloadInfo));
759 784
760 // If this next EXPECT_CALL fails flakily, it's probably a real failure. 785 // 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 786 // 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 787 // 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 788 // doesn't produce an update, as the timer update may have triggered at the
764 // same time. 789 // same time.
765 EXPECT_CALL(*(observer_.get()), 790 EXPECT_CALL(*(observer_.get()),
766 CurrentUpdateStatus(strlen(kTestData1) + strlen(kTestData2), 791 CurrentUpdateStatus(strlen(kTestData1) + strlen(kTestData2), _));
767 _, _));
768 792
769 sink_callback_.Run(); 793 sink_callback_.Run();
770 loop_.RunUntilIdle(); 794 loop_.RunUntilIdle();
771 VerifyStreamAndSize(); 795 VerifyStreamAndSize();
772 DestroyDownloadFile(0); 796 DestroyDownloadFile(0);
773 } 797 }
774 798
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 799 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/download/download_file_impl.cc ('k') | content/browser/download/download_item_factory.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698