Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / content / browser / fileapi / file_system_file_stream_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 "storage/browser/fileapi/file_system_file_stream_reader.h"
6
7 #include <limits>
8 #include <string>
9
10 #include "base/files/scoped_temp_dir.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/run_loop.h"
13 #include "content/public/test/async_file_test_helper.h"
14 #include "content/public/test/test_file_system_context.h"
15 #include "net/base/io_buffer.h"
16 #include "net/base/net_errors.h"
17 #include "net/base/test_completion_callback.h"
18 #include "storage/browser/fileapi/external_mount_points.h"
19 #include "storage/browser/fileapi/file_system_context.h"
20 #include "storage/browser/fileapi/file_system_file_util.h"
21 #include "testing/gtest/include/gtest/gtest.h"
22
23 using content::AsyncFileTestHelper;
24 using storage::FileSystemContext;
25 using storage::FileSystemFileStreamReader;
26 using storage::FileSystemType;
27 using storage::FileSystemURL;
28
29 namespace content {
30
31 namespace {
32
33 const char kURLOrigin[] = "http://remote/";
34 const char kTestFileName[] = "test.dat";
35 const char kTestData[] = "0123456789";
36 const int kTestDataSize = arraysize(kTestData) - 1;
37
38 void ReadFromReader(storage::FileSystemFileStreamReader* reader,
39                     std::string* data,
40                     size_t size,
41                     int* result) {
42   ASSERT_TRUE(reader != NULL);
43   ASSERT_TRUE(result != NULL);
44   *result = net::OK;
45   net::TestCompletionCallback callback;
46   size_t total_bytes_read = 0;
47   while (total_bytes_read < size) {
48     scoped_refptr<net::IOBufferWithSize> buf(
49         new net::IOBufferWithSize(size - total_bytes_read));
50     int rv = reader->Read(buf.get(), buf->size(), callback.callback());
51     if (rv == net::ERR_IO_PENDING)
52       rv = callback.WaitForResult();
53     if (rv < 0)
54       *result = rv;
55     if (rv <= 0)
56       break;
57     total_bytes_read += rv;
58     data->append(buf->data(), rv);
59   }
60 }
61
62 void NeverCalled(int unused) { ADD_FAILURE(); }
63
64 }  // namespace
65
66 class FileSystemFileStreamReaderTest : public testing::Test {
67  public:
68   FileSystemFileStreamReaderTest() {}
69
70   virtual void SetUp() OVERRIDE {
71     ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
72
73     file_system_context_ = CreateFileSystemContextForTesting(
74         NULL, temp_dir_.path());
75
76     file_system_context_->OpenFileSystem(
77         GURL(kURLOrigin),
78         storage::kFileSystemTypeTemporary,
79         storage::OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT,
80         base::Bind(&OnOpenFileSystem));
81     base::RunLoop().RunUntilIdle();
82
83     WriteFile(kTestFileName, kTestData, kTestDataSize,
84               &test_file_modification_time_);
85   }
86
87   virtual void TearDown() OVERRIDE {
88     base::RunLoop().RunUntilIdle();
89   }
90
91  protected:
92   storage::FileSystemFileStreamReader* CreateFileReader(
93       const std::string& file_name,
94       int64 initial_offset,
95       const base::Time& expected_modification_time) {
96     return new FileSystemFileStreamReader(file_system_context_.get(),
97                                           GetFileSystemURL(file_name),
98                                           initial_offset,
99                                           expected_modification_time);
100   }
101
102   base::Time test_file_modification_time() const {
103     return test_file_modification_time_;
104   }
105
106   void WriteFile(const std::string& file_name,
107                  const char* buf,
108                  int buf_size,
109                  base::Time* modification_time) {
110     FileSystemURL url = GetFileSystemURL(file_name);
111
112     ASSERT_EQ(base::File::FILE_OK,
113               content::AsyncFileTestHelper::CreateFileWithData(
114                   file_system_context_.get(), url, buf, buf_size));
115
116     base::File::Info file_info;
117     ASSERT_EQ(base::File::FILE_OK,
118               AsyncFileTestHelper::GetMetadata(
119                   file_system_context_.get(), url, &file_info));
120     if (modification_time)
121       *modification_time = file_info.last_modified;
122   }
123
124  private:
125   static void OnOpenFileSystem(const GURL& root_url,
126                                const std::string& name,
127                                base::File::Error result) {
128     ASSERT_EQ(base::File::FILE_OK, result);
129   }
130
131   FileSystemURL GetFileSystemURL(const std::string& file_name) {
132     return file_system_context_->CreateCrackedFileSystemURL(
133         GURL(kURLOrigin),
134         storage::kFileSystemTypeTemporary,
135         base::FilePath().AppendASCII(file_name));
136   }
137
138   base::MessageLoopForIO message_loop_;
139   base::ScopedTempDir temp_dir_;
140   scoped_refptr<FileSystemContext> file_system_context_;
141   base::Time test_file_modification_time_;
142 };
143
144 TEST_F(FileSystemFileStreamReaderTest, NonExistent) {
145   const char kFileName[] = "nonexistent";
146   scoped_ptr<FileSystemFileStreamReader> reader(
147       CreateFileReader(kFileName, 0, base::Time()));
148   int result = 0;
149   std::string data;
150   ReadFromReader(reader.get(), &data, 10, &result);
151   ASSERT_EQ(net::ERR_FILE_NOT_FOUND, result);
152   ASSERT_EQ(0U, data.size());
153 }
154
155 TEST_F(FileSystemFileStreamReaderTest, Empty) {
156   const char kFileName[] = "empty";
157   WriteFile(kFileName, NULL, 0, NULL);
158
159   scoped_ptr<FileSystemFileStreamReader> reader(
160       CreateFileReader(kFileName, 0, base::Time()));
161   int result = 0;
162   std::string data;
163   ReadFromReader(reader.get(), &data, 10, &result);
164   ASSERT_EQ(net::OK, result);
165   ASSERT_EQ(0U, data.size());
166
167   net::TestInt64CompletionCallback callback;
168   int64 length_result = reader->GetLength(callback.callback());
169   if (length_result == net::ERR_IO_PENDING)
170     length_result = callback.WaitForResult();
171   ASSERT_EQ(0, length_result);
172 }
173
174 TEST_F(FileSystemFileStreamReaderTest, GetLengthNormal) {
175   scoped_ptr<FileSystemFileStreamReader> reader(
176       CreateFileReader(kTestFileName, 0, test_file_modification_time()));
177   net::TestInt64CompletionCallback callback;
178   int64 result = reader->GetLength(callback.callback());
179   if (result == net::ERR_IO_PENDING)
180     result = callback.WaitForResult();
181   ASSERT_EQ(kTestDataSize, result);
182 }
183
184 TEST_F(FileSystemFileStreamReaderTest, GetLengthAfterModified) {
185   // Pass a fake expected modifictaion time so that the expectation fails.
186   base::Time fake_expected_modification_time =
187       test_file_modification_time() - base::TimeDelta::FromSeconds(10);
188
189   scoped_ptr<FileSystemFileStreamReader> reader(
190       CreateFileReader(kTestFileName, 0, fake_expected_modification_time));
191   net::TestInt64CompletionCallback callback;
192   int64 result = reader->GetLength(callback.callback());
193   if (result == net::ERR_IO_PENDING)
194     result = callback.WaitForResult();
195   ASSERT_EQ(net::ERR_UPLOAD_FILE_CHANGED, result);
196
197   // With NULL expected modification time this should work.
198   reader.reset(CreateFileReader(kTestFileName, 0, base::Time()));
199   result = reader->GetLength(callback.callback());
200   if (result == net::ERR_IO_PENDING)
201     result = callback.WaitForResult();
202   ASSERT_EQ(kTestDataSize, result);
203 }
204
205 TEST_F(FileSystemFileStreamReaderTest, GetLengthWithOffset) {
206   scoped_ptr<FileSystemFileStreamReader> reader(
207       CreateFileReader(kTestFileName, 3, base::Time()));
208   net::TestInt64CompletionCallback callback;
209   int64 result = reader->GetLength(callback.callback());
210   if (result == net::ERR_IO_PENDING)
211     result = callback.WaitForResult();
212   // Initial offset does not affect the result of GetLength.
213   ASSERT_EQ(kTestDataSize, result);
214 }
215
216 TEST_F(FileSystemFileStreamReaderTest, ReadNormal) {
217   scoped_ptr<FileSystemFileStreamReader> reader(
218       CreateFileReader(kTestFileName, 0, test_file_modification_time()));
219   int result = 0;
220   std::string data;
221   ReadFromReader(reader.get(), &data, kTestDataSize, &result);
222   ASSERT_EQ(net::OK, result);
223   ASSERT_EQ(kTestData, data);
224 }
225
226 TEST_F(FileSystemFileStreamReaderTest, ReadAfterModified) {
227   // Pass a fake expected modifictaion time so that the expectation fails.
228   base::Time fake_expected_modification_time =
229       test_file_modification_time() - base::TimeDelta::FromSeconds(10);
230
231   scoped_ptr<FileSystemFileStreamReader> reader(
232       CreateFileReader(kTestFileName, 0, fake_expected_modification_time));
233   int result = 0;
234   std::string data;
235   ReadFromReader(reader.get(), &data, kTestDataSize, &result);
236   ASSERT_EQ(net::ERR_UPLOAD_FILE_CHANGED, result);
237   ASSERT_EQ(0U, data.size());
238
239   // With NULL expected modification time this should work.
240   data.clear();
241   reader.reset(CreateFileReader(kTestFileName, 0, base::Time()));
242   ReadFromReader(reader.get(), &data, kTestDataSize, &result);
243   ASSERT_EQ(net::OK, result);
244   ASSERT_EQ(kTestData, data);
245 }
246
247 TEST_F(FileSystemFileStreamReaderTest, ReadWithOffset) {
248   scoped_ptr<FileSystemFileStreamReader> reader(
249       CreateFileReader(kTestFileName, 3, base::Time()));
250   int result = 0;
251   std::string data;
252   ReadFromReader(reader.get(), &data, kTestDataSize, &result);
253   ASSERT_EQ(net::OK, result);
254   ASSERT_EQ(&kTestData[3], data);
255 }
256
257 TEST_F(FileSystemFileStreamReaderTest, DeleteWithUnfinishedRead) {
258   scoped_ptr<FileSystemFileStreamReader> reader(
259       CreateFileReader(kTestFileName, 0, base::Time()));
260
261   net::TestCompletionCallback callback;
262   scoped_refptr<net::IOBufferWithSize> buf(
263       new net::IOBufferWithSize(kTestDataSize));
264   int rv = reader->Read(buf.get(), buf->size(), base::Bind(&NeverCalled));
265   ASSERT_TRUE(rv == net::ERR_IO_PENDING || rv >= 0);
266
267   // Delete immediately.
268   // Should not crash; nor should NeverCalled be callback.
269   reader.reset();
270 }
271
272 }  // namespace content