Chromium Code Reviews| Index: net/base/file_stream_unittest.cc |
| diff --git a/net/base/file_stream_unittest.cc b/net/base/file_stream_unittest.cc |
| index 292b0d207cfff37320e34e72fc53e25725302437..f15332cd48fc738733e4ec5492f0f69d180da24e 100644 |
| --- a/net/base/file_stream_unittest.cc |
| +++ b/net/base/file_stream_unittest.cc |
| @@ -12,6 +12,7 @@ |
| #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" |
| @@ -68,7 +69,7 @@ class FileStreamTest : public PlatformTest { |
| namespace { |
| -TEST_F(FileStreamTest, AsyncOpenExplicitClose) { |
| +TEST_F(FileStreamTest, OpenExplicitClose) { |
| TestCompletionCallback callback; |
| FileStream stream(base::MessageLoopProxy::current()); |
| int flags = base::File::FLAG_OPEN | |
| @@ -85,7 +86,7 @@ TEST_F(FileStreamTest, AsyncOpenExplicitClose) { |
| EXPECT_FALSE(stream.GetFileForTesting().IsValid()); |
| } |
| -TEST_F(FileStreamTest, AsyncOpenExplicitCloseOrphaned) { |
| +TEST_F(FileStreamTest, OpenExplicitCloseOrphaned) { |
| TestCompletionCallback callback; |
| scoped_ptr<FileStream> stream(new FileStream( |
| base::MessageLoopProxy::current())); |
| @@ -120,7 +121,8 @@ TEST_F(FileStreamTest, UseFileHandle) { |
| scoped_ptr<FileStream> read_stream( |
| new FileStream(file.Pass(), base::MessageLoopProxy::current())); |
| ASSERT_EQ(ERR_IO_PENDING, |
| - read_stream->Seek(FROM_BEGIN, 0, callback64.callback())); |
| + 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 = |
| @@ -139,7 +141,8 @@ TEST_F(FileStreamTest, UseFileHandle) { |
| scoped_ptr<FileStream> write_stream( |
| new FileStream(file.Pass(), base::MessageLoopProxy::current())); |
| ASSERT_EQ(ERR_IO_PENDING, |
| - write_stream->Seek(FROM_BEGIN, 0, callback64.callback())); |
| + 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, |
| @@ -164,7 +167,7 @@ TEST_F(FileStreamTest, UseClosedStream) { |
| EXPECT_FALSE(stream.IsOpen()); |
| // Try seeking... |
| - rv = stream.Seek(FROM_BEGIN, 5, callback64.callback()); |
| + rv = stream.Seek(base::File::FROM_BEGIN, 5, callback64.callback()); |
| EXPECT_EQ(ERR_UNEXPECTED, callback64.GetResult(rv)); |
| // Try reading... |
| @@ -173,7 +176,7 @@ TEST_F(FileStreamTest, UseClosedStream) { |
| EXPECT_EQ(ERR_UNEXPECTED, callback.GetResult(rv)); |
| } |
| -TEST_F(FileStreamTest, AsyncRead) { |
| +TEST_F(FileStreamTest, Read) { |
| int64 file_size; |
| EXPECT_TRUE(base::GetFileSize(temp_file_path(), &file_size)); |
| @@ -182,8 +185,7 @@ TEST_F(FileStreamTest, AsyncRead) { |
| 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()); |
| + EXPECT_EQ(OK, callback.GetResult(rv)); |
| int total_bytes_read = 0; |
| @@ -191,8 +193,7 @@ TEST_F(FileStreamTest, AsyncRead) { |
| 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(); |
| + rv = callback.GetResult(rv); |
| EXPECT_LE(0, rv); |
| if (rv <= 0) |
| break; |
| @@ -203,7 +204,63 @@ TEST_F(FileStreamTest, AsyncRead) { |
| EXPECT_EQ(kTestData, data_read); |
| } |
| -TEST_F(FileStreamTest, AsyncRead_EarlyDelete) { |
| +TEST_F(FileStreamTest, ReadNonBlocking) { |
| + TestCompletionCallback callback; |
| + |
| +#if defined(OS_WIN) |
| + 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(OK, callback.GetResult(rv)); |
| +#elif defined(OS_POSIX) |
| + int fds[2], rv; |
|
hashimoto
2014/06/13 06:10:42
Oh, I wasn't aware that libevent does nothing for
rvargas (doing something else)
2014/06/13 19:58:24
Expanded the comment.
|
| + ASSERT_EQ(0, pipe(fds)); |
| + base::File read_end(fds[0]); |
| + base::File write_end(fds[1]); |
| + ASSERT_TRUE(read_end.IsValid()); |
| + ASSERT_EQ(kTestDataSize, |
| + write_end.WriteAtCurrentPos(kTestData, kTestDataSize)); |
| + write_end.Close(); |
| + |
| + FileStream stream(read_end.Pass(), base::MessageLoopProxy::current()); |
| +#endif // OS_POSIX |
| + |
| + int total_bytes_read = 0; |
| + std::string data_read; |
| + for (;;) { |
| + scoped_refptr<IOBufferWithSize> buf = new IOBufferWithSize(4); |
| + rv = stream.ReadNonBlocking(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(kTestDataSize, total_bytes_read); |
| + EXPECT_EQ(kTestData, data_read); |
| +} |
| + |
| +// Tests for proper cleanup when waiting to issue a non-blocking operation. |
| +TEST_F(FileStreamTest, ReadNonBlocking_Stuck) { |
| + { |
| + 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)); |
| + |
| + scoped_refptr<IOBufferWithSize> buf = new IOBufferWithSize(4); |
| + // This will get stuck on POSIX. |
| + stream.ReadNonBlocking(buf.get(), buf->size(), callback.callback()); |
| + } |
| + // The stream is gone. Allow proper cleanup. |
| + base::RunLoop().RunUntilIdle(); |
| +} |
| + |
| +TEST_F(FileStreamTest, Read_EarlyDelete) { |
| int64 file_size; |
| EXPECT_TRUE(base::GetFileSize(temp_file_path(), &file_size)); |
| @@ -229,7 +286,7 @@ TEST_F(FileStreamTest, AsyncRead_EarlyDelete) { |
| } |
| } |
| -TEST_F(FileStreamTest, AsyncRead_FromOffset) { |
| +TEST_F(FileStreamTest, Read_FromOffset) { |
| int64 file_size; |
| EXPECT_TRUE(base::GetFileSize(temp_file_path(), &file_size)); |
| @@ -243,7 +300,7 @@ TEST_F(FileStreamTest, AsyncRead_FromOffset) { |
| TestInt64CompletionCallback callback64; |
| const int64 kOffset = 3; |
| - rv = stream.Seek(FROM_BEGIN, kOffset, callback64.callback()); |
| + 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); |
| @@ -266,7 +323,7 @@ TEST_F(FileStreamTest, AsyncRead_FromOffset) { |
| EXPECT_EQ(kTestData + kOffset, data_read); |
| } |
| -TEST_F(FileStreamTest, AsyncSeekAround) { |
| +TEST_F(FileStreamTest, SeekAround) { |
| FileStream stream(base::MessageLoopProxy::current()); |
| int flags = base::File::FLAG_OPEN | base::File::FLAG_ASYNC | |
| base::File::FLAG_READ; |
| @@ -278,63 +335,90 @@ TEST_F(FileStreamTest, AsyncSeekAround) { |
| TestInt64CompletionCallback callback64; |
| const int64 kOffset = 3; |
| - rv = stream.Seek(FROM_BEGIN, kOffset, callback64.callback()); |
| + 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(FROM_CURRENT, kOffset, callback64.callback()); |
| + 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(FROM_CURRENT, -kOffset, callback64.callback()); |
| + 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(FROM_END, -kTestDataLen, callback64.callback()); |
| + 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, AsyncWrite) { |
| +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(ERR_IO_PENDING, rv); |
| - EXPECT_EQ(OK, callback.WaitForResult()); |
| + EXPECT_EQ(OK, callback.GetResult(rv)); |
| int64 file_size; |
| EXPECT_TRUE(base::GetFileSize(temp_file_path(), &file_size)); |
| EXPECT_EQ(0, file_size); |
| - int total_bytes_written = 0; |
| + scoped_refptr<IOBuffer> buf = CreateTestDataBuffer(); |
| + rv = stream.Write(buf.get(), kTestDataSize, callback.callback()); |
| + rv = callback.GetResult(rv); |
| + EXPECT_EQ(kTestDataSize, rv); |
| - 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, total_bytes_written); |
| + 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, WriteNonBlocking) { |
| + TestCompletionCallback callback; |
| + |
| +#if defined(OS_WIN) |
| + FileStream stream(base::MessageLoopProxy::current()); |
| + int flags = base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE | |
| + base::File::FLAG_ASYNC; |
| + int rv = stream.Open(temp_file_path(), flags, callback.callback()); |
| + EXPECT_EQ(OK, callback.GetResult(rv)); |
| +#elif defined(OS_POSIX) |
| + int fds[2], rv; |
| + ASSERT_EQ(0, pipe(fds)); |
| + base::File read_end(fds[0]); |
| + base::File write_end(fds[1]); |
| + ASSERT_TRUE(read_end.IsValid()); |
| + FileStream stream(write_end.Pass(), base::MessageLoopProxy::current()); |
| +#endif // OS_POSIX |
| + |
| + scoped_refptr<IOBuffer> buf = CreateTestDataBuffer(); |
| + rv = stream.WriteNonBlocking(buf.get(), kTestDataSize, callback.callback()); |
| + rv = callback.GetResult(rv); |
| + EXPECT_EQ(kTestDataSize, rv); |
| + std::string data_read; |
| + |
| +#if defined(OS_WIN) |
| + EXPECT_TRUE(base::ReadFileToString(temp_file_path(), &data_read)); |
| +#elif defined(OS_POSIX) |
| + ASSERT_EQ(kTestDataSize, |
| + read_end.ReadAtCurrentPos(WriteInto(&data_read, kTestDataSize + 1), |
| + kTestDataSize)); |
| +#endif // OS_POSIX |
| + |
| + EXPECT_EQ(kTestData, data_read); |
| } |
| -TEST_F(FileStreamTest, AsyncWrite_EarlyDelete) { |
| +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 | |
| @@ -362,7 +446,7 @@ TEST_F(FileStreamTest, AsyncWrite_EarlyDelete) { |
| } |
| } |
| -TEST_F(FileStreamTest, AsyncWrite_FromOffset) { |
| +TEST_F(FileStreamTest, Write_FromOffset) { |
| int64 file_size; |
| EXPECT_TRUE(base::GetFileSize(temp_file_path(), &file_size)); |
| @@ -376,7 +460,7 @@ TEST_F(FileStreamTest, AsyncWrite_FromOffset) { |
| TestInt64CompletionCallback callback64; |
| const int64 kOffset = 0; |
| - rv = stream.Seek(FROM_END, kOffset, callback64.callback()); |
| + 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); |
| @@ -401,7 +485,7 @@ TEST_F(FileStreamTest, AsyncWrite_FromOffset) { |
| EXPECT_EQ(file_size, kTestDataSize * 2); |
| } |
| -TEST_F(FileStreamTest, BasicAsyncReadWrite) { |
| +TEST_F(FileStreamTest, BasicReadWrite) { |
| int64 file_size; |
| EXPECT_TRUE(base::GetFileSize(temp_file_path(), &file_size)); |
| @@ -454,7 +538,7 @@ TEST_F(FileStreamTest, BasicAsyncReadWrite) { |
| EXPECT_EQ(kTestDataSize * 2, file_size); |
| } |
| -TEST_F(FileStreamTest, BasicAsyncWriteRead) { |
| +TEST_F(FileStreamTest, BasicWriteRead) { |
| int64 file_size; |
| EXPECT_TRUE(base::GetFileSize(temp_file_path(), &file_size)); |
| @@ -468,7 +552,7 @@ TEST_F(FileStreamTest, BasicAsyncWriteRead) { |
| EXPECT_EQ(OK, callback.WaitForResult()); |
| TestInt64CompletionCallback callback64; |
| - rv = stream->Seek(FROM_END, 0, callback64.callback()); |
| + 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); |
| @@ -492,7 +576,7 @@ TEST_F(FileStreamTest, BasicAsyncWriteRead) { |
| EXPECT_EQ(kTestDataSize, total_bytes_written); |
| - rv = stream->Seek(FROM_BEGIN, 0, callback64.callback()); |
| + rv = stream->Seek(base::File::FROM_BEGIN, 0, callback64.callback()); |
| ASSERT_EQ(ERR_IO_PENDING, rv); |
| offset = callback64.WaitForResult(); |
| EXPECT_EQ(0, offset); |
| @@ -577,7 +661,8 @@ class TestWriteReadCompletionCallback { |
| } else { // We're done writing all data. Start reading the data. |
| TestInt64CompletionCallback callback64; |
| EXPECT_EQ(ERR_IO_PENDING, |
| - stream_->Seek(FROM_BEGIN, 0, callback64.callback())); |
| + stream_->Seek(base::File::FROM_BEGIN, 0, |
| + callback64.callback())); |
| { |
| base::MessageLoop::ScopedNestableTaskAllower allow( |
| base::MessageLoop::current()); |
| @@ -621,7 +706,7 @@ class TestWriteReadCompletionCallback { |
| DISALLOW_COPY_AND_ASSIGN(TestWriteReadCompletionCallback); |
| }; |
| -TEST_F(FileStreamTest, AsyncWriteRead) { |
| +TEST_F(FileStreamTest, WriteRead) { |
| int64 file_size; |
| EXPECT_TRUE(base::GetFileSize(temp_file_path(), &file_size)); |
| @@ -635,7 +720,8 @@ TEST_F(FileStreamTest, AsyncWriteRead) { |
| EXPECT_EQ(OK, open_callback.WaitForResult()); |
| TestInt64CompletionCallback callback64; |
| - EXPECT_EQ(ERR_IO_PENDING, stream->Seek(FROM_END, 0, callback64.callback())); |
| + 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; |
| @@ -725,7 +811,7 @@ class TestWriteCloseCompletionCallback { |
| DISALLOW_COPY_AND_ASSIGN(TestWriteCloseCompletionCallback); |
| }; |
| -TEST_F(FileStreamTest, AsyncWriteClose) { |
| +TEST_F(FileStreamTest, WriteClose) { |
| int64 file_size; |
| EXPECT_TRUE(base::GetFileSize(temp_file_path(), &file_size)); |
| @@ -739,7 +825,8 @@ TEST_F(FileStreamTest, AsyncWriteClose) { |
| EXPECT_EQ(OK, open_callback.WaitForResult()); |
| TestInt64CompletionCallback callback64; |
| - EXPECT_EQ(ERR_IO_PENDING, stream->Seek(FROM_END, 0, callback64.callback())); |
| + 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; |
| @@ -758,7 +845,7 @@ TEST_F(FileStreamTest, AsyncWriteClose) { |
| EXPECT_EQ(kTestDataSize * 2, file_size); |
| } |
| -TEST_F(FileStreamTest, AsyncOpenAndDelete) { |
| +TEST_F(FileStreamTest, OpenAndDelete) { |
| scoped_refptr<base::SequencedWorkerPool> pool( |
| new base::SequencedWorkerPool(1, "StreamTest")); |
| @@ -790,7 +877,7 @@ TEST_F(FileStreamTest, AsyncOpenAndDelete) { |
| } |
| // Verify that async Write() errors are mapped correctly. |
|
hashimoto
2014/06/13 06:10:42
nit: "async" still mentioned here.
rvargas (doing something else)
2014/06/13 19:58:24
Done.
|
| -TEST_F(FileStreamTest, AsyncWriteError) { |
| +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; |
| @@ -815,7 +902,7 @@ TEST_F(FileStreamTest, AsyncWriteError) { |
| } |
| // Verify that async Read() errors are mapped correctly. |
|
hashimoto
2014/06/13 06:10:42
ditto.
rvargas (doing something else)
2014/06/13 19:58:24
Done.
|
| -TEST_F(FileStreamTest, AsyncReadError) { |
| +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; |
| @@ -838,7 +925,7 @@ TEST_F(FileStreamTest, AsyncReadError) { |
| } |
| #if defined(OS_ANDROID) |
| -TEST_F(FileStreamTest, ContentUriAsyncRead) { |
| +TEST_F(FileStreamTest, ContentUriRead) { |
| base::FilePath test_dir; |
| PathService::Get(base::DIR_SOURCE_ROOT, &test_dir); |
| test_dir = test_dir.AppendASCII("net"); |