Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / content / browser / fileapi / upload_file_system_file_element_reader_unittest.cc
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.
4
5 #include "webkit/browser/fileapi/upload_file_system_file_element_reader.h"
6
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/async_file_test_helper.h"
11 #include "content/public/test/test_file_system_context.h"
12 #include "net/base/io_buffer.h"
13 #include "net/base/test_completion_callback.h"
14 #include "testing/gtest/include/gtest/gtest.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"
19
20 using content::AsyncFileTestHelper;
21 using fileapi::FileSystemContext;
22 using fileapi::FileSystemType;
23 using fileapi::FileSystemURL;
24 using fileapi::UploadFileSystemFileElementReader;
25
26 namespace content {
27
28 namespace {
29
30 const char kFileSystemURLOrigin[] = "http://remote";
31 const fileapi::FileSystemType kFileSystemType =
32     fileapi::kFileSystemTypeTemporary;
33
34 }  // namespace
35
36 class UploadFileSystemFileElementReaderTest : public testing::Test {
37  public:
38   UploadFileSystemFileElementReaderTest() {}
39
40   virtual void SetUp() OVERRIDE {
41     ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
42
43     file_system_context_ = CreateFileSystemContextForTesting(
44         NULL, temp_dir_.path());
45
46     file_system_context_->OpenFileSystem(
47         GURL(kFileSystemURLOrigin),
48         kFileSystemType,
49         fileapi::OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT,
50         base::Bind(&UploadFileSystemFileElementReaderTest::OnOpenFileSystem,
51                    base::Unretained(this)));
52     base::RunLoop().RunUntilIdle();
53     ASSERT_TRUE(file_system_root_url_.is_valid());
54
55     // Prepare a file on file system.
56     const char kTestData[] = "abcdefghijklmnop0123456789";
57     file_data_.assign(kTestData, kTestData + arraysize(kTestData) - 1);
58     const char kFilename[] = "File.dat";
59     file_url_ = GetFileSystemURL(kFilename);
60     WriteFileSystemFile(kFilename, &file_data_[0], file_data_.size(),
61                         &file_modification_time_);
62
63     // Create and initialize a reader.
64     reader_.reset(
65         new UploadFileSystemFileElementReader(file_system_context_.get(),
66                                               file_url_,
67                                               0,
68                                               kuint64max,
69                                               file_modification_time_));
70     net::TestCompletionCallback callback;
71     ASSERT_EQ(net::ERR_IO_PENDING, reader_->Init(callback.callback()));
72     EXPECT_EQ(net::OK, callback.WaitForResult());
73     EXPECT_EQ(file_data_.size(), reader_->GetContentLength());
74     EXPECT_EQ(file_data_.size(), reader_->BytesRemaining());
75     EXPECT_FALSE(reader_->IsInMemory());
76   }
77
78  virtual void TearDown() OVERRIDE {
79     reader_.reset();
80     base::RunLoop().RunUntilIdle();
81  }
82
83  protected:
84   GURL GetFileSystemURL(const std::string& filename) {
85     return GURL(file_system_root_url_.spec() + filename);
86   }
87
88   void WriteFileSystemFile(const std::string& filename,
89                            const char* buf,
90                            int buf_size,
91                            base::Time* modification_time) {
92     fileapi::FileSystemURL url =
93         file_system_context_->CreateCrackedFileSystemURL(
94             GURL(kFileSystemURLOrigin),
95             kFileSystemType,
96             base::FilePath().AppendASCII(filename));
97
98     ASSERT_EQ(base::File::FILE_OK,
99               AsyncFileTestHelper::CreateFileWithData(
100                   file_system_context_, url, buf, buf_size));
101
102     base::File::Info file_info;
103     ASSERT_EQ(base::File::FILE_OK,
104               AsyncFileTestHelper::GetMetadata(
105                   file_system_context_, url, &file_info));
106     *modification_time = file_info.last_modified;
107   }
108
109   void OnOpenFileSystem(const GURL& root,
110                         const std::string& name,
111                         base::File::Error result) {
112     ASSERT_EQ(base::File::FILE_OK, result);
113     ASSERT_TRUE(root.is_valid());
114     file_system_root_url_ = root;
115   }
116
117   base::MessageLoopForIO message_loop_;
118   base::ScopedTempDir temp_dir_;
119   scoped_refptr<FileSystemContext> file_system_context_;
120   GURL file_system_root_url_;
121   std::vector<char> file_data_;
122   GURL file_url_;
123   base::Time file_modification_time_;
124   scoped_ptr<UploadFileSystemFileElementReader> reader_;
125 };
126
127 TEST_F(UploadFileSystemFileElementReaderTest, ReadAll) {
128   scoped_refptr<net::IOBufferWithSize> buf =
129       new net::IOBufferWithSize(file_data_.size());
130   net::TestCompletionCallback read_callback;
131   ASSERT_EQ(net::ERR_IO_PENDING,
132             reader_->Read(buf.get(), buf->size(), read_callback.callback()));
133   EXPECT_EQ(buf->size(), read_callback.WaitForResult());
134   EXPECT_EQ(0U, reader_->BytesRemaining());
135   EXPECT_TRUE(std::equal(file_data_.begin(), file_data_.end(), buf->data()));
136   // Try to read again.
137   EXPECT_EQ(0, reader_->Read(buf.get(), buf->size(), read_callback.callback()));
138 }
139
140 TEST_F(UploadFileSystemFileElementReaderTest, ReadPartially) {
141   const size_t kHalfSize = file_data_.size() / 2;
142   ASSERT_EQ(file_data_.size(), kHalfSize * 2);
143
144   scoped_refptr<net::IOBufferWithSize> buf =
145       new net::IOBufferWithSize(kHalfSize);
146
147   net::TestCompletionCallback read_callback1;
148   ASSERT_EQ(net::ERR_IO_PENDING,
149             reader_->Read(buf.get(), buf->size(), read_callback1.callback()));
150   EXPECT_EQ(buf->size(), read_callback1.WaitForResult());
151   EXPECT_EQ(file_data_.size() - buf->size(), reader_->BytesRemaining());
152   EXPECT_TRUE(std::equal(file_data_.begin(), file_data_.begin() + kHalfSize,
153                          buf->data()));
154
155   net::TestCompletionCallback read_callback2;
156   EXPECT_EQ(net::ERR_IO_PENDING,
157             reader_->Read(buf.get(), buf->size(), read_callback2.callback()));
158   EXPECT_EQ(buf->size(), read_callback2.WaitForResult());
159   EXPECT_EQ(0U, reader_->BytesRemaining());
160   EXPECT_TRUE(std::equal(file_data_.begin() + kHalfSize, file_data_.end(),
161                          buf->data()));
162 }
163
164 TEST_F(UploadFileSystemFileElementReaderTest, ReadTooMuch) {
165   const size_t kTooLargeSize = file_data_.size() * 2;
166   scoped_refptr<net::IOBufferWithSize> buf =
167       new net::IOBufferWithSize(kTooLargeSize);
168   net::TestCompletionCallback read_callback;
169   ASSERT_EQ(net::ERR_IO_PENDING,
170             reader_->Read(buf.get(), buf->size(), read_callback.callback()));
171   EXPECT_EQ(static_cast<int>(file_data_.size()), read_callback.WaitForResult());
172   EXPECT_EQ(0U, reader_->BytesRemaining());
173   EXPECT_TRUE(std::equal(file_data_.begin(), file_data_.end(), buf->data()));
174 }
175
176 TEST_F(UploadFileSystemFileElementReaderTest, MultipleInit) {
177   scoped_refptr<net::IOBufferWithSize> buf =
178       new net::IOBufferWithSize(file_data_.size());
179
180   // Read all.
181   net::TestCompletionCallback read_callback1;
182   ASSERT_EQ(net::ERR_IO_PENDING,
183             reader_->Read(buf.get(), buf->size(), read_callback1.callback()));
184   EXPECT_EQ(buf->size(), read_callback1.WaitForResult());
185   EXPECT_EQ(0U, reader_->BytesRemaining());
186   EXPECT_TRUE(std::equal(file_data_.begin(), file_data_.end(), buf->data()));
187
188   // Call Init() again to reset the state.
189   net::TestCompletionCallback init_callback;
190   ASSERT_EQ(net::ERR_IO_PENDING, reader_->Init(init_callback.callback()));
191   EXPECT_EQ(net::OK, init_callback.WaitForResult());
192   EXPECT_EQ(file_data_.size(), reader_->GetContentLength());
193   EXPECT_EQ(file_data_.size(), reader_->BytesRemaining());
194
195   // Read again.
196   net::TestCompletionCallback read_callback2;
197   ASSERT_EQ(net::ERR_IO_PENDING,
198             reader_->Read(buf.get(), buf->size(), read_callback2.callback()));
199   EXPECT_EQ(buf->size(), read_callback2.WaitForResult());
200   EXPECT_EQ(0U, reader_->BytesRemaining());
201   EXPECT_TRUE(std::equal(file_data_.begin(), file_data_.end(), buf->data()));
202 }
203
204 TEST_F(UploadFileSystemFileElementReaderTest, InitDuringAsyncOperation) {
205   scoped_refptr<net::IOBufferWithSize> buf =
206       new net::IOBufferWithSize(file_data_.size());
207
208   // Start reading all.
209   net::TestCompletionCallback read_callback1;
210   EXPECT_EQ(net::ERR_IO_PENDING,
211             reader_->Read(buf.get(), buf->size(), read_callback1.callback()));
212
213   // Call Init to cancel the previous read.
214   net::TestCompletionCallback init_callback1;
215   EXPECT_EQ(net::ERR_IO_PENDING, reader_->Init(init_callback1.callback()));
216
217   // Call Init again to cancel the previous init.
218   net::TestCompletionCallback init_callback2;
219   EXPECT_EQ(net::ERR_IO_PENDING, reader_->Init(init_callback2.callback()));
220   EXPECT_EQ(net::OK, init_callback2.WaitForResult());
221   EXPECT_EQ(file_data_.size(), reader_->GetContentLength());
222   EXPECT_EQ(file_data_.size(), reader_->BytesRemaining());
223
224   // Read half.
225   scoped_refptr<net::IOBufferWithSize> buf2 =
226       new net::IOBufferWithSize(file_data_.size() / 2);
227   net::TestCompletionCallback read_callback2;
228   EXPECT_EQ(net::ERR_IO_PENDING,
229             reader_->Read(buf2.get(), buf2->size(), read_callback2.callback()));
230   EXPECT_EQ(buf2->size(), read_callback2.WaitForResult());
231   EXPECT_EQ(file_data_.size() - buf2->size(), reader_->BytesRemaining());
232   EXPECT_TRUE(std::equal(file_data_.begin(), file_data_.begin() + buf2->size(),
233                          buf2->data()));
234
235   // Make sure callbacks are not called for cancelled operations.
236   EXPECT_FALSE(read_callback1.have_result());
237   EXPECT_FALSE(init_callback1.have_result());
238 }
239
240 TEST_F(UploadFileSystemFileElementReaderTest, Range) {
241   const int kOffset = 2;
242   const int kLength = file_data_.size() - kOffset * 3;
243   reader_.reset(new UploadFileSystemFileElementReader(
244       file_system_context_.get(), file_url_, kOffset, kLength, base::Time()));
245   net::TestCompletionCallback init_callback;
246   ASSERT_EQ(net::ERR_IO_PENDING, reader_->Init(init_callback.callback()));
247   EXPECT_EQ(net::OK, init_callback.WaitForResult());
248   EXPECT_EQ(static_cast<uint64>(kLength), reader_->GetContentLength());
249   EXPECT_EQ(static_cast<uint64>(kLength), reader_->BytesRemaining());
250   scoped_refptr<net::IOBufferWithSize> buf = new net::IOBufferWithSize(kLength);
251   net::TestCompletionCallback read_callback;
252   ASSERT_EQ(net::ERR_IO_PENDING,
253             reader_->Read(buf.get(), buf->size(), read_callback.callback()));
254   EXPECT_EQ(kLength, read_callback.WaitForResult());
255   EXPECT_TRUE(std::equal(file_data_.begin() + kOffset,
256                          file_data_.begin() + kOffset + kLength,
257                          buf->data()));
258 }
259
260 TEST_F(UploadFileSystemFileElementReaderTest, FileChanged) {
261   // Expect one second before the actual modification time to simulate change.
262   const base::Time expected_modification_time =
263       file_modification_time_ - base::TimeDelta::FromSeconds(1);
264   reader_.reset(
265       new UploadFileSystemFileElementReader(file_system_context_.get(),
266                                             file_url_,
267                                             0,
268                                             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_.get(), 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 content