| Index: net/base/file_stream_unittest.cc
|
| diff --git a/net/base/file_stream_unittest.cc b/net/base/file_stream_unittest.cc
|
| deleted file mode 100644
|
| index 8b47eccf4144185da0a990c7f60a85fa848b7080..0000000000000000000000000000000000000000
|
| --- a/net/base/file_stream_unittest.cc
|
| +++ /dev/null
|
| @@ -1,888 +0,0 @@
|
| -// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -#include "net/base/file_stream.h"
|
| -
|
| -#include "base/bind.h"
|
| -#include "base/callback.h"
|
| -#include "base/files/file.h"
|
| -#include "base/files/file_util.h"
|
| -#include "base/message_loop/message_loop.h"
|
| -#include "base/message_loop/message_loop_proxy.h"
|
| -#include "base/path_service.h"
|
| -#include "base/run_loop.h"
|
| -#include "base/strings/string_util.h"
|
| -#include "base/synchronization/waitable_event.h"
|
| -#include "base/test/test_timeouts.h"
|
| -#include "base/threading/sequenced_worker_pool.h"
|
| -#include "base/threading/thread_restrictions.h"
|
| -#include "net/base/capturing_net_log.h"
|
| -#include "net/base/io_buffer.h"
|
| -#include "net/base/net_errors.h"
|
| -#include "net/base/test_completion_callback.h"
|
| -#include "testing/gtest/include/gtest/gtest.h"
|
| -#include "testing/platform_test.h"
|
| -
|
| -#if defined(OS_ANDROID)
|
| -#include "base/test/test_file_util.h"
|
| -#endif
|
| -
|
| -namespace net {
|
| -
|
| -namespace {
|
| -
|
| -const char kTestData[] = "0123456789";
|
| -const int kTestDataSize = arraysize(kTestData) - 1;
|
| -
|
| -// Creates an IOBufferWithSize that contains the kTestDataSize.
|
| -IOBufferWithSize* CreateTestDataBuffer() {
|
| - IOBufferWithSize* buf = new IOBufferWithSize(kTestDataSize);
|
| - memcpy(buf->data(), kTestData, kTestDataSize);
|
| - return buf;
|
| -}
|
| -
|
| -} // namespace
|
| -
|
| -class FileStreamTest : public PlatformTest {
|
| - public:
|
| - void SetUp() override {
|
| - PlatformTest::SetUp();
|
| -
|
| - base::CreateTemporaryFile(&temp_file_path_);
|
| - base::WriteFile(temp_file_path_, kTestData, kTestDataSize);
|
| - }
|
| - void TearDown() override {
|
| - // FileStreamContexts must be asynchronously closed on the file task runner
|
| - // before they can be deleted. Pump the RunLoop to avoid leaks.
|
| - base::RunLoop().RunUntilIdle();
|
| - EXPECT_TRUE(base::DeleteFile(temp_file_path_, false));
|
| -
|
| - PlatformTest::TearDown();
|
| - }
|
| -
|
| - const base::FilePath temp_file_path() const { return temp_file_path_; }
|
| -
|
| - private:
|
| - base::FilePath temp_file_path_;
|
| -};
|
| -
|
| -namespace {
|
| -
|
| -TEST_F(FileStreamTest, OpenExplicitClose) {
|
| - TestCompletionCallback callback;
|
| - FileStream stream(base::MessageLoopProxy::current());
|
| - int flags = base::File::FLAG_OPEN |
|
| - base::File::FLAG_READ |
|
| - base::File::FLAG_ASYNC;
|
| - int rv = stream.Open(temp_file_path(), flags, callback.callback());
|
| - EXPECT_EQ(ERR_IO_PENDING, rv);
|
| - EXPECT_EQ(OK, callback.WaitForResult());
|
| - EXPECT_TRUE(stream.IsOpen());
|
| - EXPECT_TRUE(stream.GetFileForTesting().IsValid());
|
| - EXPECT_EQ(ERR_IO_PENDING, stream.Close(callback.callback()));
|
| - EXPECT_EQ(OK, callback.WaitForResult());
|
| - EXPECT_FALSE(stream.IsOpen());
|
| - EXPECT_FALSE(stream.GetFileForTesting().IsValid());
|
| -}
|
| -
|
| -TEST_F(FileStreamTest, OpenExplicitCloseOrphaned) {
|
| - TestCompletionCallback callback;
|
| - scoped_ptr<FileStream> stream(new FileStream(
|
| - base::MessageLoopProxy::current()));
|
| - int flags = base::File::FLAG_OPEN | base::File::FLAG_READ |
|
| - base::File::FLAG_ASYNC;
|
| - int rv = stream->Open(temp_file_path(), flags, callback.callback());
|
| - EXPECT_EQ(ERR_IO_PENDING, rv);
|
| - EXPECT_EQ(OK, callback.WaitForResult());
|
| - EXPECT_TRUE(stream->IsOpen());
|
| - EXPECT_TRUE(stream->GetFileForTesting().IsValid());
|
| - EXPECT_EQ(ERR_IO_PENDING, stream->Close(callback.callback()));
|
| - stream.reset();
|
| - // File isn't actually closed yet.
|
| - base::RunLoop runloop;
|
| - runloop.RunUntilIdle();
|
| - // The file should now be closed, though the callback has not been called.
|
| -}
|
| -
|
| -// Test the use of FileStream with a file handle provided at construction.
|
| -TEST_F(FileStreamTest, UseFileHandle) {
|
| - int rv = 0;
|
| - TestCompletionCallback callback;
|
| - TestInt64CompletionCallback callback64;
|
| - // 1. Test reading with a file handle.
|
| - ASSERT_EQ(kTestDataSize,
|
| - base::WriteFile(temp_file_path(), kTestData, kTestDataSize));
|
| - int flags = base::File::FLAG_OPEN_ALWAYS | base::File::FLAG_READ |
|
| - base::File::FLAG_ASYNC;
|
| - base::File file(temp_file_path(), flags);
|
| -
|
| - // Seek to the beginning of the file and read.
|
| - scoped_ptr<FileStream> read_stream(
|
| - new FileStream(file.Pass(), base::MessageLoopProxy::current()));
|
| - ASSERT_EQ(ERR_IO_PENDING,
|
| - read_stream->Seek(base::File::FROM_BEGIN, 0,
|
| - callback64.callback()));
|
| - ASSERT_EQ(0, callback64.WaitForResult());
|
| - // Read into buffer and compare.
|
| - scoped_refptr<IOBufferWithSize> read_buffer =
|
| - new IOBufferWithSize(kTestDataSize);
|
| - rv = read_stream->Read(read_buffer.get(), kTestDataSize, callback.callback());
|
| - ASSERT_EQ(kTestDataSize, callback.GetResult(rv));
|
| - ASSERT_EQ(0, memcmp(kTestData, read_buffer->data(), kTestDataSize));
|
| - read_stream.reset();
|
| -
|
| - // 2. Test writing with a file handle.
|
| - base::DeleteFile(temp_file_path(), false);
|
| - flags = base::File::FLAG_OPEN_ALWAYS | base::File::FLAG_WRITE |
|
| - base::File::FLAG_ASYNC;
|
| - file.Initialize(temp_file_path(), flags);
|
| -
|
| - scoped_ptr<FileStream> write_stream(
|
| - new FileStream(file.Pass(), base::MessageLoopProxy::current()));
|
| - ASSERT_EQ(ERR_IO_PENDING,
|
| - write_stream->Seek(base::File::FROM_BEGIN, 0,
|
| - callback64.callback()));
|
| - ASSERT_EQ(0, callback64.WaitForResult());
|
| - scoped_refptr<IOBufferWithSize> write_buffer = CreateTestDataBuffer();
|
| - rv = write_stream->Write(write_buffer.get(), kTestDataSize,
|
| - callback.callback());
|
| - ASSERT_EQ(kTestDataSize, callback.GetResult(rv));
|
| - write_stream.reset();
|
| -
|
| - // Read into buffer and compare to make sure the handle worked fine.
|
| - ASSERT_EQ(kTestDataSize,
|
| - base::ReadFile(temp_file_path(), read_buffer->data(),
|
| - kTestDataSize));
|
| - ASSERT_EQ(0, memcmp(kTestData, read_buffer->data(), kTestDataSize));
|
| -}
|
| -
|
| -TEST_F(FileStreamTest, UseClosedStream) {
|
| - int rv = 0;
|
| - TestCompletionCallback callback;
|
| - TestInt64CompletionCallback callback64;
|
| -
|
| - FileStream stream(base::MessageLoopProxy::current());
|
| -
|
| - EXPECT_FALSE(stream.IsOpen());
|
| -
|
| - // Try seeking...
|
| - rv = stream.Seek(base::File::FROM_BEGIN, 5, callback64.callback());
|
| - EXPECT_EQ(ERR_UNEXPECTED, callback64.GetResult(rv));
|
| -
|
| - // Try reading...
|
| - scoped_refptr<IOBufferWithSize> buf = new IOBufferWithSize(10);
|
| - rv = stream.Read(buf.get(), buf->size(), callback.callback());
|
| - EXPECT_EQ(ERR_UNEXPECTED, callback.GetResult(rv));
|
| -}
|
| -
|
| -TEST_F(FileStreamTest, Read) {
|
| - int64 file_size;
|
| - EXPECT_TRUE(base::GetFileSize(temp_file_path(), &file_size));
|
| -
|
| - FileStream stream(base::MessageLoopProxy::current());
|
| - int flags = base::File::FLAG_OPEN | base::File::FLAG_READ |
|
| - base::File::FLAG_ASYNC;
|
| - TestCompletionCallback callback;
|
| - int rv = stream.Open(temp_file_path(), flags, callback.callback());
|
| - EXPECT_EQ(OK, callback.GetResult(rv));
|
| -
|
| - int total_bytes_read = 0;
|
| -
|
| - std::string data_read;
|
| - for (;;) {
|
| - scoped_refptr<IOBufferWithSize> buf = new IOBufferWithSize(4);
|
| - rv = stream.Read(buf.get(), buf->size(), callback.callback());
|
| - rv = callback.GetResult(rv);
|
| - EXPECT_LE(0, rv);
|
| - if (rv <= 0)
|
| - break;
|
| - total_bytes_read += rv;
|
| - data_read.append(buf->data(), rv);
|
| - }
|
| - EXPECT_EQ(file_size, total_bytes_read);
|
| - EXPECT_EQ(kTestData, data_read);
|
| -}
|
| -
|
| -TEST_F(FileStreamTest, Read_EarlyDelete) {
|
| - int64 file_size;
|
| - EXPECT_TRUE(base::GetFileSize(temp_file_path(), &file_size));
|
| -
|
| - scoped_ptr<FileStream> stream(
|
| - new FileStream(base::MessageLoopProxy::current()));
|
| - int flags = base::File::FLAG_OPEN | base::File::FLAG_READ |
|
| - base::File::FLAG_ASYNC;
|
| - TestCompletionCallback callback;
|
| - int rv = stream->Open(temp_file_path(), flags, callback.callback());
|
| - EXPECT_EQ(ERR_IO_PENDING, rv);
|
| - EXPECT_EQ(OK, callback.WaitForResult());
|
| -
|
| - scoped_refptr<IOBufferWithSize> buf = new IOBufferWithSize(4);
|
| - rv = stream->Read(buf.get(), buf->size(), callback.callback());
|
| - stream.reset(); // Delete instead of closing it.
|
| - if (rv < 0) {
|
| - EXPECT_EQ(ERR_IO_PENDING, rv);
|
| - // The callback should not be called if the request is cancelled.
|
| - base::RunLoop().RunUntilIdle();
|
| - EXPECT_FALSE(callback.have_result());
|
| - } else {
|
| - EXPECT_EQ(std::string(kTestData, rv), std::string(buf->data(), rv));
|
| - }
|
| -}
|
| -
|
| -TEST_F(FileStreamTest, Read_FromOffset) {
|
| - int64 file_size;
|
| - EXPECT_TRUE(base::GetFileSize(temp_file_path(), &file_size));
|
| -
|
| - FileStream stream(base::MessageLoopProxy::current());
|
| - int flags = base::File::FLAG_OPEN | base::File::FLAG_READ |
|
| - base::File::FLAG_ASYNC;
|
| - TestCompletionCallback callback;
|
| - int rv = stream.Open(temp_file_path(), flags, callback.callback());
|
| - EXPECT_EQ(ERR_IO_PENDING, rv);
|
| - EXPECT_EQ(OK, callback.WaitForResult());
|
| -
|
| - TestInt64CompletionCallback callback64;
|
| - const int64 kOffset = 3;
|
| - rv = stream.Seek(base::File::FROM_BEGIN, kOffset, callback64.callback());
|
| - ASSERT_EQ(ERR_IO_PENDING, rv);
|
| - int64 new_offset = callback64.WaitForResult();
|
| - EXPECT_EQ(kOffset, new_offset);
|
| -
|
| - int total_bytes_read = 0;
|
| -
|
| - std::string data_read;
|
| - for (;;) {
|
| - scoped_refptr<IOBufferWithSize> buf = new IOBufferWithSize(4);
|
| - rv = stream.Read(buf.get(), buf->size(), callback.callback());
|
| - if (rv == ERR_IO_PENDING)
|
| - rv = callback.WaitForResult();
|
| - EXPECT_LE(0, rv);
|
| - if (rv <= 0)
|
| - break;
|
| - total_bytes_read += rv;
|
| - data_read.append(buf->data(), rv);
|
| - }
|
| - EXPECT_EQ(file_size - kOffset, total_bytes_read);
|
| - EXPECT_EQ(kTestData + kOffset, data_read);
|
| -}
|
| -
|
| -TEST_F(FileStreamTest, SeekAround) {
|
| - FileStream stream(base::MessageLoopProxy::current());
|
| - int flags = base::File::FLAG_OPEN | base::File::FLAG_ASYNC |
|
| - base::File::FLAG_READ;
|
| - TestCompletionCallback callback;
|
| - int rv = stream.Open(temp_file_path(), flags, callback.callback());
|
| - EXPECT_EQ(ERR_IO_PENDING, rv);
|
| - EXPECT_EQ(OK, callback.WaitForResult());
|
| -
|
| - TestInt64CompletionCallback callback64;
|
| -
|
| - const int64 kOffset = 3;
|
| - rv = stream.Seek(base::File::FROM_BEGIN, kOffset, callback64.callback());
|
| - ASSERT_EQ(ERR_IO_PENDING, rv);
|
| - int64 new_offset = callback64.WaitForResult();
|
| - EXPECT_EQ(kOffset, new_offset);
|
| -
|
| - rv = stream.Seek(base::File::FROM_CURRENT, kOffset, callback64.callback());
|
| - ASSERT_EQ(ERR_IO_PENDING, rv);
|
| - new_offset = callback64.WaitForResult();
|
| - EXPECT_EQ(2 * kOffset, new_offset);
|
| -
|
| - rv = stream.Seek(base::File::FROM_CURRENT, -kOffset, callback64.callback());
|
| - ASSERT_EQ(ERR_IO_PENDING, rv);
|
| - new_offset = callback64.WaitForResult();
|
| - EXPECT_EQ(kOffset, new_offset);
|
| -
|
| - const int kTestDataLen = arraysize(kTestData) - 1;
|
| -
|
| - rv = stream.Seek(base::File::FROM_END, -kTestDataLen, callback64.callback());
|
| - ASSERT_EQ(ERR_IO_PENDING, rv);
|
| - new_offset = callback64.WaitForResult();
|
| - EXPECT_EQ(0, new_offset);
|
| -}
|
| -
|
| -TEST_F(FileStreamTest, Write) {
|
| - FileStream stream(base::MessageLoopProxy::current());
|
| - int flags = base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE |
|
| - base::File::FLAG_ASYNC;
|
| - TestCompletionCallback callback;
|
| - int rv = stream.Open(temp_file_path(), flags, callback.callback());
|
| - EXPECT_EQ(OK, callback.GetResult(rv));
|
| -
|
| - int64 file_size;
|
| - EXPECT_TRUE(base::GetFileSize(temp_file_path(), &file_size));
|
| - EXPECT_EQ(0, file_size);
|
| -
|
| - scoped_refptr<IOBuffer> buf = CreateTestDataBuffer();
|
| - rv = stream.Write(buf.get(), kTestDataSize, callback.callback());
|
| - rv = callback.GetResult(rv);
|
| - EXPECT_EQ(kTestDataSize, rv);
|
| -
|
| - EXPECT_TRUE(base::GetFileSize(temp_file_path(), &file_size));
|
| - EXPECT_EQ(kTestDataSize, file_size);
|
| -
|
| - std::string data_read;
|
| - EXPECT_TRUE(base::ReadFileToString(temp_file_path(), &data_read));
|
| - EXPECT_EQ(kTestData, data_read);
|
| -}
|
| -
|
| -TEST_F(FileStreamTest, Write_EarlyDelete) {
|
| - scoped_ptr<FileStream> stream(
|
| - new FileStream(base::MessageLoopProxy::current()));
|
| - int flags = base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE |
|
| - base::File::FLAG_ASYNC;
|
| - TestCompletionCallback callback;
|
| - int rv = stream->Open(temp_file_path(), flags, callback.callback());
|
| - EXPECT_EQ(ERR_IO_PENDING, rv);
|
| - EXPECT_EQ(OK, callback.WaitForResult());
|
| -
|
| - int64 file_size;
|
| - EXPECT_TRUE(base::GetFileSize(temp_file_path(), &file_size));
|
| - EXPECT_EQ(0, file_size);
|
| -
|
| - scoped_refptr<IOBufferWithSize> buf = CreateTestDataBuffer();
|
| - rv = stream->Write(buf.get(), buf->size(), callback.callback());
|
| - stream.reset();
|
| - if (rv < 0) {
|
| - EXPECT_EQ(ERR_IO_PENDING, rv);
|
| - // The callback should not be called if the request is cancelled.
|
| - base::RunLoop().RunUntilIdle();
|
| - EXPECT_FALSE(callback.have_result());
|
| - } else {
|
| - EXPECT_TRUE(base::GetFileSize(temp_file_path(), &file_size));
|
| - EXPECT_EQ(file_size, rv);
|
| - }
|
| -}
|
| -
|
| -TEST_F(FileStreamTest, Write_FromOffset) {
|
| - int64 file_size;
|
| - EXPECT_TRUE(base::GetFileSize(temp_file_path(), &file_size));
|
| -
|
| - FileStream stream(base::MessageLoopProxy::current());
|
| - int flags = base::File::FLAG_OPEN | base::File::FLAG_WRITE |
|
| - base::File::FLAG_ASYNC;
|
| - TestCompletionCallback callback;
|
| - int rv = stream.Open(temp_file_path(), flags, callback.callback());
|
| - EXPECT_EQ(ERR_IO_PENDING, rv);
|
| - EXPECT_EQ(OK, callback.WaitForResult());
|
| -
|
| - TestInt64CompletionCallback callback64;
|
| - const int64 kOffset = 0;
|
| - rv = stream.Seek(base::File::FROM_END, kOffset, callback64.callback());
|
| - ASSERT_EQ(ERR_IO_PENDING, rv);
|
| - int64 new_offset = callback64.WaitForResult();
|
| - EXPECT_EQ(kTestDataSize, new_offset);
|
| -
|
| - int total_bytes_written = 0;
|
| -
|
| - scoped_refptr<IOBufferWithSize> buf = CreateTestDataBuffer();
|
| - scoped_refptr<DrainableIOBuffer> drainable =
|
| - new DrainableIOBuffer(buf.get(), buf->size());
|
| - while (total_bytes_written != kTestDataSize) {
|
| - rv = stream.Write(drainable.get(), drainable->BytesRemaining(),
|
| - callback.callback());
|
| - if (rv == ERR_IO_PENDING)
|
| - rv = callback.WaitForResult();
|
| - EXPECT_LT(0, rv);
|
| - if (rv <= 0)
|
| - break;
|
| - drainable->DidConsume(rv);
|
| - total_bytes_written += rv;
|
| - }
|
| - EXPECT_TRUE(base::GetFileSize(temp_file_path(), &file_size));
|
| - EXPECT_EQ(file_size, kTestDataSize * 2);
|
| -}
|
| -
|
| -TEST_F(FileStreamTest, BasicReadWrite) {
|
| - int64 file_size;
|
| - EXPECT_TRUE(base::GetFileSize(temp_file_path(), &file_size));
|
| -
|
| - scoped_ptr<FileStream> stream(
|
| - new FileStream(base::MessageLoopProxy::current()));
|
| - int flags = base::File::FLAG_OPEN | base::File::FLAG_READ |
|
| - base::File::FLAG_WRITE | base::File::FLAG_ASYNC;
|
| - TestCompletionCallback callback;
|
| - int rv = stream->Open(temp_file_path(), flags, callback.callback());
|
| - EXPECT_EQ(ERR_IO_PENDING, rv);
|
| - EXPECT_EQ(OK, callback.WaitForResult());
|
| -
|
| - int64 total_bytes_read = 0;
|
| -
|
| - std::string data_read;
|
| - for (;;) {
|
| - scoped_refptr<IOBufferWithSize> buf = new IOBufferWithSize(4);
|
| - rv = stream->Read(buf.get(), buf->size(), callback.callback());
|
| - if (rv == ERR_IO_PENDING)
|
| - rv = callback.WaitForResult();
|
| - EXPECT_LE(0, rv);
|
| - if (rv <= 0)
|
| - break;
|
| - total_bytes_read += rv;
|
| - data_read.append(buf->data(), rv);
|
| - }
|
| - EXPECT_EQ(file_size, total_bytes_read);
|
| - EXPECT_TRUE(data_read == kTestData);
|
| -
|
| - int total_bytes_written = 0;
|
| -
|
| - scoped_refptr<IOBufferWithSize> buf = CreateTestDataBuffer();
|
| - scoped_refptr<DrainableIOBuffer> drainable =
|
| - new DrainableIOBuffer(buf.get(), buf->size());
|
| - while (total_bytes_written != kTestDataSize) {
|
| - rv = stream->Write(drainable.get(), drainable->BytesRemaining(),
|
| - callback.callback());
|
| - if (rv == ERR_IO_PENDING)
|
| - rv = callback.WaitForResult();
|
| - EXPECT_LT(0, rv);
|
| - if (rv <= 0)
|
| - break;
|
| - drainable->DidConsume(rv);
|
| - total_bytes_written += rv;
|
| - }
|
| -
|
| - stream.reset();
|
| -
|
| - EXPECT_TRUE(base::GetFileSize(temp_file_path(), &file_size));
|
| - EXPECT_EQ(kTestDataSize * 2, file_size);
|
| -}
|
| -
|
| -TEST_F(FileStreamTest, BasicWriteRead) {
|
| - int64 file_size;
|
| - EXPECT_TRUE(base::GetFileSize(temp_file_path(), &file_size));
|
| -
|
| - scoped_ptr<FileStream> stream(
|
| - new FileStream(base::MessageLoopProxy::current()));
|
| - int flags = base::File::FLAG_OPEN | base::File::FLAG_READ |
|
| - base::File::FLAG_WRITE | base::File::FLAG_ASYNC;
|
| - TestCompletionCallback callback;
|
| - int rv = stream->Open(temp_file_path(), flags, callback.callback());
|
| - EXPECT_EQ(ERR_IO_PENDING, rv);
|
| - EXPECT_EQ(OK, callback.WaitForResult());
|
| -
|
| - TestInt64CompletionCallback callback64;
|
| - rv = stream->Seek(base::File::FROM_END, 0, callback64.callback());
|
| - ASSERT_EQ(ERR_IO_PENDING, rv);
|
| - int64 offset = callback64.WaitForResult();
|
| - EXPECT_EQ(offset, file_size);
|
| -
|
| - int total_bytes_written = 0;
|
| -
|
| - scoped_refptr<IOBufferWithSize> buf = CreateTestDataBuffer();
|
| - scoped_refptr<DrainableIOBuffer> drainable =
|
| - new DrainableIOBuffer(buf.get(), buf->size());
|
| - while (total_bytes_written != kTestDataSize) {
|
| - rv = stream->Write(drainable.get(), drainable->BytesRemaining(),
|
| - callback.callback());
|
| - if (rv == ERR_IO_PENDING)
|
| - rv = callback.WaitForResult();
|
| - EXPECT_LT(0, rv);
|
| - if (rv <= 0)
|
| - break;
|
| - drainable->DidConsume(rv);
|
| - total_bytes_written += rv;
|
| - }
|
| -
|
| - EXPECT_EQ(kTestDataSize, total_bytes_written);
|
| -
|
| - rv = stream->Seek(base::File::FROM_BEGIN, 0, callback64.callback());
|
| - ASSERT_EQ(ERR_IO_PENDING, rv);
|
| - offset = callback64.WaitForResult();
|
| - EXPECT_EQ(0, offset);
|
| -
|
| - int total_bytes_read = 0;
|
| -
|
| - std::string data_read;
|
| - for (;;) {
|
| - scoped_refptr<IOBufferWithSize> buf = new IOBufferWithSize(4);
|
| - rv = stream->Read(buf.get(), buf->size(), callback.callback());
|
| - if (rv == ERR_IO_PENDING)
|
| - rv = callback.WaitForResult();
|
| - EXPECT_LE(0, rv);
|
| - if (rv <= 0)
|
| - break;
|
| - total_bytes_read += rv;
|
| - data_read.append(buf->data(), rv);
|
| - }
|
| - stream.reset();
|
| -
|
| - EXPECT_TRUE(base::GetFileSize(temp_file_path(), &file_size));
|
| - EXPECT_EQ(kTestDataSize * 2, file_size);
|
| -
|
| - EXPECT_EQ(kTestDataSize * 2, total_bytes_read);
|
| - const std::string kExpectedFileData =
|
| - std::string(kTestData) + std::string(kTestData);
|
| - EXPECT_EQ(kExpectedFileData, data_read);
|
| -}
|
| -
|
| -class TestWriteReadCompletionCallback {
|
| - public:
|
| - TestWriteReadCompletionCallback(FileStream* stream,
|
| - int* total_bytes_written,
|
| - int* total_bytes_read,
|
| - std::string* data_read)
|
| - : result_(0),
|
| - have_result_(false),
|
| - waiting_for_result_(false),
|
| - stream_(stream),
|
| - total_bytes_written_(total_bytes_written),
|
| - total_bytes_read_(total_bytes_read),
|
| - data_read_(data_read),
|
| - callback_(base::Bind(&TestWriteReadCompletionCallback::OnComplete,
|
| - base::Unretained(this))),
|
| - test_data_(CreateTestDataBuffer()),
|
| - drainable_(new DrainableIOBuffer(test_data_.get(), kTestDataSize)) {}
|
| -
|
| - int WaitForResult() {
|
| - DCHECK(!waiting_for_result_);
|
| - while (!have_result_) {
|
| - waiting_for_result_ = true;
|
| - base::RunLoop().Run();
|
| - waiting_for_result_ = false;
|
| - }
|
| - have_result_ = false; // auto-reset for next callback
|
| - return result_;
|
| - }
|
| -
|
| - const CompletionCallback& callback() const { return callback_; }
|
| -
|
| - void ValidateWrittenData() {
|
| - TestCompletionCallback callback;
|
| - int rv = 0;
|
| - for (;;) {
|
| - scoped_refptr<IOBufferWithSize> buf = new IOBufferWithSize(4);
|
| - rv = stream_->Read(buf.get(), buf->size(), callback.callback());
|
| - if (rv == ERR_IO_PENDING) {
|
| - base::MessageLoop::ScopedNestableTaskAllower allow(
|
| - base::MessageLoop::current());
|
| - rv = callback.WaitForResult();
|
| - }
|
| - EXPECT_LE(0, rv);
|
| - if (rv <= 0)
|
| - break;
|
| - *total_bytes_read_ += rv;
|
| - data_read_->append(buf->data(), rv);
|
| - }
|
| - }
|
| -
|
| - private:
|
| - void OnComplete(int result) {
|
| - DCHECK_LT(0, result);
|
| - *total_bytes_written_ += result;
|
| -
|
| - int rv;
|
| -
|
| - if (*total_bytes_written_ != kTestDataSize) {
|
| - // Recurse to finish writing all data.
|
| - int total_bytes_written = 0, total_bytes_read = 0;
|
| - std::string data_read;
|
| - TestWriteReadCompletionCallback callback(
|
| - stream_, &total_bytes_written, &total_bytes_read, &data_read);
|
| - rv = stream_->Write(
|
| - drainable_.get(), drainable_->BytesRemaining(), callback.callback());
|
| - DCHECK_EQ(ERR_IO_PENDING, rv);
|
| - rv = callback.WaitForResult();
|
| - drainable_->DidConsume(total_bytes_written);
|
| - *total_bytes_written_ += total_bytes_written;
|
| - *total_bytes_read_ += total_bytes_read;
|
| - *data_read_ += data_read;
|
| - } else { // We're done writing all data. Start reading the data.
|
| - TestInt64CompletionCallback callback64;
|
| - EXPECT_EQ(ERR_IO_PENDING,
|
| - stream_->Seek(base::File::FROM_BEGIN, 0,
|
| - callback64.callback()));
|
| - {
|
| - base::MessageLoop::ScopedNestableTaskAllower allow(
|
| - base::MessageLoop::current());
|
| - EXPECT_LE(0, callback64.WaitForResult());
|
| - }
|
| - }
|
| -
|
| - result_ = *total_bytes_written_;
|
| - have_result_ = true;
|
| - if (waiting_for_result_)
|
| - base::MessageLoop::current()->Quit();
|
| - }
|
| -
|
| - int result_;
|
| - bool have_result_;
|
| - bool waiting_for_result_;
|
| - FileStream* stream_;
|
| - int* total_bytes_written_;
|
| - int* total_bytes_read_;
|
| - std::string* data_read_;
|
| - const CompletionCallback callback_;
|
| - scoped_refptr<IOBufferWithSize> test_data_;
|
| - scoped_refptr<DrainableIOBuffer> drainable_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(TestWriteReadCompletionCallback);
|
| -};
|
| -
|
| -TEST_F(FileStreamTest, WriteRead) {
|
| - int64 file_size;
|
| - EXPECT_TRUE(base::GetFileSize(temp_file_path(), &file_size));
|
| -
|
| - scoped_ptr<FileStream> stream(
|
| - new FileStream(base::MessageLoopProxy::current()));
|
| - int flags = base::File::FLAG_OPEN | base::File::FLAG_READ |
|
| - base::File::FLAG_WRITE | base::File::FLAG_ASYNC;
|
| - TestCompletionCallback open_callback;
|
| - int rv = stream->Open(temp_file_path(), flags, open_callback.callback());
|
| - EXPECT_EQ(ERR_IO_PENDING, rv);
|
| - EXPECT_EQ(OK, open_callback.WaitForResult());
|
| -
|
| - TestInt64CompletionCallback callback64;
|
| - EXPECT_EQ(ERR_IO_PENDING,
|
| - stream->Seek(base::File::FROM_END, 0, callback64.callback()));
|
| - EXPECT_EQ(file_size, callback64.WaitForResult());
|
| -
|
| - int total_bytes_written = 0;
|
| - int total_bytes_read = 0;
|
| - std::string data_read;
|
| - TestWriteReadCompletionCallback callback(stream.get(), &total_bytes_written,
|
| - &total_bytes_read, &data_read);
|
| -
|
| - scoped_refptr<IOBufferWithSize> buf = CreateTestDataBuffer();
|
| - rv = stream->Write(buf.get(), buf->size(), callback.callback());
|
| - if (rv == ERR_IO_PENDING)
|
| - rv = callback.WaitForResult();
|
| - EXPECT_LT(0, rv);
|
| - EXPECT_EQ(kTestDataSize, total_bytes_written);
|
| -
|
| - callback.ValidateWrittenData();
|
| -
|
| - stream.reset();
|
| -
|
| - EXPECT_TRUE(base::GetFileSize(temp_file_path(), &file_size));
|
| - EXPECT_EQ(kTestDataSize * 2, file_size);
|
| -
|
| - EXPECT_EQ(kTestDataSize * 2, total_bytes_read);
|
| - const std::string kExpectedFileData =
|
| - std::string(kTestData) + std::string(kTestData);
|
| - EXPECT_EQ(kExpectedFileData, data_read);
|
| -}
|
| -
|
| -class TestWriteCloseCompletionCallback {
|
| - public:
|
| - TestWriteCloseCompletionCallback(FileStream* stream, int* total_bytes_written)
|
| - : result_(0),
|
| - have_result_(false),
|
| - waiting_for_result_(false),
|
| - stream_(stream),
|
| - total_bytes_written_(total_bytes_written),
|
| - callback_(base::Bind(&TestWriteCloseCompletionCallback::OnComplete,
|
| - base::Unretained(this))),
|
| - test_data_(CreateTestDataBuffer()),
|
| - drainable_(new DrainableIOBuffer(test_data_.get(), kTestDataSize)) {}
|
| -
|
| - int WaitForResult() {
|
| - DCHECK(!waiting_for_result_);
|
| - while (!have_result_) {
|
| - waiting_for_result_ = true;
|
| - base::RunLoop().Run();
|
| - waiting_for_result_ = false;
|
| - }
|
| - have_result_ = false; // auto-reset for next callback
|
| - return result_;
|
| - }
|
| -
|
| - const CompletionCallback& callback() const { return callback_; }
|
| -
|
| - private:
|
| - void OnComplete(int result) {
|
| - DCHECK_LT(0, result);
|
| - *total_bytes_written_ += result;
|
| -
|
| - int rv;
|
| -
|
| - if (*total_bytes_written_ != kTestDataSize) {
|
| - // Recurse to finish writing all data.
|
| - int total_bytes_written = 0;
|
| - TestWriteCloseCompletionCallback callback(stream_, &total_bytes_written);
|
| - rv = stream_->Write(
|
| - drainable_.get(), drainable_->BytesRemaining(), callback.callback());
|
| - DCHECK_EQ(ERR_IO_PENDING, rv);
|
| - rv = callback.WaitForResult();
|
| - drainable_->DidConsume(total_bytes_written);
|
| - *total_bytes_written_ += total_bytes_written;
|
| - }
|
| -
|
| - result_ = *total_bytes_written_;
|
| - have_result_ = true;
|
| - if (waiting_for_result_)
|
| - base::MessageLoop::current()->Quit();
|
| - }
|
| -
|
| - int result_;
|
| - bool have_result_;
|
| - bool waiting_for_result_;
|
| - FileStream* stream_;
|
| - int* total_bytes_written_;
|
| - const CompletionCallback callback_;
|
| - scoped_refptr<IOBufferWithSize> test_data_;
|
| - scoped_refptr<DrainableIOBuffer> drainable_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(TestWriteCloseCompletionCallback);
|
| -};
|
| -
|
| -TEST_F(FileStreamTest, WriteClose) {
|
| - int64 file_size;
|
| - EXPECT_TRUE(base::GetFileSize(temp_file_path(), &file_size));
|
| -
|
| - scoped_ptr<FileStream> stream(
|
| - new FileStream(base::MessageLoopProxy::current()));
|
| - int flags = base::File::FLAG_OPEN | base::File::FLAG_READ |
|
| - base::File::FLAG_WRITE | base::File::FLAG_ASYNC;
|
| - TestCompletionCallback open_callback;
|
| - int rv = stream->Open(temp_file_path(), flags, open_callback.callback());
|
| - EXPECT_EQ(ERR_IO_PENDING, rv);
|
| - EXPECT_EQ(OK, open_callback.WaitForResult());
|
| -
|
| - TestInt64CompletionCallback callback64;
|
| - EXPECT_EQ(ERR_IO_PENDING,
|
| - stream->Seek(base::File::FROM_END, 0, callback64.callback()));
|
| - EXPECT_EQ(file_size, callback64.WaitForResult());
|
| -
|
| - int total_bytes_written = 0;
|
| - TestWriteCloseCompletionCallback callback(stream.get(), &total_bytes_written);
|
| -
|
| - scoped_refptr<IOBufferWithSize> buf = CreateTestDataBuffer();
|
| - rv = stream->Write(buf.get(), buf->size(), callback.callback());
|
| - if (rv == ERR_IO_PENDING)
|
| - total_bytes_written = callback.WaitForResult();
|
| - EXPECT_LT(0, total_bytes_written);
|
| - EXPECT_EQ(kTestDataSize, total_bytes_written);
|
| -
|
| - stream.reset();
|
| -
|
| - EXPECT_TRUE(base::GetFileSize(temp_file_path(), &file_size));
|
| - EXPECT_EQ(kTestDataSize * 2, file_size);
|
| -}
|
| -
|
| -TEST_F(FileStreamTest, OpenAndDelete) {
|
| - scoped_refptr<base::SequencedWorkerPool> pool(
|
| - new base::SequencedWorkerPool(1, "StreamTest"));
|
| -
|
| - bool prev = base::ThreadRestrictions::SetIOAllowed(false);
|
| - scoped_ptr<FileStream> stream(new FileStream(pool.get()));
|
| - int flags = base::File::FLAG_OPEN | base::File::FLAG_WRITE |
|
| - base::File::FLAG_ASYNC;
|
| - TestCompletionCallback open_callback;
|
| - int rv = stream->Open(temp_file_path(), flags, open_callback.callback());
|
| - EXPECT_EQ(ERR_IO_PENDING, rv);
|
| -
|
| - // Delete the stream without waiting for the open operation to be
|
| - // complete. Should be safe.
|
| - stream.reset();
|
| -
|
| - // Force an operation through the pool.
|
| - scoped_ptr<FileStream> stream2(new FileStream(pool.get()));
|
| - TestCompletionCallback open_callback2;
|
| - rv = stream2->Open(temp_file_path(), flags, open_callback2.callback());
|
| - EXPECT_EQ(OK, open_callback2.GetResult(rv));
|
| - stream2.reset();
|
| -
|
| - pool->Shutdown();
|
| -
|
| - // open_callback won't be called.
|
| - base::RunLoop().RunUntilIdle();
|
| - EXPECT_FALSE(open_callback.have_result());
|
| - base::ThreadRestrictions::SetIOAllowed(prev);
|
| -}
|
| -
|
| -// Verify that Write() errors are mapped correctly.
|
| -TEST_F(FileStreamTest, WriteError) {
|
| - // Try opening file as read-only and then writing to it using FileStream.
|
| - uint32 flags = base::File::FLAG_OPEN | base::File::FLAG_READ |
|
| - base::File::FLAG_ASYNC;
|
| -
|
| - base::File file(temp_file_path(), flags);
|
| - ASSERT_TRUE(file.IsValid());
|
| -
|
| - scoped_ptr<FileStream> stream(
|
| - new FileStream(file.Pass(), base::MessageLoopProxy::current()));
|
| -
|
| - scoped_refptr<IOBuffer> buf = new IOBuffer(1);
|
| - buf->data()[0] = 0;
|
| -
|
| - TestCompletionCallback callback;
|
| - int rv = stream->Write(buf.get(), 1, callback.callback());
|
| - if (rv == ERR_IO_PENDING)
|
| - rv = callback.WaitForResult();
|
| - EXPECT_LT(rv, 0);
|
| -
|
| - stream.reset();
|
| - base::RunLoop().RunUntilIdle();
|
| -}
|
| -
|
| -// Verify that Read() errors are mapped correctly.
|
| -TEST_F(FileStreamTest, ReadError) {
|
| - // Try opening file for write and then reading from it using FileStream.
|
| - uint32 flags = base::File::FLAG_OPEN | base::File::FLAG_WRITE |
|
| - base::File::FLAG_ASYNC;
|
| -
|
| - base::File file(temp_file_path(), flags);
|
| - ASSERT_TRUE(file.IsValid());
|
| -
|
| - scoped_ptr<FileStream> stream(
|
| - new FileStream(file.Pass(), base::MessageLoopProxy::current()));
|
| -
|
| - scoped_refptr<IOBuffer> buf = new IOBuffer(1);
|
| - TestCompletionCallback callback;
|
| - int rv = stream->Read(buf.get(), 1, callback.callback());
|
| - if (rv == ERR_IO_PENDING)
|
| - rv = callback.WaitForResult();
|
| - EXPECT_LT(rv, 0);
|
| -
|
| - stream.reset();
|
| - base::RunLoop().RunUntilIdle();
|
| -}
|
| -
|
| -#if defined(OS_ANDROID)
|
| -TEST_F(FileStreamTest, ContentUriRead) {
|
| - base::FilePath test_dir;
|
| - PathService::Get(base::DIR_SOURCE_ROOT, &test_dir);
|
| - test_dir = test_dir.AppendASCII("net");
|
| - test_dir = test_dir.AppendASCII("data");
|
| - test_dir = test_dir.AppendASCII("file_stream_unittest");
|
| - ASSERT_TRUE(base::PathExists(test_dir));
|
| - base::FilePath image_file = test_dir.Append(FILE_PATH_LITERAL("red.png"));
|
| -
|
| - // Insert the image into MediaStore. MediaStore will do some conversions, and
|
| - // return the content URI.
|
| - base::FilePath path = base::InsertImageIntoMediaStore(image_file);
|
| - EXPECT_TRUE(path.IsContentUri());
|
| - EXPECT_TRUE(base::PathExists(path));
|
| - int64 file_size;
|
| - EXPECT_TRUE(base::GetFileSize(path, &file_size));
|
| - EXPECT_LT(0, file_size);
|
| -
|
| - FileStream stream(base::MessageLoopProxy::current());
|
| - int flags = base::File::FLAG_OPEN | base::File::FLAG_READ |
|
| - base::File::FLAG_ASYNC;
|
| - TestCompletionCallback callback;
|
| - int rv = stream.Open(path, flags, callback.callback());
|
| - EXPECT_EQ(ERR_IO_PENDING, rv);
|
| - EXPECT_EQ(OK, callback.WaitForResult());
|
| -
|
| - int total_bytes_read = 0;
|
| -
|
| - std::string data_read;
|
| - for (;;) {
|
| - scoped_refptr<IOBufferWithSize> buf = new IOBufferWithSize(4);
|
| - rv = stream.Read(buf.get(), buf->size(), callback.callback());
|
| - if (rv == ERR_IO_PENDING)
|
| - rv = callback.WaitForResult();
|
| - EXPECT_LE(0, rv);
|
| - if (rv <= 0)
|
| - break;
|
| - total_bytes_read += rv;
|
| - data_read.append(buf->data(), rv);
|
| - }
|
| - EXPECT_EQ(file_size, total_bytes_read);
|
| -}
|
| -#endif
|
| -
|
| -} // namespace
|
| -
|
| -} // namespace net
|
|
|