Files
scylladb/test/boost/group0_cmd_merge_test.cc
Takuya ASADA 03461d6a54 test: compile unit tests into a single executable
To reduce test executable size and speed up compilation time, compile unit
tests into a single executable.

Here is a file size comparison of the unit test executable:

- Before applying the patch
$ du -h --exclude='*.o' --exclude='*.o.d' build/release/test/boost/ build/debug/test/boost/
11G	build/release/test/boost/
29G	build/debug/test/boost/

- After applying the patch
du -h --exclude='*.o' --exclude='*.o.d' build/release/test/boost/ build/debug/test/boost/
5.5G	build/release/test/boost/
19G	build/debug/test/boost/

It reduces executable sizes 5.5GB on release, and 10GB on debug.

Closes #9155

Closes scylladb/scylladb#21443
2024-12-22 19:14:09 +02:00

128 lines
5.3 KiB
C++

/*
* Copyright (C) 2023-present ScyllaDB
*/
/*
* SPDX-License-Identifier: LicenseRef-ScyllaDB-Source-Available-1.0
*/
#include <fmt/ranges.h>
#undef SEASTAR_TESTING_MAIN
#include <seastar/testing/test_case.hh>
#include "test/lib/cql_test_env.hh"
#include "db/config.hh"
#include "db/system_keyspace.hh"
#include "service/migration_manager.hh"
#include "service/raft/raft_group_registry.hh"
#include "service/raft/group0_state_machine.hh"
#include "service/raft/group0_state_machine_merger.hh"
#include "idl/experimental/broadcast_tables_lang.dist.hh"
#include "idl/experimental/broadcast_tables_lang.dist.impl.hh"
#include "idl/group0_state_machine.dist.hh"
#include "idl/group0_state_machine.dist.impl.hh"
#include "utils/error_injection.hh"
#include "test/lib/expr_test_utils.hh"
BOOST_AUTO_TEST_SUITE(group0_cmd_merge_test)
const auto OLD_TIMEUUID = utils::UUID_gen::get_time_UUID(std::chrono::system_clock::time_point::min());
static service::group0_command create_command(utils::UUID id) {
auto mut = canonical_mutation{mutation{db::system_keyspace::group0_history(), partition_key::make_empty()}};
return service::group0_command {
.change{service::write_mutations{std::vector<canonical_mutation>{mut}}},
.history_append{db::system_keyspace::make_group0_history_state_id_mutation(
id, std::nullopt, "test")},
.new_state_id = id,
.creator_addr{},
.creator_id{raft::server_id::create_random_id()},
};
}
SEASTAR_TEST_CASE(test_group0_state_machine_merger_timeuuid_order) {
// Regression test for #14568 and #14600.
auto [db, db_impl] = cql3::expr::test_utils::make_data_dictionary_database(db::system_keyspace::group0_history());
semaphore s{1};
auto mutex_holder = co_await get_units(s, 1);
// From #7729
// UUID's `<=>` comparator does not preserve timeuuid monotonicity.
// Here, t1 and t2 are ordered differently as UUIDs than as timeuuids.
auto t1 = utils::UUID("13814000-1dd2-11ff-8080-808080808080"); // 2038-09-06
auto t2 = utils::UUID("6b1b3620-33fd-11eb-8080-808080808080"); // 2020-12-01
// check if UUID comparison works as expected.
BOOST_REQUIRE(t2 > t1);
// Check if timeuuid comparison works as expected.
BOOST_REQUIRE(utils::timeuuid_tri_compare(t2, t1) == std::strong_ordering::less);
auto cmd1 = create_command(t1);
auto cmd2 = create_command(t2);
service::group0_state_machine_merger merger{OLD_TIMEUUID, std::move(mutex_holder), 1024 * 1024, db};
size_t size = merger.cmd_size(cmd1);
merger.add(std::move(cmd1), size);
merger.add(std::move(cmd2), size);
// The current state_id stored in the `system.group0_history` table is always the greatest one in the timeuuid order.
// This is why we expect t1 to be stored in the merger as the current state_id.
BOOST_REQUIRE_EQUAL(merger.last_id(), t1);
}
SEASTAR_TEST_CASE(test_group0_cmd_merge) {
#ifndef SCYLLA_ENABLE_ERROR_INJECTION
fmt::print("Skipping test as it depends on error injection. Please run in mode where it's enabled (debug,dev).\n");
return make_ready_future<>();
#else
cql_test_config cfg;
cfg.db_config->commitlog_segment_size_in_mb(1);
return do_with_cql_env_thread([] (cql_test_env& env) {
auto& group0 = env.get_raft_group_registry().local().group0();
auto& mm = env.migration_manager().local();
auto id = utils::UUID_gen::get_time_UUID();
service::group0_command group0_cmd {
.history_append{db::system_keyspace::make_group0_history_state_id_mutation(
id, gc_clock::duration{0}, "test")},
.new_state_id = id,
.creator_addr{env.db().local().get_token_metadata().get_topology().my_address()},
.creator_id{group0.id()}
};
std::vector<canonical_mutation> cms;
size_t size = 0;
auto muts = service::prepare_keyspace_drop_announcement(env.local_db(), "ks", api::new_timestamp()).get();
// Maximum mutation size is 1/3 of commitlog segment size which we set
// to 1M. Make one command a little bit larger than third of the max size.
while (size < 150*1024) {
for (auto&& m : muts) {
cms.emplace_back(m);
size += cms.back().representation().size();
}
}
group0_cmd.change = service::schema_change{std::move(cms)};
raft::command cmd;
ser::serialize(cmd, group0_cmd);
auto merges = mm.canonical_mutation_merge_count;
utils::get_local_injector().enable("poll_fsm_output/pause");
auto f = when_all(
group0.add_entry(cmd, raft::wait_type::applied, nullptr),
group0.add_entry(cmd, raft::wait_type::applied, nullptr),
group0.add_entry(cmd, raft::wait_type::applied, nullptr));
// Sleep is needed for all the entries added above to hit the log
seastar::sleep(std::chrono::milliseconds(100)).get();
// After unpause all entries added above will be committed and applied together
utils::get_local_injector().disable("poll_fsm_output/pause");
f.get(); // Wait for apply to complete
// Thete should be two calls to migration manager since two out of
// three command should be merged.
BOOST_REQUIRE_EQUAL(mm.canonical_mutation_merge_count - merges, 2);
}, cfg);
#endif
}
BOOST_AUTO_TEST_SUITE_END()