Merge '[Backport 2025.4] test/raft: use valid sentinel in liveness check to prevent digest errors' from Scylladb[bot]
Replace -1 with 0 for the liveness check operation to avoid triggering digest validation failures. This prevents rare fatal errors when the cluster is recovering and ensures the test does not violate append_seq invariants. The value -1 was causing invalid digest results in the append_seq structure, leading to assertion failures. This could happen when the sentinel value was the first (or only) element being appended, resulting in a digest that did not match the expected value. By using 0 instead, we ensure that the digest calculations remain valid and consistent with the expected behavior of the test. The specific value of the sentinel is not important, as long as it is a valid elem_t that does not violate the invariants of the append_seq structure. In particular, the sentinel value is typically used only when no valid result is received from any server in the current loop iteration, in which case the loop will retry. Fixes: scylladb/scylladb#27307 Backporting to active branches - this is a test-only fix (low risk) for a flaky test that exists in older branches (thus affects the CI of active branches). - (cherry picked from commit3af5183633) - (cherry picked from commit4ba3e90f33) Parent PR: #28010 Closes scylladb/scylladb#28038 * https://github.com/scylladb/scylladb: test/raft: use valid sentinel in liveness check to prevent digest errors test/raft: improve debugging in randomized_nemesis_test test/raft: improve reporting in the randomized_nemesis_test digest functions
This commit is contained in:
@@ -2930,6 +2930,18 @@ private:
|
||||
|
||||
static constexpr elem_t magic = 54313;
|
||||
|
||||
static void check_digest_value(elem_t d) {
|
||||
if (d < 0 || d >= magic) {
|
||||
on_fatal_internal_error(tlogger, fmt::format("Digest value out of range: {}", d));
|
||||
}
|
||||
}
|
||||
|
||||
static void validate_digest_value(elem_t d_new, elem_t d_old, elem_t x) {
|
||||
if (d_new < 0 || d_new >= magic) {
|
||||
on_fatal_internal_error(tlogger, fmt::format("Digest value invalid after appending/removing element: d_new {}, d_old {}, x {}", d_new, d_old, x));
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
append_seq(std::vector<elem_t> v) : _seq{make_lw_shared<std::vector<elem_t>>(std::move(v))}, _end{_seq->size()}, _digest{0} {
|
||||
for (auto x : *_seq) {
|
||||
@@ -2938,20 +2950,28 @@ public:
|
||||
}
|
||||
|
||||
static elem_t digest_append(elem_t d, elem_t x) {
|
||||
BOOST_REQUIRE_LE(0, d);
|
||||
BOOST_REQUIRE_LT(d, magic);
|
||||
check_digest_value(d);
|
||||
|
||||
auto y = (d + x) % magic;
|
||||
|
||||
validate_digest_value(y, d, x);
|
||||
|
||||
SCYLLA_ASSERT(digest_remove(y, x) == d);
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
static elem_t digest_remove(elem_t d, elem_t x) {
|
||||
BOOST_REQUIRE_LE(0, d);
|
||||
BOOST_REQUIRE_LT(d, magic);
|
||||
check_digest_value(d);
|
||||
|
||||
auto y = (d - x) % magic;
|
||||
return y < 0 ? y + magic : y;
|
||||
|
||||
if (y < 0) {
|
||||
y += magic;
|
||||
}
|
||||
|
||||
validate_digest_value(y, d, x);
|
||||
return y;
|
||||
}
|
||||
|
||||
elem_t digest() const {
|
||||
@@ -3001,7 +3021,9 @@ public:
|
||||
|
||||
private:
|
||||
append_seq(lw_shared_ptr<std::vector<elem_t>> seq, size_t end, elem_t d)
|
||||
: _seq(std::move(seq)), _end(end), _digest(d) {}
|
||||
: _seq(std::move(seq)), _end(end), _digest(d) {
|
||||
check_digest_value(d);
|
||||
}
|
||||
};
|
||||
|
||||
struct AppendReg {
|
||||
@@ -3582,7 +3604,7 @@ SEASTAR_TEST_CASE(basic_generator_test) {
|
||||
tlogger.info("From the clients' point of view, the possible cluster members are: {}", known_config);
|
||||
|
||||
auto [res, last_attempted_server] = co_await bouncing{[&timer, &env] (raft::server_id id) {
|
||||
return env.call(id, AppendReg::append{-1}, timer.now() + 200_t, timer);
|
||||
return env.call(id, AppendReg::append{0}, timer.now() + 200_t, timer);
|
||||
}}(timer, known_config, leader, known_config.size() + 1, 10_t, 10_t);
|
||||
|
||||
if (std::holds_alternative<typename AppendReg::ret>(res)) {
|
||||
|
||||
Reference in New Issue
Block a user