| OLD | NEW |
| 1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "components/sync/syncable/directory_backing_store.h" | 5 #include "components/sync/syncable/directory_backing_store.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include <map> | 10 #include <map> |
| 11 #include <memory> | 11 #include <memory> |
| 12 #include <string> | 12 #include <string> |
| 13 | 13 |
| 14 #include "base/files/file_path.h" | 14 #include "base/files/file_path.h" |
| 15 #include "base/files/scoped_temp_dir.h" | 15 #include "base/files/scoped_temp_dir.h" |
| 16 #include "base/message_loop/message_loop.h" | 16 #include "base/message_loop/message_loop.h" |
| 17 #include "base/run_loop.h" | 17 #include "base/run_loop.h" |
| 18 #include "base/stl_util.h" | |
| 19 #include "base/strings/string_number_conversions.h" | 18 #include "base/strings/string_number_conversions.h" |
| 20 #include "base/strings/stringprintf.h" | 19 #include "base/strings/stringprintf.h" |
| 21 #include "build/build_config.h" | 20 #include "build/build_config.h" |
| 22 #include "components/sync/base/node_ordinal.h" | 21 #include "components/sync/base/node_ordinal.h" |
| 23 #include "components/sync/base/time.h" | 22 #include "components/sync/base/time.h" |
| 24 #include "components/sync/protocol/bookmark_specifics.pb.h" | 23 #include "components/sync/protocol/bookmark_specifics.pb.h" |
| 25 #include "components/sync/protocol/sync.pb.h" | 24 #include "components/sync/protocol/sync.pb.h" |
| 26 #include "components/sync/syncable/directory.h" | 25 #include "components/sync/syncable/directory.h" |
| 27 #include "components/sync/syncable/on_disk_directory_backing_store.h" | 26 #include "components/sync/syncable/on_disk_directory_backing_store.h" |
| 28 #include "components/sync/syncable/syncable-inl.h" | 27 #include "components/sync/syncable/syncable-inl.h" |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 66 std::string GetUsername() { | 65 std::string GetUsername() { |
| 67 return "nick@chromium.org"; | 66 return "nick@chromium.org"; |
| 68 } | 67 } |
| 69 | 68 |
| 70 base::FilePath GetDatabasePath() { | 69 base::FilePath GetDatabasePath() { |
| 71 return temp_dir_.path().Append(Directory::kSyncDatabaseFilename); | 70 return temp_dir_.path().Append(Directory::kSyncDatabaseFilename); |
| 72 } | 71 } |
| 73 | 72 |
| 74 static bool LoadAndIgnoreReturnedData(DirectoryBackingStore *dbs) { | 73 static bool LoadAndIgnoreReturnedData(DirectoryBackingStore *dbs) { |
| 75 Directory::MetahandlesMap tmp_handles_map; | 74 Directory::MetahandlesMap tmp_handles_map; |
| 76 JournalIndex delete_journals; | 75 JournalIndex delete_journals; |
| 77 MetahandleSet metahandles_to_purge; | 76 MetahandleSet metahandles_to_purge; |
| 78 base::STLValueDeleter<Directory::MetahandlesMap> deleter(&tmp_handles_map); | |
| 79 Directory::KernelLoadInfo kernel_load_info; | 77 Directory::KernelLoadInfo kernel_load_info; |
| 80 return dbs->Load(&tmp_handles_map, &delete_journals, &metahandles_to_purge, | 78 return dbs->Load(&tmp_handles_map, &delete_journals, &metahandles_to_purge, |
| 81 &kernel_load_info) == OPENED; | 79 &kernel_load_info) == OPENED; |
| 82 } | 80 } |
| 83 | 81 |
| 84 void SetUpVersion67Database(sql::Connection* connection); | 82 void SetUpVersion67Database(sql::Connection* connection); |
| 85 void SetUpVersion68Database(sql::Connection* connection); | 83 void SetUpVersion68Database(sql::Connection* connection); |
| 86 void SetUpVersion69Database(sql::Connection* connection); | 84 void SetUpVersion69Database(sql::Connection* connection); |
| 87 void SetUpVersion70Database(sql::Connection* connection); | 85 void SetUpVersion70Database(sql::Connection* connection); |
| 88 void SetUpVersion71Database(sql::Connection* connection); | 86 void SetUpVersion71Database(sql::Connection* connection); |
| (...skipping 3233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3322 new TestDirectoryBackingStore(GetUsername(), &connection)); | 3320 new TestDirectoryBackingStore(GetUsername(), &connection)); |
| 3323 ASSERT_FALSE(dbs->needs_column_refresh()); | 3321 ASSERT_FALSE(dbs->needs_column_refresh()); |
| 3324 ASSERT_TRUE(dbs->MigrateVersion79To80()); | 3322 ASSERT_TRUE(dbs->MigrateVersion79To80()); |
| 3325 ASSERT_EQ(80, dbs->GetVersion()); | 3323 ASSERT_EQ(80, dbs->GetVersion()); |
| 3326 ASSERT_FALSE(dbs->needs_column_refresh()); | 3324 ASSERT_FALSE(dbs->needs_column_refresh()); |
| 3327 | 3325 |
| 3328 // Ensure the bag_of_chips has been set. | 3326 // Ensure the bag_of_chips has been set. |
| 3329 Directory::MetahandlesMap handles_map; | 3327 Directory::MetahandlesMap handles_map; |
| 3330 JournalIndex delete_journals; | 3328 JournalIndex delete_journals; |
| 3331 MetahandleSet metahandles_to_purge; | 3329 MetahandleSet metahandles_to_purge; |
| 3332 base::STLValueDeleter<Directory::MetahandlesMap> deleter(&handles_map); | |
| 3333 Directory::KernelLoadInfo load_info; | 3330 Directory::KernelLoadInfo load_info; |
| 3334 | 3331 |
| 3335 ASSERT_TRUE(dbs->Load(&handles_map, &delete_journals, &metahandles_to_purge, | 3332 ASSERT_TRUE(dbs->Load(&handles_map, &delete_journals, &metahandles_to_purge, |
| 3336 &load_info)); | 3333 &load_info)); |
| 3337 // Check that the initial value is the serialization of an empty ChipBag. | 3334 // Check that the initial value is the serialization of an empty ChipBag. |
| 3338 sync_pb::ChipBag chip_bag; | 3335 sync_pb::ChipBag chip_bag; |
| 3339 std::string serialized_chip_bag; | 3336 std::string serialized_chip_bag; |
| 3340 ASSERT_TRUE(chip_bag.SerializeToString(&serialized_chip_bag)); | 3337 ASSERT_TRUE(chip_bag.SerializeToString(&serialized_chip_bag)); |
| 3341 EXPECT_EQ(serialized_chip_bag, load_info.kernel_info.bag_of_chips); | 3338 EXPECT_EQ(serialized_chip_bag, load_info.kernel_info.bag_of_chips); |
| 3342 } | 3339 } |
| (...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3561 "INSERT INTO metas " | 3558 "INSERT INTO metas " |
| 3562 "( id, metahandle, is_dir, ctime, mtime," | 3559 "( id, metahandle, is_dir, ctime, mtime," |
| 3563 " unique_position, server_unique_position) " | 3560 " unique_position, server_unique_position) " |
| 3564 "VALUES('c-invalid', 9999, 1, 0, 0, 'BAD_POS', 'BAD_POS')")); | 3561 "VALUES('c-invalid', 9999, 1, 0, 0, 'BAD_POS', 'BAD_POS')")); |
| 3565 ASSERT_TRUE(s.Run()); | 3562 ASSERT_TRUE(s.Run()); |
| 3566 | 3563 |
| 3567 // Trying to unpack this entry should signal that the DB is corrupted. | 3564 // Trying to unpack this entry should signal that the DB is corrupted. |
| 3568 Directory::MetahandlesMap handles_map; | 3565 Directory::MetahandlesMap handles_map; |
| 3569 JournalIndex delete_journals; | 3566 JournalIndex delete_journals; |
| 3570 MetahandleSet metahandles_to_purge; | 3567 MetahandleSet metahandles_to_purge; |
| 3571 base::STLValueDeleter<Directory::MetahandlesMap> deleter(&handles_map); | |
| 3572 Directory::KernelLoadInfo kernel_load_info; | 3568 Directory::KernelLoadInfo kernel_load_info; |
| 3573 ASSERT_EQ(FAILED_DATABASE_CORRUPT, | 3569 ASSERT_EQ(FAILED_DATABASE_CORRUPT, |
| 3574 dbs->Load(&handles_map, &delete_journals, &metahandles_to_purge, | 3570 dbs->Load(&handles_map, &delete_journals, &metahandles_to_purge, |
| 3575 &kernel_load_info)); | 3571 &kernel_load_info)); |
| 3576 } | 3572 } |
| 3577 | 3573 |
| 3578 TEST_P(MigrationTest, ToCurrentVersion) { | 3574 TEST_P(MigrationTest, ToCurrentVersion) { |
| 3579 sql::Connection connection; | 3575 sql::Connection connection; |
| 3580 ASSERT_TRUE(connection.Open(GetDatabasePath())); | 3576 ASSERT_TRUE(connection.Open(GetDatabasePath())); |
| 3581 // Assume all old versions have an old page size. | 3577 // Assume all old versions have an old page size. |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3660 // SetUpVersionYDatabase function with a dump of the test database | 3656 // SetUpVersionYDatabase function with a dump of the test database |
| 3661 // at the new schema. See the MigrateToLatestAndDump test case. | 3657 // at the new schema. See the MigrateToLatestAndDump test case. |
| 3662 FAIL() << "Need to supply database dump for version " << GetParam(); | 3658 FAIL() << "Need to supply database dump for version " << GetParam(); |
| 3663 } | 3659 } |
| 3664 connection.Close(); | 3660 connection.Close(); |
| 3665 | 3661 |
| 3666 syncable::Directory::KernelLoadInfo dir_info; | 3662 syncable::Directory::KernelLoadInfo dir_info; |
| 3667 Directory::MetahandlesMap handles_map; | 3663 Directory::MetahandlesMap handles_map; |
| 3668 JournalIndex delete_journals; | 3664 JournalIndex delete_journals; |
| 3669 MetahandleSet metahandles_to_purge; | 3665 MetahandleSet metahandles_to_purge; |
| 3670 base::STLValueDeleter<Directory::MetahandlesMap> index_deleter(&handles_map); | |
| 3671 | 3666 |
| 3672 { | 3667 { |
| 3673 std::unique_ptr<OnDiskDirectoryBackingStore> dbs( | 3668 std::unique_ptr<OnDiskDirectoryBackingStore> dbs( |
| 3674 new OnDiskDirectoryBackingStore(GetUsername(), GetDatabasePath())); | 3669 new OnDiskDirectoryBackingStore(GetUsername(), GetDatabasePath())); |
| 3675 ASSERT_EQ(OPENED, dbs->Load(&handles_map, &delete_journals, | 3670 ASSERT_EQ(OPENED, dbs->Load(&handles_map, &delete_journals, |
| 3676 &metahandles_to_purge, &dir_info)); | 3671 &metahandles_to_purge, &dir_info)); |
| 3677 if (!metahandles_to_purge.empty()) | 3672 if (!metahandles_to_purge.empty()) |
| 3678 dbs->DeleteEntries(DirectoryBackingStore::METAS_TABLE, | 3673 dbs->DeleteEntries(DirectoryBackingStore::METAS_TABLE, |
| 3679 metahandles_to_purge); | 3674 metahandles_to_purge); |
| 3680 ASSERT_FALSE(dbs->needs_column_refresh()); | 3675 ASSERT_FALSE(dbs->needs_column_refresh()); |
| (...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4075 } | 4070 } |
| 4076 | 4071 |
| 4077 TEST_F(DirectoryBackingStoreTest, DeleteEntries) { | 4072 TEST_F(DirectoryBackingStoreTest, DeleteEntries) { |
| 4078 sql::Connection connection; | 4073 sql::Connection connection; |
| 4079 ASSERT_TRUE(connection.OpenInMemory()); | 4074 ASSERT_TRUE(connection.OpenInMemory()); |
| 4080 | 4075 |
| 4081 SetUpCurrentDatabaseAndCheckVersion(&connection); | 4076 SetUpCurrentDatabaseAndCheckVersion(&connection); |
| 4082 std::unique_ptr<TestDirectoryBackingStore> dbs( | 4077 std::unique_ptr<TestDirectoryBackingStore> dbs( |
| 4083 new TestDirectoryBackingStore(GetUsername(), &connection)); | 4078 new TestDirectoryBackingStore(GetUsername(), &connection)); |
| 4084 Directory::MetahandlesMap handles_map; | 4079 Directory::MetahandlesMap handles_map; |
| 4085 JournalIndex delete_journals; | 4080 JournalIndex delete_journals; |
| 4086 MetahandleSet metahandles_to_purge; | 4081 MetahandleSet metahandles_to_purge; |
| 4087 Directory::KernelLoadInfo kernel_load_info; | 4082 Directory::KernelLoadInfo kernel_load_info; |
| 4088 base::STLValueDeleter<Directory::MetahandlesMap> index_deleter(&handles_map); | |
| 4089 | 4083 |
| 4090 dbs->Load(&handles_map, &delete_journals, &metahandles_to_purge, | 4084 dbs->Load(&handles_map, &delete_journals, &metahandles_to_purge, |
| 4091 &kernel_load_info); | 4085 &kernel_load_info); |
| 4092 size_t initial_size = handles_map.size(); | 4086 size_t initial_size = handles_map.size(); |
| 4093 ASSERT_LT(0U, initial_size) << "Test requires handles_map to delete."; | 4087 ASSERT_LT(0U, initial_size) << "Test requires handles_map to delete."; |
| 4094 int64_t first_to_die = handles_map.begin()->second->ref(META_HANDLE); | 4088 int64_t first_to_die = handles_map.begin()->second->ref(META_HANDLE); |
| 4095 MetahandleSet to_delete; | 4089 MetahandleSet to_delete; |
| 4096 to_delete.insert(first_to_die); | 4090 to_delete.insert(first_to_die); |
| 4097 EXPECT_TRUE(dbs->DeleteEntries(to_delete)); | 4091 EXPECT_TRUE(dbs->DeleteEntries(to_delete)); |
| 4098 | 4092 |
| 4099 base::STLDeleteValues(&handles_map); | 4093 handles_map.clear(); |
| 4100 metahandles_to_purge.clear(); | 4094 metahandles_to_purge.clear(); |
| 4101 dbs->LoadEntries(&handles_map, &metahandles_to_purge); | 4095 dbs->LoadEntries(&handles_map, &metahandles_to_purge); |
| 4102 | 4096 |
| 4103 EXPECT_EQ(initial_size - 1, handles_map.size()); | 4097 EXPECT_EQ(initial_size - 1, handles_map.size()); |
| 4104 bool delete_failed = false; | 4098 bool delete_failed = false; |
| 4105 for (Directory::MetahandlesMap::iterator it = handles_map.begin(); | 4099 for (Directory::MetahandlesMap::iterator it = handles_map.begin(); |
| 4106 it != handles_map.end(); ++it) { | 4100 it != handles_map.end(); ++it) { |
| 4107 if (it->first == first_to_die) { | 4101 if (it->first == first_to_die) { |
| 4108 delete_failed = true; | 4102 delete_failed = true; |
| 4109 break; | 4103 break; |
| 4110 } | 4104 } |
| 4111 } | 4105 } |
| 4112 EXPECT_FALSE(delete_failed); | 4106 EXPECT_FALSE(delete_failed); |
| 4113 | 4107 |
| 4114 to_delete.clear(); | 4108 to_delete.clear(); |
| 4115 for (Directory::MetahandlesMap::iterator it = handles_map.begin(); | 4109 for (Directory::MetahandlesMap::iterator it = handles_map.begin(); |
| 4116 it != handles_map.end(); ++it) { | 4110 it != handles_map.end(); ++it) { |
| 4117 to_delete.insert(it->first); | 4111 to_delete.insert(it->first); |
| 4118 } | 4112 } |
| 4119 | 4113 |
| 4120 EXPECT_TRUE(dbs->DeleteEntries(to_delete)); | 4114 EXPECT_TRUE(dbs->DeleteEntries(to_delete)); |
| 4121 | 4115 |
| 4122 base::STLDeleteValues(&handles_map); | 4116 handles_map.clear(); |
| 4123 metahandles_to_purge.clear(); | 4117 metahandles_to_purge.clear(); |
| 4124 dbs->LoadEntries(&handles_map, &metahandles_to_purge); | 4118 dbs->LoadEntries(&handles_map, &metahandles_to_purge); |
| 4125 EXPECT_EQ(0U, handles_map.size()); | 4119 EXPECT_EQ(0U, handles_map.size()); |
| 4126 } | 4120 } |
| 4127 | 4121 |
| 4128 TEST_F(DirectoryBackingStoreTest, GenerateCacheGUID) { | 4122 TEST_F(DirectoryBackingStoreTest, GenerateCacheGUID) { |
| 4129 const std::string& guid1 = TestDirectoryBackingStore::GenerateCacheGUID(); | 4123 const std::string& guid1 = TestDirectoryBackingStore::GenerateCacheGUID(); |
| 4130 const std::string& guid2 = TestDirectoryBackingStore::GenerateCacheGUID(); | 4124 const std::string& guid2 = TestDirectoryBackingStore::GenerateCacheGUID(); |
| 4131 EXPECT_EQ(24U, guid1.size()); | 4125 EXPECT_EQ(24U, guid1.size()); |
| 4132 EXPECT_EQ(24U, guid2.size()); | 4126 EXPECT_EQ(24U, guid2.size()); |
| 4133 // In theory this test can fail, but it won't before the universe | 4127 // In theory this test can fail, but it won't before the universe |
| 4134 // dies of heat death. | 4128 // dies of heat death. |
| 4135 EXPECT_NE(guid1, guid2); | 4129 EXPECT_NE(guid1, guid2); |
| 4136 } | 4130 } |
| 4137 | 4131 |
| 4138 TEST_F(DirectoryBackingStoreTest, IncreaseDatabasePageSizeFrom4KTo32K) { | 4132 TEST_F(DirectoryBackingStoreTest, IncreaseDatabasePageSizeFrom4KTo32K) { |
| 4139 sql::Connection connection; | 4133 sql::Connection connection; |
| 4140 ASSERT_TRUE(connection.Open(GetDatabasePath())); | 4134 ASSERT_TRUE(connection.Open(GetDatabasePath())); |
| 4141 | 4135 |
| 4142 SetUpCurrentDatabaseAndCheckVersion(&connection); | 4136 SetUpCurrentDatabaseAndCheckVersion(&connection); |
| 4143 std::unique_ptr<TestDirectoryBackingStore> dbs( | 4137 std::unique_ptr<TestDirectoryBackingStore> dbs( |
| 4144 new TestDirectoryBackingStore(GetUsername(), &connection)); | 4138 new TestDirectoryBackingStore(GetUsername(), &connection)); |
| 4145 Directory::MetahandlesMap handles_map; | 4139 Directory::MetahandlesMap handles_map; |
| 4146 JournalIndex delete_journals; | 4140 JournalIndex delete_journals; |
| 4147 MetahandleSet metahandles_to_purge; | 4141 MetahandleSet metahandles_to_purge; |
| 4148 Directory::KernelLoadInfo kernel_load_info; | 4142 Directory::KernelLoadInfo kernel_load_info; |
| 4149 base::STLValueDeleter<Directory::MetahandlesMap> index_deleter(&handles_map); | |
| 4150 | 4143 |
| 4151 DirOpenResult open_result = dbs->Load( | 4144 DirOpenResult open_result = dbs->Load( |
| 4152 &handles_map, &delete_journals, &metahandles_to_purge, &kernel_load_info); | 4145 &handles_map, &delete_journals, &metahandles_to_purge, &kernel_load_info); |
| 4153 EXPECT_EQ(open_result, OPENED); | 4146 EXPECT_EQ(open_result, OPENED); |
| 4154 | 4147 |
| 4155 // Set up database's page size to 4096 | 4148 // Set up database's page size to 4096 |
| 4156 EXPECT_TRUE(dbs->db_->Execute("PRAGMA page_size=4096;")); | 4149 EXPECT_TRUE(dbs->db_->Execute("PRAGMA page_size=4096;")); |
| 4157 EXPECT_TRUE(dbs->Vacuum()); | 4150 EXPECT_TRUE(dbs->Vacuum()); |
| 4158 | 4151 |
| 4159 // Check if update is successful. | 4152 // Check if update is successful. |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4263 ASSERT_FALSE(dbs->SaveChanges(snapshot)); | 4256 ASSERT_FALSE(dbs->SaveChanges(snapshot)); |
| 4264 // At this point the handler has been posted but not executed. | 4257 // At this point the handler has been posted but not executed. |
| 4265 ASSERT_FALSE(was_called); | 4258 ASSERT_FALSE(was_called); |
| 4266 // Pump the message loop and see that it is executed. | 4259 // Pump the message loop and see that it is executed. |
| 4267 base::RunLoop().RunUntilIdle(); | 4260 base::RunLoop().RunUntilIdle(); |
| 4268 ASSERT_TRUE(was_called); | 4261 ASSERT_TRUE(was_called); |
| 4269 } | 4262 } |
| 4270 | 4263 |
| 4271 } // namespace syncable | 4264 } // namespace syncable |
| 4272 } // namespace syncer | 4265 } // namespace syncer |
| OLD | NEW |