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 |