OLD | NEW |
| (Empty) |
1 // Copyright (c) 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. | |
4 | |
5 #include "webkit/fileapi/upload_file_system_file_element_reader.h" | |
6 | |
7 #include "base/files/scoped_temp_dir.h" | |
8 #include "base/message_loop.h" | |
9 #include "net/base/io_buffer.h" | |
10 #include "net/base/test_completion_callback.h" | |
11 #include "testing/gtest/include/gtest/gtest.h" | |
12 #include "webkit/browser/fileapi/file_system_file_util.h" | |
13 #include "webkit/browser/fileapi/file_system_mount_point_provider.h" | |
14 #include "webkit/browser/fileapi/mock_file_system_context.h" | |
15 #include "webkit/fileapi/file_system_context.h" | |
16 #include "webkit/fileapi/file_system_operation_context.h" | |
17 #include "webkit/fileapi/file_system_url.h" | |
18 | |
19 namespace fileapi { | |
20 | |
21 namespace { | |
22 | |
23 const char kFileSystemURLOrigin[] = "http://remote"; | |
24 const fileapi::FileSystemType kFileSystemType = | |
25 fileapi::kFileSystemTypeTemporary; | |
26 | |
27 } // namespace | |
28 | |
29 class UploadFileSystemFileElementReaderTest : public testing::Test { | |
30 public: | |
31 UploadFileSystemFileElementReaderTest() | |
32 : message_loop_(base::MessageLoop::TYPE_IO) {} | |
33 | |
34 virtual void SetUp() OVERRIDE { | |
35 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); | |
36 | |
37 file_system_context_ = fileapi::CreateFileSystemContextForTesting( | |
38 NULL, temp_dir_.path()); | |
39 | |
40 file_system_context_->OpenFileSystem( | |
41 GURL(kFileSystemURLOrigin), | |
42 kFileSystemType, | |
43 true, // create | |
44 base::Bind(&UploadFileSystemFileElementReaderTest::OnValidateFileSystem, | |
45 base::Unretained(this))); | |
46 base::MessageLoop::current()->RunUntilIdle(); | |
47 ASSERT_TRUE(file_system_root_url_.is_valid()); | |
48 | |
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_); | |
56 | |
57 // Create and initialize a reader. | |
58 reader_.reset(new UploadFileSystemFileElementReader( | |
59 file_system_context_, file_url_, 0, kuint64max, | |
60 file_modification_time_)); | |
61 net::TestCompletionCallback callback; | |
62 ASSERT_EQ(net::ERR_IO_PENDING, reader_->Init(callback.callback())); | |
63 EXPECT_EQ(net::OK, callback.WaitForResult()); | |
64 EXPECT_EQ(file_data_.size(), reader_->GetContentLength()); | |
65 EXPECT_EQ(file_data_.size(), reader_->BytesRemaining()); | |
66 EXPECT_FALSE(reader_->IsInMemory()); | |
67 } | |
68 | |
69 protected: | |
70 GURL GetFileSystemURL(const std::string& filename) { | |
71 return GURL(file_system_root_url_.spec() + filename); | |
72 } | |
73 | |
74 void WriteFileSystemFile(const std::string& filename, | |
75 const char* buf, | |
76 int buf_size, | |
77 base::Time* modification_time) { | |
78 fileapi::FileSystemURL url = | |
79 file_system_context_->CreateCrackedFileSystemURL( | |
80 GURL(kFileSystemURLOrigin), | |
81 kFileSystemType, | |
82 base::FilePath().AppendASCII(filename)); | |
83 | |
84 fileapi::FileSystemFileUtil* file_util = | |
85 file_system_context_->GetFileUtil(kFileSystemType); | |
86 | |
87 fileapi::FileSystemOperationContext context(file_system_context_); | |
88 context.set_allowed_bytes_growth(1024); | |
89 | |
90 base::PlatformFile handle = base::kInvalidPlatformFileValue; | |
91 bool created = false; | |
92 ASSERT_EQ(base::PLATFORM_FILE_OK, file_util->CreateOrOpen( | |
93 &context, | |
94 url, | |
95 base::PLATFORM_FILE_CREATE | base::PLATFORM_FILE_WRITE, | |
96 &handle, | |
97 &created)); | |
98 EXPECT_TRUE(created); | |
99 ASSERT_NE(base::kInvalidPlatformFileValue, handle); | |
100 ASSERT_EQ(buf_size, | |
101 base::WritePlatformFile(handle, 0 /* offset */, buf, buf_size)); | |
102 base::ClosePlatformFile(handle); | |
103 | |
104 base::PlatformFileInfo file_info; | |
105 base::FilePath platform_path; | |
106 ASSERT_EQ(base::PLATFORM_FILE_OK, | |
107 file_util->GetFileInfo(&context, url, &file_info, | |
108 &platform_path)); | |
109 *modification_time = file_info.last_modified; | |
110 } | |
111 | |
112 void OnValidateFileSystem(base::PlatformFileError result, | |
113 const std::string& name, | |
114 const GURL& root) { | |
115 ASSERT_EQ(base::PLATFORM_FILE_OK, result); | |
116 ASSERT_TRUE(root.is_valid()); | |
117 file_system_root_url_ = root; | |
118 } | |
119 | |
120 base::MessageLoop message_loop_; | |
121 base::ScopedTempDir temp_dir_; | |
122 scoped_refptr<FileSystemContext> file_system_context_; | |
123 GURL file_system_root_url_; | |
124 std::vector<char> file_data_; | |
125 GURL file_url_; | |
126 base::Time file_modification_time_; | |
127 scoped_ptr<UploadFileSystemFileElementReader> reader_; | |
128 }; | |
129 | |
130 TEST_F(UploadFileSystemFileElementReaderTest, ReadAll) { | |
131 scoped_refptr<net::IOBufferWithSize> buf = | |
132 new net::IOBufferWithSize(file_data_.size()); | |
133 net::TestCompletionCallback read_callback; | |
134 ASSERT_EQ(net::ERR_IO_PENDING, reader_->Read(buf, buf->size(), | |
135 read_callback.callback())); | |
136 EXPECT_EQ(buf->size(), read_callback.WaitForResult()); | |
137 EXPECT_EQ(0U, reader_->BytesRemaining()); | |
138 EXPECT_TRUE(std::equal(file_data_.begin(), file_data_.end(), buf->data())); | |
139 // Try to read again. | |
140 EXPECT_EQ(0, reader_->Read(buf, buf->size(), read_callback.callback())); | |
141 } | |
142 | |
143 TEST_F(UploadFileSystemFileElementReaderTest, ReadPartially) { | |
144 const size_t kHalfSize = file_data_.size() / 2; | |
145 ASSERT_EQ(file_data_.size(), kHalfSize * 2); | |
146 | |
147 scoped_refptr<net::IOBufferWithSize> buf = | |
148 new net::IOBufferWithSize(kHalfSize); | |
149 | |
150 net::TestCompletionCallback read_callback1; | |
151 ASSERT_EQ(net::ERR_IO_PENDING, reader_->Read(buf, buf->size(), | |
152 read_callback1.callback())); | |
153 EXPECT_EQ(buf->size(), read_callback1.WaitForResult()); | |
154 EXPECT_EQ(file_data_.size() - buf->size(), reader_->BytesRemaining()); | |
155 EXPECT_TRUE(std::equal(file_data_.begin(), file_data_.begin() + kHalfSize, | |
156 buf->data())); | |
157 | |
158 net::TestCompletionCallback read_callback2; | |
159 EXPECT_EQ(net::ERR_IO_PENDING, reader_->Read(buf, buf->size(), | |
160 read_callback2.callback())); | |
161 EXPECT_EQ(buf->size(), read_callback2.WaitForResult()); | |
162 EXPECT_EQ(0U, reader_->BytesRemaining()); | |
163 EXPECT_TRUE(std::equal(file_data_.begin() + kHalfSize, file_data_.end(), | |
164 buf->data())); | |
165 } | |
166 | |
167 TEST_F(UploadFileSystemFileElementReaderTest, ReadTooMuch) { | |
168 const size_t kTooLargeSize = file_data_.size() * 2; | |
169 scoped_refptr<net::IOBufferWithSize> buf = | |
170 new net::IOBufferWithSize(kTooLargeSize); | |
171 net::TestCompletionCallback read_callback; | |
172 ASSERT_EQ(net::ERR_IO_PENDING, reader_->Read(buf, buf->size(), | |
173 read_callback.callback())); | |
174 EXPECT_EQ(static_cast<int>(file_data_.size()), read_callback.WaitForResult()); | |
175 EXPECT_EQ(0U, reader_->BytesRemaining()); | |
176 EXPECT_TRUE(std::equal(file_data_.begin(), file_data_.end(), buf->data())); | |
177 } | |
178 | |
179 TEST_F(UploadFileSystemFileElementReaderTest, MultipleInit) { | |
180 scoped_refptr<net::IOBufferWithSize> buf = | |
181 new net::IOBufferWithSize(file_data_.size()); | |
182 | |
183 // Read all. | |
184 net::TestCompletionCallback read_callback1; | |
185 ASSERT_EQ(net::ERR_IO_PENDING, reader_->Read(buf, buf->size(), | |
186 read_callback1.callback())); | |
187 EXPECT_EQ(buf->size(), read_callback1.WaitForResult()); | |
188 EXPECT_EQ(0U, reader_->BytesRemaining()); | |
189 EXPECT_TRUE(std::equal(file_data_.begin(), file_data_.end(), buf->data())); | |
190 | |
191 // Call Init() again to reset the state. | |
192 net::TestCompletionCallback init_callback; | |
193 ASSERT_EQ(net::ERR_IO_PENDING, reader_->Init(init_callback.callback())); | |
194 EXPECT_EQ(net::OK, init_callback.WaitForResult()); | |
195 EXPECT_EQ(file_data_.size(), reader_->GetContentLength()); | |
196 EXPECT_EQ(file_data_.size(), reader_->BytesRemaining()); | |
197 | |
198 // Read again. | |
199 net::TestCompletionCallback read_callback2; | |
200 ASSERT_EQ(net::ERR_IO_PENDING, reader_->Read(buf, buf->size(), | |
201 read_callback2.callback())); | |
202 EXPECT_EQ(buf->size(), read_callback2.WaitForResult()); | |
203 EXPECT_EQ(0U, reader_->BytesRemaining()); | |
204 EXPECT_TRUE(std::equal(file_data_.begin(), file_data_.end(), buf->data())); | |
205 } | |
206 | |
207 TEST_F(UploadFileSystemFileElementReaderTest, InitDuringAsyncOperation) { | |
208 scoped_refptr<net::IOBufferWithSize> buf = | |
209 new net::IOBufferWithSize(file_data_.size()); | |
210 | |
211 // Start reading all. | |
212 net::TestCompletionCallback read_callback1; | |
213 EXPECT_EQ(net::ERR_IO_PENDING, reader_->Read(buf, buf->size(), | |
214 read_callback1.callback())); | |
215 | |
216 // Call Init to cancel the previous read. | |
217 net::TestCompletionCallback init_callback1; | |
218 EXPECT_EQ(net::ERR_IO_PENDING, reader_->Init(init_callback1.callback())); | |
219 | |
220 // Call Init again to cancel the previous init. | |
221 net::TestCompletionCallback init_callback2; | |
222 EXPECT_EQ(net::ERR_IO_PENDING, reader_->Init(init_callback2.callback())); | |
223 EXPECT_EQ(net::OK, init_callback2.WaitForResult()); | |
224 EXPECT_EQ(file_data_.size(), reader_->GetContentLength()); | |
225 EXPECT_EQ(file_data_.size(), reader_->BytesRemaining()); | |
226 | |
227 // Read half. | |
228 scoped_refptr<net::IOBufferWithSize> buf2 = | |
229 new net::IOBufferWithSize(file_data_.size() / 2); | |
230 net::TestCompletionCallback read_callback2; | |
231 EXPECT_EQ(net::ERR_IO_PENDING, reader_->Read(buf2, buf2->size(), | |
232 read_callback2.callback())); | |
233 EXPECT_EQ(buf2->size(), read_callback2.WaitForResult()); | |
234 EXPECT_EQ(file_data_.size() - buf2->size(), reader_->BytesRemaining()); | |
235 EXPECT_TRUE(std::equal(file_data_.begin(), file_data_.begin() + buf2->size(), | |
236 buf2->data())); | |
237 | |
238 // Make sure callbacks are not called for cancelled operations. | |
239 EXPECT_FALSE(read_callback1.have_result()); | |
240 EXPECT_FALSE(init_callback1.have_result()); | |
241 } | |
242 | |
243 TEST_F(UploadFileSystemFileElementReaderTest, Range) { | |
244 const int kOffset = 2; | |
245 const int kLength = file_data_.size() - kOffset * 3; | |
246 reader_.reset(new UploadFileSystemFileElementReader( | |
247 file_system_context_, file_url_, kOffset, kLength, base::Time())); | |
248 net::TestCompletionCallback init_callback; | |
249 ASSERT_EQ(net::ERR_IO_PENDING, reader_->Init(init_callback.callback())); | |
250 EXPECT_EQ(net::OK, init_callback.WaitForResult()); | |
251 EXPECT_EQ(static_cast<uint64>(kLength), reader_->GetContentLength()); | |
252 EXPECT_EQ(static_cast<uint64>(kLength), reader_->BytesRemaining()); | |
253 scoped_refptr<net::IOBufferWithSize> buf = new net::IOBufferWithSize(kLength); | |
254 net::TestCompletionCallback read_callback; | |
255 ASSERT_EQ(net::ERR_IO_PENDING, reader_->Read(buf, buf->size(), | |
256 read_callback.callback())); | |
257 EXPECT_EQ(kLength, read_callback.WaitForResult()); | |
258 EXPECT_TRUE(std::equal(file_data_.begin() + kOffset, | |
259 file_data_.begin() + kOffset + kLength, | |
260 buf->data())); | |
261 } | |
262 | |
263 TEST_F(UploadFileSystemFileElementReaderTest, FileChanged) { | |
264 // Expect one second before the actual modification time to simulate change. | |
265 const base::Time expected_modification_time = | |
266 file_modification_time_ - base::TimeDelta::FromSeconds(1); | |
267 reader_.reset(new UploadFileSystemFileElementReader( | |
268 file_system_context_, file_url_, 0, kuint64max, | |
269 expected_modification_time)); | |
270 net::TestCompletionCallback init_callback; | |
271 ASSERT_EQ(net::ERR_IO_PENDING, reader_->Init(init_callback.callback())); | |
272 EXPECT_EQ(net::ERR_UPLOAD_FILE_CHANGED, init_callback.WaitForResult()); | |
273 } | |
274 | |
275 TEST_F(UploadFileSystemFileElementReaderTest, WrongURL) { | |
276 const GURL wrong_url = GetFileSystemURL("wrong_file_name.dat"); | |
277 reader_.reset(new UploadFileSystemFileElementReader( | |
278 file_system_context_, wrong_url, 0, kuint64max, base::Time())); | |
279 net::TestCompletionCallback init_callback; | |
280 ASSERT_EQ(net::ERR_IO_PENDING, reader_->Init(init_callback.callback())); | |
281 EXPECT_EQ(net::ERR_FILE_NOT_FOUND, init_callback.WaitForResult()); | |
282 } | |
283 | |
284 } // namespace fileapi | |
OLD | NEW |