/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2024 /// \copyright SPDX-License-Identifier: Apache-2.0 #include "test.h++" registry *registry::instance() { static registry *singleton; if (!singleton) singleton = new registry(); return singleton; } bool registry::add(const record *item) { auto const singleton = instance(); assert(singleton->name2id.count(std::string(item->name)) == 0); assert(singleton->id2record.count(item->id) == 0); if (singleton->name2id.count(std::string(item->name)) + singleton->id2record.count(item->id) == 0) { singleton->name2id[std::string(item->name)] = item; singleton->id2record[item->id] = item; return true; } return false; } testcase *registry::create_actor(const actor_config &config, const mdbx_pid_t pid) { return instance()->id2record.at(config.testcase)->constructor(config, pid); } bool registry::review_actor_params(const actor_testcase id, actor_params ¶ms, const unsigned space_id) { return instance()->id2record.at(id)->review_params(params, space_id); } //----------------------------------------------------------------------------- void configure_actor(unsigned &last_space_id, const actor_testcase testcase, const char *space_id_cstr, actor_params params) { unsigned wait4id = 0; if (params.waitfor_nops) { for (auto i = global::actors.rbegin(); i != global::actors.rend(); ++i) { if (i->is_waitable(params.waitfor_nops)) { if (i->signal_nops && i->signal_nops != params.waitfor_nops) failure("Previous waitable actor (id=%u) already linked on %u-ops\n", i->actor_id, i->signal_nops); wait4id = i->actor_id; i->signal_nops = params.waitfor_nops; break; } } if (!wait4id) failure("No previous waitable actor for %u-ops\n", params.waitfor_nops); } unsigned long space_id = 0; if (!space_id_cstr || strcmp(space_id_cstr, "auto") == 0) space_id = last_space_id + 1; else { char *end = nullptr; errno = 0; space_id = strtoul(space_id_cstr, &end, 0); if (errno) failure_perror("Expects an integer value for space-id\n", errno); if (end && *end) failure("The '%s' is unexpected for space-id\n", end); } if (space_id > ACTOR_ID_MAX) failure("Invalid space-id %lu\n", space_id); if (!registry::review_actor_params(testcase, params, unsigned(space_id))) failure("Actor config-review failed for space-id %lu\n", space_id); last_space_id = unsigned(space_id); log_trace("configure_actor: space %lu for %s", space_id, testcase2str(testcase)); global::actors.emplace_back( actor_config(testcase, params, unsigned(space_id), wait4id)); global::databases.insert(params.pathname_db); } void testcase_setup(const char *casename, const actor_params ¶ms, unsigned &last_space_id) { if (strcmp(casename, "basic") == 0) { log_notice(">>> testcase_setup(%s)", casename); configure_actor(last_space_id, ac_nested, nullptr, params); configure_actor(last_space_id, ac_hill, nullptr, params); configure_actor(last_space_id, ac_ttl, nullptr, params); configure_actor(last_space_id, ac_copy, nullptr, params); configure_actor(last_space_id, ac_append, nullptr, params); configure_actor(last_space_id, ac_jitter, nullptr, params); configure_actor(last_space_id, ac_try, nullptr, params); configure_actor(last_space_id, ac_jitter, nullptr, params); configure_actor(last_space_id, ac_try, nullptr, params); #if !defined(_WIN32) && !defined(_WIN64) configure_actor(last_space_id, ac_forkread, nullptr, params); configure_actor(last_space_id, ac_forkwrite, nullptr, params); #endif /* Windows */ log_notice("<<< testcase_setup(%s): done", casename); } else { failure("unknown testcase `%s`", casename); } } void keycase_setup(const char *casename, actor_params ¶ms) { if (strcmp(casename, "random") == 0 || strcmp(casename, "prng") == 0) { log_notice(">>> keycase_setup(%s)", casename); params.keygen.keycase = kc_random; // TODO log_notice("<<< keycase_setup(%s): done", casename); } else if (strcmp(casename, "dashes") == 0 || strcmp(casename, "aside") == 0) { log_notice(">>> keycase_setup(%s)", casename); params.keygen.keycase = kc_dashes; // TODO log_notice("<<< keycase_setup(%s): done", casename); } else if (strcmp(casename, "custom") == 0) { log_notice("=== keycase_setup(%s): skip", casename); params.keygen.keycase = kc_custom; } else { failure("unknown keycase `%s`", casename); } } /* TODO */