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.
5 #include "webkit/fileapi/local_file_stream_writer.h"
9 #include "base/callback.h"
10 #include "base/file_util.h"
11 #include "base/files/scoped_temp_dir.h"
12 #include "base/logging.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "base/message_loop.h"
15 #include "net/base/io_buffer.h"
16 #include "net/base/test_completion_callback.h"
17 #include "testing/gtest/include/gtest/gtest.h"
21 using fileapi::LocalFileStreamWriter
;
23 class LocalFileStreamWriterTest
: public testing::Test
{
25 LocalFileStreamWriterTest() : message_loop_(MessageLoop::TYPE_IO
) {}
27 virtual void SetUp() OVERRIDE
{
28 ASSERT_TRUE(temp_dir_
.CreateUniqueTempDir());
32 base::FilePath
Path(const std::string
& name
) {
33 return temp_dir_
.path().AppendASCII(name
);
36 int WriteStringToWriter(LocalFileStreamWriter
* writer
,
37 const std::string
& data
) {
38 scoped_refptr
<net::StringIOBuffer
> buffer(new net::StringIOBuffer(data
));
39 scoped_refptr
<net::DrainableIOBuffer
> drainable(
40 new net::DrainableIOBuffer(buffer
, buffer
->size()));
42 while (drainable
->BytesRemaining() > 0) {
43 net::TestCompletionCallback callback
;
44 int result
= writer
->Write(drainable
, drainable
->BytesRemaining(),
46 if (result
== net::ERR_IO_PENDING
)
47 result
= callback
.WaitForResult();
50 drainable
->DidConsume(result
);
55 std::string
GetFileContent(const base::FilePath
& path
) {
57 file_util::ReadFileToString(path
, &content
);
61 base::FilePath
CreateFileWithContent(const std::string
& name
,
62 const std::string
& data
) {
63 base::FilePath path
= Path(name
);
64 file_util::WriteFile(path
, data
.c_str(), data
.size());
69 MessageLoop message_loop_
;
70 base::ScopedTempDir temp_dir_
;
73 void NeverCalled(int unused
) {
79 TEST_F(LocalFileStreamWriterTest
, Write
) {
80 base::FilePath path
= CreateFileWithContent("file_a", std::string());
81 scoped_ptr
<LocalFileStreamWriter
> writer(new LocalFileStreamWriter(path
, 0));
82 EXPECT_EQ(net::OK
, WriteStringToWriter(writer
.get(), "foo"));
83 EXPECT_EQ(net::OK
, WriteStringToWriter(writer
.get(), "bar"));
85 MessageLoop::current()->RunUntilIdle();
86 EXPECT_TRUE(file_util::PathExists(path
));
87 EXPECT_EQ("foobar", GetFileContent(path
));
90 TEST_F(LocalFileStreamWriterTest
, WriteMiddle
) {
91 base::FilePath path
= CreateFileWithContent("file_a", "foobar");
92 scoped_ptr
<LocalFileStreamWriter
> writer(new LocalFileStreamWriter(path
, 2));
93 EXPECT_EQ(net::OK
, WriteStringToWriter(writer
.get(), "xxx"));
95 MessageLoop::current()->RunUntilIdle();
96 EXPECT_TRUE(file_util::PathExists(path
));
97 EXPECT_EQ("foxxxr", GetFileContent(path
));
100 TEST_F(LocalFileStreamWriterTest
, WriteEnd
) {
101 base::FilePath path
= CreateFileWithContent("file_a", "foobar");
102 scoped_ptr
<LocalFileStreamWriter
> writer(new LocalFileStreamWriter(path
, 6));
103 EXPECT_EQ(net::OK
, WriteStringToWriter(writer
.get(), "xxx"));
105 MessageLoop::current()->RunUntilIdle();
106 EXPECT_TRUE(file_util::PathExists(path
));
107 EXPECT_EQ("foobarxxx", GetFileContent(path
));
110 TEST_F(LocalFileStreamWriterTest
, WriteFailForNonexistingFile
) {
111 base::FilePath path
= Path("file_a");
112 ASSERT_FALSE(file_util::PathExists(path
));
113 scoped_ptr
<LocalFileStreamWriter
> writer(new LocalFileStreamWriter(path
, 0));
114 EXPECT_EQ(net::ERR_FILE_NOT_FOUND
, WriteStringToWriter(writer
.get(), "foo"));
116 MessageLoop::current()->RunUntilIdle();
117 EXPECT_FALSE(file_util::PathExists(path
));
120 TEST_F(LocalFileStreamWriterTest
, CancelBeforeOperation
) {
121 base::FilePath path
= Path("file_a");
122 scoped_ptr
<LocalFileStreamWriter
> writer(new LocalFileStreamWriter(path
, 0));
123 // Cancel immediately fails when there's no in-flight operation.
124 int cancel_result
= writer
->Cancel(base::Bind(&NeverCalled
));
125 EXPECT_EQ(net::ERR_UNEXPECTED
, cancel_result
);
128 TEST_F(LocalFileStreamWriterTest
, CancelAfterFinishedOperation
) {
129 base::FilePath path
= CreateFileWithContent("file_a", std::string());
130 scoped_ptr
<LocalFileStreamWriter
> writer(new LocalFileStreamWriter(path
, 0));
131 EXPECT_EQ(net::OK
, WriteStringToWriter(writer
.get(), "foo"));
133 // Cancel immediately fails when there's no in-flight operation.
134 int cancel_result
= writer
->Cancel(base::Bind(&NeverCalled
));
135 EXPECT_EQ(net::ERR_UNEXPECTED
, cancel_result
);
138 MessageLoop::current()->RunUntilIdle();
139 // Write operation is already completed.
140 EXPECT_TRUE(file_util::PathExists(path
));
141 EXPECT_EQ("foo", GetFileContent(path
));
144 TEST_F(LocalFileStreamWriterTest
, CancelWrite
) {
145 base::FilePath path
= CreateFileWithContent("file_a", "foobar");
146 scoped_ptr
<LocalFileStreamWriter
> writer(new LocalFileStreamWriter(path
, 0));
148 scoped_refptr
<net::StringIOBuffer
> buffer(new net::StringIOBuffer("xxx"));
149 int result
= writer
->Write(buffer
, buffer
->size(), base::Bind(&NeverCalled
));
150 ASSERT_EQ(net::ERR_IO_PENDING
, result
);
152 net::TestCompletionCallback callback
;
153 writer
->Cancel(callback
.callback());
154 int cancel_result
= callback
.WaitForResult();
155 EXPECT_EQ(net::OK
, cancel_result
);