OLD | NEW |
| (Empty) |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 #include "net/base/elements_upload_data_stream.h" | |
6 | |
7 #include <algorithm> | |
8 #include <vector> | |
9 | |
10 #include "base/basictypes.h" | |
11 #include "base/bind.h" | |
12 #include "base/files/file_path.h" | |
13 #include "base/files/file_util.h" | |
14 #include "base/files/scoped_temp_dir.h" | |
15 #include "base/memory/scoped_ptr.h" | |
16 #include "base/message_loop/message_loop.h" | |
17 #include "base/run_loop.h" | |
18 #include "base/time/time.h" | |
19 #include "net/base/io_buffer.h" | |
20 #include "net/base/net_errors.h" | |
21 #include "net/base/test_completion_callback.h" | |
22 #include "net/base/upload_bytes_element_reader.h" | |
23 #include "net/base/upload_data_stream.h" | |
24 #include "net/base/upload_file_element_reader.h" | |
25 #include "testing/gmock/include/gmock/gmock.h" | |
26 #include "testing/gtest/include/gtest/gtest.h" | |
27 #include "testing/platform_test.h" | |
28 | |
29 using ::testing::DoAll; | |
30 using ::testing::Invoke; | |
31 using ::testing::Return; | |
32 using ::testing::_; | |
33 | |
34 namespace net { | |
35 | |
36 namespace { | |
37 | |
38 const char kTestData[] = "0123456789"; | |
39 const size_t kTestDataSize = arraysize(kTestData) - 1; | |
40 const size_t kTestBufferSize = 1 << 14; // 16KB. | |
41 | |
42 // Reads data from the upload data stream, and returns the data as string. | |
43 std::string ReadFromUploadDataStream(UploadDataStream* stream) { | |
44 std::string data_read; | |
45 scoped_refptr<IOBuffer> buf = new IOBuffer(kTestBufferSize); | |
46 while (!stream->IsEOF()) { | |
47 TestCompletionCallback callback; | |
48 const int result = | |
49 stream->Read(buf.get(), kTestBufferSize, callback.callback()); | |
50 const int bytes_read = | |
51 result != ERR_IO_PENDING ? result : callback.WaitForResult(); | |
52 data_read.append(buf->data(), bytes_read); | |
53 } | |
54 return data_read; | |
55 } | |
56 | |
57 // A mock class of UploadElementReader. | |
58 class MockUploadElementReader : public UploadElementReader { | |
59 public: | |
60 MockUploadElementReader(int content_length, bool is_in_memory) | |
61 : content_length_(content_length), | |
62 bytes_remaining_(content_length), | |
63 is_in_memory_(is_in_memory), | |
64 init_result_(OK), | |
65 read_result_(OK) {} | |
66 | |
67 virtual ~MockUploadElementReader() {} | |
68 | |
69 // UploadElementReader overrides. | |
70 MOCK_METHOD1(Init, int(const CompletionCallback& callback)); | |
71 virtual uint64 GetContentLength() const override { return content_length_; } | |
72 virtual uint64 BytesRemaining() const override { return bytes_remaining_; } | |
73 virtual bool IsInMemory() const override { return is_in_memory_; } | |
74 MOCK_METHOD3(Read, int(IOBuffer* buf, | |
75 int buf_length, | |
76 const CompletionCallback& callback)); | |
77 | |
78 // Sets expectation to return the specified result from Init() asynchronously. | |
79 void SetAsyncInitExpectation(int result) { | |
80 init_result_ = result; | |
81 EXPECT_CALL(*this, Init(_)) | |
82 .WillOnce(DoAll(Invoke(this, &MockUploadElementReader::OnInit), | |
83 Return(ERR_IO_PENDING))); | |
84 } | |
85 | |
86 // Sets expectation to return the specified result from Read(). | |
87 void SetReadExpectation(int result) { | |
88 read_result_ = result; | |
89 EXPECT_CALL(*this, Read(_, _, _)) | |
90 .WillOnce(Invoke(this, &MockUploadElementReader::OnRead)); | |
91 } | |
92 | |
93 private: | |
94 void OnInit(const CompletionCallback& callback) { | |
95 base::MessageLoop::current()->PostTask(FROM_HERE, | |
96 base::Bind(callback, init_result_)); | |
97 } | |
98 | |
99 int OnRead(IOBuffer* buf, | |
100 int buf_length, | |
101 const CompletionCallback& callback) { | |
102 if (read_result_ > 0) | |
103 bytes_remaining_ = std::max(0, bytes_remaining_ - read_result_); | |
104 if (IsInMemory()) { | |
105 return read_result_; | |
106 } else { | |
107 base::MessageLoop::current()->PostTask( | |
108 FROM_HERE, base::Bind(callback, read_result_)); | |
109 return ERR_IO_PENDING; | |
110 } | |
111 } | |
112 | |
113 int content_length_; | |
114 int bytes_remaining_; | |
115 bool is_in_memory_; | |
116 | |
117 // Result value returned from Init(). | |
118 int init_result_; | |
119 | |
120 // Result value returned from Read(). | |
121 int read_result_; | |
122 }; | |
123 | |
124 } // namespace | |
125 | |
126 class ElementsUploadDataStreamTest : public PlatformTest { | |
127 public: | |
128 void SetUp() override { | |
129 PlatformTest::SetUp(); | |
130 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); | |
131 } | |
132 ~ElementsUploadDataStreamTest() override { | |
133 element_readers_.clear(); | |
134 base::RunLoop().RunUntilIdle(); | |
135 } | |
136 | |
137 void FileChangedHelper(const base::FilePath& file_path, | |
138 const base::Time& time, | |
139 bool error_expected); | |
140 | |
141 base::ScopedTempDir temp_dir_; | |
142 ScopedVector<UploadElementReader> element_readers_; | |
143 }; | |
144 | |
145 TEST_F(ElementsUploadDataStreamTest, EmptyUploadData) { | |
146 scoped_ptr<UploadDataStream> stream( | |
147 new ElementsUploadDataStream(element_readers_.Pass(), 0)); | |
148 ASSERT_EQ(OK, stream->Init(CompletionCallback())); | |
149 EXPECT_TRUE(stream->IsInMemory()); | |
150 EXPECT_EQ(0U, stream->size()); | |
151 EXPECT_EQ(0U, stream->position()); | |
152 EXPECT_TRUE(stream->IsEOF()); | |
153 } | |
154 | |
155 TEST_F(ElementsUploadDataStreamTest, ConsumeAllBytes) { | |
156 element_readers_.push_back(new UploadBytesElementReader( | |
157 kTestData, kTestDataSize)); | |
158 scoped_ptr<UploadDataStream> stream( | |
159 new ElementsUploadDataStream(element_readers_.Pass(), 0)); | |
160 ASSERT_EQ(OK, stream->Init(CompletionCallback())); | |
161 EXPECT_TRUE(stream->IsInMemory()); | |
162 EXPECT_EQ(kTestDataSize, stream->size()); | |
163 EXPECT_EQ(0U, stream->position()); | |
164 EXPECT_FALSE(stream->IsEOF()); | |
165 scoped_refptr<IOBuffer> buf = new IOBuffer(kTestBufferSize); | |
166 while (!stream->IsEOF()) { | |
167 int bytes_read = | |
168 stream->Read(buf.get(), kTestBufferSize, CompletionCallback()); | |
169 ASSERT_LE(0, bytes_read); // Not an error. | |
170 } | |
171 EXPECT_EQ(kTestDataSize, stream->position()); | |
172 ASSERT_TRUE(stream->IsEOF()); | |
173 } | |
174 | |
175 TEST_F(ElementsUploadDataStreamTest, File) { | |
176 base::FilePath temp_file_path; | |
177 ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(), | |
178 &temp_file_path)); | |
179 ASSERT_EQ(static_cast<int>(kTestDataSize), | |
180 base::WriteFile(temp_file_path, kTestData, kTestDataSize)); | |
181 | |
182 element_readers_.push_back( | |
183 new UploadFileElementReader(base::MessageLoopProxy::current().get(), | |
184 temp_file_path, | |
185 0, | |
186 kuint64max, | |
187 base::Time())); | |
188 | |
189 TestCompletionCallback init_callback; | |
190 scoped_ptr<UploadDataStream> stream( | |
191 new ElementsUploadDataStream(element_readers_.Pass(), 0)); | |
192 ASSERT_EQ(ERR_IO_PENDING, stream->Init(init_callback.callback())); | |
193 ASSERT_EQ(OK, init_callback.WaitForResult()); | |
194 EXPECT_FALSE(stream->IsInMemory()); | |
195 EXPECT_EQ(kTestDataSize, stream->size()); | |
196 EXPECT_EQ(0U, stream->position()); | |
197 EXPECT_FALSE(stream->IsEOF()); | |
198 scoped_refptr<IOBuffer> buf = new IOBuffer(kTestBufferSize); | |
199 while (!stream->IsEOF()) { | |
200 TestCompletionCallback read_callback; | |
201 ASSERT_EQ( | |
202 ERR_IO_PENDING, | |
203 stream->Read(buf.get(), kTestBufferSize, read_callback.callback())); | |
204 ASSERT_LE(0, read_callback.WaitForResult()); // Not an error. | |
205 } | |
206 EXPECT_EQ(kTestDataSize, stream->position()); | |
207 ASSERT_TRUE(stream->IsEOF()); | |
208 } | |
209 | |
210 TEST_F(ElementsUploadDataStreamTest, FileSmallerThanLength) { | |
211 base::FilePath temp_file_path; | |
212 ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(), | |
213 &temp_file_path)); | |
214 ASSERT_EQ(static_cast<int>(kTestDataSize), | |
215 base::WriteFile(temp_file_path, kTestData, kTestDataSize)); | |
216 const uint64 kFakeSize = kTestDataSize*2; | |
217 | |
218 UploadFileElementReader::ScopedOverridingContentLengthForTests | |
219 overriding_content_length(kFakeSize); | |
220 | |
221 element_readers_.push_back( | |
222 new UploadFileElementReader(base::MessageLoopProxy::current().get(), | |
223 temp_file_path, | |
224 0, | |
225 kuint64max, | |
226 base::Time())); | |
227 | |
228 TestCompletionCallback init_callback; | |
229 scoped_ptr<UploadDataStream> stream( | |
230 new ElementsUploadDataStream(element_readers_.Pass(), 0)); | |
231 ASSERT_EQ(ERR_IO_PENDING, stream->Init(init_callback.callback())); | |
232 ASSERT_EQ(OK, init_callback.WaitForResult()); | |
233 EXPECT_FALSE(stream->IsInMemory()); | |
234 EXPECT_EQ(kFakeSize, stream->size()); | |
235 EXPECT_EQ(0U, stream->position()); | |
236 EXPECT_FALSE(stream->IsEOF()); | |
237 uint64 read_counter = 0; | |
238 scoped_refptr<IOBuffer> buf = new IOBuffer(kTestBufferSize); | |
239 while (!stream->IsEOF()) { | |
240 TestCompletionCallback read_callback; | |
241 ASSERT_EQ( | |
242 ERR_IO_PENDING, | |
243 stream->Read(buf.get(), kTestBufferSize, read_callback.callback())); | |
244 int bytes_read = read_callback.WaitForResult(); | |
245 ASSERT_LE(0, bytes_read); // Not an error. | |
246 read_counter += bytes_read; | |
247 EXPECT_EQ(read_counter, stream->position()); | |
248 } | |
249 // UpdateDataStream will pad out the file with 0 bytes so that the HTTP | |
250 // transaction doesn't hang. Therefore we expected the full size. | |
251 EXPECT_EQ(kFakeSize, read_counter); | |
252 EXPECT_EQ(read_counter, stream->position()); | |
253 } | |
254 | |
255 TEST_F(ElementsUploadDataStreamTest, ReadErrorSync) { | |
256 // This element cannot be read. | |
257 MockUploadElementReader* reader = | |
258 new MockUploadElementReader(kTestDataSize, true); | |
259 EXPECT_CALL(*reader, Init(_)).WillOnce(Return(OK)); | |
260 reader->SetReadExpectation(ERR_FAILED); | |
261 element_readers_.push_back(reader); | |
262 | |
263 // This element is ignored because of the error from the previous reader. | |
264 element_readers_.push_back(new UploadBytesElementReader( | |
265 kTestData, kTestDataSize)); | |
266 | |
267 scoped_ptr<UploadDataStream> stream( | |
268 new ElementsUploadDataStream(element_readers_.Pass(), 0)); | |
269 | |
270 // Run Init(). | |
271 ASSERT_EQ(OK, stream->Init(CompletionCallback())); | |
272 EXPECT_EQ(kTestDataSize*2, stream->size()); | |
273 EXPECT_EQ(0U, stream->position()); | |
274 EXPECT_FALSE(stream->IsEOF()); | |
275 | |
276 // Prepare a buffer filled with non-zero data. | |
277 scoped_refptr<IOBuffer> buf = new IOBuffer(kTestBufferSize); | |
278 std::fill_n(buf->data(), kTestBufferSize, -1); | |
279 | |
280 // Read() results in success even when the reader returns error. | |
281 EXPECT_EQ(static_cast<int>(kTestDataSize * 2), | |
282 stream->Read(buf.get(), kTestBufferSize, CompletionCallback())); | |
283 EXPECT_EQ(kTestDataSize * 2, stream->position()); | |
284 EXPECT_TRUE(stream->IsEOF()); | |
285 | |
286 // The buffer is filled with zero. | |
287 EXPECT_EQ(static_cast<int>(kTestDataSize*2), | |
288 std::count(buf->data(), buf->data() + kTestBufferSize, 0)); | |
289 } | |
290 | |
291 TEST_F(ElementsUploadDataStreamTest, ReadErrorAsync) { | |
292 // This element cannot be read. | |
293 MockUploadElementReader* reader = | |
294 new MockUploadElementReader(kTestDataSize, false); | |
295 reader->SetAsyncInitExpectation(OK); | |
296 reader->SetReadExpectation(ERR_FAILED); | |
297 element_readers_.push_back(reader); | |
298 | |
299 // This element is ignored because of the error from the previous reader. | |
300 element_readers_.push_back(new UploadBytesElementReader( | |
301 kTestData, kTestDataSize)); | |
302 | |
303 scoped_ptr<UploadDataStream> stream( | |
304 new ElementsUploadDataStream(element_readers_.Pass(), 0)); | |
305 | |
306 // Run Init(). | |
307 TestCompletionCallback init_callback; | |
308 ASSERT_EQ(ERR_IO_PENDING, stream->Init(init_callback.callback())); | |
309 EXPECT_EQ(OK, init_callback.WaitForResult()); | |
310 EXPECT_EQ(kTestDataSize*2, stream->size()); | |
311 EXPECT_EQ(0U, stream->position()); | |
312 EXPECT_FALSE(stream->IsEOF()); | |
313 | |
314 // Prepare a buffer filled with non-zero data. | |
315 scoped_refptr<IOBuffer> buf = new IOBuffer(kTestBufferSize); | |
316 std::fill_n(buf->data(), kTestBufferSize, -1); | |
317 | |
318 // Read() results in success even when the reader returns error. | |
319 TestCompletionCallback read_callback; | |
320 ASSERT_EQ(ERR_IO_PENDING, | |
321 stream->Read(buf.get(), kTestBufferSize, read_callback.callback())); | |
322 EXPECT_EQ(static_cast<int>(kTestDataSize * 2), read_callback.WaitForResult()); | |
323 EXPECT_EQ(kTestDataSize*2, stream->position()); | |
324 EXPECT_TRUE(stream->IsEOF()); | |
325 | |
326 // The buffer is filled with zero. | |
327 EXPECT_EQ(static_cast<int>(kTestDataSize*2), | |
328 std::count(buf->data(), buf->data() + kTestBufferSize, 0)); | |
329 } | |
330 | |
331 TEST_F(ElementsUploadDataStreamTest, FileAndBytes) { | |
332 base::FilePath temp_file_path; | |
333 ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(), | |
334 &temp_file_path)); | |
335 ASSERT_EQ(static_cast<int>(kTestDataSize), | |
336 base::WriteFile(temp_file_path, kTestData, kTestDataSize)); | |
337 | |
338 const uint64 kFileRangeOffset = 1; | |
339 const uint64 kFileRangeLength = 4; | |
340 element_readers_.push_back( | |
341 new UploadFileElementReader(base::MessageLoopProxy::current().get(), | |
342 temp_file_path, | |
343 kFileRangeOffset, | |
344 kFileRangeLength, | |
345 base::Time())); | |
346 | |
347 element_readers_.push_back(new UploadBytesElementReader( | |
348 kTestData, kTestDataSize)); | |
349 | |
350 const uint64 kStreamSize = kTestDataSize + kFileRangeLength; | |
351 TestCompletionCallback init_callback; | |
352 scoped_ptr<UploadDataStream> stream( | |
353 new ElementsUploadDataStream(element_readers_.Pass(), 0)); | |
354 ASSERT_EQ(ERR_IO_PENDING, stream->Init(init_callback.callback())); | |
355 ASSERT_EQ(OK, init_callback.WaitForResult()); | |
356 EXPECT_FALSE(stream->IsInMemory()); | |
357 EXPECT_EQ(kStreamSize, stream->size()); | |
358 EXPECT_EQ(0U, stream->position()); | |
359 EXPECT_FALSE(stream->IsEOF()); | |
360 scoped_refptr<IOBuffer> buf = new IOBuffer(kTestBufferSize); | |
361 while (!stream->IsEOF()) { | |
362 TestCompletionCallback read_callback; | |
363 const int result = | |
364 stream->Read(buf.get(), kTestBufferSize, read_callback.callback()); | |
365 const int bytes_read = | |
366 result != ERR_IO_PENDING ? result : read_callback.WaitForResult(); | |
367 ASSERT_LE(0, bytes_read); // Not an error. | |
368 } | |
369 EXPECT_EQ(kStreamSize, stream->position()); | |
370 ASSERT_TRUE(stream->IsEOF()); | |
371 } | |
372 | |
373 // Init() with on-memory and not-on-memory readers. | |
374 TEST_F(ElementsUploadDataStreamTest, InitAsync) { | |
375 // Create UploadDataStream with mock readers. | |
376 MockUploadElementReader* reader = NULL; | |
377 | |
378 reader = new MockUploadElementReader(kTestDataSize, true); | |
379 EXPECT_CALL(*reader, Init(_)).WillOnce(Return(OK)); | |
380 element_readers_.push_back(reader); | |
381 | |
382 reader = new MockUploadElementReader(kTestDataSize, true); | |
383 EXPECT_CALL(*reader, Init(_)).WillOnce(Return(OK)); | |
384 element_readers_.push_back(reader); | |
385 | |
386 reader = new MockUploadElementReader(kTestDataSize, false); | |
387 reader->SetAsyncInitExpectation(OK); | |
388 element_readers_.push_back(reader); | |
389 | |
390 reader = new MockUploadElementReader(kTestDataSize, false); | |
391 reader->SetAsyncInitExpectation(OK); | |
392 element_readers_.push_back(reader); | |
393 | |
394 reader = new MockUploadElementReader(kTestDataSize, true); | |
395 EXPECT_CALL(*reader, Init(_)).WillOnce(Return(OK)); | |
396 element_readers_.push_back(reader); | |
397 | |
398 scoped_ptr<UploadDataStream> stream( | |
399 new ElementsUploadDataStream(element_readers_.Pass(), 0)); | |
400 | |
401 // Run Init(). | |
402 TestCompletionCallback callback; | |
403 ASSERT_EQ(ERR_IO_PENDING, stream->Init(callback.callback())); | |
404 EXPECT_EQ(OK, callback.WaitForResult()); | |
405 } | |
406 | |
407 // Init() of a reader fails asynchronously. | |
408 TEST_F(ElementsUploadDataStreamTest, InitAsyncFailureAsync) { | |
409 // Create UploadDataStream with a mock reader. | |
410 MockUploadElementReader* reader = NULL; | |
411 | |
412 reader = new MockUploadElementReader(kTestDataSize, false); | |
413 reader->SetAsyncInitExpectation(ERR_FAILED); | |
414 element_readers_.push_back(reader); | |
415 | |
416 scoped_ptr<UploadDataStream> stream( | |
417 new ElementsUploadDataStream(element_readers_.Pass(), 0)); | |
418 | |
419 // Run Init(). | |
420 TestCompletionCallback callback; | |
421 ASSERT_EQ(ERR_IO_PENDING, stream->Init(callback.callback())); | |
422 EXPECT_EQ(ERR_FAILED, callback.WaitForResult()); | |
423 } | |
424 | |
425 // Init() of a reader fails synchronously. | |
426 TEST_F(ElementsUploadDataStreamTest, InitAsyncFailureSync) { | |
427 // Create UploadDataStream with mock readers. | |
428 MockUploadElementReader* reader = NULL; | |
429 | |
430 reader = new MockUploadElementReader(kTestDataSize, false); | |
431 reader->SetAsyncInitExpectation(OK); | |
432 element_readers_.push_back(reader); | |
433 | |
434 reader = new MockUploadElementReader(kTestDataSize, true); | |
435 EXPECT_CALL(*reader, Init(_)).WillOnce(Return(ERR_FAILED)); | |
436 element_readers_.push_back(reader); | |
437 | |
438 scoped_ptr<UploadDataStream> stream( | |
439 new ElementsUploadDataStream(element_readers_.Pass(), 0)); | |
440 | |
441 // Run Init(). | |
442 TestCompletionCallback callback; | |
443 ASSERT_EQ(ERR_IO_PENDING, stream->Init(callback.callback())); | |
444 EXPECT_EQ(ERR_FAILED, callback.WaitForResult()); | |
445 } | |
446 | |
447 // Read with a buffer whose size is same as the data. | |
448 TEST_F(ElementsUploadDataStreamTest, ReadAsyncWithExactSizeBuffer) { | |
449 element_readers_.push_back(new UploadBytesElementReader( | |
450 kTestData, kTestDataSize)); | |
451 scoped_ptr<UploadDataStream> stream( | |
452 new ElementsUploadDataStream(element_readers_.Pass(), 0)); | |
453 | |
454 ASSERT_EQ(OK, stream->Init(CompletionCallback())); | |
455 EXPECT_TRUE(stream->IsInMemory()); | |
456 EXPECT_EQ(kTestDataSize, stream->size()); | |
457 EXPECT_EQ(0U, stream->position()); | |
458 EXPECT_FALSE(stream->IsEOF()); | |
459 scoped_refptr<IOBuffer> buf = new IOBuffer(kTestDataSize); | |
460 int bytes_read = stream->Read(buf.get(), kTestDataSize, CompletionCallback()); | |
461 ASSERT_EQ(static_cast<int>(kTestDataSize), bytes_read); // Not an error. | |
462 EXPECT_EQ(kTestDataSize, stream->position()); | |
463 ASSERT_TRUE(stream->IsEOF()); | |
464 } | |
465 | |
466 // Async Read() with on-memory and not-on-memory readers. | |
467 TEST_F(ElementsUploadDataStreamTest, ReadAsync) { | |
468 // Create UploadDataStream with mock readers. | |
469 MockUploadElementReader* reader = NULL; | |
470 | |
471 reader = new MockUploadElementReader(kTestDataSize, true); | |
472 EXPECT_CALL(*reader, Init(_)).WillOnce(Return(OK)); | |
473 reader->SetReadExpectation(kTestDataSize); | |
474 element_readers_.push_back(reader); | |
475 | |
476 reader = new MockUploadElementReader(kTestDataSize, false); | |
477 reader->SetAsyncInitExpectation(OK); | |
478 reader->SetReadExpectation(kTestDataSize); | |
479 element_readers_.push_back(reader); | |
480 | |
481 reader = new MockUploadElementReader(kTestDataSize, true); | |
482 EXPECT_CALL(*reader, Init(_)).WillOnce(Return(OK)); | |
483 reader->SetReadExpectation(kTestDataSize); | |
484 element_readers_.push_back(reader); | |
485 | |
486 reader = new MockUploadElementReader(kTestDataSize, false); | |
487 reader->SetAsyncInitExpectation(OK); | |
488 reader->SetReadExpectation(kTestDataSize); | |
489 element_readers_.push_back(reader); | |
490 | |
491 scoped_ptr<UploadDataStream> stream( | |
492 new ElementsUploadDataStream(element_readers_.Pass(), 0)); | |
493 | |
494 // Run Init(). | |
495 TestCompletionCallback init_callback; | |
496 EXPECT_EQ(ERR_IO_PENDING, stream->Init(init_callback.callback())); | |
497 EXPECT_EQ(OK, init_callback.WaitForResult()); | |
498 | |
499 scoped_refptr<IOBuffer> buf = new IOBuffer(kTestBufferSize); | |
500 | |
501 // Consume the first element. | |
502 TestCompletionCallback read_callback1; | |
503 EXPECT_EQ(static_cast<int>(kTestDataSize), | |
504 stream->Read(buf.get(), kTestDataSize, read_callback1.callback())); | |
505 base::MessageLoop::current()->RunUntilIdle(); | |
506 EXPECT_FALSE(read_callback1.have_result()); | |
507 | |
508 // Consume the second element. | |
509 TestCompletionCallback read_callback2; | |
510 ASSERT_EQ(ERR_IO_PENDING, | |
511 stream->Read(buf.get(), kTestDataSize, read_callback2.callback())); | |
512 EXPECT_EQ(static_cast<int>(kTestDataSize), read_callback2.WaitForResult()); | |
513 | |
514 // Consume the third and the fourth elements. | |
515 TestCompletionCallback read_callback3; | |
516 ASSERT_EQ( | |
517 ERR_IO_PENDING, | |
518 stream->Read(buf.get(), kTestDataSize * 2, read_callback3.callback())); | |
519 EXPECT_EQ(static_cast<int>(kTestDataSize * 2), | |
520 read_callback3.WaitForResult()); | |
521 } | |
522 | |
523 void ElementsUploadDataStreamTest::FileChangedHelper( | |
524 const base::FilePath& file_path, | |
525 const base::Time& time, | |
526 bool error_expected) { | |
527 // Don't use element_readers_ here, as this function is called twice, and | |
528 // reusing element_readers_ is wrong. | |
529 ScopedVector<UploadElementReader> element_readers; | |
530 element_readers.push_back(new UploadFileElementReader( | |
531 base::MessageLoopProxy::current().get(), file_path, 1, 2, time)); | |
532 | |
533 TestCompletionCallback init_callback; | |
534 scoped_ptr<UploadDataStream> stream( | |
535 new ElementsUploadDataStream(element_readers.Pass(), 0)); | |
536 ASSERT_EQ(ERR_IO_PENDING, stream->Init(init_callback.callback())); | |
537 int error_code = init_callback.WaitForResult(); | |
538 if (error_expected) | |
539 ASSERT_EQ(ERR_UPLOAD_FILE_CHANGED, error_code); | |
540 else | |
541 ASSERT_EQ(OK, error_code); | |
542 } | |
543 | |
544 TEST_F(ElementsUploadDataStreamTest, FileChanged) { | |
545 base::FilePath temp_file_path; | |
546 ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(), | |
547 &temp_file_path)); | |
548 ASSERT_EQ(static_cast<int>(kTestDataSize), | |
549 base::WriteFile(temp_file_path, kTestData, kTestDataSize)); | |
550 | |
551 base::File::Info file_info; | |
552 ASSERT_TRUE(base::GetFileInfo(temp_file_path, &file_info)); | |
553 | |
554 // Test file not changed. | |
555 FileChangedHelper(temp_file_path, file_info.last_modified, false); | |
556 | |
557 // Test file changed. | |
558 FileChangedHelper(temp_file_path, | |
559 file_info.last_modified - base::TimeDelta::FromSeconds(1), | |
560 true); | |
561 } | |
562 | |
563 TEST_F(ElementsUploadDataStreamTest, MultipleInit) { | |
564 base::FilePath temp_file_path; | |
565 ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(), | |
566 &temp_file_path)); | |
567 ASSERT_EQ(static_cast<int>(kTestDataSize), | |
568 base::WriteFile(temp_file_path, kTestData, kTestDataSize)); | |
569 | |
570 // Prepare data. | |
571 element_readers_.push_back(new UploadBytesElementReader( | |
572 kTestData, kTestDataSize)); | |
573 element_readers_.push_back( | |
574 new UploadFileElementReader(base::MessageLoopProxy::current().get(), | |
575 temp_file_path, | |
576 0, | |
577 kuint64max, | |
578 base::Time())); | |
579 scoped_ptr<UploadDataStream> stream( | |
580 new ElementsUploadDataStream(element_readers_.Pass(), 0)); | |
581 | |
582 std::string expected_data(kTestData, kTestData + kTestDataSize); | |
583 expected_data += expected_data; | |
584 | |
585 // Call Init(). | |
586 TestCompletionCallback init_callback1; | |
587 ASSERT_EQ(ERR_IO_PENDING, stream->Init(init_callback1.callback())); | |
588 ASSERT_EQ(OK, init_callback1.WaitForResult()); | |
589 EXPECT_FALSE(stream->IsEOF()); | |
590 EXPECT_EQ(kTestDataSize*2, stream->size()); | |
591 | |
592 // Read. | |
593 EXPECT_EQ(expected_data, ReadFromUploadDataStream(stream.get())); | |
594 EXPECT_TRUE(stream->IsEOF()); | |
595 | |
596 // Call Init() again to reset. | |
597 TestCompletionCallback init_callback2; | |
598 ASSERT_EQ(ERR_IO_PENDING, stream->Init(init_callback2.callback())); | |
599 ASSERT_EQ(OK, init_callback2.WaitForResult()); | |
600 EXPECT_FALSE(stream->IsEOF()); | |
601 EXPECT_EQ(kTestDataSize*2, stream->size()); | |
602 | |
603 // Read again. | |
604 EXPECT_EQ(expected_data, ReadFromUploadDataStream(stream.get())); | |
605 EXPECT_TRUE(stream->IsEOF()); | |
606 } | |
607 | |
608 TEST_F(ElementsUploadDataStreamTest, MultipleInitAsync) { | |
609 base::FilePath temp_file_path; | |
610 ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(), | |
611 &temp_file_path)); | |
612 ASSERT_EQ(static_cast<int>(kTestDataSize), | |
613 base::WriteFile(temp_file_path, kTestData, kTestDataSize)); | |
614 TestCompletionCallback test_callback; | |
615 | |
616 // Prepare data. | |
617 element_readers_.push_back(new UploadBytesElementReader( | |
618 kTestData, kTestDataSize)); | |
619 element_readers_.push_back( | |
620 new UploadFileElementReader(base::MessageLoopProxy::current().get(), | |
621 temp_file_path, | |
622 0, | |
623 kuint64max, | |
624 base::Time())); | |
625 scoped_ptr<UploadDataStream> stream( | |
626 new ElementsUploadDataStream(element_readers_.Pass(), 0)); | |
627 | |
628 std::string expected_data(kTestData, kTestData + kTestDataSize); | |
629 expected_data += expected_data; | |
630 | |
631 // Call Init(). | |
632 ASSERT_EQ(ERR_IO_PENDING, stream->Init(test_callback.callback())); | |
633 EXPECT_EQ(OK, test_callback.WaitForResult()); | |
634 EXPECT_FALSE(stream->IsEOF()); | |
635 EXPECT_EQ(kTestDataSize*2, stream->size()); | |
636 | |
637 // Read. | |
638 EXPECT_EQ(expected_data, ReadFromUploadDataStream(stream.get())); | |
639 EXPECT_TRUE(stream->IsEOF()); | |
640 | |
641 // Call Init() again to reset. | |
642 ASSERT_EQ(ERR_IO_PENDING, stream->Init(test_callback.callback())); | |
643 EXPECT_EQ(OK, test_callback.WaitForResult()); | |
644 EXPECT_FALSE(stream->IsEOF()); | |
645 EXPECT_EQ(kTestDataSize*2, stream->size()); | |
646 | |
647 // Read again. | |
648 EXPECT_EQ(expected_data, ReadFromUploadDataStream(stream.get())); | |
649 EXPECT_TRUE(stream->IsEOF()); | |
650 } | |
651 | |
652 TEST_F(ElementsUploadDataStreamTest, InitToReset) { | |
653 base::FilePath temp_file_path; | |
654 ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(), | |
655 &temp_file_path)); | |
656 ASSERT_EQ(static_cast<int>(kTestDataSize), | |
657 base::WriteFile(temp_file_path, kTestData, kTestDataSize)); | |
658 | |
659 // Prepare data. | |
660 element_readers_.push_back(new UploadBytesElementReader( | |
661 kTestData, kTestDataSize)); | |
662 element_readers_.push_back( | |
663 new UploadFileElementReader(base::MessageLoopProxy::current().get(), | |
664 temp_file_path, | |
665 0, | |
666 kuint64max, | |
667 base::Time())); | |
668 scoped_ptr<UploadDataStream> stream( | |
669 new ElementsUploadDataStream(element_readers_.Pass(), 0)); | |
670 | |
671 std::vector<char> expected_data(kTestData, kTestData + kTestDataSize); | |
672 expected_data.insert(expected_data.end(), kTestData, | |
673 kTestData + kTestDataSize); | |
674 | |
675 // Call Init(). | |
676 TestCompletionCallback init_callback1; | |
677 ASSERT_EQ(ERR_IO_PENDING, stream->Init(init_callback1.callback())); | |
678 EXPECT_EQ(OK, init_callback1.WaitForResult()); | |
679 EXPECT_FALSE(stream->IsEOF()); | |
680 EXPECT_EQ(kTestDataSize*2, stream->size()); | |
681 | |
682 // Read some. | |
683 TestCompletionCallback read_callback1; | |
684 std::vector<char> buf(kTestDataSize + kTestDataSize/2); | |
685 scoped_refptr<IOBuffer> wrapped_buffer = new WrappedIOBuffer(&buf[0]); | |
686 EXPECT_EQ( | |
687 ERR_IO_PENDING, | |
688 stream->Read(wrapped_buffer.get(), buf.size(), | |
689 read_callback1.callback())); | |
690 EXPECT_EQ(static_cast<int>(buf.size()), read_callback1.WaitForResult()); | |
691 EXPECT_EQ(buf.size(), stream->position()); | |
692 | |
693 // Call Init to reset the state. | |
694 TestCompletionCallback init_callback2; | |
695 ASSERT_EQ(ERR_IO_PENDING, stream->Init(init_callback2.callback())); | |
696 EXPECT_EQ(OK, init_callback2.WaitForResult()); | |
697 EXPECT_FALSE(stream->IsEOF()); | |
698 EXPECT_EQ(kTestDataSize*2, stream->size()); | |
699 | |
700 // Read. | |
701 TestCompletionCallback read_callback2; | |
702 std::vector<char> buf2(kTestDataSize*2); | |
703 scoped_refptr<IOBuffer> wrapped_buffer2 = new WrappedIOBuffer(&buf2[0]); | |
704 EXPECT_EQ(ERR_IO_PENDING, | |
705 stream->Read( | |
706 wrapped_buffer2.get(), buf2.size(), read_callback2.callback())); | |
707 EXPECT_EQ(static_cast<int>(buf2.size()), read_callback2.WaitForResult()); | |
708 EXPECT_EQ(expected_data, buf2); | |
709 } | |
710 | |
711 TEST_F(ElementsUploadDataStreamTest, InitDuringAsyncInit) { | |
712 base::FilePath temp_file_path; | |
713 ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(), | |
714 &temp_file_path)); | |
715 ASSERT_EQ(static_cast<int>(kTestDataSize), | |
716 base::WriteFile(temp_file_path, kTestData, kTestDataSize)); | |
717 | |
718 // Prepare data. | |
719 element_readers_.push_back(new UploadBytesElementReader( | |
720 kTestData, kTestDataSize)); | |
721 element_readers_.push_back( | |
722 new UploadFileElementReader(base::MessageLoopProxy::current().get(), | |
723 temp_file_path, | |
724 0, | |
725 kuint64max, | |
726 base::Time())); | |
727 scoped_ptr<UploadDataStream> stream( | |
728 new ElementsUploadDataStream(element_readers_.Pass(), 0)); | |
729 | |
730 std::vector<char> expected_data(kTestData, kTestData + kTestDataSize); | |
731 expected_data.insert(expected_data.end(), kTestData, | |
732 kTestData + kTestDataSize); | |
733 | |
734 // Start Init. | |
735 TestCompletionCallback init_callback1; | |
736 EXPECT_EQ(ERR_IO_PENDING, stream->Init(init_callback1.callback())); | |
737 | |
738 // Call Init again to cancel the previous init. | |
739 TestCompletionCallback init_callback2; | |
740 EXPECT_EQ(ERR_IO_PENDING, stream->Init(init_callback2.callback())); | |
741 EXPECT_EQ(OK, init_callback2.WaitForResult()); | |
742 EXPECT_FALSE(stream->IsEOF()); | |
743 EXPECT_EQ(kTestDataSize*2, stream->size()); | |
744 | |
745 // Read. | |
746 TestCompletionCallback read_callback2; | |
747 std::vector<char> buf2(kTestDataSize*2); | |
748 scoped_refptr<IOBuffer> wrapped_buffer2 = new WrappedIOBuffer(&buf2[0]); | |
749 EXPECT_EQ(ERR_IO_PENDING, | |
750 stream->Read( | |
751 wrapped_buffer2.get(), buf2.size(), read_callback2.callback())); | |
752 EXPECT_EQ(static_cast<int>(buf2.size()), read_callback2.WaitForResult()); | |
753 EXPECT_EQ(expected_data, buf2); | |
754 EXPECT_TRUE(stream->IsEOF()); | |
755 | |
756 // Make sure callbacks are not called for cancelled operations. | |
757 EXPECT_FALSE(init_callback1.have_result()); | |
758 } | |
759 | |
760 TEST_F(ElementsUploadDataStreamTest, InitDuringAsyncRead) { | |
761 base::FilePath temp_file_path; | |
762 ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(), | |
763 &temp_file_path)); | |
764 ASSERT_EQ(static_cast<int>(kTestDataSize), | |
765 base::WriteFile(temp_file_path, kTestData, kTestDataSize)); | |
766 | |
767 // Prepare data. | |
768 element_readers_.push_back(new UploadBytesElementReader( | |
769 kTestData, kTestDataSize)); | |
770 element_readers_.push_back( | |
771 new UploadFileElementReader(base::MessageLoopProxy::current().get(), | |
772 temp_file_path, | |
773 0, | |
774 kuint64max, | |
775 base::Time())); | |
776 scoped_ptr<UploadDataStream> stream( | |
777 new ElementsUploadDataStream(element_readers_.Pass(), 0)); | |
778 | |
779 std::vector<char> expected_data(kTestData, kTestData + kTestDataSize); | |
780 expected_data.insert(expected_data.end(), kTestData, | |
781 kTestData + kTestDataSize); | |
782 | |
783 // Call Init(). | |
784 TestCompletionCallback init_callback1; | |
785 ASSERT_EQ(ERR_IO_PENDING, stream->Init(init_callback1.callback())); | |
786 EXPECT_EQ(OK, init_callback1.WaitForResult()); | |
787 EXPECT_FALSE(stream->IsEOF()); | |
788 EXPECT_EQ(kTestDataSize*2, stream->size()); | |
789 | |
790 // Start reading. | |
791 TestCompletionCallback read_callback1; | |
792 std::vector<char> buf(kTestDataSize*2); | |
793 scoped_refptr<IOBuffer> wrapped_buffer = new WrappedIOBuffer(&buf[0]); | |
794 EXPECT_EQ( | |
795 ERR_IO_PENDING, | |
796 stream->Read(wrapped_buffer.get(), buf.size(), | |
797 read_callback1.callback())); | |
798 | |
799 // Call Init to cancel the previous read. | |
800 TestCompletionCallback init_callback2; | |
801 EXPECT_EQ(ERR_IO_PENDING, stream->Init(init_callback2.callback())); | |
802 EXPECT_EQ(OK, init_callback2.WaitForResult()); | |
803 EXPECT_FALSE(stream->IsEOF()); | |
804 EXPECT_EQ(kTestDataSize*2, stream->size()); | |
805 | |
806 // Read. | |
807 TestCompletionCallback read_callback2; | |
808 std::vector<char> buf2(kTestDataSize*2); | |
809 scoped_refptr<IOBuffer> wrapped_buffer2 = new WrappedIOBuffer(&buf2[0]); | |
810 EXPECT_EQ(ERR_IO_PENDING, | |
811 stream->Read( | |
812 wrapped_buffer2.get(), buf2.size(), read_callback2.callback())); | |
813 EXPECT_EQ(static_cast<int>(buf2.size()), read_callback2.WaitForResult()); | |
814 EXPECT_EQ(expected_data, buf2); | |
815 EXPECT_TRUE(stream->IsEOF()); | |
816 | |
817 // Make sure callbacks are not called for cancelled operations. | |
818 EXPECT_FALSE(read_callback1.have_result()); | |
819 } | |
820 | |
821 } // namespace net | |
OLD | NEW |