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_browser_process.h"
15 #include "chrome/test/base/testing_profile.h"
16 #include "chrome/test/base/testing_profile_manager.h"
17 #include "content/public/test/test_browser_thread_bundle.h"
18 #include "testing/gtest/include/gtest/gtest.h"
20 namespace sync_file_system {
22 using drive_backend::APIUtilInterface;
23 using drive_backend::FakeAPIUtil;
27 const char kTestProfileName[] = "test-profile";
29 const char kSyncRootResourceId[] = "folder:sync_root_resource_id";
31 void DidInitialize(bool* done, SyncStatusCode status, bool created) {
32 EXPECT_EQ(SYNC_STATUS_OK, status);
36 void ExpectEqStatus(bool* done,
37 SyncStatusCode expected,
38 SyncStatusCode actual) {
41 EXPECT_EQ(expected, actual);
44 void ExpectOkStatus(SyncStatusCode status) {
45 EXPECT_EQ(SYNC_STATUS_OK, status);
50 class DriveFileSyncServiceTest : public testing::Test {
52 DriveFileSyncServiceTest()
53 : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
54 profile_manager_(TestingBrowserProcess::GetGlobal()),
56 metadata_store_(NULL) {}
58 virtual void SetUp() OVERRIDE {
59 ASSERT_TRUE(profile_manager_.SetUp());
61 RegisterSyncableFileSystem();
62 fake_api_util_ = new FakeAPIUtil;
64 ASSERT_TRUE(scoped_base_dir_.CreateUniqueTempDir());
65 base_dir_ = scoped_base_dir_.path();
66 metadata_store_ = new DriveMetadataStore(
67 base_dir_, base::MessageLoopProxy::current().get());
69 metadata_store_->Initialize(base::Bind(&DidInitialize, &done));
70 base::RunLoop().RunUntilIdle();
71 metadata_store_->SetSyncRootDirectory(kSyncRootResourceId);
74 sync_service_ = DriveFileSyncService::CreateForTesting(
75 profile_manager_.CreateTestingProfile(kTestProfileName),
77 scoped_ptr<APIUtilInterface>(fake_api_util_),
78 scoped_ptr<DriveMetadataStore>(metadata_store_)).Pass();
79 base::RunLoop().RunUntilIdle();
82 virtual void TearDown() OVERRIDE {
83 metadata_store_ = NULL;
84 fake_api_util_ = NULL;
85 sync_service_.reset();
86 base::RunLoop().RunUntilIdle();
88 base_dir_ = base::FilePath();
89 RevokeSyncableFileSystem();
92 virtual ~DriveFileSyncServiceTest() {
96 FakeAPIUtil* fake_api_util() { return fake_api_util_; }
97 DriveMetadataStore* metadata_store() { return metadata_store_; }
98 DriveFileSyncService* sync_service() { return sync_service_.get(); }
99 std::map<GURL, std::string>* pending_batch_sync_origins() {
100 return &(sync_service()->pending_batch_sync_origins_);
103 // Helper function to add an origin to the given origin sync status. To make
104 // naming easier, each origin, resourceID, etc. will all share the same
105 // prefixes and only be distinguished by the given suffix ID which could be a
106 // number (1, 2, 3, etc.) or a letter (A, B, C, etc.).
107 // e.g. originA, originB, folder:resource_idA, folder:resource_idB, etc.
108 void AddOrigin(std::string status, const char* suffix) {
109 const GURL origin(std::string("chrome-extension://app_") + suffix);
110 const std::string resource_id(std::string("folder:resource_id") + suffix);
112 if (status == "Pending") {
113 pending_batch_sync_origins()->insert(std::make_pair(origin, resource_id));
114 } else if (status == "Enabled") {
115 metadata_store()->AddIncrementalSyncOrigin(origin, resource_id);
116 } else if (status == "Disabled") {
117 metadata_store()->AddIncrementalSyncOrigin(origin, resource_id);
118 metadata_store()->DisableOrigin(origin, base::Bind(&ExpectOkStatus));
124 bool VerifyOriginStatusCount(size_t expected_pending,
125 size_t expected_enabled,
126 size_t expected_disabled) {
127 size_t actual_pending = pending_batch_sync_origins()->size();
128 size_t actual_enabled = metadata_store()->incremental_sync_origins().size();
129 size_t actual_disabled = metadata_store()->disabled_origins().size();
131 // Prints which counts don't match up if any.
132 EXPECT_EQ(expected_pending, actual_pending);
133 EXPECT_EQ(expected_enabled, actual_enabled);
134 EXPECT_EQ(expected_disabled, actual_disabled);
136 // If any count doesn't match, the original line number can be printed by
137 // simply adding ASSERT_TRUE on the call to this function.
138 if (expected_pending == actual_pending &&
139 expected_enabled == actual_enabled &&
140 expected_disabled == actual_disabled)
147 base::ScopedTempDir scoped_base_dir_;
148 content::TestBrowserThreadBundle thread_bundle_;
150 TestingProfileManager profile_manager_;
151 base::FilePath base_dir_;
153 FakeAPIUtil* fake_api_util_; // Owned by |sync_service_|.
154 DriveMetadataStore* metadata_store_; // Owned by |sync_service_|.
156 scoped_ptr<DriveFileSyncService> sync_service_;
158 DISALLOW_COPY_AND_ASSIGN(DriveFileSyncServiceTest);
161 TEST_F(DriveFileSyncServiceTest, UninstallOrigin) {
162 // Add fake app origin directory using fake drive_sync_client.
163 std::string origin_dir_resource_id = "uninstalledappresourceid";
164 fake_api_util()->PushRemoteChange("parent_id",
166 "uninstall_me_folder",
167 origin_dir_resource_id,
172 // Add meta_data entry so GURL->resourse_id mapping is there.
173 const GURL origin_gurl("chrome-extension://uninstallme");
174 metadata_store()->AddIncrementalSyncOrigin(origin_gurl,
175 origin_dir_resource_id);
177 // Delete the origin directory.
179 sync_service()->UninstallOrigin(
181 RemoteFileSyncService::UNINSTALL_AND_PURGE_REMOTE,
182 base::Bind(&ExpectEqStatus, &done, SYNC_STATUS_OK));
183 base::RunLoop().RunUntilIdle();
186 // Assert the App's origin folder was marked as deleted.
187 EXPECT_TRUE(fake_api_util()->remote_resources().find(
188 origin_dir_resource_id)->second.deleted);
191 TEST_F(DriveFileSyncServiceTest, UninstallUnpackedOrigin) {
192 // Add fake app origin directory using fake drive_sync_client.
193 std::string origin_dir_resource_id = "uninstalledappresourceid";
194 fake_api_util()->PushRemoteChange("parent_id",
196 "uninstall_me_folder",
197 origin_dir_resource_id,
202 // Add meta_data entry so GURL->resourse_id mapping is there.
203 const GURL origin_gurl("chrome-extension://uninstallme");
204 metadata_store()->AddIncrementalSyncOrigin(origin_gurl,
205 origin_dir_resource_id);
207 // Uninstall the origin.
209 sync_service()->UninstallOrigin(
211 RemoteFileSyncService::UNINSTALL_AND_KEEP_REMOTE,
212 base::Bind(&ExpectEqStatus, &done, SYNC_STATUS_OK));
213 base::RunLoop().RunUntilIdle();
216 // Assert the App's origin folder has not been deleted.
217 EXPECT_FALSE(fake_api_util()->remote_resources().find(
218 origin_dir_resource_id)->second.deleted);
221 TEST_F(DriveFileSyncServiceTest, UninstallOriginWithoutOriginDirectory) {
222 // Not add fake app origin directory.
223 std::string origin_dir_resource_id = "uninstalledappresourceid";
225 // Add meta_data entry so GURL->resourse_id mapping is there.
226 const GURL origin_gurl("chrome-extension://uninstallme");
227 metadata_store()->AddIncrementalSyncOrigin(origin_gurl,
228 origin_dir_resource_id);
230 // Delete the origin directory (but not found).
232 sync_service()->UninstallOrigin(
234 RemoteFileSyncService::UNINSTALL_AND_PURGE_REMOTE,
235 base::Bind(&ExpectEqStatus, &done, SYNC_STATUS_OK));
236 base::RunLoop().RunUntilIdle();
239 // Assert the App's origin folder does not exist.
240 const FakeAPIUtil::RemoteResourceByResourceId& remote_resources =
241 fake_api_util()->remote_resources();
242 EXPECT_TRUE(remote_resources.find(origin_dir_resource_id) ==
243 remote_resources.end());
246 TEST_F(DriveFileSyncServiceTest, DisableOriginPendingOrigin) {
247 // Disable a pending origin after DriveFileSystemService has already started.
248 const GURL origin("chrome-extension://app");
249 std::string origin_resource_id = "app_resource_id";
250 pending_batch_sync_origins()->insert(std::make_pair(origin,
251 origin_resource_id));
252 ASSERT_TRUE(VerifyOriginStatusCount(1u, 0u, 0u));
254 // Pending origins that are disabled are dropped and do not go to disabled.
255 sync_service()->DisableOrigin(origin, base::Bind(&ExpectOkStatus));
256 base::RunLoop().RunUntilIdle();
257 ASSERT_TRUE(VerifyOriginStatusCount(0u, 0u, 0u));
260 TEST_F(DriveFileSyncServiceTest,
261 DisableOriginIncrementalOrigin) {
262 // Disable a pending origin after DriveFileSystemService has already started.
263 const GURL origin("chrome-extension://app");
264 std::string origin_resource_id = "app_resource_id";
265 metadata_store()->AddIncrementalSyncOrigin(origin, origin_resource_id);
266 ASSERT_TRUE(VerifyOriginStatusCount(0u, 1u, 0u));
268 sync_service()->DisableOrigin(origin, base::Bind(&ExpectOkStatus));
269 base::RunLoop().RunUntilIdle();
270 ASSERT_TRUE(VerifyOriginStatusCount(0u, 0u, 1u));
273 TEST_F(DriveFileSyncServiceTest, EnableOrigin) {
274 const GURL origin("chrome-extension://app");
275 std::string origin_resource_id = "app_resource_id";
276 metadata_store()->AddIncrementalSyncOrigin(origin, origin_resource_id);
277 metadata_store()->DisableOrigin(origin, base::Bind(&ExpectOkStatus));
278 ASSERT_TRUE(VerifyOriginStatusCount(0u, 0u, 1u));
280 // Re-enable the previously disabled origin. It initially goes to pending
281 // status and then to enabled (incremental) again when NotifyTasksDone() in
282 // SyncTaskManager invokes MaybeStartFetchChanges() and pending
284 sync_service()->EnableOrigin(origin, base::Bind(&ExpectOkStatus));
285 base::RunLoop().RunUntilIdle();
286 ASSERT_TRUE(VerifyOriginStatusCount(0u, 1u, 0u));
289 TEST_F(DriveFileSyncServiceTest, GetOriginStatusMap) {
290 RemoteFileSyncService::OriginStatusMap origin_status_map;
291 sync_service()->GetOriginStatusMap(&origin_status_map);
292 ASSERT_EQ(0u, origin_status_map.size());
294 // Add 3 pending, 2 enabled and 1 disabled sync origin.
295 AddOrigin("Pending", "p0");
296 AddOrigin("Pending", "p1");
297 AddOrigin("Pending", "p2");
298 AddOrigin("Enabled", "e0");
299 AddOrigin("Enabled", "e1");
300 AddOrigin("Disabled", "d0");
302 sync_service()->GetOriginStatusMap(&origin_status_map);
303 ASSERT_EQ(6u, origin_status_map.size());
304 EXPECT_EQ("Pending", origin_status_map[GURL("chrome-extension://app_p0")]);
305 EXPECT_EQ("Pending", origin_status_map[GURL("chrome-extension://app_p1")]);
306 EXPECT_EQ("Pending", origin_status_map[GURL("chrome-extension://app_p2")]);
307 EXPECT_EQ("Enabled", origin_status_map[GURL("chrome-extension://app_e0")]);
308 EXPECT_EQ("Enabled", origin_status_map[GURL("chrome-extension://app_e1")]);
309 EXPECT_EQ("Disabled", origin_status_map[GURL("chrome-extension://app_d0")]);
312 } // namespace sync_file_system