Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / sync_file_system / drive_backend / register_app_task_unittest.cc
blobc2de43be3926209882f18bac207e791bd4ee4dcd
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/register_app_task.h"
7 #include "base/files/scoped_temp_dir.h"
8 #include "base/format_macros.h"
9 #include "base/run_loop.h"
10 #include "base/strings/string_number_conversions.h"
11 #include "base/strings/stringprintf.h"
12 #include "chrome/browser/drive/drive_uploader.h"
13 #include "chrome/browser/drive/fake_drive_service.h"
14 #include "chrome/browser/sync_file_system/drive_backend/drive_backend_constants.h"
15 #include "chrome/browser/sync_file_system/drive_backend/drive_backend_util.h"
16 #include "chrome/browser/sync_file_system/drive_backend/fake_drive_service_helper.h"
17 #include "chrome/browser/sync_file_system/drive_backend/metadata_database.h"
18 #include "chrome/browser/sync_file_system/drive_backend/metadata_database.pb.h"
19 #include "chrome/browser/sync_file_system/drive_backend/sync_engine_context.h"
20 #include "chrome/browser/sync_file_system/sync_file_system_test_util.h"
21 #include "content/public/test/test_browser_thread_bundle.h"
22 #include "google_apis/drive/gdata_wapi_parser.h"
23 #include "testing/gtest/include/gtest/gtest.h"
24 #include "third_party/leveldatabase/src/include/leveldb/db.h"
25 #include "third_party/leveldatabase/src/include/leveldb/write_batch.h"
27 namespace sync_file_system {
28 namespace drive_backend {
30 namespace {
31 const int64 kSyncRootTrackerID = 100;
32 } // namespace
34 class RegisterAppTaskTest : public testing::Test,
35 public SyncEngineContext {
36 public:
37 RegisterAppTaskTest()
38 : next_file_id_(1000),
39 next_tracker_id_(10000) {}
40 virtual ~RegisterAppTaskTest() {}
42 virtual void SetUp() OVERRIDE {
43 ASSERT_TRUE(database_dir_.CreateUniqueTempDir());
45 fake_drive_service_.reset(new drive::FakeDriveService);
46 ASSERT_TRUE(fake_drive_service_->LoadAccountMetadataForWapi(
47 "sync_file_system/account_metadata.json"));
48 ASSERT_TRUE(fake_drive_service_->LoadResourceListForWapi(
49 "gdata/empty_feed.json"));
51 drive_uploader_.reset(new drive::DriveUploader(
52 fake_drive_service_.get(), base::MessageLoopProxy::current()));
54 fake_drive_service_helper_.reset(new FakeDriveServiceHelper(
55 fake_drive_service_.get(), drive_uploader_.get(),
56 kSyncRootFolderTitle));
58 ASSERT_EQ(google_apis::HTTP_CREATED,
59 fake_drive_service_helper_->AddOrphanedFolder(
60 kSyncRootFolderTitle, &sync_root_folder_id_));
63 virtual void TearDown() OVERRIDE {
64 metadata_database_.reset();
65 base::RunLoop().RunUntilIdle();
68 virtual drive::DriveServiceInterface* GetDriveService() OVERRIDE {
69 return fake_drive_service_.get();
72 virtual drive::DriveUploaderInterface* GetDriveUploader() OVERRIDE {
73 return NULL;
76 virtual MetadataDatabase* GetMetadataDatabase() OVERRIDE {
77 return metadata_database_.get();
80 virtual RemoteChangeProcessor* GetRemoteChangeProcessor() OVERRIDE {
81 return NULL;
84 virtual base::SequencedTaskRunner* GetBlockingTaskRunner() OVERRIDE {
85 return base::MessageLoopProxy::current();
88 protected:
89 scoped_ptr<leveldb::DB> OpenLevelDB() {
90 leveldb::DB* db = NULL;
91 leveldb::Options options;
92 options.create_if_missing = true;
93 leveldb::Status status =
94 leveldb::DB::Open(options, database_dir_.path().AsUTF8Unsafe(), &db);
95 EXPECT_TRUE(status.ok());
96 return make_scoped_ptr<leveldb::DB>(db);
99 void SetUpInitialData(leveldb::DB* db) {
100 ServiceMetadata service_metadata;
101 service_metadata.set_largest_change_id(100);
102 service_metadata.set_sync_root_tracker_id(kSyncRootTrackerID);
103 service_metadata.set_next_tracker_id(next_tracker_id_);
105 FileDetails sync_root_details;
106 sync_root_details.set_title(kSyncRootFolderTitle);
107 sync_root_details.set_file_kind(FILE_KIND_FOLDER);
108 sync_root_details.set_change_id(1);
110 FileMetadata sync_root_metadata;
111 sync_root_metadata.set_file_id(sync_root_folder_id_);
112 *sync_root_metadata.mutable_details() = sync_root_details;
114 FileTracker sync_root_tracker;
115 sync_root_tracker.set_tracker_id(service_metadata.sync_root_tracker_id());
116 sync_root_tracker.set_parent_tracker_id(0);
117 sync_root_tracker.set_file_id(sync_root_metadata.file_id());
118 sync_root_tracker.set_tracker_kind(TRACKER_KIND_REGULAR);
119 *sync_root_tracker.mutable_synced_details() = sync_root_details;
120 sync_root_tracker.set_active(true);
122 leveldb::WriteBatch batch;
123 batch.Put(kDatabaseVersionKey,
124 base::Int64ToString(kCurrentDatabaseVersion));
125 PutServiceMetadataToBatch(service_metadata, &batch);
126 PutFileToBatch(sync_root_metadata, &batch);
127 PutTrackerToBatch(sync_root_tracker, &batch);
128 EXPECT_TRUE(db->Write(leveldb::WriteOptions(), &batch).ok());
131 void CreateMetadataDatabase(scoped_ptr<leveldb::DB> db) {
132 ASSERT_TRUE(db);
133 ASSERT_FALSE(metadata_database_);
134 ASSERT_EQ(SYNC_STATUS_OK,
135 MetadataDatabase::CreateForTesting(
136 db.Pass(), &metadata_database_));
139 SyncStatusCode RunRegisterAppTask(const std::string& app_id) {
140 RegisterAppTask task(this, app_id);
141 SyncStatusCode status = SYNC_STATUS_UNKNOWN;
142 task.Run(CreateResultReceiver(&status));
143 base::RunLoop().RunUntilIdle();
144 return status;
147 void SetUpRegisteredAppRoot(
148 const std::string& app_id,
149 leveldb::DB* db) {
150 FileDetails details;
151 details.set_title(app_id);
152 details.set_file_kind(FILE_KIND_FOLDER);
153 details.add_parent_folder_ids(sync_root_folder_id_);
155 FileMetadata metadata;
156 metadata.set_file_id(GenerateFileID());
157 *metadata.mutable_details() = details;
159 FileTracker tracker;
160 tracker.set_parent_tracker_id(kSyncRootTrackerID);
161 tracker.set_tracker_id(next_tracker_id_++);
162 tracker.set_file_id(metadata.file_id());
163 tracker.set_tracker_kind(TRACKER_KIND_APP_ROOT);
164 tracker.set_app_id(app_id);
165 *tracker.mutable_synced_details() = details;
166 tracker.set_active(true);
168 leveldb::WriteBatch batch;
169 PutFileToBatch(metadata, &batch);
170 PutTrackerToBatch(tracker, &batch);
171 EXPECT_TRUE(db->Write(leveldb::WriteOptions(), &batch).ok());
174 void SetUpUnregisteredAppRoot(const std::string& app_id,
175 leveldb::DB* db) {
176 FileDetails details;
177 details.set_title(app_id);
178 details.set_file_kind(FILE_KIND_FOLDER);
179 details.add_parent_folder_ids(sync_root_folder_id_);
181 FileMetadata metadata;
182 metadata.set_file_id(GenerateFileID());
183 *metadata.mutable_details() = details;
185 FileTracker tracker;
186 tracker.set_parent_tracker_id(kSyncRootTrackerID);
187 tracker.set_tracker_id(next_tracker_id_++);
188 tracker.set_file_id(metadata.file_id());
189 tracker.set_tracker_kind(TRACKER_KIND_REGULAR);
190 *tracker.mutable_synced_details() = details;
191 tracker.set_active(false);
193 leveldb::WriteBatch batch;
194 PutFileToBatch(metadata, &batch);
195 PutTrackerToBatch(tracker, &batch);
196 EXPECT_TRUE(db->Write(leveldb::WriteOptions(), &batch).ok());
199 size_t CountRegisteredAppRoot() {
200 // TODO(tzik): Add function to MetadataDatabase to list trackers by parent.
201 typedef MetadataDatabase::TrackersByTitle TrackersByTitle;
202 const TrackersByTitle& trackers_by_title =
203 metadata_database_->trackers_by_parent_and_title_[kSyncRootTrackerID];
205 size_t count = 0;
206 for (TrackersByTitle::const_iterator itr = trackers_by_title.begin();
207 itr != trackers_by_title.end(); ++itr) {
208 if (itr->second.has_active())
209 ++count;
212 return count;
215 bool IsAppRegistered(const std::string& app_id) {
216 TrackerSet trackers;
217 if (!metadata_database_->FindTrackersByParentAndTitle(
218 kSyncRootTrackerID, app_id, &trackers))
219 return false;
220 return trackers.has_active();
223 size_t CountRemoteFileInSyncRoot() {
224 ScopedVector<google_apis::ResourceEntry> files;
225 EXPECT_EQ(google_apis::HTTP_SUCCESS,
226 fake_drive_service_helper_->ListFilesInFolder(
227 sync_root_folder_id_, &files));
228 return files.size();
231 bool HasRemoteAppRoot(const std::string& app_id) {
232 TrackerSet files;
233 if (!metadata_database_->FindTrackersByParentAndTitle(
234 kSyncRootTrackerID, app_id, &files) ||
235 !files.has_active())
236 return false;
238 std::string app_root_folder_id = files.active_tracker()->file_id();
239 scoped_ptr<google_apis::ResourceEntry> entry;
240 if (google_apis::HTTP_SUCCESS !=
241 fake_drive_service_helper_->GetResourceEntry(
242 app_root_folder_id, &entry))
243 return false;
245 return !entry->deleted();
248 private:
249 std::string GenerateFileID() {
250 return base::StringPrintf("file_id_%" PRId64, next_file_id_++);
253 std::string sync_root_folder_id_;
255 int64 next_file_id_;
256 int64 next_tracker_id_;
258 content::TestBrowserThreadBundle browser_threads_;
259 base::ScopedTempDir database_dir_;
261 scoped_ptr<drive::FakeDriveService> fake_drive_service_;
262 scoped_ptr<drive::DriveUploader> drive_uploader_;
263 scoped_ptr<FakeDriveServiceHelper> fake_drive_service_helper_;
265 scoped_ptr<MetadataDatabase> metadata_database_;
267 DISALLOW_COPY_AND_ASSIGN(RegisterAppTaskTest);
270 TEST_F(RegisterAppTaskTest, AlreadyRegistered) {
271 scoped_ptr<leveldb::DB> db(OpenLevelDB());
272 ASSERT_TRUE(db);
273 SetUpInitialData(db.get());
275 const std::string kAppID = "app_id";
276 SetUpRegisteredAppRoot(kAppID, db.get());
278 CreateMetadataDatabase(db.Pass());
279 EXPECT_EQ(SYNC_STATUS_OK, RunRegisterAppTask(kAppID));
281 EXPECT_EQ(1u, CountRegisteredAppRoot());
282 EXPECT_TRUE(IsAppRegistered(kAppID));
285 TEST_F(RegisterAppTaskTest, CreateAppFolder) {
286 scoped_ptr<leveldb::DB> db(OpenLevelDB());
287 ASSERT_TRUE(db);
288 SetUpInitialData(db.get());
290 const std::string kAppID = "app_id";
291 CreateMetadataDatabase(db.Pass());
292 RunRegisterAppTask(kAppID);
294 EXPECT_EQ(1u, CountRegisteredAppRoot());
295 EXPECT_TRUE(IsAppRegistered(kAppID));
297 EXPECT_EQ(1u, CountRemoteFileInSyncRoot());
298 EXPECT_TRUE(HasRemoteAppRoot(kAppID));
301 TEST_F(RegisterAppTaskTest, RegisterExistingFolder) {
302 scoped_ptr<leveldb::DB> db(OpenLevelDB());
303 ASSERT_TRUE(db);
304 SetUpInitialData(db.get());
306 const std::string kAppID = "app_id";
307 SetUpUnregisteredAppRoot(kAppID, db.get());
309 CreateMetadataDatabase(db.Pass());
310 RunRegisterAppTask(kAppID);
312 EXPECT_EQ(1u, CountRegisteredAppRoot());
313 EXPECT_TRUE(IsAppRegistered(kAppID));
316 TEST_F(RegisterAppTaskTest, RegisterExistingFolder_MultipleCandidate) {
317 scoped_ptr<leveldb::DB> db(OpenLevelDB());
318 ASSERT_TRUE(db);
319 SetUpInitialData(db.get());
321 const std::string kAppID = "app_id";
322 SetUpUnregisteredAppRoot(kAppID, db.get());
323 SetUpUnregisteredAppRoot(kAppID, db.get());
325 CreateMetadataDatabase(db.Pass());
326 RunRegisterAppTask(kAppID);
328 EXPECT_EQ(1u, CountRegisteredAppRoot());
329 EXPECT_TRUE(IsAppRegistered(kAppID));
332 } // namespace drive_backend
333 } // namespace sync_file_system