1 // Copyright 2013 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/browser/fileapi/upload_file_system_file_element_reader.h"
7 #include "base/files/scoped_temp_dir.h"
8 #include "base/message_loop/message_loop.h"
9 #include "base/run_loop.h"
10 #include "content/public/test/test_file_system_context.h"
11 #include "net/base/io_buffer.h"
12 #include "net/base/test_completion_callback.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14 #include "webkit/browser/fileapi/async_file_test_helper.h"
15 #include "webkit/browser/fileapi/file_system_backend.h"
16 #include "webkit/browser/fileapi/file_system_context.h"
17 #include "webkit/browser/fileapi/file_system_operation_context.h"
18 #include "webkit/browser/fileapi/file_system_url.h"
24 const char kFileSystemURLOrigin
[] = "http://remote";
25 const fileapi::FileSystemType kFileSystemType
=
26 fileapi::kFileSystemTypeTemporary
;
30 class UploadFileSystemFileElementReaderTest
: public testing::Test
{
32 UploadFileSystemFileElementReaderTest() {}
34 virtual void SetUp() OVERRIDE
{
35 ASSERT_TRUE(temp_dir_
.CreateUniqueTempDir());
37 file_system_context_
= fileapi::CreateFileSystemContextForTesting(
38 NULL
, temp_dir_
.path());
40 file_system_context_
->OpenFileSystem(
41 GURL(kFileSystemURLOrigin
),
43 OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT
,
44 base::Bind(&UploadFileSystemFileElementReaderTest::OnOpenFileSystem
,
45 base::Unretained(this)));
46 base::RunLoop().RunUntilIdle();
47 ASSERT_TRUE(file_system_root_url_
.is_valid());
49 // Prepare a file on file system.
50 const char kTestData
[] = "abcdefghijklmnop0123456789";
51 file_data_
.assign(kTestData
, kTestData
+ arraysize(kTestData
) - 1);
52 const char kFilename
[] = "File.dat";
53 file_url_
= GetFileSystemURL(kFilename
);
54 WriteFileSystemFile(kFilename
, &file_data_
[0], file_data_
.size(),
55 &file_modification_time_
);
57 // Create and initialize a reader.
59 new UploadFileSystemFileElementReader(file_system_context_
.get(),
63 file_modification_time_
));
64 net::TestCompletionCallback callback
;
65 ASSERT_EQ(net::ERR_IO_PENDING
, reader_
->Init(callback
.callback()));
66 EXPECT_EQ(net::OK
, callback
.WaitForResult());
67 EXPECT_EQ(file_data_
.size(), reader_
->GetContentLength());
68 EXPECT_EQ(file_data_
.size(), reader_
->BytesRemaining());
69 EXPECT_FALSE(reader_
->IsInMemory());
72 virtual void TearDown() OVERRIDE
{
74 base::RunLoop().RunUntilIdle();
78 GURL
GetFileSystemURL(const std::string
& filename
) {
79 return GURL(file_system_root_url_
.spec() + filename
);
82 void WriteFileSystemFile(const std::string
& filename
,
85 base::Time
* modification_time
) {
86 fileapi::FileSystemURL url
=
87 file_system_context_
->CreateCrackedFileSystemURL(
88 GURL(kFileSystemURLOrigin
),
90 base::FilePath().AppendASCII(filename
));
92 ASSERT_EQ(base::PLATFORM_FILE_OK
,
93 AsyncFileTestHelper::CreateFileWithData(
94 file_system_context_
, url
, buf
, buf_size
));
96 base::PlatformFileInfo file_info
;
97 ASSERT_EQ(base::PLATFORM_FILE_OK
,
98 AsyncFileTestHelper::GetMetadata(
99 file_system_context_
, url
, &file_info
));
100 *modification_time
= file_info
.last_modified
;
103 void OnOpenFileSystem(const GURL
& root
,
104 const std::string
& name
,
105 base::PlatformFileError result
) {
106 ASSERT_EQ(base::PLATFORM_FILE_OK
, result
);
107 ASSERT_TRUE(root
.is_valid());
108 file_system_root_url_
= root
;
111 base::MessageLoopForIO message_loop_
;
112 base::ScopedTempDir temp_dir_
;
113 scoped_refptr
<FileSystemContext
> file_system_context_
;
114 GURL file_system_root_url_
;
115 std::vector
<char> file_data_
;
117 base::Time file_modification_time_
;
118 scoped_ptr
<UploadFileSystemFileElementReader
> reader_
;
121 TEST_F(UploadFileSystemFileElementReaderTest
, ReadAll
) {
122 scoped_refptr
<net::IOBufferWithSize
> buf
=
123 new net::IOBufferWithSize(file_data_
.size());
124 net::TestCompletionCallback read_callback
;
125 ASSERT_EQ(net::ERR_IO_PENDING
,
126 reader_
->Read(buf
.get(), buf
->size(), read_callback
.callback()));
127 EXPECT_EQ(buf
->size(), read_callback
.WaitForResult());
128 EXPECT_EQ(0U, reader_
->BytesRemaining());
129 EXPECT_TRUE(std::equal(file_data_
.begin(), file_data_
.end(), buf
->data()));
130 // Try to read again.
131 EXPECT_EQ(0, reader_
->Read(buf
.get(), buf
->size(), read_callback
.callback()));
134 TEST_F(UploadFileSystemFileElementReaderTest
, ReadPartially
) {
135 const size_t kHalfSize
= file_data_
.size() / 2;
136 ASSERT_EQ(file_data_
.size(), kHalfSize
* 2);
138 scoped_refptr
<net::IOBufferWithSize
> buf
=
139 new net::IOBufferWithSize(kHalfSize
);
141 net::TestCompletionCallback read_callback1
;
142 ASSERT_EQ(net::ERR_IO_PENDING
,
143 reader_
->Read(buf
.get(), buf
->size(), read_callback1
.callback()));
144 EXPECT_EQ(buf
->size(), read_callback1
.WaitForResult());
145 EXPECT_EQ(file_data_
.size() - buf
->size(), reader_
->BytesRemaining());
146 EXPECT_TRUE(std::equal(file_data_
.begin(), file_data_
.begin() + kHalfSize
,
149 net::TestCompletionCallback read_callback2
;
150 EXPECT_EQ(net::ERR_IO_PENDING
,
151 reader_
->Read(buf
.get(), buf
->size(), read_callback2
.callback()));
152 EXPECT_EQ(buf
->size(), read_callback2
.WaitForResult());
153 EXPECT_EQ(0U, reader_
->BytesRemaining());
154 EXPECT_TRUE(std::equal(file_data_
.begin() + kHalfSize
, file_data_
.end(),
158 TEST_F(UploadFileSystemFileElementReaderTest
, ReadTooMuch
) {
159 const size_t kTooLargeSize
= file_data_
.size() * 2;
160 scoped_refptr
<net::IOBufferWithSize
> buf
=
161 new net::IOBufferWithSize(kTooLargeSize
);
162 net::TestCompletionCallback read_callback
;
163 ASSERT_EQ(net::ERR_IO_PENDING
,
164 reader_
->Read(buf
.get(), buf
->size(), read_callback
.callback()));
165 EXPECT_EQ(static_cast<int>(file_data_
.size()), read_callback
.WaitForResult());
166 EXPECT_EQ(0U, reader_
->BytesRemaining());
167 EXPECT_TRUE(std::equal(file_data_
.begin(), file_data_
.end(), buf
->data()));
170 TEST_F(UploadFileSystemFileElementReaderTest
, MultipleInit
) {
171 scoped_refptr
<net::IOBufferWithSize
> buf
=
172 new net::IOBufferWithSize(file_data_
.size());
175 net::TestCompletionCallback read_callback1
;
176 ASSERT_EQ(net::ERR_IO_PENDING
,
177 reader_
->Read(buf
.get(), buf
->size(), read_callback1
.callback()));
178 EXPECT_EQ(buf
->size(), read_callback1
.WaitForResult());
179 EXPECT_EQ(0U, reader_
->BytesRemaining());
180 EXPECT_TRUE(std::equal(file_data_
.begin(), file_data_
.end(), buf
->data()));
182 // Call Init() again to reset the state.
183 net::TestCompletionCallback init_callback
;
184 ASSERT_EQ(net::ERR_IO_PENDING
, reader_
->Init(init_callback
.callback()));
185 EXPECT_EQ(net::OK
, init_callback
.WaitForResult());
186 EXPECT_EQ(file_data_
.size(), reader_
->GetContentLength());
187 EXPECT_EQ(file_data_
.size(), reader_
->BytesRemaining());
190 net::TestCompletionCallback read_callback2
;
191 ASSERT_EQ(net::ERR_IO_PENDING
,
192 reader_
->Read(buf
.get(), buf
->size(), read_callback2
.callback()));
193 EXPECT_EQ(buf
->size(), read_callback2
.WaitForResult());
194 EXPECT_EQ(0U, reader_
->BytesRemaining());
195 EXPECT_TRUE(std::equal(file_data_
.begin(), file_data_
.end(), buf
->data()));
198 TEST_F(UploadFileSystemFileElementReaderTest
, InitDuringAsyncOperation
) {
199 scoped_refptr
<net::IOBufferWithSize
> buf
=
200 new net::IOBufferWithSize(file_data_
.size());
202 // Start reading all.
203 net::TestCompletionCallback read_callback1
;
204 EXPECT_EQ(net::ERR_IO_PENDING
,
205 reader_
->Read(buf
.get(), buf
->size(), read_callback1
.callback()));
207 // Call Init to cancel the previous read.
208 net::TestCompletionCallback init_callback1
;
209 EXPECT_EQ(net::ERR_IO_PENDING
, reader_
->Init(init_callback1
.callback()));
211 // Call Init again to cancel the previous init.
212 net::TestCompletionCallback init_callback2
;
213 EXPECT_EQ(net::ERR_IO_PENDING
, reader_
->Init(init_callback2
.callback()));
214 EXPECT_EQ(net::OK
, init_callback2
.WaitForResult());
215 EXPECT_EQ(file_data_
.size(), reader_
->GetContentLength());
216 EXPECT_EQ(file_data_
.size(), reader_
->BytesRemaining());
219 scoped_refptr
<net::IOBufferWithSize
> buf2
=
220 new net::IOBufferWithSize(file_data_
.size() / 2);
221 net::TestCompletionCallback read_callback2
;
222 EXPECT_EQ(net::ERR_IO_PENDING
,
223 reader_
->Read(buf2
.get(), buf2
->size(), read_callback2
.callback()));
224 EXPECT_EQ(buf2
->size(), read_callback2
.WaitForResult());
225 EXPECT_EQ(file_data_
.size() - buf2
->size(), reader_
->BytesRemaining());
226 EXPECT_TRUE(std::equal(file_data_
.begin(), file_data_
.begin() + buf2
->size(),
229 // Make sure callbacks are not called for cancelled operations.
230 EXPECT_FALSE(read_callback1
.have_result());
231 EXPECT_FALSE(init_callback1
.have_result());
234 TEST_F(UploadFileSystemFileElementReaderTest
, Range
) {
235 const int kOffset
= 2;
236 const int kLength
= file_data_
.size() - kOffset
* 3;
237 reader_
.reset(new UploadFileSystemFileElementReader(
238 file_system_context_
.get(), file_url_
, kOffset
, kLength
, base::Time()));
239 net::TestCompletionCallback init_callback
;
240 ASSERT_EQ(net::ERR_IO_PENDING
, reader_
->Init(init_callback
.callback()));
241 EXPECT_EQ(net::OK
, init_callback
.WaitForResult());
242 EXPECT_EQ(static_cast<uint64
>(kLength
), reader_
->GetContentLength());
243 EXPECT_EQ(static_cast<uint64
>(kLength
), reader_
->BytesRemaining());
244 scoped_refptr
<net::IOBufferWithSize
> buf
= new net::IOBufferWithSize(kLength
);
245 net::TestCompletionCallback read_callback
;
246 ASSERT_EQ(net::ERR_IO_PENDING
,
247 reader_
->Read(buf
.get(), buf
->size(), read_callback
.callback()));
248 EXPECT_EQ(kLength
, read_callback
.WaitForResult());
249 EXPECT_TRUE(std::equal(file_data_
.begin() + kOffset
,
250 file_data_
.begin() + kOffset
+ kLength
,
254 TEST_F(UploadFileSystemFileElementReaderTest
, FileChanged
) {
255 // Expect one second before the actual modification time to simulate change.
256 const base::Time expected_modification_time
=
257 file_modification_time_
- base::TimeDelta::FromSeconds(1);
259 new UploadFileSystemFileElementReader(file_system_context_
.get(),
263 expected_modification_time
));
264 net::TestCompletionCallback init_callback
;
265 ASSERT_EQ(net::ERR_IO_PENDING
, reader_
->Init(init_callback
.callback()));
266 EXPECT_EQ(net::ERR_UPLOAD_FILE_CHANGED
, init_callback
.WaitForResult());
269 TEST_F(UploadFileSystemFileElementReaderTest
, WrongURL
) {
270 const GURL wrong_url
= GetFileSystemURL("wrong_file_name.dat");
271 reader_
.reset(new UploadFileSystemFileElementReader(
272 file_system_context_
.get(), wrong_url
, 0, kuint64max
, base::Time()));
273 net::TestCompletionCallback init_callback
;
274 ASSERT_EQ(net::ERR_IO_PENDING
, reader_
->Init(init_callback
.callback()));
275 EXPECT_EQ(net::ERR_FILE_NOT_FOUND
, init_callback
.WaitForResult());
278 } // namespace fileapi