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

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

Issue 2712713007: Make DownloadFileImpl handle multiple byte streams. (Closed)
Patch Set: Work on feedback. Created 3 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
8 #include <utility> 8 #include <utility>
9 #include <vector> 9 #include <vector>
10 10
11 #include "base/files/file.h" 11 #include "base/files/file.h"
12 #include "base/files/file_util.h" 12 #include "base/files/file_util.h"
13 #include "base/location.h" 13 #include "base/location.h"
14 #include "base/memory/ptr_util.h"
14 #include "base/run_loop.h" 15 #include "base/run_loop.h"
15 #include "base/single_thread_task_runner.h" 16 #include "base/single_thread_task_runner.h"
16 #include "base/strings/string_number_conversions.h" 17 #include "base/strings/string_number_conversions.h"
17 #include "base/test/test_file_util.h" 18 #include "base/test/test_file_util.h"
18 #include "base/threading/thread_task_runner_handle.h" 19 #include "base/threading/thread_task_runner_handle.h"
19 #include "build/build_config.h" 20 #include "build/build_config.h"
20 #include "content/browser/byte_stream.h" 21 #include "content/browser/byte_stream.h"
21 #include "content/browser/download/download_create_info.h" 22 #include "content/browser/download/download_create_info.h"
22 #include "content/browser/download/download_destination_observer.h" 23 #include "content/browser/download/download_destination_observer.h"
23 #include "content/browser/download/download_file_impl.h" 24 #include "content/browser/download/download_file_impl.h"
(...skipping 13 matching lines...) Expand all
37 using ::testing::AnyNumber; 38 using ::testing::AnyNumber;
38 using ::testing::DoAll; 39 using ::testing::DoAll;
39 using ::testing::InSequence; 40 using ::testing::InSequence;
40 using ::testing::Return; 41 using ::testing::Return;
41 using ::testing::SetArgPointee; 42 using ::testing::SetArgPointee;
42 using ::testing::StrictMock; 43 using ::testing::StrictMock;
43 44
44 namespace content { 45 namespace content {
45 namespace { 46 namespace {
46 47
48 // Struct for SourceStream states verification.
49 struct SourceStreamTestData {
50 SourceStreamTestData(int64_t offset, int64_t bytes_written, bool finished)
51 : offset(offset), bytes_written(bytes_written), finished(finished) {}
52 int64_t offset;
53 int64_t bytes_written;
54 bool finished;
55 };
56
47 std::string GetHexEncodedHashValue(crypto::SecureHash* hash_state) { 57 std::string GetHexEncodedHashValue(crypto::SecureHash* hash_state) {
48 if (!hash_state) 58 if (!hash_state)
49 return std::string(); 59 return std::string();
50 std::vector<char> hash_value(hash_state->GetHashLength()); 60 std::vector<char> hash_value(hash_state->GetHashLength());
51 hash_state->Finish(&hash_value.front(), hash_value.size()); 61 hash_state->Finish(&hash_value.front(), hash_value.size());
52 return base::HexEncode(&hash_value.front(), hash_value.size()); 62 return base::HexEncode(&hash_value.front(), hash_value.size());
53 } 63 }
54 64
55 class MockByteStreamReader : public ByteStreamReader { 65 class MockByteStreamReader : public ByteStreamReader {
56 public: 66 public:
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
96 enum DownloadFileRenameMethodType { RENAME_AND_UNIQUIFY, RENAME_AND_ANNOTATE }; 106 enum DownloadFileRenameMethodType { RENAME_AND_UNIQUIFY, RENAME_AND_ANNOTATE };
97 107
98 // This is a test DownloadFileImpl that has no retry delay and, on Posix, 108 // This is a test DownloadFileImpl that has no retry delay and, on Posix,
99 // retries renames failed due to ACCESS_DENIED. 109 // retries renames failed due to ACCESS_DENIED.
100 class TestDownloadFileImpl : public DownloadFileImpl { 110 class TestDownloadFileImpl : public DownloadFileImpl {
101 public: 111 public:
102 TestDownloadFileImpl(std::unique_ptr<DownloadSaveInfo> save_info, 112 TestDownloadFileImpl(std::unique_ptr<DownloadSaveInfo> save_info,
103 const base::FilePath& default_downloads_directory, 113 const base::FilePath& default_downloads_directory,
104 std::unique_ptr<ByteStreamReader> stream, 114 std::unique_ptr<ByteStreamReader> stream,
105 const net::NetLogWithSource& net_log, 115 const net::NetLogWithSource& net_log,
116 bool is_sparse_file,
106 base::WeakPtr<DownloadDestinationObserver> observer) 117 base::WeakPtr<DownloadDestinationObserver> observer)
107 : DownloadFileImpl(std::move(save_info), 118 : DownloadFileImpl(std::move(save_info),
108 default_downloads_directory, 119 default_downloads_directory,
109 std::move(stream), 120 std::move(stream),
110 net_log, 121 net_log,
122 is_sparse_file,
111 observer) {} 123 observer) {}
112 124
113 protected: 125 protected:
114 base::TimeDelta GetRetryDelayForFailedRename(int attempt_count) override { 126 base::TimeDelta GetRetryDelayForFailedRename(int attempt_count) override {
115 return base::TimeDelta::FromMilliseconds(0); 127 return base::TimeDelta::FromMilliseconds(0);
116 } 128 }
117 129
118 #if !defined(OS_WIN) 130 #if !defined(OS_WIN)
119 // On Posix, we don't encounter transient errors during renames, except 131 // On Posix, we don't encounter transient errors during renames, except
120 // possibly EAGAIN, which is difficult to replicate reliably. So we resort to 132 // possibly EAGAIN, which is difficult to replicate reliably. So we resort to
121 // simulating a transient error using ACCESS_DENIED instead. 133 // simulating a transient error using ACCESS_DENIED instead.
122 bool ShouldRetryFailedRename(DownloadInterruptReason reason) override { 134 bool ShouldRetryFailedRename(DownloadInterruptReason reason) override {
123 return reason == DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED; 135 return reason == DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED;
124 } 136 }
125 #endif 137 #endif
126 }; 138 };
127 139
128 } // namespace 140 } // namespace
129 141
130 class DownloadFileTest : public testing::Test { 142 class DownloadFileTest : public testing::Test {
131 public: 143 public:
132 static const char kTestData1[]; 144 static const char kTestData1[];
133 static const char kTestData2[]; 145 static const char kTestData2[];
134 static const char kTestData3[]; 146 static const char kTestData3[];
147 static const char kTestData4[];
148 static const char kTestData5[];
135 static const char kDataHash[]; 149 static const char kDataHash[];
136 static const char kEmptyHash[]; 150 static const char kEmptyHash[];
137 static const uint32_t kDummyDownloadId; 151 static const uint32_t kDummyDownloadId;
138 static const int kDummyChildId; 152 static const int kDummyChildId;
139 static const int kDummyRequestId; 153 static const int kDummyRequestId;
140 154
141 DownloadFileTest() 155 DownloadFileTest()
142 : observer_(new StrictMock<MockDownloadDestinationObserver>), 156 : observer_(new StrictMock<MockDownloadDestinationObserver>),
143 observer_factory_(observer_.get()), 157 observer_factory_(observer_.get()),
144 input_stream_(NULL), 158 input_stream_(NULL),
159 input_stream_1_(NULL),
145 bytes_(-1), 160 bytes_(-1),
146 bytes_per_sec_(-1) {} 161 bytes_per_sec_(-1) {}
147 162
148 ~DownloadFileTest() override {} 163 ~DownloadFileTest() override {}
149 164
150 void SetUpdateDownloadInfo(int64_t bytes, int64_t bytes_per_sec) { 165 void SetUpdateDownloadInfo(int64_t bytes, int64_t bytes_per_sec) {
151 bytes_ = bytes; 166 bytes_ = bytes;
152 bytes_per_sec_ = bytes_per_sec; 167 bytes_per_sec_ = bytes_per_sec;
153 } 168 }
154 169
(...skipping 12 matching lines...) Expand all
167 sink_callback_ = sink_callback; 182 sink_callback_ = sink_callback;
168 } 183 }
169 184
170 void SetInterruptReasonCallback(const base::Closure& closure, 185 void SetInterruptReasonCallback(const base::Closure& closure,
171 DownloadInterruptReason* reason_p, 186 DownloadInterruptReason* reason_p,
172 DownloadInterruptReason reason) { 187 DownloadInterruptReason reason) {
173 *reason_p = reason; 188 *reason_p = reason;
174 closure.Run(); 189 closure.Run();
175 } 190 }
176 191
177 bool CreateDownloadFile(int offset, bool calculate_hash) { 192 bool CreateDownloadFile(int offset,
193 bool calculate_hash,
194 bool is_sparse_file = false) {
178 // There can be only one. 195 // There can be only one.
179 DCHECK(!download_file_.get()); 196 DCHECK(!download_file_.get());
180 197
181 input_stream_ = new StrictMock<MockByteStreamReader>(); 198 input_stream_ = new StrictMock<MockByteStreamReader>();
182 199
183 // TODO: Need to actually create a function that'll set the variables 200 // TODO: Need to actually create a function that'll set the variables
184 // based on the inputs from the callback. 201 // based on the inputs from the callback.
185 EXPECT_CALL(*input_stream_, RegisterCallback(_)) 202 EXPECT_CALL(*input_stream_, RegisterCallback(_))
186 .WillOnce(Invoke(this, &DownloadFileTest::RegisterCallback)) 203 .WillOnce(Invoke(this, &DownloadFileTest::RegisterCallback))
187 .RetiresOnSaturation(); 204 .RetiresOnSaturation();
188 205
189 std::unique_ptr<DownloadSaveInfo> save_info(new DownloadSaveInfo()); 206 std::unique_ptr<DownloadSaveInfo> save_info(new DownloadSaveInfo());
190 download_file_.reset(new TestDownloadFileImpl( 207 download_file_.reset(new TestDownloadFileImpl(
191 std::move(save_info), base::FilePath(), 208 std::move(save_info), base::FilePath(),
192 std::unique_ptr<ByteStreamReader>(input_stream_), 209 std::unique_ptr<ByteStreamReader>(input_stream_),
193 net::NetLogWithSource(), observer_factory_.GetWeakPtr())); 210 net::NetLogWithSource(), is_sparse_file,
211 observer_factory_.GetWeakPtr()));
194 212
195 EXPECT_CALL(*input_stream_, Read(_, _)) 213 EXPECT_CALL(*input_stream_, Read(_, _))
196 .WillOnce(Return(ByteStreamReader::STREAM_EMPTY)) 214 .WillOnce(Return(ByteStreamReader::STREAM_EMPTY))
197 .RetiresOnSaturation(); 215 .RetiresOnSaturation();
198 216
199 base::WeakPtrFactory<DownloadFileTest> weak_ptr_factory(this); 217 base::WeakPtrFactory<DownloadFileTest> weak_ptr_factory(this);
200 DownloadInterruptReason result = DOWNLOAD_INTERRUPT_REASON_NONE; 218 DownloadInterruptReason result = DOWNLOAD_INTERRUPT_REASON_NONE;
201 base::RunLoop loop_runner; 219 base::RunLoop loop_runner;
202 download_file_->Initialize(base::Bind( 220 download_file_->Initialize(base::Bind(
203 &DownloadFileTest::SetInterruptReasonCallback, 221 &DownloadFileTest::SetInterruptReasonCallback,
(...skipping 10 matching lines...) Expand all
214 // Make sure the data has been properly written to disk. 232 // Make sure the data has been properly written to disk.
215 std::string disk_data; 233 std::string disk_data;
216 EXPECT_TRUE(base::ReadFileToString(download_file_->FullPath(), &disk_data)); 234 EXPECT_TRUE(base::ReadFileToString(download_file_->FullPath(), &disk_data));
217 EXPECT_EQ(expected_data_, disk_data); 235 EXPECT_EQ(expected_data_, disk_data);
218 236
219 // Make sure the Browser and File threads outlive the DownloadFile 237 // Make sure the Browser and File threads outlive the DownloadFile
220 // to satisfy thread checks inside it. 238 // to satisfy thread checks inside it.
221 download_file_.reset(); 239 download_file_.reset();
222 } 240 }
223 241
224 // Setup the stream to do be a data append; don't actually trigger 242 // Setup the stream to append data or write from |offset| to the file.
225 // the callback or do verifications. 243 // Don't actually trigger the callback or do verifications.
226 void SetupDataAppend(const char **data_chunks, size_t num_chunks, 244 void SetupDataAppend(const char** data_chunks,
227 ::testing::Sequence s) { 245 size_t num_chunks,
228 DCHECK(input_stream_); 246 MockByteStreamReader* stream_reader,
247 ::testing::Sequence s,
248 int64_t offset = -1) {
249 DCHECK(stream_reader);
250 size_t current_pos = static_cast<size_t>(offset);
229 for (size_t i = 0; i < num_chunks; i++) { 251 for (size_t i = 0; i < num_chunks; i++) {
230 const char *source_data = data_chunks[i]; 252 const char *source_data = data_chunks[i];
231 size_t length = strlen(source_data); 253 size_t length = strlen(source_data);
232 scoped_refptr<net::IOBuffer> data = new net::IOBuffer(length); 254 scoped_refptr<net::IOBuffer> data = new net::IOBuffer(length);
233 memcpy(data->data(), source_data, length); 255 memcpy(data->data(), source_data, length);
234 EXPECT_CALL(*input_stream_, Read(_, _)) 256 EXPECT_CALL(*stream_reader, Read(_, _))
235 .InSequence(s) 257 .InSequence(s)
236 .WillOnce(DoAll(SetArgPointee<0>(data), 258 .WillOnce(DoAll(SetArgPointee<0>(data), SetArgPointee<1>(length),
237 SetArgPointee<1>(length),
238 Return(ByteStreamReader::STREAM_HAS_DATA))) 259 Return(ByteStreamReader::STREAM_HAS_DATA)))
239 .RetiresOnSaturation(); 260 .RetiresOnSaturation();
240 expected_data_ += source_data; 261
262 if (offset < 0) {
263 // Append data.
264 expected_data_ += source_data;
265 continue;
266 }
267
268 // Write from offset. May fill holes with '\0'.
269 size_t new_len = current_pos + length;
270 if (new_len > expected_data_.size())
271 expected_data_.append(new_len - expected_data_.size(), '\0');
272 expected_data_.replace(current_pos, length, source_data);
273 current_pos += length;
241 } 274 }
242 } 275 }
243 276
244 void VerifyStreamAndSize() { 277 void VerifyStreamAndSize() {
245 ::testing::Mock::VerifyAndClearExpectations(input_stream_); 278 ::testing::Mock::VerifyAndClearExpectations(input_stream_);
246 int64_t size; 279 int64_t size;
247 EXPECT_TRUE(base::GetFileSize(download_file_->FullPath(), &size)); 280 EXPECT_TRUE(base::GetFileSize(download_file_->FullPath(), &size));
248 EXPECT_EQ(expected_data_.size(), static_cast<size_t>(size)); 281 EXPECT_EQ(expected_data_.size(), static_cast<size_t>(size));
249 } 282 }
250 283
251 // TODO(rdsmith): Manage full percentage issues properly. 284 // TODO(rdsmith): Manage full percentage issues properly.
252 void AppendDataToFile(const char **data_chunks, size_t num_chunks) { 285 void AppendDataToFile(const char **data_chunks, size_t num_chunks) {
253 ::testing::Sequence s1; 286 ::testing::Sequence s1;
254 SetupDataAppend(data_chunks, num_chunks, s1); 287 SetupDataAppend(data_chunks, num_chunks, input_stream_, s1);
255 EXPECT_CALL(*input_stream_, Read(_, _)) 288 EXPECT_CALL(*input_stream_, Read(_, _))
256 .InSequence(s1) 289 .InSequence(s1)
257 .WillOnce(Return(ByteStreamReader::STREAM_EMPTY)) 290 .WillOnce(Return(ByteStreamReader::STREAM_EMPTY))
258 .RetiresOnSaturation(); 291 .RetiresOnSaturation();
259 sink_callback_.Run(); 292 sink_callback_.Run();
260 VerifyStreamAndSize(); 293 VerifyStreamAndSize();
261 } 294 }
262 295
263 void SetupFinishStream(DownloadInterruptReason interrupt_reason, 296 void SetupFinishStream(DownloadInterruptReason interrupt_reason,
264 ::testing::Sequence s) { 297 MockByteStreamReader* stream_reader,
265 EXPECT_CALL(*input_stream_, Read(_, _)) 298 ::testing::Sequence s) {
299 EXPECT_CALL(*stream_reader, Read(_, _))
266 .InSequence(s) 300 .InSequence(s)
267 .WillOnce(Return(ByteStreamReader::STREAM_COMPLETE)) 301 .WillOnce(Return(ByteStreamReader::STREAM_COMPLETE))
268 .RetiresOnSaturation(); 302 .RetiresOnSaturation();
269 EXPECT_CALL(*input_stream_, GetStatus()) 303 EXPECT_CALL(*stream_reader, GetStatus())
270 .InSequence(s) 304 .InSequence(s)
271 .WillOnce(Return(interrupt_reason)) 305 .WillOnce(Return(interrupt_reason))
272 .RetiresOnSaturation(); 306 .RetiresOnSaturation();
273 EXPECT_CALL(*input_stream_, RegisterCallback(_)) 307 EXPECT_CALL(*stream_reader, RegisterCallback(_)).RetiresOnSaturation();
274 .RetiresOnSaturation();
275 } 308 }
276 309
277 void FinishStream(DownloadInterruptReason interrupt_reason, 310 void FinishStream(DownloadInterruptReason interrupt_reason,
278 bool check_observer, 311 bool check_observer,
279 const std::string& expected_hash) { 312 const std::string& expected_hash) {
280 ::testing::Sequence s1; 313 ::testing::Sequence s1;
281 SetupFinishStream(interrupt_reason, s1); 314 SetupFinishStream(interrupt_reason, input_stream_, s1);
282 sink_callback_.Run(); 315 sink_callback_.Run();
283 VerifyStreamAndSize(); 316 VerifyStreamAndSize();
284 if (check_observer) { 317 if (check_observer) {
285 EXPECT_CALL(*(observer_.get()), 318 EXPECT_CALL(*(observer_.get()),
286 MockDestinationCompleted(_, expected_hash)); 319 MockDestinationCompleted(_, expected_hash));
287 base::RunLoop().RunUntilIdle(); 320 base::RunLoop().RunUntilIdle();
288 ::testing::Mock::VerifyAndClearExpectations(observer_.get()); 321 ::testing::Mock::VerifyAndClearExpectations(observer_.get());
289 EXPECT_CALL(*(observer_.get()), DestinationUpdate(_, _)) 322 EXPECT_CALL(*(observer_.get()), DestinationUpdate(_, _))
290 .Times(AnyNumber()) 323 .Times(AnyNumber())
291 .WillRepeatedly( 324 .WillRepeatedly(
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
345 base::Bind(&DownloadFileTest::SetRenameResult, 378 base::Bind(&DownloadFileTest::SetRenameResult,
346 base::Unretained(this), 379 base::Unretained(this),
347 loop_runner.QuitClosure(), 380 loop_runner.QuitClosure(),
348 &result_reason, 381 &result_reason,
349 result_path_p); 382 result_path_p);
350 InvokeRenameMethod(method, full_path, completion_callback); 383 InvokeRenameMethod(method, full_path, completion_callback);
351 loop_runner.Run(); 384 loop_runner.Run();
352 return result_reason; 385 return result_reason;
353 } 386 }
354 387
388 // Prepare two byte streams to write to the same file sink.
389 void PrepareMultipleStreams() {
390 // Create a sparse file.
391 ASSERT_TRUE(CreateDownloadFile(0, true, true));
392 base::FilePath initial_path(download_file_->FullPath());
393 EXPECT_TRUE(base::PathExists(initial_path));
394 DCHECK(download_file_);
395
396 const char* stream_0_data[] = {kTestData1, kTestData2};
397 const char* stream_1_data[] = {kTestData4, kTestData5};
398 size_t stream_1_offset = strlen(kTestData1) + strlen(kTestData2);
399
400 // Register second SourceStream entry for the second stream.
401 // The first stream should be registered in ctor of DownloadFile.
402 DownloadFileImpl::SourceStreams& source_streams =
403 download_file_->source_streams_;
404 EXPECT_EQ(static_cast<size_t>(1), source_streams.size());
405 source_streams[stream_1_offset] =
406 base::MakeUnique<DownloadFileImpl::SourceStream>(stream_1_offset, 0);
407
408 // Create the second byte stream. Will be moved to DownloadFile.
409 input_stream_1_ = new MockByteStreamReader();
410
411 // Fill up two streams and setup expectation.
412 ::testing::Sequence s0;
413 ::testing::Sequence s1;
414 SetupDataAppend(stream_1_data, 2, input_stream_1_, s1, stream_1_offset);
415 SetupDataAppend(stream_0_data, 2, input_stream_, s0, 0);
416 SetupFinishStream(DOWNLOAD_INTERRUPT_REASON_NONE, input_stream_1_, s1);
417 SetupFinishStream(DOWNLOAD_INTERRUPT_REASON_NONE, input_stream_, s0);
418
419 // Every ByteStreamReader should call RegisterCallback twice.
420 // One to set the callback, the other to null the callback.
421 EXPECT_CALL(*input_stream_1_, RegisterCallback(_)).RetiresOnSaturation();
422 }
423
424 void VerifySourceStreamsStates(const SourceStreamTestData& data) {
425 DCHECK(download_file_->source_streams_.find(data.offset) !=
426 download_file_->source_streams_.end());
427 DownloadFileImpl::SourceStream* stream =
428 download_file_->source_streams_[data.offset].get();
429 DCHECK(stream);
430 EXPECT_EQ(data.offset, stream->offset());
431 EXPECT_EQ(data.bytes_written, stream->bytes_written());
432 EXPECT_EQ(data.finished, stream->is_finished());
433 }
434
435 int64_t TotalBytesReceived() const {
436 DCHECK(download_file_);
437 return download_file_->TotalBytesReceived();
438 }
439
355 std::unique_ptr<StrictMock<MockDownloadDestinationObserver>> observer_; 440 std::unique_ptr<StrictMock<MockDownloadDestinationObserver>> observer_;
356 base::WeakPtrFactory<DownloadDestinationObserver> observer_factory_; 441 base::WeakPtrFactory<DownloadDestinationObserver> observer_factory_;
357 442
358 // DownloadFile instance we are testing. 443 // DownloadFile instance we are testing.
359 std::unique_ptr<DownloadFile> download_file_; 444 std::unique_ptr<DownloadFileImpl> download_file_;
360 445
361 // Stream for sending data into the download file. 446 // Stream for sending data into the download file.
362 // Owned by download_file_; will be alive for lifetime of download_file_. 447 // Owned by download_file_; will be alive for lifetime of download_file_.
363 StrictMock<MockByteStreamReader>* input_stream_; 448 StrictMock<MockByteStreamReader>* input_stream_;
364 449
450 // A second byte stream to test multiple stream write.
451 MockByteStreamReader* input_stream_1_;
452
365 // Sink callback data for stream. 453 // Sink callback data for stream.
366 base::Closure sink_callback_; 454 base::Closure sink_callback_;
367 455
368 // Latest update sent to the observer. 456 // Latest update sent to the observer.
369 int64_t bytes_; 457 int64_t bytes_;
370 int64_t bytes_per_sec_; 458 int64_t bytes_per_sec_;
371 459
372 private: 460 private:
373 void SetRenameResult(const base::Closure& closure, 461 void SetRenameResult(const base::Closure& closure,
374 DownloadInterruptReason* reason_p, 462 DownloadInterruptReason* reason_p,
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
412 // the value parameter. 500 // the value parameter.
413 INSTANTIATE_TEST_CASE_P(DownloadFile, 501 INSTANTIATE_TEST_CASE_P(DownloadFile,
414 DownloadFileTestWithRename, 502 DownloadFileTestWithRename,
415 ::testing::Values(RENAME_AND_ANNOTATE, 503 ::testing::Values(RENAME_AND_ANNOTATE,
416 RENAME_AND_UNIQUIFY)); 504 RENAME_AND_UNIQUIFY));
417 505
418 const char DownloadFileTest::kTestData1[] = 506 const char DownloadFileTest::kTestData1[] =
419 "Let's write some data to the file!\n"; 507 "Let's write some data to the file!\n";
420 const char DownloadFileTest::kTestData2[] = "Writing more data.\n"; 508 const char DownloadFileTest::kTestData2[] = "Writing more data.\n";
421 const char DownloadFileTest::kTestData3[] = "Final line."; 509 const char DownloadFileTest::kTestData3[] = "Final line.";
510 const char DownloadFileTest::kTestData4[] = "abcdefg";
511 const char DownloadFileTest::kTestData5[] = "01234";
422 const char DownloadFileTest::kDataHash[] = 512 const char DownloadFileTest::kDataHash[] =
423 "CBF68BF10F8003DB86B31343AFAC8C7175BD03FB5FC905650F8C80AF087443A8"; 513 "CBF68BF10F8003DB86B31343AFAC8C7175BD03FB5FC905650F8C80AF087443A8";
424 const char DownloadFileTest::kEmptyHash[] = 514 const char DownloadFileTest::kEmptyHash[] =
425 "E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855"; 515 "E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855";
426 516
427 const uint32_t DownloadFileTest::kDummyDownloadId = 23; 517 const uint32_t DownloadFileTest::kDummyDownloadId = 23;
428 const int DownloadFileTest::kDummyChildId = 3; 518 const int DownloadFileTest::kDummyChildId = 3;
429 const int DownloadFileTest::kDummyRequestId = 67; 519 const int DownloadFileTest::kDummyRequestId = 67;
430 520
431 // Rename the file before any data is downloaded, after some has, after it all 521 // Rename the file before any data is downloaded, after some has, after it all
(...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after
742 DestroyDownloadFile(0); 832 DestroyDownloadFile(0);
743 } 833 }
744 834
745 TEST_F(DownloadFileTest, StreamNonEmptySuccess) { 835 TEST_F(DownloadFileTest, StreamNonEmptySuccess) {
746 ASSERT_TRUE(CreateDownloadFile(0, true)); 836 ASSERT_TRUE(CreateDownloadFile(0, true));
747 base::FilePath initial_path(download_file_->FullPath()); 837 base::FilePath initial_path(download_file_->FullPath());
748 EXPECT_TRUE(base::PathExists(initial_path)); 838 EXPECT_TRUE(base::PathExists(initial_path));
749 839
750 const char* chunks1[] = { kTestData1, kTestData2 }; 840 const char* chunks1[] = { kTestData1, kTestData2 };
751 ::testing::Sequence s1; 841 ::testing::Sequence s1;
752 SetupDataAppend(chunks1, 2, s1); 842 SetupDataAppend(chunks1, 2, input_stream_, s1);
753 SetupFinishStream(DOWNLOAD_INTERRUPT_REASON_NONE, s1); 843 SetupFinishStream(DOWNLOAD_INTERRUPT_REASON_NONE, input_stream_, s1);
754 EXPECT_CALL(*(observer_.get()), MockDestinationCompleted(_, _)); 844 EXPECT_CALL(*(observer_.get()), MockDestinationCompleted(_, _));
755 sink_callback_.Run(); 845 sink_callback_.Run();
756 VerifyStreamAndSize(); 846 VerifyStreamAndSize();
757 base::RunLoop().RunUntilIdle(); 847 base::RunLoop().RunUntilIdle();
758 DestroyDownloadFile(0); 848 DestroyDownloadFile(0);
759 } 849 }
760 850
761 TEST_F(DownloadFileTest, StreamNonEmptyError) { 851 TEST_F(DownloadFileTest, StreamNonEmptyError) {
762 ASSERT_TRUE(CreateDownloadFile(0, true)); 852 ASSERT_TRUE(CreateDownloadFile(0, true));
763 base::FilePath initial_path(download_file_->FullPath()); 853 base::FilePath initial_path(download_file_->FullPath());
764 EXPECT_TRUE(base::PathExists(initial_path)); 854 EXPECT_TRUE(base::PathExists(initial_path));
765 855
766 const char* chunks1[] = { kTestData1, kTestData2 }; 856 const char* chunks1[] = { kTestData1, kTestData2 };
767 ::testing::Sequence s1; 857 ::testing::Sequence s1;
768 SetupDataAppend(chunks1, 2, s1); 858 SetupDataAppend(chunks1, 2, input_stream_, s1);
769 SetupFinishStream(DOWNLOAD_INTERRUPT_REASON_NETWORK_DISCONNECTED, s1); 859 SetupFinishStream(DOWNLOAD_INTERRUPT_REASON_NETWORK_DISCONNECTED,
860 input_stream_, s1);
770 861
771 EXPECT_CALL(*(observer_.get()), 862 EXPECT_CALL(*(observer_.get()),
772 MockDestinationError( 863 MockDestinationError(
773 DOWNLOAD_INTERRUPT_REASON_NETWORK_DISCONNECTED, _, _)) 864 DOWNLOAD_INTERRUPT_REASON_NETWORK_DISCONNECTED, _, _))
774 .WillOnce(InvokeWithoutArgs( 865 .WillOnce(InvokeWithoutArgs(
775 this, &DownloadFileTest::ConfirmUpdateDownloadInfo)); 866 this, &DownloadFileTest::ConfirmUpdateDownloadInfo));
776 867
777 // If this next EXPECT_CALL fails flakily, it's probably a real failure. 868 // If this next EXPECT_CALL fails flakily, it's probably a real failure.
778 // We'll be getting a stream of UpdateDownload calls from the timer, and 869 // We'll be getting a stream of UpdateDownload calls from the timer, and
779 // the last one may have the correct information even if the failure 870 // the last one may have the correct information even if the failure
780 // doesn't produce an update, as the timer update may have triggered at the 871 // doesn't produce an update, as the timer update may have triggered at the
781 // same time. 872 // same time.
782 EXPECT_CALL(*(observer_.get()), 873 EXPECT_CALL(*(observer_.get()),
783 CurrentUpdateStatus(strlen(kTestData1) + strlen(kTestData2), _)); 874 CurrentUpdateStatus(strlen(kTestData1) + strlen(kTestData2), _));
784 875
785 sink_callback_.Run(); 876 sink_callback_.Run();
786 base::RunLoop().RunUntilIdle(); 877 base::RunLoop().RunUntilIdle();
787 VerifyStreamAndSize(); 878 VerifyStreamAndSize();
788 DestroyDownloadFile(0); 879 DestroyDownloadFile(0);
789 } 880 }
790 881
882 // Tests for concurrent streams handling, used for parallel download.
883 //
884 // Activate both streams at the same time.
885 TEST_F(DownloadFileTest, MutipleStreamsWrite) {
886 PrepareMultipleStreams();
887 EXPECT_CALL(*(observer_.get()), MockDestinationCompleted(_, _));
888
889 int64_t stream_0_length =
890 static_cast<int64_t>(strlen(kTestData1) + strlen(kTestData2));
891 int64_t stream_1_length =
892 static_cast<int64_t>(strlen(kTestData4) + strlen(kTestData5));
893
894 download_file_->AddByteStream(
895 std::unique_ptr<MockByteStreamReader>(input_stream_1_), stream_0_length);
896 sink_callback_.Run();
897 base::RunLoop().RunUntilIdle();
898
899 SourceStreamTestData stream_data_0(0, stream_0_length, true);
900 SourceStreamTestData stream_data_1(stream_0_length, stream_1_length, true);
901 VerifySourceStreamsStates(stream_data_0);
902 VerifySourceStreamsStates(stream_data_1);
903 EXPECT_EQ(stream_0_length + stream_1_length, TotalBytesReceived());
904
905 DestroyDownloadFile(0);
906 }
907
908 // Activate and deplete one stream, later add the second stream.
909 TEST_F(DownloadFileTest, MutipleStreamsOneStreamFirst) {
910 PrepareMultipleStreams();
911
912 int64_t stream_0_length =
913 static_cast<int64_t>(strlen(kTestData1) + strlen(kTestData2));
914 int64_t stream_1_length =
915 static_cast<int64_t>(strlen(kTestData4) + strlen(kTestData5));
916
917 // Deplete the first stream.
918 sink_callback_.Run();
919 base::RunLoop().RunUntilIdle();
920
921 SourceStreamTestData stream_data_0(0, stream_0_length, true);
922 SourceStreamTestData stream_data_1(stream_0_length, 0, false);
923 VerifySourceStreamsStates(stream_data_0);
924 VerifySourceStreamsStates(stream_data_1);
925 EXPECT_EQ(stream_0_length, TotalBytesReceived());
926
927 // Won't inform the observer until the second stream is depleted.
928 EXPECT_CALL(*(observer_.get()), MockDestinationCompleted(_, _));
929
930 // Drain the second stream after the first stream is depleted.
931 download_file_->AddByteStream(
932 std::unique_ptr<MockByteStreamReader>(input_stream_1_), stream_0_length);
933 base::RunLoop().RunUntilIdle();
934
935 stream_data_1.bytes_written = stream_1_length;
936 stream_data_1.finished = true;
937 VerifySourceStreamsStates(stream_data_0);
938 VerifySourceStreamsStates(stream_data_1);
939 EXPECT_EQ(stream_0_length + stream_1_length, TotalBytesReceived());
940
941 DestroyDownloadFile(0);
942 }
943
791 } // namespace content 944 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698