mirror of
https://github.com/isar/libmdbx.git
synced 2024-12-29 08:38:49 +08:00
test: jitter testcase (squashed major refine).
This commit is contained in:
parent
101e015d2c
commit
f3e31a74ee
2
Makefile
2
Makefile
@ -66,7 +66,7 @@ clean:
|
||||
rm -rf $(TOOLS) test/test @* *.[ao] *.[ls]o *~ tmp.db/* *.gcov *.log *.err
|
||||
|
||||
check: test/test
|
||||
test/test --pathname=tmp.db --basic --dont-cleanup-after && ./mdbx_chk -vn tmp.db
|
||||
test/test --pathname=tmp.db --dont-cleanup-after basic && ./mdbx_chk -vn tmp.db
|
||||
|
||||
mdbx.o: $(MDBX_SRC) Makefile
|
||||
$(CC) $(CFLAGS) -c src/mdbx.c -o $@
|
||||
|
@ -23,8 +23,8 @@ void configure_actor(unsigned &lastid, const actor_testcase testcase,
|
||||
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->id, i->signal_nops);
|
||||
wait4id = i->id;
|
||||
i->actor_id, i->signal_nops);
|
||||
wait4id = i->actor_id;
|
||||
i->signal_nops = params.waitfor_nops;
|
||||
break;
|
||||
}
|
||||
@ -33,7 +33,7 @@ void configure_actor(unsigned &lastid, const actor_testcase testcase,
|
||||
failure("No previous waitable actor for %u-ops\n", params.waitfor_nops);
|
||||
}
|
||||
|
||||
unsigned long id = 0;
|
||||
unsigned id = 0;
|
||||
if (!id_cstr || strcmp(id_cstr, "auto") == 0)
|
||||
id = lastid + 1;
|
||||
else {
|
||||
@ -47,23 +47,26 @@ void configure_actor(unsigned &lastid, const actor_testcase testcase,
|
||||
}
|
||||
|
||||
if (id < 1 || id > ACTOR_ID_MAX)
|
||||
failure("Invalid actor-id %lu\n", id);
|
||||
failure("Invalid actor-id %u\n", id);
|
||||
lastid = id;
|
||||
|
||||
log_trace("configure_actor: %u for %s", id, testcase2str(testcase));
|
||||
global::actors.emplace_back(actor_config(testcase, params, id, wait4id));
|
||||
global::databases.insert(params.pathname_db);
|
||||
}
|
||||
|
||||
bool testcase_setup(const char *casename, const actor_params ¶ms,
|
||||
void testcase_setup(const char *casename, actor_params ¶ms,
|
||||
unsigned &lastid) {
|
||||
log_notice("testcase_setup(%s): TODO", casename);
|
||||
|
||||
if (strcmp(casename, "basic") == 0) {
|
||||
log_notice(">>> testcase_setup(%s)", casename);
|
||||
configure_actor(lastid, ac_hill, nullptr, params);
|
||||
return true;
|
||||
configure_actor(lastid, ac_jitter, nullptr, params);
|
||||
configure_actor(lastid, ac_jitter, nullptr, params);
|
||||
configure_actor(lastid, ac_jitter, nullptr, params);
|
||||
log_notice("<<< testcase_setup(%s): done", casename);
|
||||
} else {
|
||||
failure("unknown testcase `%s`", casename);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* TODO */
|
||||
|
@ -32,26 +32,23 @@ bool parse_option(int argc, char *const argv[], int &narg, const char *option,
|
||||
if (!value) {
|
||||
if (current[optlen + 2] == '=')
|
||||
failure("Option '--%s' doen't accept any value\n", option);
|
||||
narg += 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
*value = nullptr;
|
||||
if (current[optlen + 2] == '=') {
|
||||
*value = ¤t[optlen + 3];
|
||||
narg += 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (narg + 1 < argc && strncmp("--", argv[narg + 1], 2)) {
|
||||
if (narg + 1 < argc && strncmp("--", argv[narg + 1], 2) != 0) {
|
||||
*value = argv[narg + 1];
|
||||
narg += 2;
|
||||
++narg;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (default_value) {
|
||||
*value = default_value;
|
||||
narg += 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -184,11 +181,16 @@ bool parse_option(int argc, char *const argv[], int &narg, const char *option,
|
||||
const char *value_cstr = NULL;
|
||||
if (!parse_option(argc, argv, narg, option, &value_cstr, "yes")) {
|
||||
const char *current = argv[narg];
|
||||
if (strncmp(current, "--no-", 5) || strcmp(current + 5, option))
|
||||
return false;
|
||||
value = false;
|
||||
narg += 1;
|
||||
return true;
|
||||
if (strncmp(current, "--no-", 5) == 0 && strcmp(current + 5, option) == 0) {
|
||||
value = false;
|
||||
return true;
|
||||
}
|
||||
if (strncmp(current, "--dont-", 7) == 0 &&
|
||||
strcmp(current + 7, option) == 0) {
|
||||
value = false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!value_cstr) {
|
||||
@ -266,8 +268,8 @@ void dump(const char *title) {
|
||||
logging::local_suffix indent(title);
|
||||
|
||||
for (auto i = global::actors.begin(); i != global::actors.end(); ++i) {
|
||||
log_info("#%u, testcase %s, id/table %u\n", i->order,
|
||||
testcase2str(i->testcase), i->id);
|
||||
log_info("#%u, testcase %s, space_id/table %u\n", i->actor_id,
|
||||
testcase2str(i->testcase), i->space_id);
|
||||
indent.push();
|
||||
|
||||
if (i->params.loglevel) {
|
||||
@ -284,8 +286,8 @@ void dump(const char *title) {
|
||||
|
||||
log_info("seed %u\n", i->params.seed);
|
||||
|
||||
if (i->params.test_nrecords)
|
||||
log_info("records %u\n", i->params.test_nrecords);
|
||||
if (i->params.test_nops)
|
||||
log_info("iterations/records %u\n", i->params.test_nops);
|
||||
else
|
||||
dump_duration("duration", i->params.test_duration);
|
||||
|
||||
@ -319,10 +321,10 @@ void dump(const char *title) {
|
||||
indent.pop();
|
||||
}
|
||||
|
||||
dump_duration("timeout", global::config::timeout);
|
||||
dump_duration("timeout", global::config::timeout_duration_seconds);
|
||||
log_info("cleanup: before %s, after %s\n",
|
||||
global::config::dont_cleanup_before ? "No" : "Yes",
|
||||
global::config::dont_cleanup_after ? "No" : "Yes");
|
||||
global::config::cleanup_before ? "Yes" : "No",
|
||||
global::config::cleanup_after ? "Yes" : "No");
|
||||
}
|
||||
|
||||
} /* namespace config */
|
||||
@ -332,10 +334,10 @@ void dump(const char *title) {
|
||||
using namespace config;
|
||||
|
||||
actor_config::actor_config(actor_testcase testcase, const actor_params ¶ms,
|
||||
unsigned id, unsigned wait4id)
|
||||
unsigned space_id, unsigned wait4id)
|
||||
: params(params) {
|
||||
this->id = id;
|
||||
this->order = (unsigned)global::actors.size();
|
||||
this->space_id = space_id;
|
||||
this->actor_id = 1 + (unsigned)global::actors.size();
|
||||
this->testcase = testcase;
|
||||
this->wait4id = wait4id;
|
||||
signal_nops = 0;
|
||||
|
@ -78,7 +78,7 @@ struct actor_params_pod {
|
||||
unsigned seed;
|
||||
|
||||
unsigned test_duration;
|
||||
unsigned test_nrecords;
|
||||
unsigned test_nops;
|
||||
unsigned nrepeat;
|
||||
unsigned nthreads;
|
||||
|
||||
@ -98,7 +98,7 @@ struct actor_params_pod {
|
||||
};
|
||||
|
||||
struct actor_config_pod {
|
||||
unsigned id, order;
|
||||
unsigned actor_id, space_id;
|
||||
actor_testcase testcase;
|
||||
unsigned wait4id;
|
||||
unsigned signal_nops;
|
||||
@ -123,8 +123,8 @@ struct actor_config : public config::actor_config_pod {
|
||||
|
||||
bool wanna_event4signalling() const { return true /* TODO ? */; }
|
||||
|
||||
actor_config(actor_testcase testcase, const actor_params ¶ms, unsigned id,
|
||||
unsigned wait4id);
|
||||
actor_config(actor_testcase testcase, const actor_params ¶ms,
|
||||
unsigned space_id, unsigned wait4id);
|
||||
|
||||
actor_config(const char *str) {
|
||||
if (!deserialize(str, *this))
|
||||
@ -140,7 +140,7 @@ struct actor_config : public config::actor_config_pod {
|
||||
bool is_waitable(size_t nops) const {
|
||||
switch (testcase) {
|
||||
case ac_hill:
|
||||
if (!params.test_nrecords || params.test_nrecords >= nops)
|
||||
if (!params.test_nops || params.test_nops >= nops)
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
|
10
test/dead.cc
10
test/dead.cc
@ -24,7 +24,8 @@ bool testcase_deadread::setup() {
|
||||
}
|
||||
|
||||
bool testcase_deadread::run() {
|
||||
/* TODO */
|
||||
db_open();
|
||||
txn_begin(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -33,7 +34,7 @@ bool testcase_deadread::teardown() {
|
||||
cursor_guard.release();
|
||||
txn_guard.release();
|
||||
db_guard.release();
|
||||
return true;
|
||||
return inherited::teardown();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -48,7 +49,8 @@ bool testcase_deadwrite::setup() {
|
||||
}
|
||||
|
||||
bool testcase_deadwrite::run() {
|
||||
/* TODO */
|
||||
db_open();
|
||||
txn_begin(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -57,5 +59,5 @@ bool testcase_deadwrite::teardown() {
|
||||
cursor_guard.release();
|
||||
txn_guard.release();
|
||||
db_guard.release();
|
||||
return true;
|
||||
return inherited::teardown();
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ bool testcase_hill::setup() {
|
||||
}
|
||||
|
||||
bool testcase_hill::run() {
|
||||
mdbx_open();
|
||||
db_open();
|
||||
/* TODO */
|
||||
return true;
|
||||
}
|
||||
|
@ -19,13 +19,47 @@ bool testcase_jitter::setup() {
|
||||
if (!inherited::setup())
|
||||
return false;
|
||||
|
||||
/* TODO */
|
||||
|
||||
log_trace("<< setup");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool testcase_jitter::run() { return true; }
|
||||
bool testcase_jitter::run() {
|
||||
while (should_continue()) {
|
||||
jitter_delay();
|
||||
db_open();
|
||||
|
||||
if (flipcoin()) {
|
||||
jitter_delay();
|
||||
txn_begin(true);
|
||||
jitter_delay();
|
||||
txn_end(false);
|
||||
}
|
||||
|
||||
jitter_delay();
|
||||
txn_begin(mode_readonly());
|
||||
jitter_delay();
|
||||
if (!mode_readonly()) {
|
||||
/* TODO:
|
||||
* - db_sequence()
|
||||
* - db_setsize()
|
||||
* ...
|
||||
*/
|
||||
}
|
||||
txn_end(false);
|
||||
|
||||
if (flipcoin()) {
|
||||
jitter_delay();
|
||||
txn_begin(true);
|
||||
jitter_delay();
|
||||
txn_end(false);
|
||||
}
|
||||
|
||||
jitter_delay();
|
||||
db_close();
|
||||
report(1);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool testcase_jitter::teardown() {
|
||||
log_trace(">> teardown");
|
||||
|
342
test/main.cc
342
test/main.cc
@ -44,7 +44,7 @@ void actor_params::set_defaults(void) {
|
||||
seed = 1;
|
||||
|
||||
test_duration = 0;
|
||||
test_nrecords = 1000;
|
||||
test_nops = 1000;
|
||||
nrepeat = 1;
|
||||
nthreads = 1;
|
||||
|
||||
@ -63,6 +63,11 @@ void actor_params::set_defaults(void) {
|
||||
|
||||
max_readers = 42;
|
||||
max_tables = 42;
|
||||
|
||||
global::config::timeout_duration_seconds = 0 /* infinite */;
|
||||
global::config::dump_config = true;
|
||||
global::config::cleanup_before = true;
|
||||
global::config::cleanup_after = true;
|
||||
}
|
||||
|
||||
namespace global {
|
||||
@ -72,12 +77,15 @@ std::unordered_map<unsigned, actor_config *> events;
|
||||
std::unordered_map<mdbx_pid_t, actor_config *> pid2actor;
|
||||
std::set<std::string> databases;
|
||||
unsigned nactors;
|
||||
chrono::time start_motonic;
|
||||
chrono::time deadline_motonic;
|
||||
bool singlemode;
|
||||
|
||||
namespace config {
|
||||
unsigned timeout;
|
||||
unsigned timeout_duration_seconds;
|
||||
bool dump_config;
|
||||
bool dont_cleanup_before;
|
||||
bool dont_cleanup_after;
|
||||
bool cleanup_before;
|
||||
bool cleanup_after;
|
||||
} /* namespace config */
|
||||
|
||||
} /* namespace global */
|
||||
@ -121,122 +129,154 @@ int main(int argc, char *const argv[]) {
|
||||
logging::setup((logging::loglevel)params.loglevel, "main");
|
||||
unsigned lastid = 0;
|
||||
|
||||
if (argc == 2 && strncmp(argv[1], "--case=", 7) == 0) {
|
||||
const char *casename = argv[1] + 7;
|
||||
if (!testcase_setup(casename, params, lastid))
|
||||
failure("unknown testcase `%s`", casename);
|
||||
} else {
|
||||
for (int i = 1; i < argc;) {
|
||||
const char *value = nullptr;
|
||||
if (config::parse_option(argc, argv, i, "basic", nullptr)) {
|
||||
bool ok = testcase_setup("basic", params, lastid);
|
||||
assert(ok);
|
||||
(void)ok;
|
||||
} else if (config::parse_option(argc, argv, i, "race", nullptr)) {
|
||||
bool ok = testcase_setup("race", params, lastid);
|
||||
assert(ok);
|
||||
(void)ok;
|
||||
} else if (config::parse_option(argc, argv, i, "bench", nullptr)) {
|
||||
bool ok = testcase_setup("bench", params, lastid);
|
||||
assert(ok);
|
||||
(void)ok;
|
||||
} else if (config::parse_option(argc, argv, i, "pathname",
|
||||
params.pathname_db) ||
|
||||
config::parse_option(argc, argv, i, "mode", params.mode_flags,
|
||||
config::mode_bits) ||
|
||||
config::parse_option(argc, argv, i, "table",
|
||||
params.table_flags, config::table_bits) ||
|
||||
config::parse_option(argc, argv, i, "size", params.size,
|
||||
config::binary, 4096 * 4) ||
|
||||
config::parse_option(argc, argv, i, "seed", params.seed,
|
||||
config::no_scale) ||
|
||||
config::parse_option(argc, argv, i, "repeat", params.nrepeat,
|
||||
config::no_scale) ||
|
||||
config::parse_option(argc, argv, i, "threads", params.nthreads,
|
||||
config::no_scale, 1, 64) ||
|
||||
config::parse_option(argc, argv, i, "timeout",
|
||||
global::config::timeout, config::duration,
|
||||
1) ||
|
||||
config::parse_option(argc, argv, i, "keylen.min",
|
||||
params.keylen_min, config::no_scale, 0,
|
||||
params.keylen_max) ||
|
||||
config::parse_option(argc, argv, i, "keylen.max",
|
||||
params.keylen_max, config::no_scale,
|
||||
params.keylen_min,
|
||||
mdbx_get_maxkeysize(0)) ||
|
||||
config::parse_option(argc, argv, i, "datalen.min",
|
||||
params.datalen_min, config::no_scale, 0,
|
||||
params.datalen_max) ||
|
||||
config::parse_option(argc, argv, i, "datalen.max",
|
||||
params.datalen_max, config::no_scale,
|
||||
params.datalen_min, MDBX_MAXDATASIZE) ||
|
||||
config::parse_option(argc, argv, i, "batch.read",
|
||||
params.batch_read, config::no_scale, 1) ||
|
||||
config::parse_option(argc, argv, i, "batch.write",
|
||||
params.batch_write, config::no_scale,
|
||||
1) ||
|
||||
config::parse_option(argc, argv, i, "delay", params.delaystart,
|
||||
config::duration) ||
|
||||
config::parse_option(argc, argv, i, "wait4ops",
|
||||
params.waitfor_nops, config::decimal) ||
|
||||
config::parse_option(argc, argv, i, "drop",
|
||||
params.drop_table) ||
|
||||
config::parse_option(argc, argv, i, "dump-config",
|
||||
global::config::dump_config) ||
|
||||
config::parse_option(argc, argv, i, "dont-cleanup-before",
|
||||
global::config::dont_cleanup_before) ||
|
||||
config::parse_option(argc, argv, i, "dont-cleanup-after",
|
||||
global::config::dont_cleanup_after) ||
|
||||
config::parse_option(argc, argv, i, "max-readers",
|
||||
params.max_readers, config::no_scale, 1,
|
||||
255) ||
|
||||
config::parse_option(argc, argv, i, "max-tables",
|
||||
params.max_tables, config::no_scale, 1,
|
||||
INT16_MAX) ||
|
||||
false) {
|
||||
continue;
|
||||
} else if (config::parse_option(argc, argv, i, "no-delay", nullptr)) {
|
||||
params.delaystart = 0;
|
||||
} else if (config::parse_option(argc, argv, i, "no-wait", nullptr)) {
|
||||
params.waitfor_nops = 0;
|
||||
} else if (config::parse_option(argc, argv, i, "duration",
|
||||
params.test_duration, config::duration,
|
||||
1)) {
|
||||
params.test_nrecords = 0;
|
||||
continue;
|
||||
} else if (config::parse_option(argc, argv, i, "records",
|
||||
params.test_nrecords, config::decimal,
|
||||
1)) {
|
||||
params.test_duration = 0;
|
||||
continue;
|
||||
} else if (config::parse_option(argc, argv, i, "hill", &value)) {
|
||||
configure_actor(lastid, ac_hill, value, params);
|
||||
continue;
|
||||
} else if (config::parse_option(argc, argv, i, "jitter", nullptr)) {
|
||||
configure_actor(lastid, ac_jitter, value, params);
|
||||
continue;
|
||||
} else if (config::parse_option(argc, argv, i, "dead.reader", nullptr)) {
|
||||
configure_actor(lastid, ac_deadread, value, params);
|
||||
continue;
|
||||
} else if (config::parse_option(argc, argv, i, "dead.writer", nullptr)) {
|
||||
configure_actor(lastid, ac_deadwrite, value, params);
|
||||
continue;
|
||||
} else {
|
||||
failure("Unknown option '%s'\n", argv[i]);
|
||||
}
|
||||
for (int narg = 1; narg < argc; ++narg) {
|
||||
const char *value = nullptr;
|
||||
|
||||
if (config::parse_option(argc, argv, narg, "case", &value)) {
|
||||
testcase_setup(value, params, lastid);
|
||||
continue;
|
||||
}
|
||||
if (config::parse_option(argc, argv, narg, "pathname", params.pathname_db))
|
||||
continue;
|
||||
if (config::parse_option(argc, argv, narg, "mode", params.mode_flags,
|
||||
config::mode_bits))
|
||||
continue;
|
||||
if (config::parse_option(argc, argv, narg, "table", params.table_flags,
|
||||
config::table_bits))
|
||||
continue;
|
||||
if (config::parse_option(argc, argv, narg, "size", params.size,
|
||||
config::binary, 4096 * 4))
|
||||
continue;
|
||||
if (config::parse_option(argc, argv, narg, "seed", params.seed,
|
||||
config::no_scale))
|
||||
continue;
|
||||
if (config::parse_option(argc, argv, narg, "repeat", params.nrepeat,
|
||||
config::no_scale))
|
||||
continue;
|
||||
if (config::parse_option(argc, argv, narg, "threads", params.nthreads,
|
||||
config::no_scale, 1, 64))
|
||||
continue;
|
||||
if (config::parse_option(argc, argv, narg, "timeout",
|
||||
global::config::timeout_duration_seconds,
|
||||
config::duration, 1))
|
||||
continue;
|
||||
if (config::parse_option(argc, argv, narg, "keylen.min", params.keylen_min,
|
||||
config::no_scale, 0, params.keylen_max))
|
||||
continue;
|
||||
if (config::parse_option(argc, argv, narg, "keylen.max", params.keylen_max,
|
||||
config::no_scale, params.keylen_min,
|
||||
mdbx_get_maxkeysize(0)))
|
||||
continue;
|
||||
if (config::parse_option(argc, argv, narg, "datalen.min",
|
||||
params.datalen_min, config::no_scale, 0,
|
||||
params.datalen_max))
|
||||
continue;
|
||||
if (config::parse_option(argc, argv, narg, "datalen.max",
|
||||
params.datalen_max, config::no_scale,
|
||||
params.datalen_min, MDBX_MAXDATASIZE))
|
||||
continue;
|
||||
if (config::parse_option(argc, argv, narg, "batch.read", params.batch_read,
|
||||
config::no_scale, 1))
|
||||
continue;
|
||||
if (config::parse_option(argc, argv, narg, "batch.write",
|
||||
params.batch_write, config::no_scale, 1))
|
||||
continue;
|
||||
if (config::parse_option(argc, argv, narg, "delay", params.delaystart,
|
||||
config::duration))
|
||||
continue;
|
||||
if (config::parse_option(argc, argv, narg, "wait4ops", params.waitfor_nops,
|
||||
config::decimal))
|
||||
continue;
|
||||
if (config::parse_option(argc, argv, narg, "drop", params.drop_table))
|
||||
continue;
|
||||
if (config::parse_option(argc, argv, narg, "dump-config",
|
||||
global::config::dump_config))
|
||||
continue;
|
||||
if (config::parse_option(argc, argv, narg, "cleanup-before",
|
||||
global::config::cleanup_before))
|
||||
continue;
|
||||
if (config::parse_option(argc, argv, narg, "cleanup-after",
|
||||
global::config::cleanup_after))
|
||||
continue;
|
||||
if (config::parse_option(argc, argv, narg, "max-readers",
|
||||
params.max_readers, config::no_scale, 1, 255))
|
||||
continue;
|
||||
if (config::parse_option(argc, argv, narg, "max-tables", params.max_tables,
|
||||
config::no_scale, 1, INT16_MAX))
|
||||
continue;
|
||||
|
||||
if (config::parse_option(argc, argv, narg, "no-delay", nullptr)) {
|
||||
params.delaystart = 0;
|
||||
continue;
|
||||
}
|
||||
if (config::parse_option(argc, argv, narg, "no-wait", nullptr)) {
|
||||
params.waitfor_nops = 0;
|
||||
continue;
|
||||
}
|
||||
if (config::parse_option(argc, argv, narg, "duration", params.test_duration,
|
||||
config::duration, 1)) {
|
||||
params.test_nops = 0;
|
||||
continue;
|
||||
}
|
||||
if (config::parse_option(argc, argv, narg, "nops", params.test_nops,
|
||||
config::decimal, 1)) {
|
||||
params.test_duration = 0;
|
||||
continue;
|
||||
}
|
||||
if (config::parse_option(argc, argv, narg, "hill", &value)) {
|
||||
configure_actor(lastid, ac_hill, value, params);
|
||||
continue;
|
||||
}
|
||||
if (config::parse_option(argc, argv, narg, "jitter", nullptr)) {
|
||||
configure_actor(lastid, ac_jitter, value, params);
|
||||
continue;
|
||||
}
|
||||
if (config::parse_option(argc, argv, narg, "dead.reader", nullptr)) {
|
||||
configure_actor(lastid, ac_deadread, value, params);
|
||||
continue;
|
||||
}
|
||||
if (config::parse_option(argc, argv, narg, "dead.writer", nullptr)) {
|
||||
configure_actor(lastid, ac_deadwrite, value, params);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (*argv[narg] != '-')
|
||||
testcase_setup(argv[narg], params, lastid);
|
||||
else
|
||||
failure("Unknown option '%s'\n", argv[narg]);
|
||||
}
|
||||
|
||||
if (global::config::dump_config)
|
||||
config::dump();
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
if (global::actors.empty()) {
|
||||
log_notice("no testcase(s) configured, exiting");
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
bool failed = false;
|
||||
if (global::actors.size()) {
|
||||
global::start_motonic = chrono::now_motonic();
|
||||
global::deadline_motonic.fixedpoint =
|
||||
(global::config::timeout_duration_seconds == 0)
|
||||
? chrono::infinite().fixedpoint
|
||||
: global::start_motonic.fixedpoint +
|
||||
chrono::from_seconds(global::config::timeout_duration_seconds)
|
||||
.fixedpoint;
|
||||
|
||||
if (global::config::cleanup_before)
|
||||
cleanup();
|
||||
|
||||
if (global::actors.size() == 1) {
|
||||
logging::setup("main");
|
||||
global::singlemode = true;
|
||||
if (!test_execute(global::actors.front()))
|
||||
failed = true;
|
||||
} else {
|
||||
logging::setup("overlord");
|
||||
|
||||
if (!global::config::dont_cleanup_before)
|
||||
cleanup();
|
||||
|
||||
log_trace("=== preparing...");
|
||||
log_trace(">> osal_setup");
|
||||
osal_setup(global::actors);
|
||||
log_trace("<< osal_setup");
|
||||
@ -250,58 +290,60 @@ int main(int argc, char *const argv[]) {
|
||||
log_trace(">> killall_actors");
|
||||
osal_killall_actors();
|
||||
log_trace("<< killall_actors");
|
||||
failure("Failed to start actor #%u (%s)\n", a.order, test_strerror(rc));
|
||||
failure("Failed to start actor #%u (%s)\n", a.actor_id,
|
||||
test_strerror(rc));
|
||||
}
|
||||
global::pid2actor[pid] = &a;
|
||||
}
|
||||
|
||||
log_trace("=== ready to start...");
|
||||
atexit(osal_killall_actors);
|
||||
log_trace(">> wait4barrier");
|
||||
osal_wait4barrier();
|
||||
log_trace("<< wait4barrier");
|
||||
}
|
||||
|
||||
time_t timestamp_start = time(nullptr);
|
||||
size_t left = global::actors.size();
|
||||
|
||||
while (left > 0) {
|
||||
unsigned timeout = INT_MAX;
|
||||
if (global::config::timeout) {
|
||||
time_t timestamp_now = time(nullptr);
|
||||
if (timestamp_now - timestamp_start > global::config::timeout)
|
||||
timeout = 0;
|
||||
else
|
||||
timeout = global::config::timeout -
|
||||
(unsigned)(timestamp_now - timestamp_start);
|
||||
}
|
||||
|
||||
mdbx_pid_t pid;
|
||||
int rc = osal_actor_poll(pid, timeout);
|
||||
if (rc)
|
||||
failure("Poll error: %s (%d)\n", test_strerror(rc), rc);
|
||||
|
||||
if (pid) {
|
||||
actor_status status = osal_actor_info(pid);
|
||||
actor_config *actor = global::pid2actor.at(pid);
|
||||
if (!actor)
|
||||
continue;
|
||||
|
||||
log_info("actor #%u, id %d, pid %u: %s\n", actor->order, actor->id, pid,
|
||||
status2str(status));
|
||||
if (status > as_running) {
|
||||
left -= 1;
|
||||
if (status != as_successful)
|
||||
failed = true;
|
||||
size_t left = global::actors.size();
|
||||
log_trace("=== polling...");
|
||||
while (left > 0) {
|
||||
unsigned timeout_seconds_left = INT_MAX;
|
||||
chrono::time now_motonic = chrono::now_motonic();
|
||||
if (now_motonic.fixedpoint >= global::deadline_motonic.fixedpoint)
|
||||
timeout_seconds_left = 0;
|
||||
else {
|
||||
chrono::time left_motonic;
|
||||
left_motonic.fixedpoint =
|
||||
global::deadline_motonic.fixedpoint - now_motonic.fixedpoint;
|
||||
timeout_seconds_left = left_motonic.seconds();
|
||||
}
|
||||
|
||||
mdbx_pid_t pid;
|
||||
int rc = osal_actor_poll(pid, timeout_seconds_left);
|
||||
if (rc)
|
||||
failure("Poll error: %s (%d)\n", test_strerror(rc), rc);
|
||||
|
||||
if (pid) {
|
||||
actor_status status = osal_actor_info(pid);
|
||||
actor_config *actor = global::pid2actor.at(pid);
|
||||
if (!actor)
|
||||
continue;
|
||||
|
||||
log_info("actor #%u, id %d, pid %u: %s\n", actor->actor_id,
|
||||
actor->space_id, pid, status2str(status));
|
||||
if (status > as_running) {
|
||||
left -= 1;
|
||||
if (status != as_successful)
|
||||
failed = true;
|
||||
}
|
||||
} else {
|
||||
if (timeout_seconds_left == 0)
|
||||
failure("Timeout\n");
|
||||
}
|
||||
} else {
|
||||
if (global::config::timeout &&
|
||||
time(nullptr) - timestamp_start > global::config::timeout)
|
||||
failure("Timeout\n");
|
||||
}
|
||||
log_trace("=== done...");
|
||||
}
|
||||
|
||||
log_notice("OVERALL: %s\n", failed ? "Failed" : "Successful");
|
||||
if (!global::config::dont_cleanup_before) {
|
||||
log_notice("RESULT: %s\n", failed ? "Failed" : "Successful");
|
||||
if (global::config::cleanup_before) {
|
||||
if (failed)
|
||||
log_info("skip cleanup");
|
||||
else
|
||||
|
@ -24,11 +24,11 @@
|
||||
struct shared_t {
|
||||
pthread_barrier_t barrier;
|
||||
pthread_mutex_t mutex;
|
||||
pthread_cond_t conds[0];
|
||||
size_t conds_size;
|
||||
pthread_cond_t conds[1];
|
||||
};
|
||||
|
||||
static shared_t *shared;
|
||||
static std::unordered_map<unsigned, pthread_cond_t *> events;
|
||||
|
||||
void osal_wait4barrier(void) {
|
||||
assert(shared != nullptr && shared != MAP_FAILED);
|
||||
@ -65,13 +65,8 @@ void osal_setup(const std::vector<actor_config> &actors) {
|
||||
if (rc)
|
||||
failure_perror("pthread_condattr_setpshared()", rc);
|
||||
|
||||
size_t n = 0;
|
||||
for (const auto &a : actors)
|
||||
if (a.wanna_event4signalling())
|
||||
++n;
|
||||
|
||||
shared = (shared_t *)mmap(
|
||||
nullptr, sizeof(shared_t) + n * sizeof(pthread_cond_t),
|
||||
nullptr, sizeof(shared_t) + actors.size() * sizeof(pthread_cond_t),
|
||||
PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
|
||||
if (MAP_FAILED == (void *)shared)
|
||||
failure_perror("mmap(shared_conds)", errno);
|
||||
@ -84,24 +79,15 @@ void osal_setup(const std::vector<actor_config> &actors) {
|
||||
if (rc)
|
||||
failure_perror("pthread_barrier_init(shared)", rc);
|
||||
|
||||
auto a = actors.begin();
|
||||
const size_t n = actors.size() + 1;
|
||||
for (size_t i = 0; i < n; ++i) {
|
||||
pthread_cond_t *event = &shared->conds[i];
|
||||
rc = pthread_cond_init(event, &condattr);
|
||||
if (rc)
|
||||
failure_perror("pthread_cond_init(shared)", rc);
|
||||
|
||||
unsigned id = 0;
|
||||
while (a != actors.end()) {
|
||||
if (a->wanna_event4signalling()) {
|
||||
id = a->id;
|
||||
break;
|
||||
}
|
||||
++a;
|
||||
}
|
||||
assert(id != 0);
|
||||
events[id] = event;
|
||||
log_trace("osal_setup: event(shared pthread_cond) %zu -> %p", i, event);
|
||||
}
|
||||
shared->conds_size = actors.size() + 1;
|
||||
|
||||
pthread_barrierattr_destroy(&barrierattr);
|
||||
pthread_condattr_destroy(&condattr);
|
||||
@ -110,7 +96,10 @@ void osal_setup(const std::vector<actor_config> &actors) {
|
||||
|
||||
void osal_broadcast(unsigned id) {
|
||||
assert(shared != nullptr && shared != MAP_FAILED);
|
||||
int rc = pthread_cond_broadcast(events.at(id));
|
||||
log_trace("osal_broadcast: event %u", id);
|
||||
if (id >= shared->conds_size)
|
||||
failure("osal_broadcast: id > limit");
|
||||
int rc = pthread_cond_broadcast(shared->conds + id);
|
||||
if (rc)
|
||||
failure_perror("sem_post(shared)", rc);
|
||||
}
|
||||
@ -118,11 +107,15 @@ void osal_broadcast(unsigned id) {
|
||||
int osal_waitfor(unsigned id) {
|
||||
assert(shared != nullptr && shared != MAP_FAILED);
|
||||
|
||||
log_trace("osal_waitfor: event %u", id);
|
||||
if (id >= shared->conds_size)
|
||||
failure("osal_waitfor: id > limit");
|
||||
|
||||
int rc = pthread_mutex_lock(&shared->mutex);
|
||||
if (rc != 0)
|
||||
failure_perror("pthread_mutex_lock(shared)", rc);
|
||||
|
||||
rc = pthread_cond_wait(events.at(id), &shared->mutex);
|
||||
rc = pthread_cond_wait(shared->conds + id, &shared->mutex);
|
||||
if (rc && rc != EINTR)
|
||||
failure_perror("pthread_cond_wait(shared)", rc);
|
||||
|
||||
@ -173,6 +166,7 @@ int osal_actor_start(const actor_config &config, mdbx_pid_t &pid) {
|
||||
if (pid < 0)
|
||||
return errno;
|
||||
|
||||
log_trace("osal_actor_start: fork pid %i for %u", pid, config.actor_id);
|
||||
childs[pid] = as_running;
|
||||
return 0;
|
||||
}
|
||||
|
@ -14,7 +14,7 @@
|
||||
|
||||
#include "test.h"
|
||||
|
||||
static std::unordered_map<unsigned, HANDLE> events;
|
||||
static std::vector<HANDLE> events;
|
||||
static HANDLE hBarrierSemaphore, hBarrierEvent;
|
||||
|
||||
static int waitstatus2errcode(DWORD result) {
|
||||
@ -63,15 +63,17 @@ static HANDLE make_inharitable(HANDLE hHandle) {
|
||||
}
|
||||
|
||||
void osal_setup(const std::vector<actor_config> &actors) {
|
||||
size_t n = 0;
|
||||
for (const auto &a : actors) {
|
||||
if (a.wanna_event4signalling()) {
|
||||
HANDLE hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
if (!hEvent)
|
||||
failure_perror("CreateEvent()", GetLastError());
|
||||
hEvent = make_inharitable(hEvent);
|
||||
events[a.id] = hEvent;
|
||||
}
|
||||
assert(events.empty());
|
||||
const size_t n = actors.size() + 1;
|
||||
events.reserve(n);
|
||||
|
||||
for (size_t i = 0; i < n; ++i) {
|
||||
HANDLE hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
if (!hEvent)
|
||||
failure_perror("CreateEvent()", GetLastError());
|
||||
hEvent = make_inharitable(hEvent);
|
||||
log_trace("osal_setup: event %zu -> %p", i, hEvent);
|
||||
events.push_back(hEvent);
|
||||
}
|
||||
|
||||
hBarrierSemaphore = CreateSemaphore(NULL, 0, (LONG)actors.size(), NULL);
|
||||
@ -86,11 +88,13 @@ void osal_setup(const std::vector<actor_config> &actors) {
|
||||
}
|
||||
|
||||
void osal_broadcast(unsigned id) {
|
||||
log_trace("osal_broadcast: event %u", id);
|
||||
if (!SetEvent(events.at(id)))
|
||||
failure_perror("SetEvent()", GetLastError());
|
||||
}
|
||||
|
||||
int osal_waitfor(unsigned id) {
|
||||
log_trace("osal_waitfor: event %u", id);
|
||||
DWORD rc = WaitForSingleObject(events.at(id), INFINITE);
|
||||
return waitstatus2errcode(rc);
|
||||
}
|
||||
|
156
test/test.cc
156
test/test.cc
@ -53,25 +53,37 @@ const char *status2str(actor_status status) {
|
||||
|
||||
static void mdbx_debug_logger(int type, const char *function, int line,
|
||||
const char *msg, va_list args) {
|
||||
logging::loglevel level = logging::trace;
|
||||
logging::loglevel level = logging::info;
|
||||
if (type & MDBX_DBG_EXTRA)
|
||||
level = logging::extra;
|
||||
if (type & MDBX_DBG_TRACE)
|
||||
level = logging::trace;
|
||||
if (type & MDBX_DBG_PRINT)
|
||||
level = logging::info;
|
||||
level = logging::verbose;
|
||||
|
||||
if (type & MDBX_DBG_ASSERT) {
|
||||
log_error("libmdbx assertion failure: %s, %d",
|
||||
log_error("mdbx: assertion failure: %s, %d",
|
||||
function ? function : "unknown", line);
|
||||
level = logging::failure;
|
||||
}
|
||||
|
||||
output(level, msg, args);
|
||||
if (logging::output(level, "mdbx: "))
|
||||
logging::feed(msg, args);
|
||||
if (type & MDBX_DBG_ASSERT)
|
||||
abort();
|
||||
}
|
||||
|
||||
void testcase::mdbx_prepare() {
|
||||
log_trace(">> mdbx_prepare");
|
||||
void testcase::db_prepare() {
|
||||
log_trace(">> db_prepare");
|
||||
assert(!db_guard);
|
||||
|
||||
int rc = mdbx_setup_debug(MDBX_DBG_DNT, mdbx_debug_logger, MDBX_DBG_DNT);
|
||||
log_info("libmdbx debug-flags: 0x%02x", rc);
|
||||
int mdbx_dbg_opts = MDBX_DBG_ASSERT;
|
||||
if (config.params.loglevel <= logging::trace)
|
||||
mdbx_dbg_opts |= MDBX_DBG_TRACE;
|
||||
if (config.params.loglevel <= logging::verbose)
|
||||
mdbx_dbg_opts |= MDBX_DBG_PRINT;
|
||||
int rc = mdbx_setup_debug(mdbx_dbg_opts, mdbx_debug_logger, MDBX_DBG_DNT);
|
||||
log_info("set mdbx debug-opts: 0x%02x", rc);
|
||||
|
||||
MDB_env *env = nullptr;
|
||||
rc = mdbx_env_create(&env);
|
||||
@ -97,83 +109,163 @@ void testcase::mdbx_prepare() {
|
||||
if (rc != MDB_SUCCESS)
|
||||
failure_perror("mdbx_env_set_mapsize()", rc);
|
||||
|
||||
log_trace("<< mdbx_prepare");
|
||||
log_trace("<< db_prepare");
|
||||
}
|
||||
|
||||
void testcase::mdbx_open() {
|
||||
log_trace(">> mdbx_open");
|
||||
void testcase::db_open() {
|
||||
log_trace(">> db_open");
|
||||
|
||||
if (!db_guard)
|
||||
db_prepare();
|
||||
int rc = mdbx_env_open(db_guard.get(), config.params.pathname_db.c_str(),
|
||||
(unsigned)config.params.mode_flags, 0640);
|
||||
if (rc != MDB_SUCCESS)
|
||||
failure_perror("mdbx_env_open()", rc);
|
||||
log_trace("<< mdbx_open");
|
||||
|
||||
log_trace("<< db_open");
|
||||
}
|
||||
|
||||
void testcase::mdbx_close() {
|
||||
log_trace(">> mdbx_close");
|
||||
void testcase::db_close() {
|
||||
log_trace(">> db_close");
|
||||
cursor_guard.reset();
|
||||
txn_guard.reset();
|
||||
db_guard.reset();
|
||||
log_trace("<< mdbx_close");
|
||||
log_trace("<< db_close");
|
||||
}
|
||||
|
||||
void testcase::txn_begin(bool readonly) {
|
||||
log_trace(">> txn_begin(%s)", readonly ? "read-only" : "read-write");
|
||||
assert(!txn_guard);
|
||||
|
||||
MDB_txn *txn = nullptr;
|
||||
int rc =
|
||||
mdbx_txn_begin(db_guard.get(), nullptr, readonly ? MDB_RDONLY : 0, &txn);
|
||||
if (rc != MDB_SUCCESS)
|
||||
failure_perror("mdbx_txn_begin()", rc);
|
||||
txn_guard.reset(txn);
|
||||
|
||||
log_trace("<< txn_begin(%s)", readonly ? "read-only" : "read-write");
|
||||
}
|
||||
|
||||
void testcase::txn_end(bool abort) {
|
||||
log_trace(">> txn_end(%s)", abort ? "abort" : "commit");
|
||||
assert(txn_guard);
|
||||
|
||||
MDB_txn *txn = txn_guard.release();
|
||||
if (abort) {
|
||||
int rc = mdbx_txn_abort(txn);
|
||||
if (rc != MDB_SUCCESS)
|
||||
failure_perror("mdbx_txn_abort()", rc);
|
||||
} else {
|
||||
int rc = mdbx_txn_commit(txn);
|
||||
if (rc != MDB_SUCCESS)
|
||||
failure_perror("mdbx_txn_commit()", rc);
|
||||
}
|
||||
|
||||
log_trace("<< txn_end(%s)", abort ? "abort" : "commit");
|
||||
}
|
||||
|
||||
bool testcase::wait4start() {
|
||||
if (config.wait4id) {
|
||||
log_trace(">> wait4start(%u)", config.wait4id);
|
||||
assert(!global::singlemode);
|
||||
int rc = osal_waitfor(config.wait4id);
|
||||
if (rc) {
|
||||
log_trace("<< wait4start(%u), failed %s", config.wait4id,
|
||||
test_strerror(rc));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
log_trace("== wait4start(not needed)");
|
||||
return true;
|
||||
log_trace("== skip wait4start: not needed");
|
||||
}
|
||||
|
||||
if (config.params.delaystart) {
|
||||
int rc = osal_delay(config.params.delaystart);
|
||||
if (rc) {
|
||||
log_trace("<< delay(%u), failed %s", config.params.delaystart,
|
||||
test_strerror(rc));
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
log_trace("== skip delay: not needed");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void testcase::report(size_t nops_done) {
|
||||
if (config.signal_nops && !signalled && config.signal_nops <= nops_done) {
|
||||
log_trace(">> signal(n-ops %zu)", nops_done);
|
||||
osal_broadcast(config.id);
|
||||
nops_completed += nops_done;
|
||||
log_verbose("== complete +%zu iteration, total %zu done", nops_done,
|
||||
nops_completed);
|
||||
|
||||
if (config.signal_nops && !signalled &&
|
||||
config.signal_nops <= nops_completed) {
|
||||
log_trace(">> signal(n-ops %zu)", nops_completed);
|
||||
if (!global::singlemode)
|
||||
osal_broadcast(config.actor_id);
|
||||
signalled = true;
|
||||
log_trace("<< signal(n-ops %zu)", nops_done);
|
||||
log_trace("<< signal(n-ops %zu)", nops_completed);
|
||||
}
|
||||
}
|
||||
|
||||
void testcase::signal() {
|
||||
if (!signalled) {
|
||||
log_trace(">> signal(forced)");
|
||||
osal_broadcast(config.id);
|
||||
if (!global::singlemode)
|
||||
osal_broadcast(config.actor_id);
|
||||
signalled = true;
|
||||
log_trace("<< signal(forced)");
|
||||
}
|
||||
}
|
||||
|
||||
bool testcase::setup() {
|
||||
mdbx_prepare();
|
||||
return wait4start();
|
||||
db_prepare();
|
||||
if (!wait4start())
|
||||
return false;
|
||||
|
||||
start_timestamp = chrono::now_motonic();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool testcase::teardown() {
|
||||
log_trace(">> testcase::teardown");
|
||||
signal();
|
||||
mdbx_close();
|
||||
db_close();
|
||||
log_trace("<< testcase::teardown");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool testcase::should_continue() const {
|
||||
bool result = true;
|
||||
|
||||
if (config.params.test_duration) {
|
||||
chrono::time since;
|
||||
since.fixedpoint =
|
||||
chrono::now_motonic().fixedpoint - start_timestamp.fixedpoint;
|
||||
if (since.seconds() >= config.params.test_duration)
|
||||
result = false;
|
||||
}
|
||||
|
||||
if (config.params.test_nops && nops_completed >= config.params.test_nops)
|
||||
result = false;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool test_execute(const actor_config &config) {
|
||||
const mdbx_pid_t pid = osal_getpid();
|
||||
logging::setup((logging::loglevel)config.params.loglevel,
|
||||
format("child_%u.%u", config.order, config.id));
|
||||
|
||||
log_trace(">> wait4barrier");
|
||||
osal_wait4barrier();
|
||||
log_trace("<< wait4barrier");
|
||||
if (global::singlemode) {
|
||||
logging::setup(format("single_%s", testcase2str(config.testcase)));
|
||||
} else {
|
||||
logging::setup((logging::loglevel)config.params.loglevel,
|
||||
format("child_%u.%u", config.actor_id, config.space_id));
|
||||
log_trace(">> wait4barrier");
|
||||
osal_wait4barrier();
|
||||
log_trace("<< wait4barrier");
|
||||
}
|
||||
|
||||
try {
|
||||
std::unique_ptr<testcase> test;
|
||||
@ -206,7 +298,7 @@ bool test_execute(const actor_config &config) {
|
||||
return true;
|
||||
}
|
||||
} catch (const std::exception &pipets) {
|
||||
failure("Exception: %s", pipets.what());
|
||||
failure("***** Exception: %s *****", pipets.what());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
33
test/test.h
33
test/test.h
@ -24,7 +24,7 @@
|
||||
|
||||
bool test_execute(const actor_config &config);
|
||||
std::string thunk_param(const actor_config &config);
|
||||
bool testcase_setup(const char *casename, const actor_params ¶ms,
|
||||
void testcase_setup(const char *casename, actor_params ¶ms,
|
||||
unsigned &lastid);
|
||||
void configure_actor(unsigned &lastid, const actor_testcase testcase,
|
||||
const char *id_cstr, const actor_params ¶ms);
|
||||
@ -36,12 +36,16 @@ extern std::vector<actor_config> actors;
|
||||
extern std::unordered_map<unsigned, actor_config *> events;
|
||||
extern std::unordered_map<mdbx_pid_t, actor_config *> pid2actor;
|
||||
extern std::set<std::string> databases;
|
||||
extern unsigned nactors;
|
||||
extern chrono::time start_motonic;
|
||||
extern chrono::time deadline_motonic;
|
||||
extern bool singlemode;
|
||||
|
||||
namespace config {
|
||||
extern unsigned timeout;
|
||||
extern unsigned timeout_duration_seconds;
|
||||
extern bool dump_config;
|
||||
extern bool dont_cleanup_before;
|
||||
extern bool dont_cleanup_after;
|
||||
extern bool cleanup_before;
|
||||
extern bool cleanup_after;
|
||||
} /* namespace config */
|
||||
|
||||
} /* namespace global */
|
||||
@ -80,19 +84,28 @@ protected:
|
||||
scoped_cursor_guard cursor_guard;
|
||||
bool signalled;
|
||||
|
||||
void mdbx_prepare();
|
||||
void mdbx_open();
|
||||
void mdbx_close();
|
||||
size_t nops_completed;
|
||||
chrono::time start_timestamp;
|
||||
|
||||
void db_prepare();
|
||||
void db_open();
|
||||
void db_close();
|
||||
void txn_begin(bool readonly);
|
||||
void txn_end(bool abort);
|
||||
|
||||
bool wait4start();
|
||||
void report(size_t nops_done);
|
||||
void signal();
|
||||
bool should_continue() const;
|
||||
|
||||
bool mode_readonly() const {
|
||||
return (config.params.mode_flags & MDB_RDONLY) ? true : false;
|
||||
}
|
||||
|
||||
public:
|
||||
testcase(const actor_config &config, const mdbx_pid_t pid)
|
||||
: config(config), pid(pid) {
|
||||
logging::setup(format("%s_%u.%u", testcase2str(config.testcase),
|
||||
config.order, config.id));
|
||||
: config(config), pid(pid), nops_completed(0) {
|
||||
start_timestamp.reset();
|
||||
}
|
||||
|
||||
virtual bool setup();
|
||||
|
Loading…
x
Reference in New Issue
Block a user