Upstream version 5.34.92.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / sync_file_system / local / syncable_file_system_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 "base/stl_util.h"
6 #include "chrome/browser/sync_file_system/local/canned_syncable_file_system.h"
7 #include "chrome/browser/sync_file_system/local/local_file_change_tracker.h"
8 #include "chrome/browser/sync_file_system/local/local_file_sync_context.h"
9 #include "chrome/browser/sync_file_system/local/sync_file_system_backend.h"
10 #include "chrome/browser/sync_file_system/syncable_file_system_util.h"
11 #include "content/public/test/sandbox_file_system_test_helper.h"
12 #include "content/public/test/test_browser_thread_bundle.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_context.h"
16 #include "webkit/browser/fileapi/file_system_operation_context.h"
17 #include "webkit/browser/fileapi/isolated_context.h"
18 #include "webkit/browser/quota/quota_manager.h"
19 #include "webkit/common/fileapi/file_system_types.h"
20 #include "webkit/common/quota/quota_types.h"
21
22 using base::PlatformFileError;
23 using content::SandboxFileSystemTestHelper;
24 using fileapi::FileSystemContext;
25 using fileapi::FileSystemOperationContext;
26 using fileapi::FileSystemURL;
27 using fileapi::FileSystemURLSet;
28 using quota::QuotaManager;
29 using quota::QuotaStatusCode;
30
31 namespace sync_file_system {
32
33 class SyncableFileSystemTest : public testing::Test {
34  public:
35   SyncableFileSystemTest()
36       : file_system_(GURL("http://example.com/"),
37                      base::MessageLoopProxy::current().get(),
38                      base::MessageLoopProxy::current().get()),
39         weak_factory_(this) {}
40
41   virtual void SetUp() {
42     ASSERT_TRUE(data_dir_.CreateUniqueTempDir());
43
44     file_system_.SetUp();
45
46     sync_context_ =
47         new LocalFileSyncContext(data_dir_.path(),
48                                  base::MessageLoopProxy::current().get(),
49                                  base::MessageLoopProxy::current().get());
50     ASSERT_EQ(
51         sync_file_system::SYNC_STATUS_OK,
52         file_system_.MaybeInitializeFileSystemContext(sync_context_.get()));
53   }
54
55   virtual void TearDown() {
56     if (sync_context_.get())
57       sync_context_->ShutdownOnUIThread();
58     sync_context_ = NULL;
59
60     file_system_.TearDown();
61
62     // Make sure we don't leave the external filesystem.
63     // (CannedSyncableFileSystem::TearDown does not do this as there may be
64     // multiple syncable file systems registered for the name)
65     RevokeSyncableFileSystem();
66   }
67
68  protected:
69   void VerifyAndClearChange(const FileSystemURL& url,
70                             const FileChange& expected_change) {
71     SCOPED_TRACE(testing::Message() << url.DebugString() <<
72                  " expecting:" << expected_change.DebugString());
73     // Get the changes for URL and verify.
74     FileChangeList changes;
75     change_tracker()->GetChangesForURL(url, &changes);
76     ASSERT_EQ(1U, changes.size());
77     SCOPED_TRACE(testing::Message() << url.DebugString() <<
78                  " actual:" << changes.DebugString());
79     EXPECT_EQ(expected_change, changes.front());
80
81     // Clear the URL from the change tracker.
82     change_tracker()->ClearChangesForURL(url);
83   }
84
85   FileSystemURL URL(const std::string& path) {
86     return file_system_.URL(path);
87   }
88
89   FileSystemContext* file_system_context() {
90     return file_system_.file_system_context();
91   }
92
93   LocalFileChangeTracker* change_tracker() {
94     return file_system_.backend()->change_tracker();
95   }
96
97   ScopedEnableSyncFSDirectoryOperation enable_directory_operation_;
98
99   base::ScopedTempDir data_dir_;
100   content::TestBrowserThreadBundle thread_bundle_;
101   CannedSyncableFileSystem file_system_;
102
103  private:
104   scoped_refptr<LocalFileSyncContext> sync_context_;
105
106   base::WeakPtrFactory<SyncableFileSystemTest> weak_factory_;
107
108   DISALLOW_COPY_AND_ASSIGN(SyncableFileSystemTest);
109 };
110
111 // Brief combined testing. Just see if all the sandbox feature works.
112 TEST_F(SyncableFileSystemTest, SyncableLocalSandboxCombined) {
113   // Opens a syncable file system.
114   EXPECT_EQ(base::File::FILE_OK,
115             file_system_.OpenFileSystem());
116
117   // Do some operations.
118   EXPECT_EQ(base::File::FILE_OK,
119             file_system_.CreateDirectory(URL("dir")));
120   EXPECT_EQ(base::File::FILE_OK,
121             file_system_.CreateFile(URL("dir/foo")));
122
123   const int64 kOriginalQuota = QuotaManager::kSyncableStorageDefaultHostQuota;
124
125   const int64 kQuota = 12345 * 1024;
126   QuotaManager::kSyncableStorageDefaultHostQuota = kQuota;
127   int64 usage, quota;
128   EXPECT_EQ(quota::kQuotaStatusOk,
129             file_system_.GetUsageAndQuota(&usage, &quota));
130
131   // Returned quota must be what we overrode. Usage must be greater than 0
132   // as creating a file or directory consumes some space.
133   EXPECT_EQ(kQuota, quota);
134   EXPECT_GT(usage, 0);
135
136   // Truncate to extend an existing file and see if the usage reflects it.
137   const int64 kFileSizeToExtend = 333;
138   EXPECT_EQ(base::File::FILE_OK,
139             file_system_.CreateFile(URL("dir/foo")));
140
141   EXPECT_EQ(base::File::FILE_OK,
142             file_system_.TruncateFile(URL("dir/foo"), kFileSizeToExtend));
143
144   int64 new_usage;
145   EXPECT_EQ(quota::kQuotaStatusOk,
146             file_system_.GetUsageAndQuota(&new_usage, &quota));
147   EXPECT_EQ(kFileSizeToExtend, new_usage - usage);
148
149   // Shrink the quota to the current usage, try to extend the file further
150   // and see if it fails.
151   QuotaManager::kSyncableStorageDefaultHostQuota = new_usage;
152   EXPECT_EQ(base::File::FILE_ERROR_NO_SPACE,
153             file_system_.TruncateFile(URL("dir/foo"), kFileSizeToExtend + 1));
154
155   usage = new_usage;
156   EXPECT_EQ(quota::kQuotaStatusOk,
157             file_system_.GetUsageAndQuota(&new_usage, &quota));
158   EXPECT_EQ(usage, new_usage);
159
160   // Deletes the file system.
161   EXPECT_EQ(base::File::FILE_OK,
162             file_system_.DeleteFileSystem());
163
164   // Now the usage must be zero.
165   EXPECT_EQ(quota::kQuotaStatusOk,
166             file_system_.GetUsageAndQuota(&usage, &quota));
167   EXPECT_EQ(0, usage);
168
169   // Restore the system default quota.
170   QuotaManager::kSyncableStorageDefaultHostQuota = kOriginalQuota;
171 }
172
173 // Combined testing with LocalFileChangeTracker.
174 TEST_F(SyncableFileSystemTest, ChangeTrackerSimple) {
175   EXPECT_EQ(base::File::FILE_OK,
176             file_system_.OpenFileSystem());
177
178   const char kPath0[] = "dir a";
179   const char kPath1[] = "dir a/dir";   // child of kPath0
180   const char kPath2[] = "dir a/file";  // child of kPath0
181   const char kPath3[] = "dir b";
182
183   // Do some operations.
184   EXPECT_EQ(base::File::FILE_OK,
185             file_system_.CreateDirectory(URL(kPath0)));  // Creates a dir.
186   EXPECT_EQ(base::File::FILE_OK,
187             file_system_.CreateDirectory(URL(kPath1)));  // Creates another.
188   EXPECT_EQ(base::File::FILE_OK,
189             file_system_.CreateFile(URL(kPath2)));       // Creates a file.
190   EXPECT_EQ(base::File::FILE_OK,
191             file_system_.TruncateFile(URL(kPath2), 1));  // Modifies the file.
192   EXPECT_EQ(base::File::FILE_OK,
193             file_system_.TruncateFile(URL(kPath2), 2));  // Modifies it again.
194
195   FileSystemURLSet urls;
196   file_system_.GetChangedURLsInTracker(&urls);
197
198   EXPECT_EQ(3U, urls.size());
199   EXPECT_TRUE(ContainsKey(urls, URL(kPath0)));
200   EXPECT_TRUE(ContainsKey(urls, URL(kPath1)));
201   EXPECT_TRUE(ContainsKey(urls, URL(kPath2)));
202
203   VerifyAndClearChange(URL(kPath0),
204                        FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
205                                   sync_file_system::SYNC_FILE_TYPE_DIRECTORY));
206   VerifyAndClearChange(URL(kPath1),
207                        FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
208                                   sync_file_system::SYNC_FILE_TYPE_DIRECTORY));
209   VerifyAndClearChange(URL(kPath2),
210                        FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
211                                   sync_file_system::SYNC_FILE_TYPE_FILE));
212
213   // Creates and removes a same directory.
214   EXPECT_EQ(base::File::FILE_OK,
215             file_system_.CreateDirectory(URL(kPath3)));
216   EXPECT_EQ(base::File::FILE_OK,
217             file_system_.Remove(URL(kPath3), false /* recursive */));
218
219   // The changes will be offset.
220   urls.clear();
221   file_system_.GetChangedURLsInTracker(&urls);
222   EXPECT_TRUE(urls.empty());
223
224   // Recursively removes the kPath0 directory.
225   EXPECT_EQ(base::File::FILE_OK,
226             file_system_.Remove(URL(kPath0), true /* recursive */));
227
228   urls.clear();
229   file_system_.GetChangedURLsInTracker(&urls);
230
231   // kPath0 and its all chidren (kPath1 and kPath2) must have been deleted.
232   EXPECT_EQ(3U, urls.size());
233   EXPECT_TRUE(ContainsKey(urls, URL(kPath0)));
234   EXPECT_TRUE(ContainsKey(urls, URL(kPath1)));
235   EXPECT_TRUE(ContainsKey(urls, URL(kPath2)));
236
237   VerifyAndClearChange(URL(kPath0),
238                        FileChange(FileChange::FILE_CHANGE_DELETE,
239                                   sync_file_system::SYNC_FILE_TYPE_DIRECTORY));
240   VerifyAndClearChange(URL(kPath1),
241                        FileChange(FileChange::FILE_CHANGE_DELETE,
242                                   sync_file_system::SYNC_FILE_TYPE_DIRECTORY));
243   VerifyAndClearChange(URL(kPath2),
244                        FileChange(FileChange::FILE_CHANGE_DELETE,
245                                   sync_file_system::SYNC_FILE_TYPE_FILE));
246 }
247
248 // Make sure directory operation is disabled (when it's configured so).
249 TEST_F(SyncableFileSystemTest, DisableDirectoryOperations) {
250   bool was_enabled = IsSyncFSDirectoryOperationEnabled();
251   SetEnableSyncFSDirectoryOperation(false);
252   EXPECT_EQ(base::File::FILE_OK,
253             file_system_.OpenFileSystem());
254
255   // Try some directory operations (which should fail).
256   EXPECT_EQ(base::File::FILE_ERROR_INVALID_OPERATION,
257             file_system_.CreateDirectory(URL("dir")));
258
259   // Set up another (non-syncable) local file system.
260   SandboxFileSystemTestHelper other_file_system_(
261       GURL("http://foo.com/"), fileapi::kFileSystemTypeTemporary);
262   other_file_system_.SetUp(file_system_.file_system_context());
263
264   // Create directory '/a' and file '/a/b' in the other file system.
265   const FileSystemURL kSrcDir = other_file_system_.CreateURLFromUTF8("/a");
266   const FileSystemURL kSrcChild = other_file_system_.CreateURLFromUTF8("/a/b");
267
268   EXPECT_EQ(base::File::FILE_OK,
269             fileapi::AsyncFileTestHelper::CreateDirectory(
270                 other_file_system_.file_system_context(), kSrcDir));
271   EXPECT_EQ(base::File::FILE_OK,
272             fileapi::AsyncFileTestHelper::CreateFile(
273                 other_file_system_.file_system_context(), kSrcChild));
274
275   // Now try copying the directory into the syncable file system, which should
276   // fail if directory operation is disabled. (http://crbug.com/161442)
277   EXPECT_NE(base::File::FILE_OK,
278             file_system_.Copy(kSrcDir, URL("dest")));
279
280   other_file_system_.TearDown();
281   SetEnableSyncFSDirectoryOperation(was_enabled);
282 }
283
284 }  // namespace sync_file_system