diff options
author | furszy <matiasfurszyfer@protonmail.com> | 2024-01-08 11:19:25 -0300 |
---|---|---|
committer | furszy <matiasfurszyfer@protonmail.com> | 2024-01-30 17:27:36 -0300 |
commit | b298242c8d495c36072415e1b95eaa7bf485a38a (patch) | |
tree | 97e2c2104962da68074620af87c7fb24792e9dc3 /src/wallet/test/db_tests.cpp | |
parent | fc0e747192e98e779c5f31f2df808f62b3fdd071 (diff) |
test: sqlite, add coverage for dangling to-be-reverted db txns
Diffstat (limited to 'src/wallet/test/db_tests.cpp')
-rw-r--r-- | src/wallet/test/db_tests.cpp | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/src/wallet/test/db_tests.cpp b/src/wallet/test/db_tests.cpp index c6b2154efd..7e6219378f 100644 --- a/src/wallet/test/db_tests.cpp +++ b/src/wallet/test/db_tests.cpp @@ -228,6 +228,59 @@ BOOST_AUTO_TEST_CASE(db_availability_after_write_error) } } +#ifdef USE_SQLITE + +// Test-only statement execution error +constexpr int TEST_SQLITE_ERROR = -999; + +class DbExecBlocker : public SQliteExecHandler +{ +private: + SQliteExecHandler m_base_exec; + std::set<std::string> m_blocked_statements; +public: + DbExecBlocker(std::set<std::string> blocked_statements) : m_blocked_statements(blocked_statements) {} + int Exec(SQLiteDatabase& database, const std::string& statement) override { + if (m_blocked_statements.contains(statement)) return TEST_SQLITE_ERROR; + return m_base_exec.Exec(database, statement); + } +}; + +BOOST_AUTO_TEST_CASE(txn_close_failure_dangling_txn) +{ + // Verifies that there is no active dangling, to-be-reversed db txn + // after the batch object that initiated it is destroyed. + DatabaseOptions options; + DatabaseStatus status; + bilingual_str error; + std::unique_ptr<SQLiteDatabase> database = MakeSQLiteDatabase(m_path_root / "sqlite", options, status, error); + + std::string key = "key"; + std::string value = "value"; + + std::unique_ptr<SQLiteBatch> batch = std::make_unique<SQLiteBatch>(*database); + BOOST_CHECK(batch->TxnBegin()); + BOOST_CHECK(batch->Write(key, value)); + // Set a handler to prevent txn abortion during destruction. + // Mimicking a db statement execution failure. + batch->SetExecHandler(std::make_unique<DbExecBlocker>(std::set<std::string>{"ROLLBACK TRANSACTION"})); + // Destroy batch + batch.reset(); + + // Ensure there is no dangling, to-be-reversed db txn + BOOST_CHECK(!database->HasActiveTxn()); + + // And, just as a sanity check; verify that new batchs only write what they suppose to write + // and nothing else. + std::string key2 = "key2"; + std::unique_ptr<SQLiteBatch> batch2 = std::make_unique<SQLiteBatch>(*database); + BOOST_CHECK(batch2->Write(key2, value)); + // The first key must not exist + BOOST_CHECK(!batch2->Exists(key)); +} + +#endif // USE_SQLITE + BOOST_AUTO_TEST_SUITE_END() } // namespace wallet |