OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 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 "base/file_util.h" | 5 #include "base/file_util.h" |
6 #include "base/files/scoped_temp_dir.h" | 6 #include "base/files/scoped_temp_dir.h" |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "sql/connection.h" | 8 #include "sql/connection.h" |
9 #include "sql/meta_table.h" | 9 #include "sql/meta_table.h" |
10 #include "sql/statement.h" | 10 #include "sql/statement.h" |
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
273 const char *kQuery = "SELECT COUNT(*) FROM foo"; | 273 const char *kQuery = "SELECT COUNT(*) FROM foo"; |
274 sql::Statement s(other_db.GetUniqueStatement(kQuery)); | 274 sql::Statement s(other_db.GetUniqueStatement(kQuery)); |
275 ASSERT_TRUE(s.Step()); | 275 ASSERT_TRUE(s.Step()); |
276 ASSERT_FALSE(db().Raze()); | 276 ASSERT_FALSE(db().Raze()); |
277 | 277 |
278 // Complete the statement unlocks the database. | 278 // Complete the statement unlocks the database. |
279 ASSERT_FALSE(s.Step()); | 279 ASSERT_FALSE(s.Step()); |
280 ASSERT_TRUE(db().Raze()); | 280 ASSERT_TRUE(db().Raze()); |
281 } | 281 } |
282 | 282 |
| 283 // Most corruptions seen in the wild seem to happen when two pages in |
| 284 // the database were not written transactionally (the transaction |
| 285 // changed both, but one wasn't successfully written for some reason). |
| 286 // A special case of that is when the header indicates that the |
| 287 // database contains more pages than are in the file. This breaks |
| 288 // things at a very basic level, verify that Raze() can handle it. |
| 289 TEST_F(SQLConnectionTest, RazeShortDB) { |
| 290 const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)"; |
| 291 ASSERT_TRUE(db().Execute(kCreateSql)); |
| 292 |
| 293 db().Close(); |
| 294 { |
| 295 file_util::ScopedFILE file(file_util::OpenFile(db_path(), "r+")); |
| 296 ASSERT_TRUE(file.get() != NULL); |
| 297 ASSERT_EQ(0, fseek(file.get(), 1024, SEEK_END)); |
| 298 ASSERT_TRUE(file_util::TruncateFile(file.get())); |
| 299 } |
| 300 ASSERT_TRUE(db().Open(db_path())); |
| 301 ASSERT_TRUE(db().Raze()); |
| 302 } |
| 303 |
| 304 // Verify that Raze() can handle a completely empty database file. |
| 305 TEST_F(SQLConnectionTest, RazeEmptyDB) { |
| 306 const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)"; |
| 307 ASSERT_TRUE(db().Execute(kCreateSql)); |
| 308 |
| 309 db().Close(); |
| 310 { |
| 311 file_util::ScopedFILE file(file_util::OpenFile(db_path(), "r+")); |
| 312 ASSERT_TRUE(file.get() != NULL); |
| 313 ASSERT_EQ(0, fseek(file.get(), 0, SEEK_SET)); |
| 314 ASSERT_TRUE(file_util::TruncateFile(file.get())); |
| 315 } |
| 316 ASSERT_TRUE(db().Open(db_path())); |
| 317 ASSERT_TRUE(db().Raze()); |
| 318 } |
| 319 |
| 320 // Verify that Raze() can handle garbage. |
| 321 TEST_F(SQLConnectionTest, RazeNOTADB) { |
| 322 db().Close(); |
| 323 |
| 324 { |
| 325 file_util::ScopedFILE file(file_util::OpenFile(db_path(), "w")); |
| 326 ASSERT_TRUE(file.get() != NULL); |
| 327 |
| 328 const char* kJunk = "This is the hour of our discontent."; |
| 329 fputs(kJunk, file.get()); |
| 330 } |
| 331 |
| 332 sql::ScopedErrorIgnorer ignore_errors; |
| 333 ignore_errors.IgnoreError(SQLITE_IOERR_SHORT_READ); |
| 334 EXPECT_TRUE(db().Open(db_path())); |
| 335 EXPECT_TRUE(db().Raze()); |
| 336 ASSERT_TRUE(ignore_errors.CheckIgnoredErrors()); |
| 337 } |
| 338 |
| 339 // Verify that Raze() can handle garbage. |
| 340 TEST_F(SQLConnectionTest, RazeNOTADB2) { |
| 341 const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)"; |
| 342 ASSERT_TRUE(db().Execute(kCreateSql)); |
| 343 |
| 344 db().Close(); |
| 345 { |
| 346 file_util::ScopedFILE file(file_util::OpenFile(db_path(), "r+")); |
| 347 ASSERT_TRUE(file.get() != NULL); |
| 348 ASSERT_EQ(0, fseek(file.get(), 0, SEEK_SET)); |
| 349 |
| 350 const char* kJunk = "This is the hour of our discontent."; |
| 351 fputs(kJunk, file.get()); |
| 352 } |
| 353 |
| 354 sql::ScopedErrorIgnorer ignore_errors; |
| 355 ignore_errors.IgnoreError(SQLITE_NOTADB); |
| 356 EXPECT_TRUE(db().Open(db_path())); |
| 357 EXPECT_TRUE(db().Raze()); |
| 358 ASSERT_TRUE(ignore_errors.CheckIgnoredErrors()); |
| 359 } |
| 360 |
283 // Basic test of RazeAndClose() operation. | 361 // Basic test of RazeAndClose() operation. |
284 TEST_F(SQLConnectionTest, RazeAndClose) { | 362 TEST_F(SQLConnectionTest, RazeAndClose) { |
285 const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)"; | 363 const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)"; |
286 const char* kPopulateSql = "INSERT INTO foo (value) VALUES (12)"; | 364 const char* kPopulateSql = "INSERT INTO foo (value) VALUES (12)"; |
287 | 365 |
288 // Test that RazeAndClose() closes the database, and that the | 366 // Test that RazeAndClose() closes the database, and that the |
289 // database is empty when re-opened. | 367 // database is empty when re-opened. |
290 ASSERT_TRUE(db().Execute(kCreateSql)); | 368 ASSERT_TRUE(db().Execute(kCreateSql)); |
291 ASSERT_TRUE(db().Execute(kPopulateSql)); | 369 ASSERT_TRUE(db().Execute(kPopulateSql)); |
292 ASSERT_TRUE(db().RazeAndClose()); | 370 ASSERT_TRUE(db().RazeAndClose()); |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
390 | 468 |
391 sql::MetaTable meta_table; | 469 sql::MetaTable meta_table; |
392 // Below call needs a temporary directory in sqlite3 | 470 // Below call needs a temporary directory in sqlite3 |
393 // On Android, it can pass only when the temporary directory is set. | 471 // On Android, it can pass only when the temporary directory is set. |
394 // Otherwise, sqlite3 doesn't find the correct directory to store | 472 // Otherwise, sqlite3 doesn't find the correct directory to store |
395 // temporary files and will report the error 'unable to open | 473 // temporary files and will report the error 'unable to open |
396 // database file'. | 474 // database file'. |
397 ASSERT_TRUE(meta_table.Init(&db(), 4, 4)); | 475 ASSERT_TRUE(meta_table.Init(&db(), 4, 4)); |
398 } | 476 } |
399 #endif | 477 #endif |
OLD | NEW |