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