9931fe15a5697df38268a25543d2c566ad0c0a19
[platform/framework/web/crosswalk.git] / src / chrome / browser / sync_file_system / drive_backend_v1 / drive_file_sync_service_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 "chrome/browser/sync_file_system/drive_backend_v1/drive_file_sync_service.h"
6
7 #include "base/bind.h"
8 #include "base/message_loop/message_loop_proxy.h"
9 #include "base/run_loop.h"
10 #include "chrome/browser/sync_file_system/drive_backend_v1/drive_metadata_store.h"
11 #include "chrome/browser/sync_file_system/drive_backend_v1/fake_api_util.h"
12 #include "chrome/browser/sync_file_system/sync_file_system.pb.h"
13 #include "chrome/browser/sync_file_system/syncable_file_system_util.h"
14 #include "chrome/test/base/testing_profile.h"
15 #include "content/public/test/test_browser_thread_bundle.h"
16 #include "testing/gtest/include/gtest/gtest.h"
17
18 namespace sync_file_system {
19
20 using drive_backend::APIUtilInterface;
21 using drive_backend::FakeAPIUtil;
22
23 namespace {
24
25 const char kSyncRootResourceId[] = "folder:sync_root_resource_id";
26
27 void DidInitialize(bool* done, SyncStatusCode status, bool created) {
28   EXPECT_EQ(SYNC_STATUS_OK, status);
29   *done = true;
30 }
31
32 void ExpectEqStatus(bool* done,
33                     SyncStatusCode expected,
34                     SyncStatusCode actual) {
35   EXPECT_FALSE(*done);
36   *done = true;
37   EXPECT_EQ(expected, actual);
38 }
39
40 void ExpectOkStatus(SyncStatusCode status) {
41   EXPECT_EQ(SYNC_STATUS_OK, status);
42 }
43
44 }  // namespace
45
46 class DriveFileSyncServiceTest : public testing::Test {
47  public:
48   DriveFileSyncServiceTest()
49       : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
50         fake_api_util_(NULL),
51         metadata_store_(NULL) {}
52
53   virtual void SetUp() OVERRIDE {
54     RegisterSyncableFileSystem();
55     fake_api_util_ = new FakeAPIUtil;
56
57     ASSERT_TRUE(scoped_base_dir_.CreateUniqueTempDir());
58     base_dir_ = scoped_base_dir_.path();
59     metadata_store_ = new DriveMetadataStore(
60         base_dir_, base::MessageLoopProxy::current().get());
61     bool done = false;
62     metadata_store_->Initialize(base::Bind(&DidInitialize, &done));
63     base::RunLoop().RunUntilIdle();
64     metadata_store_->SetSyncRootDirectory(kSyncRootResourceId);
65     EXPECT_TRUE(done);
66
67     sync_service_ = DriveFileSyncService::CreateForTesting(
68         &profile_,
69         base_dir_,
70         scoped_ptr<APIUtilInterface>(fake_api_util_),
71         scoped_ptr<DriveMetadataStore>(metadata_store_)).Pass();
72     base::RunLoop().RunUntilIdle();
73   }
74
75   virtual void TearDown() OVERRIDE {
76     metadata_store_ = NULL;
77     fake_api_util_ = NULL;
78     sync_service_.reset();
79     base::RunLoop().RunUntilIdle();
80
81     base_dir_ = base::FilePath();
82     RevokeSyncableFileSystem();
83   }
84
85   virtual ~DriveFileSyncServiceTest() {
86   }
87
88  protected:
89   FakeAPIUtil* fake_api_util() { return fake_api_util_; }
90   DriveMetadataStore* metadata_store() { return metadata_store_; }
91   DriveFileSyncService* sync_service() { return sync_service_.get(); }
92   std::map<GURL, std::string>* pending_batch_sync_origins() {
93     return &(sync_service()->pending_batch_sync_origins_);
94   }
95
96   // Helper function to add an origin to the given origin sync status. To make
97   // naming easier, each origin, resourceID, etc. will all share the same
98   // prefixes and only be distinguished by the given suffix ID which could be a
99   // number (1, 2, 3, etc.) or a letter (A, B, C, etc.).
100   // e.g. originA, originB, folder:resource_idA, folder:resource_idB, etc.
101   void AddOrigin(std::string status, const char* suffix) {
102     const GURL origin(std::string("chrome-extension://app_") + suffix);
103     const std::string resource_id(std::string("folder:resource_id") + suffix);
104
105     if (status == "Pending") {
106       pending_batch_sync_origins()->insert(std::make_pair(origin, resource_id));
107     } else if (status == "Enabled") {
108       metadata_store()->AddIncrementalSyncOrigin(origin, resource_id);
109     } else if (status == "Disabled") {
110       metadata_store()->AddIncrementalSyncOrigin(origin, resource_id);
111       metadata_store()->DisableOrigin(origin, base::Bind(&ExpectOkStatus));
112     } else {
113       NOTREACHED();
114     }
115   }
116
117   bool VerifyOriginStatusCount(size_t expected_pending,
118                                size_t expected_enabled,
119                                size_t expected_disabled) {
120     size_t actual_pending = pending_batch_sync_origins()->size();
121     size_t actual_enabled = metadata_store()->incremental_sync_origins().size();
122     size_t actual_disabled = metadata_store()->disabled_origins().size();
123
124     // Prints which counts don't match up if any.
125     EXPECT_EQ(expected_pending, actual_pending);
126     EXPECT_EQ(expected_enabled, actual_enabled);
127     EXPECT_EQ(expected_disabled, actual_disabled);
128
129     // If any count doesn't match, the original line number can be printed by
130     // simply adding ASSERT_TRUE on the call to this function.
131     if (expected_pending == actual_pending &&
132         expected_enabled == actual_enabled &&
133         expected_disabled == actual_disabled)
134       return true;
135
136     return false;
137   }
138
139  private:
140   base::ScopedTempDir scoped_base_dir_;
141   content::TestBrowserThreadBundle thread_bundle_;
142
143   TestingProfile profile_;
144   base::FilePath base_dir_;
145
146   FakeAPIUtil* fake_api_util_;          // Owned by |sync_service_|.
147   DriveMetadataStore* metadata_store_;  // Owned by |sync_service_|.
148
149   scoped_ptr<DriveFileSyncService> sync_service_;
150
151   DISALLOW_COPY_AND_ASSIGN(DriveFileSyncServiceTest);
152 };
153
154 TEST_F(DriveFileSyncServiceTest, UninstallOrigin) {
155   // Add fake app origin directory using fake drive_sync_client.
156   std::string origin_dir_resource_id = "uninstalledappresourceid";
157   fake_api_util()->PushRemoteChange("parent_id",
158                                     "parent_title",
159                                     "uninstall_me_folder",
160                                     origin_dir_resource_id,
161                                     "resource_md5",
162                                     SYNC_FILE_TYPE_FILE,
163                                     false);
164
165   // Add meta_data entry so GURL->resourse_id mapping is there.
166   const GURL origin_gurl("chrome-extension://uninstallme");
167   metadata_store()->AddIncrementalSyncOrigin(origin_gurl,
168                                              origin_dir_resource_id);
169
170   // Delete the origin directory.
171   bool done = false;
172   sync_service()->UninstallOrigin(
173       origin_gurl,
174       RemoteFileSyncService::UNINSTALL_AND_PURGE_REMOTE,
175       base::Bind(&ExpectEqStatus, &done, SYNC_STATUS_OK));
176   base::RunLoop().RunUntilIdle();
177   EXPECT_TRUE(done);
178
179   // Assert the App's origin folder was marked as deleted.
180   EXPECT_TRUE(fake_api_util()->remote_resources().find(
181       origin_dir_resource_id)->second.deleted);
182 }
183
184 TEST_F(DriveFileSyncServiceTest, UninstallUnpackedOrigin) {
185   // Add fake app origin directory using fake drive_sync_client.
186   std::string origin_dir_resource_id = "uninstalledappresourceid";
187   fake_api_util()->PushRemoteChange("parent_id",
188                                     "parent_title",
189                                     "uninstall_me_folder",
190                                     origin_dir_resource_id,
191                                     "resource_md5",
192                                     SYNC_FILE_TYPE_FILE,
193                                     false);
194
195   // Add meta_data entry so GURL->resourse_id mapping is there.
196   const GURL origin_gurl("chrome-extension://uninstallme");
197   metadata_store()->AddIncrementalSyncOrigin(origin_gurl,
198                                              origin_dir_resource_id);
199
200   // Uninstall the origin.
201   bool done = false;
202   sync_service()->UninstallOrigin(
203       origin_gurl,
204       RemoteFileSyncService::UNINSTALL_AND_KEEP_REMOTE,
205       base::Bind(&ExpectEqStatus, &done, SYNC_STATUS_OK));
206   base::RunLoop().RunUntilIdle();
207   EXPECT_TRUE(done);
208
209   // Assert the App's origin folder has not been deleted.
210   EXPECT_FALSE(fake_api_util()->remote_resources().find(
211       origin_dir_resource_id)->second.deleted);
212 }
213
214 TEST_F(DriveFileSyncServiceTest, UninstallOriginWithoutOriginDirectory) {
215   // Not add fake app origin directory.
216   std::string origin_dir_resource_id = "uninstalledappresourceid";
217
218   // Add meta_data entry so GURL->resourse_id mapping is there.
219   const GURL origin_gurl("chrome-extension://uninstallme");
220   metadata_store()->AddIncrementalSyncOrigin(origin_gurl,
221                                              origin_dir_resource_id);
222
223   // Delete the origin directory (but not found).
224   bool done = false;
225   sync_service()->UninstallOrigin(
226       origin_gurl,
227       RemoteFileSyncService::UNINSTALL_AND_PURGE_REMOTE,
228       base::Bind(&ExpectEqStatus, &done, SYNC_STATUS_OK));
229   base::RunLoop().RunUntilIdle();
230   EXPECT_TRUE(done);
231
232   // Assert the App's origin folder does not exist.
233   const FakeAPIUtil::RemoteResourceByResourceId& remote_resources =
234       fake_api_util()->remote_resources();
235   EXPECT_TRUE(remote_resources.find(origin_dir_resource_id) ==
236               remote_resources.end());
237 }
238
239 TEST_F(DriveFileSyncServiceTest, DisableOriginPendingOrigin) {
240   // Disable a pending origin after DriveFileSystemService has already started.
241   const GURL origin("chrome-extension://app");
242   std::string origin_resource_id = "app_resource_id";
243   pending_batch_sync_origins()->insert(std::make_pair(origin,
244                                                       origin_resource_id));
245   ASSERT_TRUE(VerifyOriginStatusCount(1u, 0u, 0u));
246
247   // Pending origins that are disabled are dropped and do not go to disabled.
248   sync_service()->DisableOrigin(origin, base::Bind(&ExpectOkStatus));
249   base::RunLoop().RunUntilIdle();
250   ASSERT_TRUE(VerifyOriginStatusCount(0u, 0u, 0u));
251 }
252
253 TEST_F(DriveFileSyncServiceTest,
254        DisableOriginIncrementalOrigin) {
255   // Disable a pending origin after DriveFileSystemService has already started.
256   const GURL origin("chrome-extension://app");
257   std::string origin_resource_id = "app_resource_id";
258   metadata_store()->AddIncrementalSyncOrigin(origin, origin_resource_id);
259   ASSERT_TRUE(VerifyOriginStatusCount(0u, 1u, 0u));
260
261   sync_service()->DisableOrigin(origin, base::Bind(&ExpectOkStatus));
262   base::RunLoop().RunUntilIdle();
263   ASSERT_TRUE(VerifyOriginStatusCount(0u, 0u, 1u));
264 }
265
266 TEST_F(DriveFileSyncServiceTest, EnableOrigin) {
267   const GURL origin("chrome-extension://app");
268   std::string origin_resource_id = "app_resource_id";
269   metadata_store()->AddIncrementalSyncOrigin(origin, origin_resource_id);
270   metadata_store()->DisableOrigin(origin, base::Bind(&ExpectOkStatus));
271   ASSERT_TRUE(VerifyOriginStatusCount(0u, 0u, 1u));
272
273   // Re-enable the previously disabled origin. It initially goes to pending
274   // status and then to enabled (incremental) again when NotifyTasksDone() in
275   // SyncTaskManager invokes MaybeStartFetchChanges() and pending
276   // origins > 0.
277   sync_service()->EnableOrigin(origin, base::Bind(&ExpectOkStatus));
278   base::RunLoop().RunUntilIdle();
279   ASSERT_TRUE(VerifyOriginStatusCount(0u, 1u, 0u));
280 }
281
282 TEST_F(DriveFileSyncServiceTest, GetOriginStatusMap) {
283   RemoteFileSyncService::OriginStatusMap origin_status_map;
284   sync_service()->GetOriginStatusMap(&origin_status_map);
285   ASSERT_EQ(0u, origin_status_map.size());
286
287   // Add 3 pending, 2 enabled and 1 disabled sync origin.
288   AddOrigin("Pending", "p0");
289   AddOrigin("Pending", "p1");
290   AddOrigin("Pending", "p2");
291   AddOrigin("Enabled", "e0");
292   AddOrigin("Enabled", "e1");
293   AddOrigin("Disabled", "d0");
294
295   sync_service()->GetOriginStatusMap(&origin_status_map);
296   ASSERT_EQ(6u, origin_status_map.size());
297   EXPECT_EQ("Pending", origin_status_map[GURL("chrome-extension://app_p0")]);
298   EXPECT_EQ("Pending", origin_status_map[GURL("chrome-extension://app_p1")]);
299   EXPECT_EQ("Pending", origin_status_map[GURL("chrome-extension://app_p2")]);
300   EXPECT_EQ("Enabled", origin_status_map[GURL("chrome-extension://app_e0")]);
301   EXPECT_EQ("Enabled", origin_status_map[GURL("chrome-extension://app_e1")]);
302   EXPECT_EQ("Disabled", origin_status_map[GURL("chrome-extension://app_d0")]);
303 }
304
305 }  // namespace sync_file_system