mirror of
https://github.com/isar/libmdbx.git
synced 2024-10-30 11:29:19 +08:00
193 lines
4.7 KiB
C++
193 lines
4.7 KiB
C++
|
/*
|
||
|
* Copyright 2017 Leonid Yuriev <leo@yuriev.ru>
|
||
|
* and other libmdbx authors: please see AUTHORS file.
|
||
|
* All rights reserved.
|
||
|
*
|
||
|
* Redistribution and use in source and binary forms, with or without
|
||
|
* modification, are permitted only as authorized by the OpenLDAP
|
||
|
* Public License.
|
||
|
*
|
||
|
* A copy of this license is available in the file LICENSE in the
|
||
|
* top-level directory of the distribution or, alternatively, at
|
||
|
* <http://www.OpenLDAP.org/license.html>.
|
||
|
*/
|
||
|
|
||
|
#include "test.h"
|
||
|
|
||
|
const char *testcase2str(const actor_testcase testcase) {
|
||
|
switch (testcase) {
|
||
|
default:
|
||
|
return "?!";
|
||
|
case ac_none:
|
||
|
return "none";
|
||
|
case ac_hill:
|
||
|
return "hill";
|
||
|
case ac_deadread:
|
||
|
return "deadread";
|
||
|
case ac_deadwrite:
|
||
|
return "deadwrite";
|
||
|
case ac_jitter:
|
||
|
return "jitter";
|
||
|
}
|
||
|
}
|
||
|
|
||
|
const char *status2str(actor_status status) {
|
||
|
switch (status) {
|
||
|
default:
|
||
|
assert(false);
|
||
|
return "?!";
|
||
|
case as_debuging:
|
||
|
return "debuging";
|
||
|
case as_running:
|
||
|
return "running";
|
||
|
case as_successful:
|
||
|
return "successful";
|
||
|
case as_killed:
|
||
|
return "killed";
|
||
|
case as_failed:
|
||
|
return "failed";
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
|
||
|
void testcase::mdbx_prepare() {
|
||
|
log_trace(">> mdbx_prepare");
|
||
|
|
||
|
MDB_env *env = nullptr;
|
||
|
int rc = mdbx_env_create(&env);
|
||
|
if (rc != MDB_SUCCESS)
|
||
|
failure_perror("mdbx_env_create()", rc);
|
||
|
|
||
|
assert(env != nullptr);
|
||
|
db_guard.reset(env);
|
||
|
|
||
|
rc = mdbx_env_set_userctx(env, this);
|
||
|
if (rc != MDB_SUCCESS)
|
||
|
failure_perror("mdbx_env_set_userctx()", rc);
|
||
|
|
||
|
rc = mdbx_env_set_maxreaders(env, config.params.max_readers);
|
||
|
if (rc != MDB_SUCCESS)
|
||
|
failure_perror("mdbx_env_set_maxreaders()", rc);
|
||
|
|
||
|
rc = mdbx_env_set_maxdbs(env, config.params.max_tables);
|
||
|
if (rc != MDB_SUCCESS)
|
||
|
failure_perror("mdbx_env_set_maxdbs()", rc);
|
||
|
|
||
|
rc = mdbx_env_set_mapsize(env, (size_t)config.params.size);
|
||
|
if (rc != MDB_SUCCESS)
|
||
|
failure_perror("mdbx_env_set_mapsize()", rc);
|
||
|
|
||
|
log_trace("<< mdbx_prepare");
|
||
|
}
|
||
|
|
||
|
void testcase::mdbx_open() {
|
||
|
log_trace(">> mdbx_open");
|
||
|
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");
|
||
|
}
|
||
|
|
||
|
void testcase::mdbx_close() {
|
||
|
log_trace(">> mdbx_close");
|
||
|
cursor_guard.reset();
|
||
|
txn_guard.reset();
|
||
|
db_guard.reset();
|
||
|
log_trace("<< mdbx_close");
|
||
|
}
|
||
|
|
||
|
bool testcase::wait4start() {
|
||
|
if (config.wait4id) {
|
||
|
log_trace(">> wait4start(%u)", config.wait4id);
|
||
|
int rc = osal_waitfor(config.wait4id);
|
||
|
if (rc) {
|
||
|
log_trace("<< wait4start(%u), failed %s", test_strerror(rc));
|
||
|
return false;
|
||
|
}
|
||
|
return true;
|
||
|
} else {
|
||
|
log_trace("== wait4start(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);
|
||
|
signalled = true;
|
||
|
log_trace("<< signal(n-ops %zu)", nops_done);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void testcase::signal() {
|
||
|
if (!signalled) {
|
||
|
log_trace(">> signal(forced)");
|
||
|
osal_broadcast(config.id);
|
||
|
signalled = true;
|
||
|
log_trace("<< signal(forced)");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
bool testcase::setup() {
|
||
|
mdbx_prepare();
|
||
|
return wait4start();
|
||
|
}
|
||
|
|
||
|
bool testcase::teardown() {
|
||
|
log_trace(">> testcase::teardown");
|
||
|
signal();
|
||
|
mdbx_close();
|
||
|
log_trace("<< testcase::teardown");
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
|
||
|
bool test_execute(const actor_config &config) {
|
||
|
const mdbx_pid_t pid = osal_getpid();
|
||
|
loggging::setup((loggging::loglevel)config.params.loglevel,
|
||
|
format("child_%u.%u", config.order, config.id));
|
||
|
|
||
|
log_trace(">> wait4barrier");
|
||
|
osal_wait4barrier();
|
||
|
log_trace("<< wait4barrier");
|
||
|
|
||
|
try {
|
||
|
std::unique_ptr<testcase> test;
|
||
|
switch (config.testcase) {
|
||
|
case ac_hill:
|
||
|
test.reset(new testcase_hill(config, pid));
|
||
|
break;
|
||
|
case ac_deadread:
|
||
|
test.reset(new testcase_deadread(config, pid));
|
||
|
break;
|
||
|
case ac_deadwrite:
|
||
|
test.reset(new testcase_deadwrite(config, pid));
|
||
|
break;
|
||
|
case ac_jitter:
|
||
|
test.reset(new testcase_jitter(config, pid));
|
||
|
break;
|
||
|
default:
|
||
|
test.reset(new testcase(config, pid));
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if (!test->setup())
|
||
|
log_notice("test setup failed");
|
||
|
else if (!test->run())
|
||
|
log_notice("test failed");
|
||
|
else if (!test->teardown())
|
||
|
log_notice("test teardown failed");
|
||
|
else {
|
||
|
log_info("test successed");
|
||
|
return true;
|
||
|
}
|
||
|
} catch (const std::exception &pipets) {
|
||
|
failure("Exception: %s", pipets.what());
|
||
|
}
|
||
|
return false;
|
||
|
}
|