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.
5 #include "chrome/browser/sync_file_system/drive_backend_v1/drive_file_sync_service.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"
18 namespace sync_file_system {
20 using drive_backend::APIUtilInterface;
21 using drive_backend::FakeAPIUtil;
25 const char kSyncRootResourceId[] = "folder:sync_root_resource_id";
27 void DidInitialize(bool* done, SyncStatusCode status, bool created) {
28 EXPECT_EQ(SYNC_STATUS_OK, status);
32 void ExpectEqStatus(bool* done,
33 SyncStatusCode expected,
34 SyncStatusCode actual) {
37 EXPECT_EQ(expected, actual);
40 void ExpectOkStatus(SyncStatusCode status) {
41 EXPECT_EQ(SYNC_STATUS_OK, status);
46 class DriveFileSyncServiceTest : public testing::Test {
48 DriveFileSyncServiceTest()
49 : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
51 metadata_store_(NULL) {}
53 virtual void SetUp() OVERRIDE {
54 RegisterSyncableFileSystem();
55 fake_api_util_ = new FakeAPIUtil;
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());
62 metadata_store_->Initialize(base::Bind(&DidInitialize, &done));
63 base::RunLoop().RunUntilIdle();
64 metadata_store_->SetSyncRootDirectory(kSyncRootResourceId);
67 sync_service_ = DriveFileSyncService::CreateForTesting(
70 scoped_ptr<APIUtilInterface>(fake_api_util_),
71 scoped_ptr<DriveMetadataStore>(metadata_store_)).Pass();
72 base::RunLoop().RunUntilIdle();
75 virtual void TearDown() OVERRIDE {
76 metadata_store_ = NULL;
77 fake_api_util_ = NULL;
78 sync_service_.reset();
79 base::RunLoop().RunUntilIdle();
81 base_dir_ = base::FilePath();
82 RevokeSyncableFileSystem();
85 virtual ~DriveFileSyncServiceTest() {
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_);
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);
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));
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();
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);
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)
140 base::ScopedTempDir scoped_base_dir_;
141 content::TestBrowserThreadBundle thread_bundle_;
143 TestingProfile profile_;
144 base::FilePath base_dir_;
146 FakeAPIUtil* fake_api_util_; // Owned by |sync_service_|.
147 DriveMetadataStore* metadata_store_; // Owned by |sync_service_|.
149 scoped_ptr<DriveFileSyncService> sync_service_;
151 DISALLOW_COPY_AND_ASSIGN(DriveFileSyncServiceTest);
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",
159 "uninstall_me_folder",
160 origin_dir_resource_id,
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);
170 // Delete the origin directory.
172 sync_service()->UninstallOrigin(
174 RemoteFileSyncService::UNINSTALL_AND_PURGE_REMOTE,
175 base::Bind(&ExpectEqStatus, &done, SYNC_STATUS_OK));
176 base::RunLoop().RunUntilIdle();
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);
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",
189 "uninstall_me_folder",
190 origin_dir_resource_id,
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);
200 // Uninstall the origin.
202 sync_service()->UninstallOrigin(
204 RemoteFileSyncService::UNINSTALL_AND_KEEP_REMOTE,
205 base::Bind(&ExpectEqStatus, &done, SYNC_STATUS_OK));
206 base::RunLoop().RunUntilIdle();
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);
214 TEST_F(DriveFileSyncServiceTest, UninstallOriginWithoutOriginDirectory) {
215 // Not add fake app origin directory.
216 std::string origin_dir_resource_id = "uninstalledappresourceid";
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);
223 // Delete the origin directory (but not found).
225 sync_service()->UninstallOrigin(
227 RemoteFileSyncService::UNINSTALL_AND_PURGE_REMOTE,
228 base::Bind(&ExpectEqStatus, &done, SYNC_STATUS_OK));
229 base::RunLoop().RunUntilIdle();
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());
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));
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));
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));
261 sync_service()->DisableOrigin(origin, base::Bind(&ExpectOkStatus));
262 base::RunLoop().RunUntilIdle();
263 ASSERT_TRUE(VerifyOriginStatusCount(0u, 0u, 1u));
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));
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
277 sync_service()->EnableOrigin(origin, base::Bind(&ExpectOkStatus));
278 base::RunLoop().RunUntilIdle();
279 ASSERT_TRUE(VerifyOriginStatusCount(0u, 1u, 0u));
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());
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");
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")]);
305 } // namespace sync_file_system