summaryrefslogtreecommitdiffstats
path: root/sql/recovery_unittest.cc
diff options
context:
space:
mode:
authorshess@chromium.org <shess@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-12-08 06:49:12 +0000
committershess@chromium.org <shess@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-12-08 06:49:12 +0000
commitae4f1625a8a4d8ea9bde7f4a107d60814b12e593 (patch)
tree24be90bb9b4b1c2f422ef0aac1da515b68e0753c /sql/recovery_unittest.cc
parent8837674f3446a46adc28e4c73444c4fc8689dc15 (diff)
downloadchromium_src-ae4f1625a8a4d8ea9bde7f4a107d60814b12e593.zip
chromium_src-ae4f1625a8a4d8ea9bde7f4a107d60814b12e593.tar.gz
chromium_src-ae4f1625a8a4d8ea9bde7f4a107d60814b12e593.tar.bz2
[sql] Recovery code for "Top Sites" database.
Port recovery code from thumbnail_database.cc to top_sites_database.cc. Also retry Init() in case the recovery code fixes things (a quarter to a third of databases have problems detected during open). Extend sql::Recovery::AutoRecoverTable() to handle DOUBLE columns. Abstract out sql::test::CorruptTableOrIndex() to ease writing corruption tests. IWYU pass on various files. BUG=321852 Review URL: https://codereview.chromium.org/86653002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@239377 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'sql/recovery_unittest.cc')
-rw-r--r--sql/recovery_unittest.cc91
1 files changed, 11 insertions, 80 deletions
diff --git a/sql/recovery_unittest.cc b/sql/recovery_unittest.cc
index e3c9738..ce3884b 100644
--- a/sql/recovery_unittest.cc
+++ b/sql/recovery_unittest.cc
@@ -2,17 +2,18 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <string>
+
#include "base/bind.h"
-#include "base/file_util.h"
+#include "base/files/file_path.h"
#include "base/files/scoped_temp_dir.h"
-#include "base/logging.h"
#include "base/strings/string_number_conversions.h"
-#include "base/strings/stringprintf.h"
#include "sql/connection.h"
#include "sql/meta_table.h"
#include "sql/recovery.h"
#include "sql/statement.h"
#include "sql/test/scoped_error_ignorer.h"
+#include "sql/test/test_helpers.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/sqlite/sqlite3.h"
@@ -57,51 +58,6 @@ std::string GetSchema(sql::Connection* db) {
return ExecuteWithResults(db, kSql, "|", "\n");
}
-#if !defined(USE_SYSTEM_SQLITE)
-int GetPageSize(sql::Connection* db) {
- sql::Statement s(db->GetUniqueStatement("PRAGMA page_size"));
- EXPECT_TRUE(s.Step());
- return s.ColumnInt(0);
-}
-
-// Get |name|'s root page number in the database.
-int GetRootPage(sql::Connection* db, const char* name) {
- const char kPageSql[] = "SELECT rootpage FROM sqlite_master WHERE name = ?";
- sql::Statement s(db->GetUniqueStatement(kPageSql));
- s.BindString(0, name);
- EXPECT_TRUE(s.Step());
- return s.ColumnInt(0);
-}
-
-// Helper to read a SQLite page into a buffer. |page_no| is 1-based
-// per SQLite usage.
-bool ReadPage(const base::FilePath& path, size_t page_no,
- char* buf, size_t page_size) {
- file_util::ScopedFILE file(base::OpenFile(path, "rb"));
- if (!file.get())
- return false;
- if (0 != fseek(file.get(), (page_no - 1) * page_size, SEEK_SET))
- return false;
- if (1u != fread(buf, page_size, 1, file.get()))
- return false;
- return true;
-}
-
-// Helper to write a SQLite page into a buffer. |page_no| is 1-based
-// per SQLite usage.
-bool WritePage(const base::FilePath& path, size_t page_no,
- const char* buf, size_t page_size) {
- file_util::ScopedFILE file(base::OpenFile(path, "rb+"));
- if (!file.get())
- return false;
- if (0 != fseek(file.get(), (page_no - 1) * page_size, SEEK_SET))
- return false;
- if (1u != fwrite(buf, page_size, 1, file.get()))
- return false;
- return true;
-}
-#endif // !defined(USE_SYSTEM_SQLITE)
-
class SQLRecoveryTest : public testing::Test {
public:
SQLRecoveryTest() {}
@@ -296,24 +252,12 @@ TEST_F(SQLRecoveryTest, RecoverCorruptIndex) {
ASSERT_TRUE(db().CommitTransaction());
}
-
-
- // Capture the index's root page into |buf|.
- int index_page = GetRootPage(&db(), "x_id");
- int page_size = GetPageSize(&db());
- scoped_ptr<char[]> buf(new char[page_size]);
- ASSERT_TRUE(ReadPage(db_path(), index_page, buf.get(), page_size));
-
- // Delete the row from the table and index.
- ASSERT_TRUE(db().Execute("DELETE FROM x WHERE id = 0"));
-
- // Close to clear any cached data.
db().Close();
- // Put the stale index page back.
- ASSERT_TRUE(WritePage(db_path(), index_page, buf.get(), page_size));
-
- // At this point, the index references a value not in the table.
+ // Delete a row from the table, while leaving the index entry which
+ // references it.
+ const char kDeleteSql[] = "DELETE FROM x WHERE id = 0";
+ ASSERT_TRUE(sql::test::CorruptTableOrIndex(db_path(), "x_id", kDeleteSql));
ASSERT_TRUE(Reopen());
@@ -368,25 +312,12 @@ TEST_F(SQLRecoveryTest, RecoverCorruptTable) {
ASSERT_TRUE(db().CommitTransaction());
}
-
- // Capture the table's root page into |buf|.
- // Find the page the table is stored on.
- const int table_page = GetRootPage(&db(), "x");
- const int page_size = GetPageSize(&db());
- scoped_ptr<char[]> buf(new char[page_size]);
- ASSERT_TRUE(ReadPage(db_path(), table_page, buf.get(), page_size));
-
- // Delete the row from the table and index.
- ASSERT_TRUE(db().Execute("DELETE FROM x WHERE id = 0"));
-
- // Close to clear any cached data.
db().Close();
- // Put the stale table page back.
- ASSERT_TRUE(WritePage(db_path(), table_page, buf.get(), page_size));
+ // Delete a row from the index while leaving a table entry.
+ const char kDeleteSql[] = "DELETE FROM x WHERE id = 0";
+ ASSERT_TRUE(sql::test::CorruptTableOrIndex(db_path(), "x", kDeleteSql));
- // At this point, the table contains a value not referenced by the
- // index.
// TODO(shess): Figure out a query which causes SQLite to notice
// this organically. Meanwhile, just handle it manually.