[sql] sql::ScopedErrorIgnorer rename to sql::test::ScopedErrorExpecter
"Ignore" was a result of focussing on avoiding the DCHECK in the
sql::Connection implementation, while "expect" focusses on what the test
is trying to do. Changing because "ignore" is ambiguous.
BUG=597785
[email protected], [email protected]
Review-Url: https://codereview.chromium.org/1991503002
Cr-Commit-Position: refs/heads/master@{#400910}
diff --git a/sql/BUILD.gn b/sql/BUILD.gn
index fb1bd2f..4767855 100644
--- a/sql/BUILD.gn
+++ b/sql/BUILD.gn
@@ -42,8 +42,8 @@
sources = [
"test/error_callback_support.cc",
"test/error_callback_support.h",
- "test/scoped_error_ignorer.cc",
- "test/scoped_error_ignorer.h",
+ "test/scoped_error_expecter.cc",
+ "test/scoped_error_expecter.h",
"test/test_helpers.cc",
"test/test_helpers.h",
]
diff --git a/sql/connection.cc b/sql/connection.cc
index 5900e89..f748449 100644
--- a/sql/connection.cc
+++ b/sql/connection.cc
@@ -230,13 +230,13 @@
namespace sql {
// static
-Connection::ErrorIgnorerCallback* Connection::current_ignorer_cb_ = NULL;
+Connection::ErrorExpecterCallback* Connection::current_expecter_cb_ = NULL;
// static
-bool Connection::ShouldIgnoreSqliteError(int error) {
- if (!current_ignorer_cb_)
+bool Connection::IsExpectedSqliteError(int error) {
+ if (!current_expecter_cb_)
return false;
- return current_ignorer_cb_->Run(error);
+ return current_expecter_cb_->Run(error);
}
void Connection::ReportDiagnosticInfo(int extended_error, Statement* stmt) {
@@ -268,15 +268,15 @@
}
// static
-void Connection::SetErrorIgnorer(Connection::ErrorIgnorerCallback* cb) {
- CHECK(current_ignorer_cb_ == NULL);
- current_ignorer_cb_ = cb;
+void Connection::SetErrorExpecter(Connection::ErrorExpecterCallback* cb) {
+ CHECK(current_expecter_cb_ == NULL);
+ current_expecter_cb_ = cb;
}
// static
-void Connection::ResetErrorIgnorer() {
- CHECK(current_ignorer_cb_);
- current_ignorer_cb_ = NULL;
+void Connection::ResetErrorExpecter() {
+ CHECK(current_expecter_cb_);
+ current_expecter_cb_ = NULL;
}
bool StatementID::operator<(const StatementID& other) const {
@@ -1529,8 +1529,8 @@
"SELECT name FROM sqlite_master WHERE type=? AND name=? COLLATE NOCASE";
Statement statement(GetUntrackedStatement(kSql));
- // This can happen if the database is corrupt and the error is being ignored
- // for testing purposes.
+ // This can happen if the database is corrupt and the error is a test
+ // expectation.
if (!statement.is_valid())
return false;
@@ -1548,8 +1548,8 @@
Statement statement(GetUntrackedStatement(sql.c_str()));
- // This can happen if the database is corrupt and the error is being ignored
- // for testing purposes.
+ // This can happen if the database is corrupt and the error is a test
+ // expectation.
if (!statement.is_valid())
return false;
@@ -1902,7 +1902,7 @@
}
// The default handling is to assert on debug and to ignore on release.
- if (!ShouldIgnoreSqliteError(err))
+ if (!IsExpectedSqliteError(err))
DLOG(FATAL) << GetErrorMessage();
return err;
}
diff --git a/sql/connection.h b/sql/connection.h
index 959a1b1..12e7041c 100644
--- a/sql/connection.h
+++ b/sql/connection.h
@@ -39,6 +39,7 @@
// To allow some test classes to be friended.
namespace test {
class ScopedCommitHook;
+class ScopedErrorExpecter;
class ScopedScalarFunction;
class ScopedMockTimeSource;
}
@@ -474,11 +475,12 @@
// SELECT type, name, tbl_name, sql FROM sqlite_master ORDER BY 1, 2, 3, 4;
std::string GetSchema() const;
- // Clients which provide an error_callback don't see the
- // error-handling at the end of OnSqliteError(). Expose to allow
- // those clients to work appropriately with ScopedErrorIgnorer in
- // tests.
- static bool ShouldIgnoreSqliteError(int error);
+ // Returns |true| if there is an error expecter (see SetErrorExpecter), and
+ // that expecter returns |true| when passed |error|. Clients which provide an
+ // |error_callback| should use IsExpectedSqliteError() to check for unexpected
+ // errors; if one is detected, DLOG(FATAL) is generally appropriate (see
+ // OnSqliteError implementation).
+ static bool IsExpectedSqliteError(int error);
// Collect various diagnostic information and post a crash dump to aid
// debugging. Dump rate per database is limited to prevent overwhelming the
@@ -489,8 +491,8 @@
// For recovery module.
friend class Recovery;
- // Allow test-support code to set/reset error ignorer.
- friend class ScopedErrorIgnorer;
+ // Allow test-support code to set/reset error expecter.
+ friend class test::ScopedErrorExpecter;
// Statement accesses StatementRef which we don't want to expose to everybody
// (they should go through Statement).
@@ -532,12 +534,12 @@
// Internal helper for DoesTableExist and DoesIndexExist.
bool DoesTableOrIndexExist(const char* name, const char* type) const;
- // Accessors for global error-ignorer, for injecting behavior during tests.
- // See test/scoped_error_ignorer.h.
- typedef base::Callback<bool(int)> ErrorIgnorerCallback;
- static ErrorIgnorerCallback* current_ignorer_cb_;
- static void SetErrorIgnorer(ErrorIgnorerCallback* ignorer);
- static void ResetErrorIgnorer();
+ // Accessors for global error-expecter, for injecting behavior during tests.
+ // See test/scoped_error_expecter.h.
+ typedef base::Callback<bool(int)> ErrorExpecterCallback;
+ static ErrorExpecterCallback* current_expecter_cb_;
+ static void SetErrorExpecter(ErrorExpecterCallback* expecter);
+ static void ResetErrorExpecter();
// A StatementRef is a refcounted wrapper around a sqlite statement pointer.
// Refcounting allows us to give these statements out to sql::Statement
diff --git a/sql/connection_unittest.cc b/sql/connection_unittest.cc
index 2618bb4a..f90574a 100644
--- a/sql/connection_unittest.cc
+++ b/sql/connection_unittest.cc
@@ -20,7 +20,7 @@
#include "sql/meta_table.h"
#include "sql/statement.h"
#include "sql/test/error_callback_support.h"
-#include "sql/test/scoped_error_ignorer.h"
+#include "sql/test/scoped_error_expecter.h"
#include "sql/test/test_helpers.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/sqlite/sqlite3.h"
@@ -358,23 +358,23 @@
EXPECT_TRUE(db().BeginTransaction());
}
-// Test the scoped error ignorer by attempting to insert a duplicate
+// Test the scoped error expecter by attempting to insert a duplicate
// value into an index.
-TEST_F(SQLConnectionTest, ScopedIgnoreError) {
+TEST_F(SQLConnectionTest, ScopedErrorExpecter) {
const char* kCreateSql = "CREATE TABLE foo (id INTEGER UNIQUE)";
ASSERT_TRUE(db().Execute(kCreateSql));
ASSERT_TRUE(db().Execute("INSERT INTO foo (id) VALUES (12)"));
{
- sql::ScopedErrorIgnorer ignore_errors;
- ignore_errors.IgnoreError(SQLITE_CONSTRAINT);
+ sql::test::ScopedErrorExpecter expecter;
+ expecter.ExpectError(SQLITE_CONSTRAINT);
ASSERT_FALSE(db().Execute("INSERT INTO foo (id) VALUES (12)"));
- ASSERT_TRUE(ignore_errors.CheckIgnoredErrors());
+ ASSERT_TRUE(expecter.SawExpectedErrors());
}
}
// Test that clients of GetUntrackedStatement() can test corruption-handling
-// with ScopedErrorIgnorer.
+// with ScopedErrorExpecter.
TEST_F(SQLConnectionTest, ScopedIgnoreUntracked) {
const char* kCreateSql = "CREATE TABLE foo (id INTEGER UNIQUE)";
ASSERT_TRUE(db().Execute(kCreateSql));
@@ -387,13 +387,13 @@
ASSERT_TRUE(CorruptSizeInHeaderOfDB());
{
- sql::ScopedErrorIgnorer ignore_errors;
- ignore_errors.IgnoreError(SQLITE_CORRUPT);
+ sql::test::ScopedErrorExpecter expecter;
+ expecter.ExpectError(SQLITE_CORRUPT);
ASSERT_TRUE(db().Open(db_path()));
ASSERT_FALSE(db().DoesTableExist("bar"));
ASSERT_FALSE(db().DoesTableExist("foo"));
ASSERT_FALSE(db().DoesColumnExist("foo", "id"));
- ASSERT_TRUE(ignore_errors.CheckIgnoredErrors());
+ ASSERT_TRUE(expecter.SawExpectedErrors());
}
}
@@ -416,10 +416,10 @@
// Callback is no longer in force due to reset.
{
error = SQLITE_OK;
- sql::ScopedErrorIgnorer ignore_errors;
- ignore_errors.IgnoreError(SQLITE_CONSTRAINT);
+ sql::test::ScopedErrorExpecter expecter;
+ expecter.ExpectError(SQLITE_CONSTRAINT);
ASSERT_FALSE(db().Execute("INSERT INTO foo (id) VALUES (12)"));
- ASSERT_TRUE(ignore_errors.CheckIgnoredErrors());
+ ASSERT_TRUE(expecter.SawExpectedErrors());
EXPECT_EQ(SQLITE_OK, error);
}
@@ -616,19 +616,19 @@
// SQLite will successfully open the handle, but fail when running PRAGMA
// statements that access the database.
{
- sql::ScopedErrorIgnorer ignore_errors;
+ sql::test::ScopedErrorExpecter expecter;
// Earlier versions of Chromium compiled against SQLite 3.6.7.3, which
// returned SQLITE_IOERR_SHORT_READ in this case. Some platforms may still
// compile against an earlier SQLite via USE_SYSTEM_SQLITE.
- if (ignore_errors.SQLiteLibVersionNumber() < 3008005) {
- ignore_errors.IgnoreError(SQLITE_IOERR_SHORT_READ);
+ if (expecter.SQLiteLibVersionNumber() < 3008005) {
+ expecter.ExpectError(SQLITE_IOERR_SHORT_READ);
} else {
- ignore_errors.IgnoreError(SQLITE_NOTADB);
+ expecter.ExpectError(SQLITE_NOTADB);
}
EXPECT_TRUE(db().Open(db_path()));
- ASSERT_TRUE(ignore_errors.CheckIgnoredErrors());
+ ASSERT_TRUE(expecter.SawExpectedErrors());
}
EXPECT_TRUE(db().Raze());
db().Close();
@@ -651,10 +651,10 @@
// SQLITE_NOTADB on pragma statemenets which attempt to read the
// corrupted header.
{
- sql::ScopedErrorIgnorer ignore_errors;
- ignore_errors.IgnoreError(SQLITE_NOTADB);
+ sql::test::ScopedErrorExpecter expecter;
+ expecter.ExpectError(SQLITE_NOTADB);
EXPECT_TRUE(db().Open(db_path()));
- ASSERT_TRUE(ignore_errors.CheckIgnoredErrors());
+ ASSERT_TRUE(expecter.SawExpectedErrors());
}
EXPECT_TRUE(db().Raze());
db().Close();
@@ -680,12 +680,12 @@
// Open() will succeed, even though the PRAGMA calls within will
// fail with SQLITE_CORRUPT, as will this PRAGMA.
{
- sql::ScopedErrorIgnorer ignore_errors;
- ignore_errors.IgnoreError(SQLITE_CORRUPT);
+ sql::test::ScopedErrorExpecter expecter;
+ expecter.ExpectError(SQLITE_CORRUPT);
ASSERT_TRUE(db().Open(db_path()));
ASSERT_FALSE(db().Execute("PRAGMA auto_vacuum"));
db().Close();
- ASSERT_TRUE(ignore_errors.CheckIgnoredErrors());
+ ASSERT_TRUE(expecter.SawExpectedErrors());
}
db().set_error_callback(base::Bind(&SQLConnectionTest::RazeErrorCallback,
@@ -966,10 +966,10 @@
// Attach fails in a transaction.
EXPECT_TRUE(db().BeginTransaction());
{
- sql::ScopedErrorIgnorer ignore_errors;
- ignore_errors.IgnoreError(SQLITE_ERROR);
+ sql::test::ScopedErrorExpecter expecter;
+ expecter.ExpectError(SQLITE_ERROR);
EXPECT_FALSE(db().AttachDatabase(attach_path, kAttachmentPoint));
- ASSERT_TRUE(ignore_errors.CheckIgnoredErrors());
+ ASSERT_TRUE(expecter.SawExpectedErrors());
}
// Attach succeeds when the transaction is closed.
@@ -988,11 +988,11 @@
// Detach also fails in a transaction.
EXPECT_TRUE(db().BeginTransaction());
{
- sql::ScopedErrorIgnorer ignore_errors;
- ignore_errors.IgnoreError(SQLITE_ERROR);
+ sql::test::ScopedErrorExpecter expecter;
+ expecter.ExpectError(SQLITE_ERROR);
EXPECT_FALSE(db().DetachDatabase(kAttachmentPoint));
EXPECT_TRUE(db().IsSQLValid("SELECT count(*) from other.bar"));
- ASSERT_TRUE(ignore_errors.CheckIgnoredErrors());
+ ASSERT_TRUE(expecter.SawExpectedErrors());
}
// Detach succeeds outside of a transaction.
@@ -1011,11 +1011,11 @@
ASSERT_TRUE(CorruptSizeInHeaderOfDB());
{
- sql::ScopedErrorIgnorer ignore_errors;
- ignore_errors.IgnoreError(SQLITE_CORRUPT);
+ sql::test::ScopedErrorExpecter expecter;
+ expecter.ExpectError(SQLITE_CORRUPT);
ASSERT_TRUE(db().Open(db_path()));
EXPECT_FALSE(db().QuickIntegrityCheck());
- ASSERT_TRUE(ignore_errors.CheckIgnoredErrors());
+ ASSERT_TRUE(expecter.SawExpectedErrors());
}
}
@@ -1033,13 +1033,13 @@
ASSERT_TRUE(CorruptSizeInHeaderOfDB());
{
- sql::ScopedErrorIgnorer ignore_errors;
- ignore_errors.IgnoreError(SQLITE_CORRUPT);
+ sql::test::ScopedErrorExpecter expecter;
+ expecter.ExpectError(SQLITE_CORRUPT);
ASSERT_TRUE(db().Open(db_path()));
EXPECT_TRUE(db().FullIntegrityCheck(&messages));
EXPECT_LT(1u, messages.size());
EXPECT_NE(kOk, messages[0]);
- ASSERT_TRUE(ignore_errors.CheckIgnoredErrors());
+ ASSERT_TRUE(expecter.SawExpectedErrors());
}
// TODO(shess): CorruptTableOrIndex could be used to produce a
diff --git a/sql/recovery_unittest.cc b/sql/recovery_unittest.cc
index b215777..a117690 100644
--- a/sql/recovery_unittest.cc
+++ b/sql/recovery_unittest.cc
@@ -20,7 +20,7 @@
#include "sql/meta_table.h"
#include "sql/statement.h"
#include "sql/test/paths.h"
-#include "sql/test/scoped_error_ignorer.h"
+#include "sql/test/scoped_error_expecter.h"
#include "sql/test/sql_test_base.h"
#include "sql/test/test_helpers.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -422,12 +422,12 @@
// Test meta table missing.
EXPECT_TRUE(db().Execute("DROP TABLE meta"));
{
- sql::ScopedErrorIgnorer ignore_errors;
- ignore_errors.IgnoreError(SQLITE_CORRUPT); // From virtual table.
+ sql::test::ScopedErrorExpecter expecter;
+ expecter.ExpectError(SQLITE_CORRUPT); // From virtual table.
std::unique_ptr<sql::Recovery> recovery =
sql::Recovery::Begin(&db(), db_path());
EXPECT_FALSE(recovery->SetupMeta());
- ASSERT_TRUE(ignore_errors.CheckIgnoredErrors());
+ ASSERT_TRUE(expecter.SawExpectedErrors());
}
}
diff --git a/sql/sql.gyp b/sql/sql.gyp
index cde3057..66e3e7f 100644
--- a/sql/sql.gyp
+++ b/sql/sql.gyp
@@ -65,8 +65,8 @@
'sources': [
'test/error_callback_support.cc',
'test/error_callback_support.h',
- 'test/scoped_error_ignorer.cc',
- 'test/scoped_error_ignorer.h',
+ 'test/scoped_error_expecter.cc',
+ 'test/scoped_error_expecter.h',
'test/test_helpers.cc',
'test/test_helpers.h',
],
diff --git a/sql/statement_unittest.cc b/sql/statement_unittest.cc
index 1565b3e..75adf63 100644
--- a/sql/statement_unittest.cc
+++ b/sql/statement_unittest.cc
@@ -11,7 +11,7 @@
#include "sql/correct_sql_test_base.h"
#include "sql/statement.h"
#include "sql/test/error_callback_support.h"
-#include "sql/test/scoped_error_ignorer.h"
+#include "sql/test/scoped_error_expecter.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/sqlite/sqlite3.h"
@@ -78,18 +78,20 @@
EXPECT_EQ(SQLITE_MISMATCH, error);
}
-// Error ignorer works for error running a statement.
+// Error expecter works for error running a statement.
TEST_F(SQLStatementTest, ScopedIgnoreError) {
ASSERT_TRUE(db().Execute("CREATE TABLE foo (a INTEGER PRIMARY KEY, b)"));
sql::Statement s(db().GetUniqueStatement("INSERT INTO foo (a) VALUES (?)"));
EXPECT_TRUE(s.is_valid());
- sql::ScopedErrorIgnorer ignore_errors;
- ignore_errors.IgnoreError(SQLITE_MISMATCH);
- s.BindCString(0, "bad bad");
- ASSERT_FALSE(s.Run());
- ASSERT_TRUE(ignore_errors.CheckIgnoredErrors());
+ {
+ sql::test::ScopedErrorExpecter expecter;
+ expecter.ExpectError(SQLITE_MISMATCH);
+ s.BindCString(0, "bad bad");
+ ASSERT_FALSE(s.Run());
+ ASSERT_TRUE(expecter.SawExpectedErrors());
+ }
}
TEST_F(SQLStatementTest, Reset) {
diff --git a/sql/test/scoped_error_expecter.cc b/sql/test/scoped_error_expecter.cc
new file mode 100644
index 0000000..e19dc89c
--- /dev/null
+++ b/sql/test/scoped_error_expecter.cc
@@ -0,0 +1,63 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "sql/test/scoped_error_expecter.h"
+
+#include "base/bind.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace sql {
+namespace test {
+
+// static
+int ScopedErrorExpecter::SQLiteLibVersionNumber() {
+ return sqlite3_libversion_number();
+}
+
+ScopedErrorExpecter::ScopedErrorExpecter()
+ : checked_(false) {
+ callback_ =
+ base::Bind(&ScopedErrorExpecter::ErrorSeen, base::Unretained(this));
+ Connection::SetErrorExpecter(&callback_);
+}
+
+ScopedErrorExpecter::~ScopedErrorExpecter() {
+ EXPECT_TRUE(checked_) << " Test must call SawExpectedErrors()";
+ Connection::ResetErrorExpecter();
+}
+
+void ScopedErrorExpecter::ExpectError(int err) {
+ EXPECT_EQ(0u, errors_expected_.count(err))
+ << " Error " << err << " is already expected";
+ errors_expected_.insert(err);
+}
+
+bool ScopedErrorExpecter::SawExpectedErrors() {
+ checked_ = true;
+ return errors_expected_ == errors_seen_;
+}
+
+bool ScopedErrorExpecter::ErrorSeen(int err) {
+ // Look for extended code.
+ if (errors_expected_.count(err) > 0) {
+ // Record that the error was seen.
+ errors_seen_.insert(err);
+ return true;
+ }
+
+ // Trim extended codes and check again.
+ int base_err = err & 0xff;
+ if (errors_expected_.count(base_err) > 0) {
+ // Record that the error was seen.
+ errors_seen_.insert(base_err);
+ return true;
+ }
+
+ // Unexpected error.
+ ADD_FAILURE() << " Unexpected SQLite error " << err;
+ return false;
+}
+
+} // namespace test
+} // namespace sql
diff --git a/sql/test/scoped_error_expecter.h b/sql/test/scoped_error_expecter.h
new file mode 100644
index 0000000..0eeaf45
--- /dev/null
+++ b/sql/test/scoped_error_expecter.h
@@ -0,0 +1,76 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef SQL_TEST_SCOPED_ERROR_EXPECTER_H_
+#define SQL_TEST_SCOPED_ERROR_EXPECTER_H_
+
+#include <set>
+
+#include "base/macros.h"
+#include "sql/connection.h"
+
+// This is not strictly necessary for the operation of ScopedErrorExpecter, but
+// the class is not useful without the SQLite error codes.
+#include "third_party/sqlite/sqlite3.h"
+
+namespace sql {
+namespace test {
+
+// sql::Connection and sql::Statement treat most SQLite errors as fatal in debug
+// mode. The goal is to catch SQL errors before code is shipped to production.
+// That fatal check makes it hard to write tests for error-handling code. This
+// scoper lists errors to expect and treat as non-fatal. Errors are expected
+// globally (on all connections).
+//
+// Since errors can be very context-dependent, the class is pedantic - specific
+// errors must be expected, and every expected error must be seen.
+//
+// NOTE(shess): There are still fatal error cases this does not address. If
+// your test is handling database errors and you're hitting a case not handled,
+// contact me.
+class ScopedErrorExpecter {
+ public:
+ ScopedErrorExpecter();
+ ~ScopedErrorExpecter();
+
+ // Add an error to expect. Extended error codes can be specified
+ // individually, or the base code can be specified to expect errors for the
+ // entire group (SQLITE_IOERR_* versus SQLITE_IOERR).
+ void ExpectError(int err);
+
+ // Return |true| if the all of the expected errors were encountered. Failure
+ // to call this results in an EXPECT failure when the instance is destructed.
+ bool SawExpectedErrors() WARN_UNUSED_RESULT;
+
+ // Expose sqlite3_libversion_number() so that clients don't have to add a
+ // dependency on third_party/sqlite.
+ static int SQLiteLibVersionNumber() WARN_UNUSED_RESULT;
+
+ private:
+ // The target of the callback passed to Connection::SetErrorExpecter(). If
+ // |err| matches an error passed to ExpectError(), records |err| and returns
+ // |true|; this indicates that the enclosing test expected this error and the
+ // caller should continue as it would in production. Otherwise returns
+ // |false| and adds a failure to the current test.
+ bool ErrorSeen(int err);
+
+ // Callback passed to Connection::SetErrorExpecter().
+ Connection::ErrorExpecterCallback callback_;
+
+ // Record whether SawExpectedErrors() has been called.
+ bool checked_;
+
+ // Errors to expect.
+ std::set<int> errors_expected_;
+
+ // Expected errors which have been encountered.
+ std::set<int> errors_seen_;
+
+ DISALLOW_COPY_AND_ASSIGN(ScopedErrorExpecter);
+};
+
+} // namespace test
+} // namespace sql
+
+#endif // SQL_TEST_SCOPED_ERROR_EXPECTER_H_
diff --git a/sql/test/scoped_error_ignorer.cc b/sql/test/scoped_error_ignorer.cc
deleted file mode 100644
index 7e07cf12..0000000
--- a/sql/test/scoped_error_ignorer.cc
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "sql/test/scoped_error_ignorer.h"
-
-#include "base/bind.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace sql {
-
-// static
-int ScopedErrorIgnorer::SQLiteLibVersionNumber() {
- return sqlite3_libversion_number();
-}
-
-ScopedErrorIgnorer::ScopedErrorIgnorer()
- : checked_(false) {
- callback_ =
- base::Bind(&ScopedErrorIgnorer::ShouldIgnore, base::Unretained(this));
- Connection::SetErrorIgnorer(&callback_);
-}
-
-ScopedErrorIgnorer::~ScopedErrorIgnorer() {
- EXPECT_TRUE(checked_) << " Test must call CheckIgnoredErrors()";
- Connection::ResetErrorIgnorer();
-}
-
-void ScopedErrorIgnorer::IgnoreError(int err) {
- EXPECT_EQ(0u, ignore_errors_.count(err))
- << " Error " << err << " is already ignored";
- ignore_errors_.insert(err);
-}
-
-bool ScopedErrorIgnorer::CheckIgnoredErrors() {
- checked_ = true;
- return errors_ignored_ == ignore_errors_;
-}
-
-bool ScopedErrorIgnorer::ShouldIgnore(int err) {
- // Look for extended code.
- if (ignore_errors_.count(err) > 0) {
- // Record that the error was seen and ignore it.
- errors_ignored_.insert(err);
- return true;
- }
-
- // Trim extended codes and check again.
- int base_err = err & 0xff;
- if (ignore_errors_.count(base_err) > 0) {
- // Record that the error was seen and ignore it.
- errors_ignored_.insert(base_err);
- return true;
- }
-
- // Unexpected error.
- ADD_FAILURE() << " Unexpected SQLite error " << err;
-
- // TODO(shess): If it never makes sense to pass through an error
- // under the test harness, then perhaps the ignore callback
- // signature should be changed.
- return true;
-}
-
-} // namespace sql
diff --git a/sql/test/scoped_error_ignorer.h b/sql/test/scoped_error_ignorer.h
deleted file mode 100644
index 6d1c5df..0000000
--- a/sql/test/scoped_error_ignorer.h
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef SQL_TEST_SCOPED_ERROR_IGNORER_H_
-#define SQL_TEST_SCOPED_ERROR_IGNORER_H_
-
-#include <set>
-
-#include "base/macros.h"
-#include "sql/connection.h"
-
-// This is not strictly necessary for the operation of ScopedErrorIgnorer, but
-// the class is not useful without the SQLite error codes.
-#include "third_party/sqlite/sqlite3.h"
-
-// TODO(shess): sql::test:: seems like it could be in order for this.
-namespace sql {
-
-// sql::Connection and sql::Statement treat most SQLite errors as
-// fatal in debug mode. The intention is to catch inappropriate uses
-// of SQL before the code is shipped to production. This makes it
-// challenging to write tests for things like recovery from
-// corruption. This scoper can be used to ignore selected errors
-// during a test. Errors are ignored globally (on all connections).
-//
-// Since errors can be very context-dependent, the class is pedantic -
-// specific errors must be ignored, and every error ignored must be
-// seen.
-//
-// NOTE(shess): There are still fatal error cases this does not
-// address. If your test is handling database errors and you're
-// hitting a case not handled, contact me.
-class ScopedErrorIgnorer {
- public:
- ScopedErrorIgnorer();
- ~ScopedErrorIgnorer();
-
- // Add an error to ignore. Extended error codes can be ignored
- // specifically, or the base code can ignore an entire group
- // (SQLITE_IOERR_* versus SQLITE_IOERR).
- void IgnoreError(int err);
-
- // Allow containing test to check if the errors were encountered.
- // Failure to call results in ADD_FAILURE() in destructor.
- bool CheckIgnoredErrors();
-
- // Record an error and check if it should be ignored.
- bool ShouldIgnore(int err);
-
- // Expose sqlite3_libversion_number() so that clients don't have to add a
- // dependency on third_party/sqlite.
- static int SQLiteLibVersionNumber();
-
- private:
- // Storage for callback passed to Connection::SetErrorIgnorer().
- Connection::ErrorIgnorerCallback callback_;
-
- // Record whether CheckIgnoredErrors() has been called.
- bool checked_;
-
- // Errors to ignore.
- std::set<int> ignore_errors_;
-
- // Errors which have been ignored.
- std::set<int> errors_ignored_;
-
- DISALLOW_COPY_AND_ASSIGN(ScopedErrorIgnorer);
-};
-
-} // namespace sql
-
-#endif // SQL_TEST_SCOPED_ERROR_IGNORER_H_