| 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 |