Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / chromeos / file_system_provider / fileapi / file_stream_reader_unittest.cc
1 // Copyright 2014 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 "chrome/browser/chromeos/file_system_provider/fileapi/file_stream_reader.h"
6
7 #include <string>
8 #include <vector>
9
10 #include "base/files/file.h"
11 #include "base/files/file_path.h"
12 #include "base/files/scoped_temp_dir.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "base/memory/weak_ptr.h"
15 #include "base/run_loop.h"
16 #include "chrome/browser/chromeos/file_system_provider/fake_provided_file_system.h"
17 #include "chrome/browser/chromeos/file_system_provider/service.h"
18 #include "chrome/browser/chromeos/file_system_provider/service_factory.h"
19 #include "chrome/test/base/testing_browser_process.h"
20 #include "chrome/test/base/testing_profile.h"
21 #include "chrome/test/base/testing_profile_manager.h"
22 #include "content/public/test/test_browser_thread_bundle.h"
23 #include "content/public/test/test_file_system_context.h"
24 #include "extensions/browser/extension_registry.h"
25 #include "net/base/io_buffer.h"
26 #include "net/base/net_errors.h"
27 #include "testing/gtest/include/gtest/gtest.h"
28 #include "webkit/browser/fileapi/async_file_util.h"
29 #include "webkit/browser/fileapi/external_mount_points.h"
30 #include "webkit/browser/fileapi/file_system_url.h"
31
32 namespace chromeos {
33 namespace file_system_provider {
34 namespace {
35
36 const char kExtensionId[] = "mbflcebpggnecokmikipoihdbecnjfoj";
37 const char kFileSystemId[] = "testing-file-system";
38
39 // Logs callbacks invocations on the file stream reader.
40 class EventLogger {
41  public:
42   EventLogger() : weak_ptr_factory_(this) {}
43   virtual ~EventLogger() {}
44
45   void OnRead(int result) { results_.push_back(result); }
46   void OnGetLength(int64 result) { results_.push_back(result); }
47
48   base::WeakPtr<EventLogger> GetWeakPtr() {
49     return weak_ptr_factory_.GetWeakPtr();
50   }
51
52   const std::vector<int64>& results() const { return results_; }
53
54  private:
55   std::vector<int64> results_;
56   base::WeakPtrFactory<EventLogger> weak_ptr_factory_;
57
58   DISALLOW_COPY_AND_ASSIGN(EventLogger);
59 };
60
61 // Creates a cracked FileSystemURL for tests.
62 fileapi::FileSystemURL CreateFileSystemURL(const std::string& mount_point_name,
63                                            const base::FilePath& file_path) {
64   const std::string origin = std::string("chrome-extension://") + kExtensionId;
65   const fileapi::ExternalMountPoints* const mount_points =
66       fileapi::ExternalMountPoints::GetSystemInstance();
67   return mount_points->CreateCrackedFileSystemURL(
68       GURL(origin),
69       fileapi::kFileSystemTypeExternal,
70       base::FilePath::FromUTF8Unsafe(mount_point_name).Append(file_path));
71 }
72
73 // Creates a Service instance. Used to be able to destroy the service in
74 // TearDown().
75 KeyedService* CreateService(content::BrowserContext* context) {
76   return new Service(Profile::FromBrowserContext(context),
77                      extensions::ExtensionRegistry::Get(context));
78 }
79
80 }  // namespace
81
82 class FileSystemProviderFileStreamReader : public testing::Test {
83  protected:
84   FileSystemProviderFileStreamReader() {}
85   virtual ~FileSystemProviderFileStreamReader() {}
86
87   virtual void SetUp() OVERRIDE {
88     ASSERT_TRUE(data_dir_.CreateUniqueTempDir());
89     profile_manager_.reset(
90         new TestingProfileManager(TestingBrowserProcess::GetGlobal()));
91     ASSERT_TRUE(profile_manager_->SetUp());
92     profile_ = profile_manager_->CreateTestingProfile("testing-profile");
93
94     ServiceFactory::GetInstance()->SetTestingFactory(profile_, &CreateService);
95     Service* service = Service::Get(profile_);  // Owned by its factory.
96     service->SetFileSystemFactoryForTesting(
97         base::Bind(&FakeProvidedFileSystem::Create));
98
99     const bool result = service->MountFileSystem(kExtensionId,
100                                                  kFileSystemId,
101                                                  "Testing File System",
102                                                  false /* writable */);
103     ASSERT_TRUE(result);
104     FakeProvidedFileSystem* provided_file_system =
105         static_cast<FakeProvidedFileSystem*>(
106             service->GetProvidedFileSystem(kExtensionId, kFileSystemId));
107     ASSERT_TRUE(provided_file_system);
108     ASSERT_TRUE(provided_file_system->GetEntry(
109         base::FilePath::FromUTF8Unsafe(kFakeFilePath), &fake_file_));
110     const ProvidedFileSystemInfo& file_system_info =
111         service->GetProvidedFileSystem(kExtensionId, kFileSystemId)
112             ->GetFileSystemInfo();
113     const std::string mount_point_name =
114         file_system_info.mount_path().BaseName().AsUTF8Unsafe();
115
116     file_url_ = CreateFileSystemURL(
117         mount_point_name, base::FilePath::FromUTF8Unsafe(kFakeFilePath + 1));
118     ASSERT_TRUE(file_url_.is_valid());
119     wrong_file_url_ = CreateFileSystemURL(
120         mount_point_name, base::FilePath::FromUTF8Unsafe("im-not-here.txt"));
121     ASSERT_TRUE(wrong_file_url_.is_valid());
122   }
123
124   virtual void TearDown() OVERRIDE {
125     // Setting the testing factory to NULL will destroy the created service
126     // associated with the testing profile.
127     ServiceFactory::GetInstance()->SetTestingFactory(profile_, NULL);
128   }
129
130   content::TestBrowserThreadBundle thread_bundle_;
131   base::ScopedTempDir data_dir_;
132   scoped_ptr<TestingProfileManager> profile_manager_;
133   TestingProfile* profile_;  // Owned by TestingProfileManager.
134   FakeEntry fake_file_;
135   fileapi::FileSystemURL file_url_;
136   fileapi::FileSystemURL wrong_file_url_;
137 };
138
139 TEST_F(FileSystemProviderFileStreamReader, Read_AllAtOnce) {
140   EventLogger logger;
141
142   const int64 initial_offset = 0;
143   FileStreamReader reader(
144       NULL, file_url_, initial_offset, fake_file_.metadata.modification_time);
145   scoped_refptr<net::IOBuffer> io_buffer(
146       new net::IOBuffer(fake_file_.metadata.size));
147
148   const int result =
149       reader.Read(io_buffer.get(),
150                   fake_file_.metadata.size,
151                   base::Bind(&EventLogger::OnRead, logger.GetWeakPtr()));
152   EXPECT_EQ(net::ERR_IO_PENDING, result);
153   base::RunLoop().RunUntilIdle();
154
155   ASSERT_EQ(1u, logger.results().size());
156   EXPECT_LT(0, logger.results()[0]);
157   EXPECT_EQ(fake_file_.metadata.size, logger.results()[0]);
158
159   std::string buffer_as_string(io_buffer->data(), fake_file_.metadata.size);
160   EXPECT_EQ(fake_file_.contents, buffer_as_string);
161 }
162
163 TEST_F(FileSystemProviderFileStreamReader, Read_WrongFile) {
164   EventLogger logger;
165
166   const int64 initial_offset = 0;
167   FileStreamReader reader(NULL,
168                           wrong_file_url_,
169                           initial_offset,
170                           fake_file_.metadata.modification_time);
171   scoped_refptr<net::IOBuffer> io_buffer(
172       new net::IOBuffer(fake_file_.metadata.size));
173
174   const int result =
175       reader.Read(io_buffer.get(),
176                   fake_file_.metadata.size,
177                   base::Bind(&EventLogger::OnRead, logger.GetWeakPtr()));
178   EXPECT_EQ(net::ERR_IO_PENDING, result);
179   base::RunLoop().RunUntilIdle();
180
181   ASSERT_EQ(1u, logger.results().size());
182   EXPECT_EQ(net::ERR_FILE_NOT_FOUND, logger.results()[0]);
183 }
184
185 TEST_F(FileSystemProviderFileStreamReader, Read_InChunks) {
186   EventLogger logger;
187
188   const int64 initial_offset = 0;
189   FileStreamReader reader(
190       NULL, file_url_, initial_offset, fake_file_.metadata.modification_time);
191
192   for (int64 offset = 0; offset < fake_file_.metadata.size; ++offset) {
193     scoped_refptr<net::IOBuffer> io_buffer(new net::IOBuffer(1));
194     const int result =
195         reader.Read(io_buffer.get(),
196                     1,
197                     base::Bind(&EventLogger::OnRead, logger.GetWeakPtr()));
198     EXPECT_EQ(net::ERR_IO_PENDING, result);
199     base::RunLoop().RunUntilIdle();
200     ASSERT_EQ(offset + 1, static_cast<int64>(logger.results().size()));
201     EXPECT_EQ(1, logger.results()[offset]);
202     EXPECT_EQ(fake_file_.contents[offset], io_buffer->data()[0]);
203   }
204 }
205
206 TEST_F(FileSystemProviderFileStreamReader, Read_Slice) {
207   EventLogger logger;
208
209   // Trim first 3 and last 3 characters.
210   const int64 initial_offset = 3;
211   const int length = fake_file_.metadata.size - initial_offset - 3;
212   ASSERT_GT(fake_file_.metadata.size, initial_offset);
213   ASSERT_LT(0, length);
214
215   FileStreamReader reader(
216       NULL, file_url_, initial_offset, fake_file_.metadata.modification_time);
217   scoped_refptr<net::IOBuffer> io_buffer(new net::IOBuffer(length));
218
219   const int result =
220       reader.Read(io_buffer.get(),
221                   length,
222                   base::Bind(&EventLogger::OnRead, logger.GetWeakPtr()));
223   EXPECT_EQ(net::ERR_IO_PENDING, result);
224   base::RunLoop().RunUntilIdle();
225
226   ASSERT_EQ(1u, logger.results().size());
227   EXPECT_EQ(length, logger.results()[0]);
228
229   std::string buffer_as_string(io_buffer->data(), length);
230   std::string expected_buffer(fake_file_.contents.data() + initial_offset,
231                               length);
232   EXPECT_EQ(expected_buffer, buffer_as_string);
233 }
234
235 TEST_F(FileSystemProviderFileStreamReader, Read_Beyond) {
236   EventLogger logger;
237
238   // Request reading 1KB more than available.
239   const int64 initial_offset = 0;
240   const int length = fake_file_.metadata.size + 1024;
241
242   FileStreamReader reader(
243       NULL, file_url_, initial_offset, fake_file_.metadata.modification_time);
244   scoped_refptr<net::IOBuffer> io_buffer(new net::IOBuffer(length));
245
246   const int result =
247       reader.Read(io_buffer.get(),
248                   length,
249                   base::Bind(&EventLogger::OnRead, logger.GetWeakPtr()));
250   EXPECT_EQ(net::ERR_IO_PENDING, result);
251   base::RunLoop().RunUntilIdle();
252
253   ASSERT_EQ(1u, logger.results().size());
254   EXPECT_LT(0, logger.results()[0]);
255   EXPECT_EQ(fake_file_.metadata.size, logger.results()[0]);
256
257   std::string buffer_as_string(io_buffer->data(), fake_file_.metadata.size);
258   EXPECT_EQ(fake_file_.contents, buffer_as_string);
259 }
260
261 TEST_F(FileSystemProviderFileStreamReader, Read_ModifiedFile) {
262   EventLogger logger;
263
264   const int64 initial_offset = 0;
265   FileStreamReader reader(NULL, file_url_, initial_offset, base::Time::Max());
266
267   scoped_refptr<net::IOBuffer> io_buffer(
268       new net::IOBuffer(fake_file_.metadata.size));
269   const int result =
270       reader.Read(io_buffer.get(),
271                   fake_file_.metadata.size,
272                   base::Bind(&EventLogger::OnRead, logger.GetWeakPtr()));
273
274   EXPECT_EQ(net::ERR_IO_PENDING, result);
275   base::RunLoop().RunUntilIdle();
276
277   ASSERT_EQ(1u, logger.results().size());
278   EXPECT_EQ(net::ERR_UPLOAD_FILE_CHANGED, logger.results()[0]);
279 }
280
281 TEST_F(FileSystemProviderFileStreamReader, Read_ExpectedModificationTimeNull) {
282   EventLogger logger;
283
284   const int64 initial_offset = 0;
285   FileStreamReader reader(NULL, file_url_, initial_offset, base::Time());
286
287   scoped_refptr<net::IOBuffer> io_buffer(
288       new net::IOBuffer(fake_file_.metadata.size));
289   const int result =
290       reader.Read(io_buffer.get(),
291                   fake_file_.metadata.size,
292                   base::Bind(&EventLogger::OnRead, logger.GetWeakPtr()));
293
294   EXPECT_EQ(net::ERR_IO_PENDING, result);
295   base::RunLoop().RunUntilIdle();
296
297   ASSERT_EQ(1u, logger.results().size());
298   EXPECT_EQ(fake_file_.metadata.size, logger.results()[0]);
299
300   std::string buffer_as_string(io_buffer->data(), fake_file_.metadata.size);
301   EXPECT_EQ(fake_file_.contents, buffer_as_string);
302 }
303
304 TEST_F(FileSystemProviderFileStreamReader, GetLength) {
305   EventLogger logger;
306
307   const int64 initial_offset = 0;
308   FileStreamReader reader(
309       NULL, file_url_, initial_offset, fake_file_.metadata.modification_time);
310
311   const int result = reader.GetLength(
312       base::Bind(&EventLogger::OnGetLength, logger.GetWeakPtr()));
313   EXPECT_EQ(net::ERR_IO_PENDING, result);
314   base::RunLoop().RunUntilIdle();
315
316   ASSERT_EQ(1u, logger.results().size());
317   EXPECT_LT(0, logger.results()[0]);
318   EXPECT_EQ(fake_file_.metadata.size, logger.results()[0]);
319 }
320
321 TEST_F(FileSystemProviderFileStreamReader, GetLength_WrongFile) {
322   EventLogger logger;
323
324   const int64 initial_offset = 0;
325   FileStreamReader reader(NULL,
326                           wrong_file_url_,
327                           initial_offset,
328                           fake_file_.metadata.modification_time);
329
330   const int result = reader.GetLength(
331       base::Bind(&EventLogger::OnGetLength, logger.GetWeakPtr()));
332   EXPECT_EQ(net::ERR_IO_PENDING, result);
333   base::RunLoop().RunUntilIdle();
334
335   ASSERT_EQ(1u, logger.results().size());
336   EXPECT_EQ(net::ERR_FILE_NOT_FOUND, logger.results()[0]);
337 }
338
339 TEST_F(FileSystemProviderFileStreamReader, GetLength_ModifiedFile) {
340   EventLogger logger;
341
342   const int64 initial_offset = 0;
343   FileStreamReader reader(NULL, file_url_, initial_offset, base::Time::Max());
344
345   const int result = reader.GetLength(
346       base::Bind(&EventLogger::OnGetLength, logger.GetWeakPtr()));
347   EXPECT_EQ(net::ERR_IO_PENDING, result);
348   base::RunLoop().RunUntilIdle();
349
350   ASSERT_EQ(1u, logger.results().size());
351   EXPECT_EQ(net::ERR_UPLOAD_FILE_CHANGED, logger.results()[0]);
352 }
353
354 TEST_F(FileSystemProviderFileStreamReader,
355        GetLength_ExpectedModificationTimeNull) {
356   EventLogger logger;
357
358   const int64 initial_offset = 0;
359   FileStreamReader reader(NULL, file_url_, initial_offset, base::Time());
360
361   const int result = reader.GetLength(
362       base::Bind(&EventLogger::OnGetLength, logger.GetWeakPtr()));
363   EXPECT_EQ(net::ERR_IO_PENDING, result);
364   base::RunLoop().RunUntilIdle();
365
366   ASSERT_EQ(1u, logger.results().size());
367   EXPECT_LT(0, logger.results()[0]);
368   EXPECT_EQ(fake_file_.metadata.size, logger.results()[0]);
369 }
370
371 }  // namespace file_system_provider
372 }  // namespace chromeos