test: locator_topology: add test_update_node

Reproduces issue fixed in PR #13502

Signed-off-by: Benny Halevy <bhalevy@scylladb.com>
This commit is contained in:
Benny Halevy
2023-04-13 22:39:26 +03:00
parent e29994b2aa
commit e18eb71fa3

View File

@@ -11,6 +11,7 @@
#include <seastar/core/on_internal_error.hh>
#include <seastar/util/defer.hh>
#include "locator/types.hh"
#include "test/lib/scylla_test_case.hh"
#include "utils/fb_utilities.hh"
@@ -66,3 +67,85 @@ SEASTAR_THREAD_TEST_CASE(test_add_node) {
topo.clear_gently().get();
}
SEASTAR_THREAD_TEST_CASE(test_update_node) {
auto id1 = host_id::create_random_id();
auto ep1 = gms::inet_address("127.0.0.1");
auto id2 = host_id::create_random_id();
auto ep2 = gms::inet_address("127.0.0.2");
auto ep3 = gms::inet_address("127.0.0.3");
utils::fb_utilities::set_broadcast_address(ep1);
topology::config cfg = {
.this_host_id = host_id::create_null_id(),
.this_endpoint = ep1,
.local_dc_rack = endpoint_dc_rack::default_location,
};
auto topo = topology(cfg);
set_abort_on_internal_error(false);
auto reset_on_internal_abort = seastar::defer([] {
set_abort_on_internal_error(true);
});
auto node = topo.this_node();
auto mutable_node = const_cast<locator::node*>(node);
node = topo.update_node(mutable_node, id1, std::nullopt, std::nullopt, std::nullopt);
BOOST_REQUIRE_EQUAL(topo.find_node(id1), node);
mutable_node = const_cast<locator::node*>(node);
BOOST_REQUIRE_THROW(topo.update_node(mutable_node, host_id::create_null_id(), std::nullopt, std::nullopt, std::nullopt), std::runtime_error);
BOOST_REQUIRE_THROW(topo.update_node(mutable_node, id2, std::nullopt, std::nullopt, std::nullopt), std::runtime_error);
BOOST_REQUIRE_EQUAL(topo.find_node(id1), node);
BOOST_REQUIRE_EQUAL(topo.find_node(id2), nullptr);
node = topo.update_node(mutable_node, std::nullopt, ep2, std::nullopt, std::nullopt);
mutable_node = const_cast<locator::node*>(node);
BOOST_REQUIRE_EQUAL(topo.find_node(ep1), nullptr);
BOOST_REQUIRE_EQUAL(topo.find_node(ep2), node);
auto dc_rack1 = endpoint_dc_rack{"DC1", "RACK1"};
node = topo.update_node(mutable_node, std::nullopt, std::nullopt, dc_rack1, std::nullopt);
mutable_node = const_cast<locator::node*>(node);
BOOST_REQUIRE(topo.get_location(id1) == dc_rack1);
BOOST_REQUIRE(topo.get_location(ep1) == dc_rack1);
auto dc_rack2 = endpoint_dc_rack{"DC2", "RACK2"};
node = topo.update_node(mutable_node, std::nullopt, std::nullopt, dc_rack2, std::nullopt);
mutable_node = const_cast<locator::node*>(node);
BOOST_REQUIRE(topo.get_location(id1) == dc_rack2);
BOOST_REQUIRE(topo.get_location(ep1) == dc_rack2);
BOOST_REQUIRE_NE(node->get_state(), locator::node::state::leaving);
node = topo.update_node(mutable_node, std::nullopt, std::nullopt, std::nullopt, locator::node::state::leaving);
mutable_node = const_cast<locator::node*>(node);
BOOST_REQUIRE_EQUAL(node->get_state(), locator::node::state::leaving);
auto dc_rack3 = endpoint_dc_rack{"DC3", "RACK3"};
// Note: engage state option, but keep node::state value the same
// to reproduce #13502
node = topo.update_node(mutable_node, std::nullopt, ep3, dc_rack3, locator::node::state::leaving);
mutable_node = const_cast<locator::node*>(node);
BOOST_REQUIRE_EQUAL(topo.find_node(id1), node);
BOOST_REQUIRE_EQUAL(topo.find_node(ep1), nullptr);
BOOST_REQUIRE_EQUAL(topo.find_node(ep2), nullptr);
BOOST_REQUIRE_EQUAL(topo.find_node(ep3), node);
BOOST_REQUIRE(topo.get_location(id1) == dc_rack3);
BOOST_REQUIRE(topo.get_location(ep2) == endpoint_dc_rack::default_location);
BOOST_REQUIRE(topo.get_location(ep3) == dc_rack3);
BOOST_REQUIRE_EQUAL(node->get_state(), locator::node::state::leaving);
// In state::left the ndoe will remain indexed only by its host_id
node = topo.update_node(mutable_node, std::nullopt, std::nullopt, std::nullopt, locator::node::state::left);
BOOST_REQUIRE_EQUAL(topo.find_node(id1), node);
BOOST_REQUIRE_EQUAL(topo.find_node(ep1), nullptr);
BOOST_REQUIRE_EQUAL(topo.find_node(ep2), nullptr);
BOOST_REQUIRE_EQUAL(topo.find_node(ep3), nullptr);
BOOST_REQUIRE(topo.get_location(id1) == dc_rack3);
BOOST_REQUIRE(topo.get_location(ep2) == endpoint_dc_rack::default_location);
BOOST_REQUIRE(topo.get_location(ep3) == endpoint_dc_rack::default_location);
BOOST_REQUIRE_EQUAL(node->get_state(), locator::node::state::left);
}