| Index: components/omnibox/browser/shortcuts_database_unittest.cc
|
| diff --git a/components/omnibox/browser/shortcuts_database_unittest.cc b/components/omnibox/browser/shortcuts_database_unittest.cc
|
| index 6648d8272bb0d66f65cf652a6a456c74ad500e70..c98bdeb673397abc62695ec61d567572da25601c 100644
|
| --- a/components/omnibox/browser/shortcuts_database_unittest.cc
|
| +++ b/components/omnibox/browser/shortcuts_database_unittest.cc
|
| @@ -17,6 +17,7 @@
|
| #include "components/omnibox/browser/autocomplete_match_type.h"
|
| #include "components/omnibox/browser/shortcuts_constants.h"
|
| #include "sql/statement.h"
|
| +#include "sql/test/scoped_error_expecter.h"
|
| #include "sql/test/test_helpers.h"
|
| #include "testing/gtest/include/gtest/gtest.h"
|
| #include "ui/base/page_transition_types.h"
|
| @@ -233,7 +234,7 @@ TEST(ShortcutsDatabaseMigrationTest, MigrateTableAddFillIntoEdit) {
|
| #endif
|
| base::ScopedTempDir temp_dir;
|
| ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
|
| - base::FilePath db_path(temp_dir.path().AppendASCII("TestShortcuts1.db"));
|
| + base::FilePath db_path(temp_dir.path().AppendASCII("TestShortcuts.db"));
|
| ASSERT_TRUE(sql::test::CreateDatabaseFromSQL(db_path, sql_path));
|
|
|
| CheckV2ColumnExistence(db_path, false);
|
| @@ -277,7 +278,7 @@ TEST(ShortcutsDatabaseMigrationTest, MigrateV0ToV1) {
|
| base::FilePath sql_path = GetTestDataDir().AppendASCII("Shortcuts.v0.sql");
|
| base::ScopedTempDir temp_dir;
|
| ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
|
| - base::FilePath db_path(temp_dir.path().AppendASCII("TestShortcuts2.db"));
|
| + base::FilePath db_path(temp_dir.path().AppendASCII("TestShortcuts.db"));
|
| ASSERT_TRUE(sql::test::CreateDatabaseFromSQL(db_path, sql_path));
|
|
|
| // Create a ShortcutsDatabase from the test database, which will migrate the
|
| @@ -300,3 +301,72 @@ TEST(ShortcutsDatabaseMigrationTest, MigrateV0ToV1) {
|
| EXPECT_TRUE(temp_dir.Delete());
|
| #endif
|
| }
|
| +
|
| +TEST(ShortcutsDatabaseMigrationTest, Recovery1) {
|
| +#if defined(OS_ANDROID)
|
| + char kBasename[] = "Shortcuts.v1.sql";
|
| +#else
|
| + char kBasename[] = "Shortcuts.no_fill_into_edit.sql";
|
| +#endif
|
| + // Use the pre-v0 test file to create a test database in a temp dir.
|
| + base::FilePath sql_path = GetTestDataDir().AppendASCII(kBasename);
|
| + base::ScopedTempDir temp_dir;
|
| + ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
|
| + base::FilePath db_path(temp_dir.path().AppendASCII("TestShortcuts.db"));
|
| + ASSERT_TRUE(sql::test::CreateDatabaseFromSQL(db_path, sql_path));
|
| +
|
| + // Capture the row count from the golden file before corrupting the database.
|
| + const char kCountSql[] = "SELECT COUNT(*) FROM omni_box_shortcuts";
|
| + int row_count;
|
| + {
|
| + sql::Connection connection;
|
| + ASSERT_TRUE(connection.Open(db_path));
|
| + sql::Statement statement(connection.GetUniqueStatement(kCountSql));
|
| + ASSERT_TRUE(statement.is_valid());
|
| + ASSERT_TRUE(statement.Step());
|
| + row_count = statement.ColumnInt(0);
|
| + }
|
| +
|
| + // Break the database.
|
| + ASSERT_TRUE(sql::test::CorruptSizeInHeader(db_path));
|
| +
|
| + // Verify that the database is broken. The corruption will prevent reading
|
| + // the schema, causing the prepared statement to not compile.
|
| + {
|
| + sql::test::ScopedErrorExpecter expecter;
|
| + expecter.ExpectError(SQLITE_CORRUPT);
|
| +
|
| + sql::Connection connection;
|
| + ASSERT_TRUE(connection.Open(db_path));
|
| + sql::Statement statement(connection.GetUniqueStatement(kCountSql));
|
| + ASSERT_FALSE(statement.is_valid());
|
| +
|
| + ASSERT_TRUE(expecter.SawExpectedErrors());
|
| + }
|
| +
|
| + // The sql::Connection::Open() called by ShortcutsDatabase::Init() will hit
|
| + // the corruption, the error callback will recover and poison the database,
|
| + // then Open() will retry successfully, allowing Init() to succeed.
|
| + {
|
| + sql::test::ScopedErrorExpecter expecter;
|
| + expecter.ExpectError(SQLITE_CORRUPT);
|
| +
|
| + scoped_refptr<ShortcutsDatabase> db(new ShortcutsDatabase(db_path));
|
| + ASSERT_TRUE(db->Init());
|
| +
|
| + ASSERT_TRUE(expecter.SawExpectedErrors());
|
| + }
|
| +
|
| + CheckV2ColumnExistence(db_path, true);
|
| +
|
| + // The previously-broken statement works and all of the data should have been
|
| + // recovered.
|
| + {
|
| + sql::Connection connection;
|
| + ASSERT_TRUE(connection.Open(db_path));
|
| + sql::Statement statement(connection.GetUniqueStatement(kCountSql));
|
| + ASSERT_TRUE(statement.is_valid());
|
| + ASSERT_TRUE(statement.Step());
|
| + EXPECT_EQ(row_count, statement.ColumnInt(0));
|
| + }
|
| +}
|
|
|