diff --git a/.github/actions/code_coverage/action.yml b/.github/actions/code_coverage/action.yml index eb3a72c7..f6c58742 100644 --- a/.github/actions/code_coverage/action.yml +++ b/.github/actions/code_coverage/action.yml @@ -6,7 +6,7 @@ runs: - name: Run tests shell: bash run: | - build/clio_tests --gtest_filter="-BackendCassandraBaseTest*:BackendCassandraTest*:BackendCassandraFactoryTestWithDB*" + build/clio_tests --backend_host=scylladb - name: Run gcovr shell: bash diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ab630d2d..40ed52a6 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -39,6 +39,15 @@ jobs: runs-on: [self-hosted, "${{ matrix.os }}"] container: ${{ matrix.container }} + services: + scylladb: + image: ${{ (matrix.code_coverage) && 'scylladb/scylla' || '' }} + options: >- + --health-cmd "cqlsh -e 'describe cluster'" + --health-interval 10s + --health-timeout 5s + --health-retries 5 + steps: - uses: actions/checkout@v4 with: diff --git a/CMakeLists.txt b/CMakeLists.txt index 287efb7f..56cb7397 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -187,6 +187,7 @@ if (tests) unittests/ProfilerTests.cpp unittests/JsonUtilTests.cpp unittests/DOSGuardTests.cpp + unittests/util/TestGlobals.cpp unittests/util/AssertTests.cpp unittests/util/BatchingTests.cpp unittests/util/TestObject.cpp diff --git a/unittests/Main.cpp b/unittests/Main.cpp index c63140c3..d2df56fe 100644 --- a/unittests/Main.cpp +++ b/unittests/Main.cpp @@ -18,15 +18,23 @@ //============================================================================== #include "util/TerminationHandler.h" +#include "util/TestGlobals.h" #include "util/prometheus/Prometheus.h" #include +/* + * Supported custom command line options for clio_tests: + * --backend_host= - sets the cassandra/scylladb host for backend tests + * --backend_keyspace= - sets the cassandra/scylladb keyspace for backend tests + */ int -main(int argc, char** argv) +main(int argc, char* argv[]) { util::setTerminationHandler(); PrometheusService::init(); testing::InitGoogleTest(&argc, argv); + TestGlobals::instance().parse(argc, argv); + return RUN_ALL_TESTS(); } diff --git a/unittests/data/BackendFactoryTests.cpp b/unittests/data/BackendFactoryTests.cpp index c52e2545..6727e667 100644 --- a/unittests/data/BackendFactoryTests.cpp +++ b/unittests/data/BackendFactoryTests.cpp @@ -20,6 +20,7 @@ #include "data/BackendFactory.h" #include "data/cassandra/Handle.h" #include "util/Fixtures.h" +#include "util/TestGlobals.h" #include "util/config/Config.h" #include @@ -30,7 +31,6 @@ #include namespace { -constexpr auto contactPoints = "127.0.0.1"; constexpr auto keyspace = "factory_test"; } // namespace @@ -62,7 +62,7 @@ protected: { BackendCassandraFactoryTest::TearDown(); // drop the keyspace for next test - data::cassandra::Handle const handle{contactPoints}; + data::cassandra::Handle const handle{TestGlobals::instance().backendHost}; EXPECT_TRUE(handle.connect()); handle.execute("DROP KEYSPACE " + std::string{keyspace}); } @@ -116,7 +116,7 @@ TEST_F(BackendCassandraFactoryTestWithDB, CreateCassandraBackend) }} }} }})", - contactPoints, + TestGlobals::instance().backendHost, keyspace ))}; @@ -128,7 +128,7 @@ TEST_F(BackendCassandraFactoryTestWithDB, CreateCassandraBackend) EXPECT_FALSE(backend->fetchLedgerRange()); // insert range table - data::cassandra::Handle const handle{contactPoints}; + data::cassandra::Handle const handle{TestGlobals::instance().backendHost}; EXPECT_TRUE(handle.connect()); handle.execute(fmt::format("INSERT INTO {}.ledger_range (is_latest, sequence) VALUES (False, 100)", keyspace)); handle.execute(fmt::format("INSERT INTO {}.ledger_range (is_latest, sequence) VALUES (True, 500)", keyspace)); @@ -159,7 +159,7 @@ TEST_F(BackendCassandraFactoryTestWithDB, CreateCassandraBackendReadOnlyWithEmpt }} }} }})", - contactPoints, + TestGlobals::instance().backendHost, keyspace ))}; EXPECT_THROW(make_Backend(cfg), std::runtime_error); @@ -180,7 +180,7 @@ TEST_F(BackendCassandraFactoryTestWithDB, CreateCassandraBackendReadOnlyWithDBRe }} }} }})", - contactPoints, + TestGlobals::instance().backendHost, keyspace ))}; @@ -197,7 +197,7 @@ TEST_F(BackendCassandraFactoryTestWithDB, CreateCassandraBackendReadOnlyWithDBRe }} }} }})", - contactPoints, + TestGlobals::instance().backendHost, keyspace ))}; diff --git a/unittests/data/cassandra/BackendTests.cpp b/unittests/data/cassandra/BackendTests.cpp index 7c6507e7..a954134d 100644 --- a/unittests/data/cassandra/BackendTests.cpp +++ b/unittests/data/cassandra/BackendTests.cpp @@ -29,6 +29,7 @@ #include "util/LedgerUtils.h" #include "util/Random.h" #include "util/StringUtils.h" +#include "util/TestGlobals.h" #include "util/config/Config.h" #include @@ -68,11 +69,6 @@ namespace json = boost::json; using namespace data::cassandra; -namespace { -constexpr auto contactPoints = "127.0.0.1"; -constexpr auto keyspace = "clio_test"; -} // namespace - class BackendCassandraTest : public SyncAsioContextTest { protected: Config cfg{json::parse(fmt::format( @@ -81,8 +77,8 @@ protected: "keyspace": "{}", "replication_factor": 1 }})JSON", - contactPoints, - keyspace + TestGlobals::instance().backendHost, + TestGlobals::instance().backendKeyspace ))}; SettingsProvider settingsProvider{cfg, 0}; @@ -101,9 +97,9 @@ protected: backend.reset(); // drop the keyspace for next test - Handle const handle{contactPoints}; + Handle const handle{TestGlobals::instance().backendHost}; EXPECT_TRUE(handle.connect()); - handle.execute("DROP KEYSPACE " + std::string{keyspace}); + handle.execute("DROP KEYSPACE " + TestGlobals::instance().backendKeyspace); } std::default_random_engine randomEngine{0}; diff --git a/unittests/data/cassandra/BaseTests.cpp b/unittests/data/cassandra/BaseTests.cpp index 26eaf7cd..7255bc52 100644 --- a/unittests/data/cassandra/BaseTests.cpp +++ b/unittests/data/cassandra/BaseTests.cpp @@ -20,6 +20,7 @@ #include "data/cassandra/Handle.h" #include "data/cassandra/Types.h" #include "util/Fixtures.h" +#include "util/TestGlobals.h" #include #include @@ -107,7 +108,7 @@ protected: TEST_F(BackendCassandraBaseTest, ConnectionSuccess) { - Handle const handle{"127.0.0.1"}; + Handle const handle{TestGlobals::instance().backendHost}; auto const f = handle.asyncConnect(); auto const res = f.await(); @@ -144,7 +145,7 @@ TEST_F(BackendCassandraBaseTest, ConnectionFailTimeout) TEST_F(BackendCassandraBaseTest, FutureCallback) { - Handle const handle{"127.0.0.1"}; + Handle const handle{TestGlobals::instance().backendHost}; ASSERT_TRUE(handle.connect()); auto const statement = handle.prepare("SELECT keyspace_name FROM system_schema.keyspaces").bind(); @@ -165,7 +166,7 @@ TEST_F(BackendCassandraBaseTest, FutureCallback) TEST_F(BackendCassandraBaseTest, FutureCallbackSurviveMove) { - Handle const handle{"127.0.0.1"}; + Handle const handle{TestGlobals::instance().backendHost}; ASSERT_TRUE(handle.connect()); auto const statement = handle.prepare("SELECT keyspace_name FROM system_schema.keyspaces").bind(); @@ -192,7 +193,7 @@ TEST_F(BackendCassandraBaseTest, FutureCallbackSurviveMove) TEST_F(BackendCassandraBaseTest, KeyspaceManipulation) { - Handle const handle{"127.0.0.1"}; + Handle const handle{TestGlobals::instance().backendHost}; std::string keyspace = "test_keyspace_manipulation"; { @@ -244,7 +245,7 @@ TEST_F(BackendCassandraBaseTest, CreateTableWithStrings) "fifth", }; - auto handle = createHandle("127.0.0.1", "test"); + auto handle = createHandle(TestGlobals::instance().backendHost, "test"); auto q1 = fmt::format( R"( CREATE TABLE IF NOT EXISTS strings (hash blob PRIMARY KEY, sequence bigint) @@ -309,7 +310,7 @@ TEST_F(BackendCassandraBaseTest, BatchInsert) "fifth", }; - auto handle = createHandle("127.0.0.1", "test"); + auto handle = createHandle(TestGlobals::instance().backendHost, "test"); auto const q1 = fmt::format( R"( CREATE TABLE IF NOT EXISTS strings (hash blob PRIMARY KEY, sequence bigint) @@ -368,7 +369,7 @@ TEST_F(BackendCassandraBaseTest, BatchInsertAsync) "fifth", }; - auto handle = createHandle("127.0.0.1", "test"); + auto handle = createHandle(TestGlobals::instance().backendHost, "test"); auto const q1 = fmt::format( R"( CREATE TABLE IF NOT EXISTS strings (hash blob PRIMARY KEY, sequence bigint) @@ -414,7 +415,7 @@ TEST_F(BackendCassandraBaseTest, BatchInsertAsync) TEST_F(BackendCassandraBaseTest, AlterTableAddColumn) { - auto handle = createHandle("127.0.0.1", "test"); + auto handle = createHandle(TestGlobals::instance().backendHost, "test"); auto const q1 = fmt::format( R"( CREATE TABLE IF NOT EXISTS strings (hash blob PRIMARY KEY, sequence bigint) @@ -432,7 +433,7 @@ TEST_F(BackendCassandraBaseTest, AlterTableAddColumn) TEST_F(BackendCassandraBaseTest, AlterTableMoveToNewTable) { - auto handle = createHandle("127.0.0.1", "test"); + auto handle = createHandle(TestGlobals::instance().backendHost, "test"); prepStringsTable(handle); auto const newTable = fmt::format( diff --git a/unittests/util/TestGlobals.cpp b/unittests/util/TestGlobals.cpp new file mode 100644 index 00000000..3b412304 --- /dev/null +++ b/unittests/util/TestGlobals.cpp @@ -0,0 +1,56 @@ +//------------------------------------------------------------------------------ +/* + This file is part of clio: https://github.com/XRPLF/clio + Copyright (c) 2024, the clio developers. + + Permission to use, copy, modify, and distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ +//============================================================================== + +#include "util/TestGlobals.h" + +#include +#include +#include +#include +#include + +TestGlobals& +TestGlobals::instance() +{ + static TestGlobals inst; + return inst; +} + +void +TestGlobals::parse(int argc, char* argv[]) +{ + namespace po = boost::program_options; + + // clang-format off + po::options_description description("Clio UT options"); + description.add_options() + ("backend_host", po::value()->default_value(TestGlobals::backendHost), + "sets the cassandra/scylladb host for backend tests") + ("backend_keyspace", po::value()->default_value(TestGlobals::backendKeyspace), + "sets the cassandra/scylladb keyspace for backend tests") + ; + // clang-format on + + po::variables_map parsed; + po::store(po::command_line_parser(argc, argv).options(description).run(), parsed); + po::notify(parsed); + + backendHost = parsed["backend_host"].as(); + backendKeyspace = parsed["backend_keyspace"].as(); +} diff --git a/unittests/util/TestGlobals.h b/unittests/util/TestGlobals.h new file mode 100644 index 00000000..dc4ac2b9 --- /dev/null +++ b/unittests/util/TestGlobals.h @@ -0,0 +1,45 @@ +//------------------------------------------------------------------------------ +/* + This file is part of clio: https://github.com/XRPLF/clio + Copyright (c) 2024, the clio developers. + + Permission to use, copy, modify, and distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ +//============================================================================== + +#pragma once + +#include + +/* + * Contains global variables for use in tests. + */ +struct TestGlobals { + std::string backendHost = "127.0.0.1"; + std::string backendKeyspace = "clio_test"; + + static TestGlobals& + instance(); + + void + parse(int argc, char* argv[]); + +private: + TestGlobals() = default; + TestGlobals(TestGlobals const&) = delete; + TestGlobals(TestGlobals&&) = delete; + TestGlobals& + operator=(TestGlobals const&) = delete; + TestGlobals& + operator=(TestGlobals&&) = delete; +};