diff --git a/test/nested.cc b/test/nested.cc index beebd880..335b22bc 100644 --- a/test/nested.cc +++ b/test/nested.cc @@ -178,7 +178,6 @@ bool testcase_nested::trim_tail(unsigned window_width) { fifo.size()); db_table_clear(dbi, txn_guard.get()); fifo.clear(); - speculum.clear(); } return true; } diff --git a/test/test.cc b/test/test.cc index 9da2cf2f..4cc4e286 100644 --- a/test/test.cc +++ b/test/test.cc @@ -172,6 +172,7 @@ void testcase::txn_begin(bool readonly, unsigned flags) { if (unlikely(rc != MDBX_SUCCESS)) failure_perror("mdbx_txn_begin()", rc); txn_guard.reset(txn); + need_speculum_assign = config.params.speculum && !readonly; log_trace("<< txn_begin(%s, 0x%04X)", readonly ? "read-only" : "read-write", flags); @@ -192,9 +193,12 @@ int testcase::breakable_commit() { if (unlikely(err != MDBX_SUCCESS && err != MDBX_THREAD_MISMATCH && err != MDBX_BAD_TXN)) failure_perror("mdbx_txn_abort()", err); + if (need_speculum_assign) + speculum = speculum_commited; } else failure_perror("mdbx_txn_commit()", err); - } + } else if (need_speculum_assign) + speculum_commited = speculum; log_trace("<< txn_commit: %s", rc ? "failed" : "Ok"); return rc; @@ -224,11 +228,15 @@ void testcase::txn_end(bool abort) { if (unlikely(err != MDBX_SUCCESS && err != MDBX_THREAD_MISMATCH && err != MDBX_BAD_TXN)) failure_perror("mdbx_txn_abort()", err); + if (need_speculum_assign) + speculum = speculum_commited; } else { txn_inject_writefault(txn); int err = mdbx_txn_commit(txn); if (unlikely(err != MDBX_SUCCESS)) failure_perror("mdbx_txn_commit()", err); + if (need_speculum_assign) + speculum_commited = speculum; } log_trace("<< txn_end(%s)", abort ? "abort" : "commit"); @@ -491,6 +499,7 @@ void testcase::db_table_drop(MDBX_dbi handle) { int rc = mdbx_drop(txn_guard.get(), handle, true); if (unlikely(rc != MDBX_SUCCESS)) failure_perror("mdbx_drop(delete=true)", rc); + speculum.clear(); log_trace("<< testcase::db_table_drop"); } else { log_trace("<< testcase::db_table_drop: not needed"); @@ -502,6 +511,7 @@ void testcase::db_table_clear(MDBX_dbi handle, MDBX_txn *txn) { int rc = mdbx_drop(txn ? txn : txn_guard.get(), handle, false); if (unlikely(rc != MDBX_SUCCESS)) failure_perror("mdbx_drop(delete=false)", rc); + speculum.clear(); log_trace("<< testcase::db_table_clear"); } diff --git a/test/test.h b/test/test.h index 5024589e..8194b057 100644 --- a/test/test.h +++ b/test/test.h @@ -133,6 +133,9 @@ protected: return cmp < 0; } }; + + // for simplify the set> + // is used instead of multimap using SET = std::set; const actor_config &config; @@ -143,6 +146,7 @@ protected: scoped_txn_guard txn_guard; scoped_cursor_guard cursor_guard; bool signalled{false}; + bool need_speculum_assign{false}; size_t nops_completed{0}; chrono::time start_timestamp; @@ -154,7 +158,7 @@ protected: mdbx_canary canary; } last; - SET speculum{ItemCompare(this)}; + SET speculum{ItemCompare(this)}, speculum_commited{ItemCompare(this)}; bool speculum_verify(); int insert(const keygen::buffer &akey, const keygen::buffer &adata, unsigned flags); @@ -233,11 +237,10 @@ public: class testcase_hill : public testcase { using inherited = testcase; - SET speculum_commited; public: testcase_hill(const actor_config &config, const mdbx_pid_t pid) - : testcase(config, pid), speculum_commited(ItemCompare(this)) {} + : testcase(config, pid) {} bool run() override; }; diff --git a/test/ttl.cc b/test/ttl.cc index 92e99b82..a410d943 100644 --- a/test/ttl.cc +++ b/test/ttl.cc @@ -97,7 +97,7 @@ bool testcase_ttl::run() { for (unsigned n = 0; n < tail_count; ++n) { log_trace("ttl: remove-tail %" PRIu64, tail_serial); generate_pair(tail_serial); - err = mdbx_del(txn_guard.get(), dbi, &key->value, &data->value); + err = remove(key, data); if (unlikely(err != MDBX_SUCCESS)) { if (err == MDBX_MAP_FULL && config.params.ignore_dbfull) { log_notice("ttl: tail-bailout due '%s'", mdbx_strerror(err)); @@ -120,13 +120,17 @@ bool testcase_ttl::run() { log_notice("ttl: bailout at commit due '%s'", mdbx_strerror(err)); break; } + if (!speculum_verify()) { + log_notice("ttl: bailout after tail-trim"); + return false; + } + fifo.push_front(std::make_pair(serial, head_count)); retry: for (unsigned n = 0; n < head_count; ++n) { log_trace("ttl: insert-head %" PRIu64, serial); generate_pair(serial); - err = mdbx_put(txn_guard.get(), dbi, &key->value, &data->value, - insert_flags); + err = insert(key, data, insert_flags); if (unlikely(err != MDBX_SUCCESS)) { if (err == MDBX_MAP_FULL && config.params.ignore_dbfull) { log_notice("ttl: head-insert skip due '%s'", mdbx_strerror(err)); @@ -149,6 +153,10 @@ bool testcase_ttl::run() { serial = fifo.front().first; fifo.pop_front(); } + if (!speculum_verify()) { + log_notice("ttl: bailout after head-grow"); + return false; + } report(1); rc = true;