diff --git a/src/uhs/twophase/coordinator/interface.hpp b/src/uhs/twophase/coordinator/interface.hpp index 291cf2be7..d8f4cc511 100644 --- a/src/uhs/twophase/coordinator/interface.hpp +++ b/src/uhs/twophase/coordinator/interface.hpp @@ -8,6 +8,8 @@ #include "uhs/transaction/transaction.hpp" +#include + namespace cbdc::coordinator { /// \brief Interface for a coordinator. /// Provides consistent semantics whether using a remote coordinator via diff --git a/src/util/common/logging.hpp b/src/util/common/logging.hpp index 8b12f3764..821ada900 100644 --- a/src/util/common/logging.hpp +++ b/src/util/common/logging.hpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include diff --git a/src/util/rpc/tcp_client.hpp b/src/util/rpc/tcp_client.hpp index fed5025af..2b13b9283 100644 --- a/src/util/rpc/tcp_client.hpp +++ b/src/util/rpc/tcp_client.hpp @@ -55,7 +55,7 @@ namespace cbdc::rpc { /// starts the response handler thread. /// \return true. [[nodiscard]] auto init() -> bool { - if(!m_net.cluster_connect(m_server_endpoints, false)) { + if(!m_net.cluster_connect(m_server_endpoints, true)) { return false; } diff --git a/tests/unit/rpc/tcp_test.cpp b/tests/unit/rpc/tcp_test.cpp index 74f1b67bd..5f06f58e7 100644 --- a/tests/unit/rpc/tcp_test.cpp +++ b/tests/unit/rpc/tcp_test.cpp @@ -126,7 +126,7 @@ TEST(tcp_rpc_test, send_fail_test) { auto client = cbdc::rpc::tcp_client( {{cbdc::network::localhost, 55555}, {cbdc::network::localhost, 55556}}); - ASSERT_TRUE(client.init()); + ASSERT_FALSE(client.init()); auto req = request{0}; auto resp = client.call(req); diff --git a/tests/unit/sentinel_2pc/controller_test.cpp b/tests/unit/sentinel_2pc/controller_test.cpp index da2ed4a89..c0bad32ed 100644 --- a/tests/unit/sentinel_2pc/controller_test.cpp +++ b/tests/unit/sentinel_2pc/controller_test.cpp @@ -169,3 +169,60 @@ TEST_F(sentinel_2pc_test, tx_validation_test) { }); ASSERT_TRUE(res); } + +TEST_F(sentinel_2pc_test, bad_coordinator_endpoint) { + // Replace the valid coordinator endpoint defined in the fixture + // with an invalid endpoint. + m_opts.m_coordinator_endpoints.clear(); + const auto bad_coordinator_ep + = std::make_pair("abcdefg", m_coordinator_port); + m_opts.m_coordinator_endpoints.resize(1); + m_opts.m_coordinator_endpoints[0].push_back(bad_coordinator_ep); + + // Initialize a new controller with the invalid coordinator endpoint. + auto ctl = std::make_unique(0, + m_opts, + m_logger); + + // Check that the controller with the invalid coordinator endpoint + // fails to initialize correctly. + ASSERT_FALSE(ctl->init()); +} + +TEST_F(sentinel_2pc_test, bad_sentinel_client_endpoint) { + // Test that a sentinel client fails to initialize + // when given a bad endpoint. + constexpr auto bad_endpoint = std::make_pair("abcdefg", m_sentinel_port); + const std::vector bad_endpoints{bad_endpoint}; + auto client = cbdc::sentinel::rpc::client(bad_endpoints, m_logger); + ASSERT_FALSE(client.init()); + + // Test that the controller fails to initialize when given a bad endpoint + // for a sentinel client. + m_opts.m_sentinel_endpoints.emplace_back(bad_endpoint); + auto ctl = std::make_unique(0, + m_opts, + m_logger); + ASSERT_FALSE(ctl->init()); +} + +TEST_F(sentinel_2pc_test, bad_rpc_server_endpoint) { + // The sentinel endpoint defined below (which corresponds to sentinel_id + // also defined below) is used by the sentinel_2pc controller to initialize + // an rpc server. Replacing the valid endpoint defined in the fixture with + // an invalid endpoint should cause the rpc server to fail to initialize. + m_opts.m_sentinel_endpoints.clear(); + constexpr auto bad_endpoint = std::make_pair("abcdefg", m_sentinel_port); + m_opts.m_sentinel_endpoints.resize(1); + m_opts.m_sentinel_endpoints.emplace_back(bad_endpoint); + + // Initialize a new controller with the invalid endpoint for the server. + constexpr uint32_t sentinel_id = 0; + const auto ctl + = std::make_unique(sentinel_id, + m_opts, + m_logger); + + // Check that the controller with the invalid endpoint fails to initialize. + ASSERT_FALSE(ctl->init()); +}