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_file_element_reader.h" 6 7 #include "base/file_util.h" 8 #include "base/files/scoped_temp_dir.h" 9 #include "base/message_loop/message_loop_proxy.h" 10 #include "base/run_loop.h" 11 #include "net/base/io_buffer.h" 12 #include "net/base/net_errors.h" 13 #include "net/base/test_completion_callback.h" 14 #include "testing/gtest/include/gtest/gtest.h" 15 #include "testing/platform_test.h" 16 17 namespace net { 18 19 class UploadFileElementReaderTest : public PlatformTest { 20 protected: 21 virtual void SetUp() { 22 PlatformTest::SetUp(); 23 // Some tests (*.ReadPartially) rely on bytes_.size() being even. 24 const char kData[] = "123456789abcdefghi"; 25 bytes_.assign(kData, kData + arraysize(kData) - 1); 26 27 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); 28 29 ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(), 30 &temp_file_path_)); 31 ASSERT_EQ( 32 static_cast<int>(bytes_.size()), 33 file_util::WriteFile(temp_file_path_, &bytes_[0], bytes_.size())); 34 35 reader_.reset( 36 new UploadFileElementReader(base::MessageLoopProxy::current().get(), 37 temp_file_path_, 38 0, 39 kuint64max, 40 base::Time())); 41 TestCompletionCallback callback; 42 ASSERT_EQ(ERR_IO_PENDING, reader_->Init(callback.callback())); 43 EXPECT_EQ(OK, callback.WaitForResult()); 44 EXPECT_EQ(bytes_.size(), reader_->GetContentLength()); 45 EXPECT_EQ(bytes_.size(), reader_->BytesRemaining()); 46 EXPECT_FALSE(reader_->IsInMemory()); 47 } 48 49 virtual ~UploadFileElementReaderTest() { 50 reader_.reset(); 51 base::RunLoop().RunUntilIdle(); 52 } 53 54 std::vector<char> bytes_; 55 scoped_ptr<UploadElementReader> reader_; 56 base::ScopedTempDir temp_dir_; 57 base::FilePath temp_file_path_; 58 }; 59 60 TEST_F(UploadFileElementReaderTest, ReadPartially) { 61 const size_t kHalfSize = bytes_.size() / 2; 62 ASSERT_EQ(bytes_.size(), kHalfSize * 2); 63 std::vector<char> buf(kHalfSize); 64 scoped_refptr<IOBuffer> wrapped_buffer = new WrappedIOBuffer(&buf[0]); 65 TestCompletionCallback read_callback1; 66 ASSERT_EQ(ERR_IO_PENDING, 67 reader_->Read( 68 wrapped_buffer.get(), buf.size(), read_callback1.callback())); 69 EXPECT_EQ(static_cast<int>(buf.size()), read_callback1.WaitForResult()); 70 EXPECT_EQ(bytes_.size() - buf.size(), reader_->BytesRemaining()); 71 EXPECT_EQ(std::vector<char>(bytes_.begin(), bytes_.begin() + kHalfSize), buf); 72 73 TestCompletionCallback read_callback2; 74 EXPECT_EQ(ERR_IO_PENDING, 75 reader_->Read( 76 wrapped_buffer.get(), buf.size(), read_callback2.callback())); 77 EXPECT_EQ(static_cast<int>(buf.size()), read_callback2.WaitForResult()); 78 EXPECT_EQ(0U, reader_->BytesRemaining()); 79 EXPECT_EQ(std::vector<char>(bytes_.begin() + kHalfSize, bytes_.end()), buf); 80 } 81 82 TEST_F(UploadFileElementReaderTest, ReadAll) { 83 std::vector<char> buf(bytes_.size()); 84 scoped_refptr<IOBuffer> wrapped_buffer = new WrappedIOBuffer(&buf[0]); 85 TestCompletionCallback read_callback; 86 ASSERT_EQ(ERR_IO_PENDING, 87 reader_->Read( 88 wrapped_buffer.get(), buf.size(), read_callback.callback())); 89 EXPECT_EQ(static_cast<int>(buf.size()), read_callback.WaitForResult()); 90 EXPECT_EQ(0U, reader_->BytesRemaining()); 91 EXPECT_EQ(bytes_, buf); 92 // Try to read again. 93 EXPECT_EQ(0, 94 reader_->Read( 95 wrapped_buffer.get(), buf.size(), read_callback.callback())); 96 } 97 98 TEST_F(UploadFileElementReaderTest, ReadTooMuch) { 99 const size_t kTooLargeSize = bytes_.size() * 2; 100 std::vector<char> buf(kTooLargeSize); 101 scoped_refptr<IOBuffer> wrapped_buffer = new WrappedIOBuffer(&buf[0]); 102 TestCompletionCallback read_callback; 103 ASSERT_EQ(ERR_IO_PENDING, 104 reader_->Read( 105 wrapped_buffer.get(), buf.size(), read_callback.callback())); 106 EXPECT_EQ(static_cast<int>(bytes_.size()), read_callback.WaitForResult()); 107 EXPECT_EQ(0U, reader_->BytesRemaining()); 108 buf.resize(bytes_.size()); // Resize to compare. 109 EXPECT_EQ(bytes_, buf); 110 } 111 112 TEST_F(UploadFileElementReaderTest, MultipleInit) { 113 std::vector<char> buf(bytes_.size()); 114 scoped_refptr<IOBuffer> wrapped_buffer = new WrappedIOBuffer(&buf[0]); 115 116 // Read all. 117 TestCompletionCallback read_callback1; 118 ASSERT_EQ(ERR_IO_PENDING, 119 reader_->Read( 120 wrapped_buffer.get(), buf.size(), read_callback1.callback())); 121 EXPECT_EQ(static_cast<int>(buf.size()), read_callback1.WaitForResult()); 122 EXPECT_EQ(0U, reader_->BytesRemaining()); 123 EXPECT_EQ(bytes_, buf); 124 125 // Call Init() again to reset the state. 126 TestCompletionCallback init_callback; 127 ASSERT_EQ(ERR_IO_PENDING, reader_->Init(init_callback.callback())); 128 EXPECT_EQ(OK, init_callback.WaitForResult()); 129 EXPECT_EQ(bytes_.size(), reader_->GetContentLength()); 130 EXPECT_EQ(bytes_.size(), reader_->BytesRemaining()); 131 132 // Read again. 133 TestCompletionCallback read_callback2; 134 ASSERT_EQ(ERR_IO_PENDING, 135 reader_->Read( 136 wrapped_buffer.get(), buf.size(), read_callback2.callback())); 137 EXPECT_EQ(static_cast<int>(buf.size()), read_callback2.WaitForResult()); 138 EXPECT_EQ(0U, reader_->BytesRemaining()); 139 EXPECT_EQ(bytes_, buf); 140 } 141 142 TEST_F(UploadFileElementReaderTest, InitDuringAsyncOperation) { 143 std::vector<char> buf(bytes_.size()); 144 scoped_refptr<IOBuffer> wrapped_buffer = new WrappedIOBuffer(&buf[0]); 145 146 // Start reading all. 147 TestCompletionCallback read_callback1; 148 EXPECT_EQ(ERR_IO_PENDING, 149 reader_->Read( 150 wrapped_buffer.get(), buf.size(), read_callback1.callback())); 151 152 // Call Init to cancel the previous read. 153 TestCompletionCallback init_callback1; 154 EXPECT_EQ(ERR_IO_PENDING, reader_->Init(init_callback1.callback())); 155 156 // Call Init again to cancel the previous init. 157 TestCompletionCallback init_callback2; 158 EXPECT_EQ(ERR_IO_PENDING, reader_->Init(init_callback2.callback())); 159 EXPECT_EQ(OK, init_callback2.WaitForResult()); 160 EXPECT_EQ(bytes_.size(), reader_->GetContentLength()); 161 EXPECT_EQ(bytes_.size(), reader_->BytesRemaining()); 162 163 // Read half. 164 std::vector<char> buf2(bytes_.size() / 2); 165 scoped_refptr<IOBuffer> wrapped_buffer2 = new WrappedIOBuffer(&buf2[0]); 166 TestCompletionCallback read_callback2; 167 EXPECT_EQ(ERR_IO_PENDING, 168 reader_->Read( 169 wrapped_buffer2.get(), buf2.size(), read_callback2.callback())); 170 EXPECT_EQ(static_cast<int>(buf2.size()), read_callback2.WaitForResult()); 171 EXPECT_EQ(bytes_.size() - buf2.size(), reader_->BytesRemaining()); 172 EXPECT_EQ(std::vector<char>(bytes_.begin(), bytes_.begin() + buf2.size()), 173 buf2); 174 175 // Make sure callbacks are not called for cancelled operations. 176 EXPECT_FALSE(read_callback1.have_result()); 177 EXPECT_FALSE(init_callback1.have_result()); 178 } 179 180 TEST_F(UploadFileElementReaderTest, Range) { 181 const uint64 kOffset = 2; 182 const uint64 kLength = bytes_.size() - kOffset * 3; 183 reader_.reset( 184 new UploadFileElementReader(base::MessageLoopProxy::current().get(), 185 temp_file_path_, 186 kOffset, 187 kLength, 188 base::Time())); 189 TestCompletionCallback init_callback; 190 ASSERT_EQ(ERR_IO_PENDING, reader_->Init(init_callback.callback())); 191 EXPECT_EQ(OK, init_callback.WaitForResult()); 192 EXPECT_EQ(kLength, reader_->GetContentLength()); 193 EXPECT_EQ(kLength, reader_->BytesRemaining()); 194 std::vector<char> buf(kLength); 195 scoped_refptr<IOBuffer> wrapped_buffer = new WrappedIOBuffer(&buf[0]); 196 TestCompletionCallback read_callback; 197 ASSERT_EQ( 198 ERR_IO_PENDING, 199 reader_->Read(wrapped_buffer.get(), kLength, read_callback.callback())); 200 EXPECT_EQ(static_cast<int>(kLength), read_callback.WaitForResult()); 201 const std::vector<char> expected(bytes_.begin() + kOffset, 202 bytes_.begin() + kOffset + kLength); 203 EXPECT_EQ(expected, buf); 204 } 205 206 TEST_F(UploadFileElementReaderTest, FileChanged) { 207 base::PlatformFileInfo info; 208 ASSERT_TRUE(base::GetFileInfo(temp_file_path_, &info)); 209 210 // Expect one second before the actual modification time to simulate change. 211 const base::Time expected_modification_time = 212 info.last_modified - base::TimeDelta::FromSeconds(1); 213 reader_.reset( 214 new UploadFileElementReader(base::MessageLoopProxy::current().get(), 215 temp_file_path_, 216 0, 217 kuint64max, 218 expected_modification_time)); 219 TestCompletionCallback init_callback; 220 ASSERT_EQ(ERR_IO_PENDING, reader_->Init(init_callback.callback())); 221 EXPECT_EQ(ERR_UPLOAD_FILE_CHANGED, init_callback.WaitForResult()); 222 } 223 224 TEST_F(UploadFileElementReaderTest, WrongPath) { 225 const base::FilePath wrong_path(FILE_PATH_LITERAL("wrong_path")); 226 reader_.reset( 227 new UploadFileElementReader(base::MessageLoopProxy::current().get(), 228 wrong_path, 229 0, 230 kuint64max, 231 base::Time())); 232 TestCompletionCallback init_callback; 233 ASSERT_EQ(ERR_IO_PENDING, reader_->Init(init_callback.callback())); 234 EXPECT_EQ(ERR_FILE_NOT_FOUND, init_callback.WaitForResult()); 235 } 236 237 238 class UploadFileElementReaderSyncTest : public PlatformTest { 239 protected: 240 virtual void SetUp() OVERRIDE { 241 // Some tests (*.ReadPartially) rely on bytes_.size() being even. 242 const char kData[] = "123456789abcdefghi"; 243 bytes_.assign(kData, kData + arraysize(kData) - 1); 244 245 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); 246 247 ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(), 248 &temp_file_path_)); 249 ASSERT_EQ( 250 static_cast<int>(bytes_.size()), 251 file_util::WriteFile(temp_file_path_, &bytes_[0], bytes_.size())); 252 253 reader_.reset(new UploadFileElementReaderSync( 254 temp_file_path_, 0, kuint64max, base::Time())); 255 ASSERT_EQ(OK, reader_->Init(CompletionCallback())); 256 EXPECT_EQ(bytes_.size(), reader_->GetContentLength()); 257 EXPECT_EQ(bytes_.size(), reader_->BytesRemaining()); 258 EXPECT_FALSE(reader_->IsInMemory()); 259 } 260 261 std::vector<char> bytes_; 262 scoped_ptr<UploadElementReader> reader_; 263 base::ScopedTempDir temp_dir_; 264 base::FilePath temp_file_path_; 265 }; 266 267 TEST_F(UploadFileElementReaderSyncTest, ReadPartially) { 268 const size_t kHalfSize = bytes_.size() / 2; 269 ASSERT_EQ(bytes_.size(), kHalfSize * 2); 270 std::vector<char> buf(kHalfSize); 271 scoped_refptr<IOBuffer> wrapped_buffer = new WrappedIOBuffer(&buf[0]); 272 EXPECT_EQ( 273 static_cast<int>(buf.size()), 274 reader_->Read(wrapped_buffer.get(), buf.size(), CompletionCallback())); 275 EXPECT_EQ(bytes_.size() - buf.size(), reader_->BytesRemaining()); 276 EXPECT_EQ(std::vector<char>(bytes_.begin(), bytes_.begin() + kHalfSize), buf); 277 278 EXPECT_EQ( 279 static_cast<int>(buf.size()), 280 reader_->Read(wrapped_buffer.get(), buf.size(), CompletionCallback())); 281 EXPECT_EQ(0U, reader_->BytesRemaining()); 282 EXPECT_EQ(std::vector<char>(bytes_.begin() + kHalfSize, bytes_.end()), buf); 283 } 284 285 TEST_F(UploadFileElementReaderSyncTest, ReadAll) { 286 std::vector<char> buf(bytes_.size()); 287 scoped_refptr<IOBuffer> wrapped_buffer = new WrappedIOBuffer(&buf[0]); 288 EXPECT_EQ( 289 static_cast<int>(buf.size()), 290 reader_->Read(wrapped_buffer.get(), buf.size(), CompletionCallback())); 291 EXPECT_EQ(0U, reader_->BytesRemaining()); 292 EXPECT_EQ(bytes_, buf); 293 // Try to read again. 294 EXPECT_EQ( 295 0, reader_->Read(wrapped_buffer.get(), buf.size(), CompletionCallback())); 296 } 297 298 TEST_F(UploadFileElementReaderSyncTest, ReadTooMuch) { 299 const size_t kTooLargeSize = bytes_.size() * 2; 300 std::vector<char> buf(kTooLargeSize); 301 scoped_refptr<IOBuffer> wrapped_buffer = new WrappedIOBuffer(&buf[0]); 302 EXPECT_EQ( 303 static_cast<int>(bytes_.size()), 304 reader_->Read(wrapped_buffer.get(), buf.size(), CompletionCallback())); 305 EXPECT_EQ(0U, reader_->BytesRemaining()); 306 buf.resize(bytes_.size()); // Resize to compare. 307 EXPECT_EQ(bytes_, buf); 308 } 309 310 TEST_F(UploadFileElementReaderSyncTest, MultipleInit) { 311 std::vector<char> buf(bytes_.size()); 312 scoped_refptr<IOBuffer> wrapped_buffer = new WrappedIOBuffer(&buf[0]); 313 314 // Read all. 315 EXPECT_EQ( 316 static_cast<int>(buf.size()), 317 reader_->Read(wrapped_buffer.get(), buf.size(), CompletionCallback())); 318 EXPECT_EQ(0U, reader_->BytesRemaining()); 319 EXPECT_EQ(bytes_, buf); 320 321 // Call Init() again to reset the state. 322 ASSERT_EQ(OK, reader_->Init(CompletionCallback())); 323 EXPECT_EQ(bytes_.size(), reader_->GetContentLength()); 324 EXPECT_EQ(bytes_.size(), reader_->BytesRemaining()); 325 326 // Read again. 327 EXPECT_EQ( 328 static_cast<int>(buf.size()), 329 reader_->Read(wrapped_buffer.get(), buf.size(), CompletionCallback())); 330 EXPECT_EQ(0U, reader_->BytesRemaining()); 331 EXPECT_EQ(bytes_, buf); 332 } 333 334 TEST_F(UploadFileElementReaderSyncTest, Range) { 335 const uint64 kOffset = 2; 336 const uint64 kLength = bytes_.size() - kOffset * 3; 337 reader_.reset(new UploadFileElementReaderSync( 338 temp_file_path_, kOffset, kLength, base::Time())); 339 ASSERT_EQ(OK, reader_->Init(CompletionCallback())); 340 EXPECT_EQ(kLength, reader_->GetContentLength()); 341 EXPECT_EQ(kLength, reader_->BytesRemaining()); 342 std::vector<char> buf(kLength); 343 scoped_refptr<IOBuffer> wrapped_buffer = new WrappedIOBuffer(&buf[0]); 344 EXPECT_EQ(static_cast<int>(kLength), 345 reader_->Read(wrapped_buffer.get(), kLength, CompletionCallback())); 346 const std::vector<char> expected(bytes_.begin() + kOffset, 347 bytes_.begin() + kOffset + kLength); 348 EXPECT_EQ(expected, buf); 349 } 350 351 TEST_F(UploadFileElementReaderSyncTest, FileChanged) { 352 base::PlatformFileInfo info; 353 ASSERT_TRUE(base::GetFileInfo(temp_file_path_, &info)); 354 355 // Expect one second before the actual modification time to simulate change. 356 const base::Time expected_modification_time = 357 info.last_modified - base::TimeDelta::FromSeconds(1); 358 reader_.reset(new UploadFileElementReaderSync( 359 temp_file_path_, 0, kuint64max, expected_modification_time)); 360 EXPECT_EQ(ERR_UPLOAD_FILE_CHANGED, reader_->Init(CompletionCallback())); 361 } 362 363 TEST_F(UploadFileElementReaderSyncTest, WrongPath) { 364 const base::FilePath wrong_path(FILE_PATH_LITERAL("wrong_path")); 365 reader_.reset(new UploadFileElementReaderSync( 366 wrong_path, 0, kuint64max, base::Time())); 367 ASSERT_EQ(ERR_FILE_NOT_FOUND, reader_->Init(CompletionCallback())); 368 } 369 370 } // namespace net 371