| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2011 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 <limits> | |
| 6 #include <string> | |
| 7 | |
| 8 #include "base/file_util.h" | |
| 9 #include "base/scoped_temp_dir.h" | |
| 10 #include "base/utf_string_conversions.h" | |
| 11 #include "build/build_config.h" | |
| 12 #include "chrome/browser/password_manager/encryptor.h" | |
| 13 #include "chrome/browser/sync/syncable/directory_manager.h" | |
| 14 #include "chrome/browser/sync/util/user_settings.h" | |
| 15 #include "sql/statement.h" | |
| 16 #include "testing/gtest/include/gtest/gtest.h" | |
| 17 | |
| 18 using std::numeric_limits; | |
| 19 | |
| 20 namespace { | |
| 21 | |
| 22 const FilePath::CharType kV10UserSettingsDB[] = | |
| 23 FILE_PATH_LITERAL("Version10Settings.sqlite3"); | |
| 24 const FilePath::CharType kV11UserSettingsDB[] = | |
| 25 FILE_PATH_LITERAL("Version11Settings.sqlite3"); | |
| 26 const FilePath::CharType kOldStyleSyncDataDB[] = | |
| 27 FILE_PATH_LITERAL("OldStyleSyncData.sqlite3"); | |
| 28 | |
| 29 } // namespace | |
| 30 | |
| 31 class UserSettingsTest : public testing::Test { | |
| 32 public: | |
| 33 UserSettingsTest() : sync_data_("Some sync data") {} | |
| 34 | |
| 35 virtual void SetUp() { | |
| 36 #if defined(OS_MACOSX) | |
| 37 // Need to mock the Keychain for unit tests on Mac to avoid possible | |
| 38 // blocking UI. |SetAuthTokenForService| uses Encryptor. | |
| 39 Encryptor::UseMockKeychain(true); | |
| 40 #endif | |
| 41 } | |
| 42 | |
| 43 // Creates and populates the V10 database files within | |
| 44 // |destination_directory|. | |
| 45 void SetUpVersion10Databases(const FilePath& destination_directory) { | |
| 46 v10_user_setting_db_path_ = | |
| 47 destination_directory.Append(FilePath(kV10UserSettingsDB)); | |
| 48 | |
| 49 sql::Connection db; | |
| 50 ASSERT_TRUE(db.Open(v10_user_setting_db_path_)); | |
| 51 | |
| 52 old_style_sync_data_path_ = | |
| 53 destination_directory.Append(FilePath(kOldStyleSyncDataDB)); | |
| 54 | |
| 55 ASSERT_EQ(sync_data_.length(), | |
| 56 static_cast<size_t>(file_util::WriteFile( | |
| 57 old_style_sync_data_path_, sync_data_.data(), | |
| 58 sync_data_.length()))); | |
| 59 | |
| 60 // Create settings table. | |
| 61 ASSERT_TRUE(db.Execute( | |
| 62 "CREATE TABLE settings (email, key, value, PRIMARY KEY(email, key)" | |
| 63 " ON CONFLICT REPLACE)")); | |
| 64 | |
| 65 // Add a blank signin table. | |
| 66 ASSERT_TRUE(db.Execute( | |
| 67 "CREATE TABLE signin_types (signin, signin_type)")); | |
| 68 | |
| 69 // Create and populate version table. | |
| 70 ASSERT_TRUE(db.Execute("CREATE TABLE db_version (version)")); | |
| 71 { | |
| 72 const char* query = "INSERT INTO db_version VALUES(?)"; | |
| 73 sql::Statement s(db.GetUniqueStatement(query)); | |
| 74 if (!s) | |
| 75 LOG(FATAL) << query << "\n" << db.GetErrorMessage(); | |
| 76 | |
| 77 s.BindInt(0, 10); | |
| 78 if (!s.Run()) | |
| 79 LOG(FATAL) << query << "\n" << db.GetErrorMessage(); | |
| 80 } | |
| 81 | |
| 82 // Create shares table. | |
| 83 ASSERT_TRUE(db.Execute( | |
| 84 "CREATE TABLE shares (email, share_name, file_name," | |
| 85 " PRIMARY KEY(email, share_name) ON CONFLICT REPLACE)")); | |
| 86 // Populate a share. | |
| 87 { | |
| 88 const char* query = "INSERT INTO shares VALUES(?, ?, ?)"; | |
| 89 sql::Statement s(db.GetUniqueStatement(query)); | |
| 90 if (!s) | |
| 91 LOG(FATAL) << query << "\n" << db.GetErrorMessage(); | |
| 92 | |
| 93 s.BindString(0, "foo@foo.com"); | |
| 94 s.BindString(1, "foo@foo.com"); | |
| 95 #if defined(OS_WIN) | |
| 96 s.BindString(2, WideToUTF8(old_style_sync_data_path_.value())); | |
| 97 #elif defined(OS_POSIX) | |
| 98 s.BindString(2, old_style_sync_data_path_.value()); | |
| 99 #endif | |
| 100 if (!s.Run()) | |
| 101 LOG(FATAL) << query << "\n" << db.GetErrorMessage(); | |
| 102 } | |
| 103 } | |
| 104 | |
| 105 // Creates and populates the V11 database file within | |
| 106 // |destination_directory|. | |
| 107 void SetUpVersion11Database(const FilePath& destination_directory) { | |
| 108 v11_user_setting_db_path_ = | |
| 109 destination_directory.Append(FilePath(kV11UserSettingsDB)); | |
| 110 | |
| 111 sql::Connection db; | |
| 112 ASSERT_TRUE(db.Open(v11_user_setting_db_path_)); | |
| 113 | |
| 114 // Create settings table. | |
| 115 ASSERT_TRUE(db.Execute( | |
| 116 "CREATE TABLE settings (email, key, value, PRIMARY KEY(email, key)" | |
| 117 " ON CONFLICT REPLACE)")); | |
| 118 | |
| 119 // Create and populate version table. | |
| 120 ASSERT_TRUE(db.Execute("CREATE TABLE db_version (version)")); | |
| 121 { | |
| 122 const char* query = "INSERT INTO db_version VALUES(?)"; | |
| 123 sql::Statement s(db.GetUniqueStatement(query)); | |
| 124 if (!s) | |
| 125 LOG(FATAL) << query << "\n" << db.GetErrorMessage(); | |
| 126 | |
| 127 s.BindInt(0, 11); | |
| 128 if (!s.Run()) | |
| 129 LOG(FATAL) << query << "\n" << db.GetErrorMessage(); | |
| 130 } | |
| 131 | |
| 132 ASSERT_TRUE(db.Execute( | |
| 133 "CREATE TABLE signin_types (signin, signin_type)")); | |
| 134 { | |
| 135 const char* query = "INSERT INTO signin_types VALUES(?, ?)"; | |
| 136 sql::Statement s(db.GetUniqueStatement(query)); | |
| 137 if (!s) | |
| 138 LOG(FATAL) << query << "\n" << db.GetErrorMessage(); | |
| 139 | |
| 140 s.BindString(0, "test"); | |
| 141 s.BindString(1, "test"); | |
| 142 if (!s.Run()) | |
| 143 LOG(FATAL) << query << "\n" << db.GetErrorMessage(); | |
| 144 } | |
| 145 } | |
| 146 | |
| 147 const std::string& sync_data() const { return sync_data_; } | |
| 148 const FilePath& v10_user_setting_db_path() const { | |
| 149 return v10_user_setting_db_path_; | |
| 150 } | |
| 151 const FilePath& v11_user_setting_db_path() const { | |
| 152 return v11_user_setting_db_path_; | |
| 153 } | |
| 154 const FilePath& old_style_sync_data_path() const { | |
| 155 return old_style_sync_data_path_; | |
| 156 } | |
| 157 | |
| 158 private: | |
| 159 FilePath v10_user_setting_db_path_; | |
| 160 FilePath old_style_sync_data_path_; | |
| 161 | |
| 162 FilePath v11_user_setting_db_path_; | |
| 163 | |
| 164 std::string sync_data_; | |
| 165 }; | |
| 166 | |
| 167 TEST_F(UserSettingsTest, MigrateFromV10ToV11) { | |
| 168 ScopedTempDir temp_dir; | |
| 169 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); | |
| 170 SetUpVersion10Databases(temp_dir.path()); | |
| 171 { | |
| 172 // Create a UserSettings, which should trigger migration code. We do this | |
| 173 // inside a scoped block so it closes itself and we can poke around to see | |
| 174 // what happened later. | |
| 175 browser_sync::UserSettings settings; | |
| 176 settings.Init(v10_user_setting_db_path()); | |
| 177 } | |
| 178 | |
| 179 // Now poke around using sqlite to see if UserSettings migrated properly. | |
| 180 sql::Connection db; | |
| 181 ASSERT_TRUE(db.Open(v10_user_setting_db_path())); | |
| 182 | |
| 183 // Note that we don't use ScopedStatement to avoid closing the sqlite handle | |
| 184 // before finalizing the statement. | |
| 185 { | |
| 186 const char* query = "SELECT version FROM db_version"; | |
| 187 sql::Statement version_query(db.GetUniqueStatement(query)); | |
| 188 if (!version_query) | |
| 189 LOG(FATAL) << query << "\n" << db.GetErrorMessage(); | |
| 190 | |
| 191 ASSERT_TRUE(version_query.Step()); | |
| 192 const int version = version_query.ColumnInt(0); | |
| 193 EXPECT_GE(version, 11); | |
| 194 } | |
| 195 | |
| 196 EXPECT_FALSE(file_util::PathExists(old_style_sync_data_path())); | |
| 197 | |
| 198 FilePath new_style_path = temp_dir.path().Append( | |
| 199 syncable::DirectoryManager::GetSyncDataDatabaseFilename()); | |
| 200 | |
| 201 std::string contents; | |
| 202 ASSERT_TRUE(file_util::ReadFileToString(new_style_path, &contents)); | |
| 203 EXPECT_TRUE(sync_data() == contents); | |
| 204 } | |
| 205 | |
| 206 TEST_F(UserSettingsTest, MigrateFromV11ToV12) { | |
| 207 ScopedTempDir temp_dir; | |
| 208 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); | |
| 209 SetUpVersion11Database(temp_dir.path()); | |
| 210 { | |
| 211 browser_sync::UserSettings settings; | |
| 212 settings.Init(v11_user_setting_db_path()); | |
| 213 } | |
| 214 sql::Connection db; | |
| 215 ASSERT_TRUE(db.Open(v11_user_setting_db_path())); | |
| 216 | |
| 217 { | |
| 218 const char* query = "SELECT version FROM db_version"; | |
| 219 sql::Statement version_query(db.GetUniqueStatement(query)); | |
| 220 if (!version_query) | |
| 221 LOG(FATAL) << query << "\n" << db.GetErrorMessage(); | |
| 222 | |
| 223 ASSERT_TRUE(version_query.Step()); | |
| 224 const int version = version_query.ColumnInt(0); | |
| 225 EXPECT_GE(version, 12); | |
| 226 | |
| 227 const char* query2 = "SELECT name FROM sqlite_master " | |
| 228 "WHERE type='table' AND name='signin_types'"; | |
| 229 sql::Statement table_query(db.GetUniqueStatement(query2)); | |
| 230 if (!table_query) | |
| 231 LOG(FATAL) << query2 << "\n" << db.GetErrorMessage(); | |
| 232 | |
| 233 ASSERT_FALSE(table_query.Step()); | |
| 234 } | |
| 235 } | |
| 236 | |
| 237 TEST_F(UserSettingsTest, APEncode) { | |
| 238 std::string test; | |
| 239 char i; | |
| 240 for (i = numeric_limits<char>::min(); i < numeric_limits<char>::max(); ++i) | |
| 241 test.push_back(i); | |
| 242 test.push_back(i); | |
| 243 const std::string encoded = browser_sync::APEncode(test); | |
| 244 const std::string decoded = browser_sync::APDecode(encoded); | |
| 245 ASSERT_EQ(test, decoded); | |
| 246 } | |
| 247 | |
| 248 TEST_F(UserSettingsTest, PersistEmptyToken) { | |
| 249 ScopedTempDir temp_dir; | |
| 250 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); | |
| 251 browser_sync::UserSettings settings; | |
| 252 settings.Init(temp_dir.path().AppendASCII("UserSettings.sqlite3")); | |
| 253 settings.SetAuthTokenForService("username", "service", ""); | |
| 254 std::string username; | |
| 255 std::string token; | |
| 256 ASSERT_TRUE(settings.GetLastUserAndServiceToken("service", &username, | |
| 257 &token)); | |
| 258 EXPECT_EQ("", token); | |
| 259 EXPECT_EQ("username", username); | |
| 260 } | |
| 261 | |
| 262 TEST_F(UserSettingsTest, PersistNonEmptyToken) { | |
| 263 ScopedTempDir temp_dir; | |
| 264 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); | |
| 265 browser_sync::UserSettings settings; | |
| 266 settings.Init(temp_dir.path().AppendASCII("UserSettings.sqlite3")); | |
| 267 settings.SetAuthTokenForService("username", "service", | |
| 268 "oonetuhasonteuhasonetuhasonetuhasonetuhasouhasonetuhasonetuhasonetuhah" | |
| 269 "oonetuhasonteuhasonetuhasonetuhasonetuhasouhasonetuhasonetuhasonetuhah" | |
| 270 "oonetuhasonteuhasonetuhasonetuhasonetuhasouhasonetuhasonetuhasonetuhah"); | |
| 271 std::string username; | |
| 272 std::string token; | |
| 273 ASSERT_TRUE(settings.GetLastUserAndServiceToken("service", &username, | |
| 274 &token)); | |
| 275 EXPECT_EQ( | |
| 276 "oonetuhasonteuhasonetuhasonetuhasonetuhasouhasonetuhasonetuhasonetuhah" | |
| 277 "oonetuhasonteuhasonetuhasonetuhasonetuhasouhasonetuhasonetuhasonetuhah" | |
| 278 "oonetuhasonteuhasonetuhasonetuhasonetuhasouhasonetuhasonetuhasonetuhah", | |
| 279 token); | |
| 280 EXPECT_EQ("username", username); | |
| 281 } | |
| OLD | NEW |