mirror of
https://github.com/isar/libmdbx.git
synced 2025-06-07 18:12:39 +08:00
mdbx-testing: вывод "табло" с информацией о положении курсоров для удобства отладки.
This commit is contained in:
parent
a10506fb6a
commit
9670cf5709
150
test/test.c++
150
test/test.c++
@ -728,22 +728,26 @@ void testcase::verbose(const char *where, const char *stage, const MDBX_val &k,
|
|||||||
|
|
||||||
bool testcase::speculum_check_iterator(const char *where, const char *stage,
|
bool testcase::speculum_check_iterator(const char *where, const char *stage,
|
||||||
const testcase::SET::const_iterator &it,
|
const testcase::SET::const_iterator &it,
|
||||||
const MDBX_val &k,
|
const MDBX_val &k, const MDBX_val &v,
|
||||||
const MDBX_val &v) const {
|
MDBX_cursor *cursor) const {
|
||||||
char dump_key[32], dump_value[32];
|
char dump_key[32], dump_value[32];
|
||||||
MDBX_val it_key = dataview2iov(it->first);
|
MDBX_val it_key = dataview2iov(it->first);
|
||||||
MDBX_val it_data = dataview2iov(it->second);
|
MDBX_val it_data = dataview2iov(it->second);
|
||||||
// log_verbose("speculum-%s: %s expect {%s, %s}", where, stage,
|
// log_verbose("speculum-%s: %s expect {%s, %s}", where, stage,
|
||||||
// mdbx_dump_val(&it_key, dump_key, sizeof(dump_key)),
|
// mdbx_dump_val(&it_key, dump_key, sizeof(dump_key)),
|
||||||
// mdbx_dump_val(&it_data, dump_value, sizeof(dump_value)));
|
// mdbx_dump_val(&it_data, dump_value, sizeof(dump_value)));
|
||||||
if (!is_samedata(it_key, k))
|
if (!is_samedata(it_key, k)) {
|
||||||
|
speculum_render(it, cursor);
|
||||||
return failure("speculum-%s: %s key mismatch %s (must) != %s", where, stage,
|
return failure("speculum-%s: %s key mismatch %s (must) != %s", where, stage,
|
||||||
mdbx_dump_val(&it_key, dump_key, sizeof(dump_key)),
|
mdbx_dump_val(&it_key, dump_key, sizeof(dump_key)),
|
||||||
mdbx_dump_val(&k, dump_value, sizeof(dump_value)));
|
mdbx_dump_val(&k, dump_value, sizeof(dump_value)));
|
||||||
if (!is_samedata(it_data, v))
|
}
|
||||||
|
if (!is_samedata(it_data, v)) {
|
||||||
|
speculum_render(it, cursor);
|
||||||
return failure("speculum-%s: %s data mismatch %s (must) != %s", where,
|
return failure("speculum-%s: %s data mismatch %s (must) != %s", where,
|
||||||
stage, mdbx_dump_val(&it_data, dump_key, sizeof(dump_key)),
|
stage, mdbx_dump_val(&it_data, dump_key, sizeof(dump_key)),
|
||||||
mdbx_dump_val(&v, dump_value, sizeof(dump_value)));
|
mdbx_dump_val(&v, dump_value, sizeof(dump_value)));
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -761,32 +765,139 @@ bool testcase::failure(const char *fmt, ...) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if SPECULUM_CURSORS
|
#if SPECULUM_CURSORS
|
||||||
|
|
||||||
|
static void speculum_render_cursor(const MDBX_val &ikey, const MDBX_val &ival,
|
||||||
|
const MDBX_cursor *cursor,
|
||||||
|
const MDBX_cursor *ref) {
|
||||||
|
scoped_cursor_guard guard(mdbx_cursor_create(nullptr));
|
||||||
|
if (!guard)
|
||||||
|
failure("mdbx_cursor_create()");
|
||||||
|
/* работаем с копией курсора, чтобы не влиять на состояние оригинала. */
|
||||||
|
int err = mdbx_cursor_copy(cursor, guard.get());
|
||||||
|
if (err)
|
||||||
|
failure("mdbx_cursor_copy(), err %d", err);
|
||||||
|
|
||||||
|
MDBX_cursor *const clone = guard.get();
|
||||||
|
char status[10], *s = status;
|
||||||
|
if (cursor == ref) {
|
||||||
|
*s++ = '_';
|
||||||
|
*s++ = '_';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mdbx_cursor_eof(clone) == MDBX_RESULT_TRUE)
|
||||||
|
*s++ = 'e';
|
||||||
|
if (mdbx_cursor_on_first(clone) == MDBX_RESULT_TRUE)
|
||||||
|
*s++ = 'F';
|
||||||
|
if (mdbx_cursor_on_first_dup(clone) == MDBX_RESULT_TRUE)
|
||||||
|
*s++ = 'f';
|
||||||
|
if (mdbx_cursor_on_last(clone) == MDBX_RESULT_TRUE)
|
||||||
|
*s++ = 'L';
|
||||||
|
if (mdbx_cursor_on_last_dup(clone) == MDBX_RESULT_TRUE)
|
||||||
|
*s++ = 'l';
|
||||||
|
|
||||||
|
MDBX_val ckey, cval;
|
||||||
|
if (mdbx_cursor_get(clone, &ckey, &cval, MDBX_GET_CURRENT) != MDBX_SUCCESS)
|
||||||
|
*s++ = '!';
|
||||||
|
else {
|
||||||
|
const int kcmp =
|
||||||
|
mdbx_cmp(mdbx_cursor_txn(clone), mdbx_cursor_dbi(clone), &ikey, &ckey);
|
||||||
|
if (kcmp < 0)
|
||||||
|
*s++ = '<';
|
||||||
|
else if (kcmp > 0)
|
||||||
|
*s++ = '>';
|
||||||
|
else {
|
||||||
|
*s++ = '=';
|
||||||
|
const int vcmp = mdbx_dcmp(mdbx_cursor_txn(clone), mdbx_cursor_dbi(clone),
|
||||||
|
&ival, &cval);
|
||||||
|
if (vcmp < 0)
|
||||||
|
*s++ = '<';
|
||||||
|
else if (vcmp > 0)
|
||||||
|
*s++ = '>';
|
||||||
|
else
|
||||||
|
*s++ = '=';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (clone == ref) {
|
||||||
|
*s++ = '_';
|
||||||
|
*s++ = '_';
|
||||||
|
}
|
||||||
|
*s = '\0';
|
||||||
|
|
||||||
|
printf(" | %-10.10s", status);
|
||||||
|
}
|
||||||
|
|
||||||
|
void testcase::speculum_render(const testcase::SET::const_iterator &it,
|
||||||
|
const MDBX_cursor *ref) const {
|
||||||
|
char dump_key[32], dump_value[32];
|
||||||
|
|
||||||
|
auto top = it;
|
||||||
|
int offset = 0;
|
||||||
|
while (offset > -5 && top != speculum.begin()) {
|
||||||
|
--top;
|
||||||
|
--offset;
|
||||||
|
}
|
||||||
|
printf("## %-20.20s %-20.20s | %-10.10s | %-10.10s | %-10.10s | %-10.10s | "
|
||||||
|
"%-10.10s | %-10.10s |\n",
|
||||||
|
"k0_1_2_3_4_5_6_7_8_9", "v0_1_2_3_4_5_6_7_8_9", "prev-prev", "prev",
|
||||||
|
"seek", "lowerbound", "next", "next-next");
|
||||||
|
while (offset < 5 && top != speculum.end()) {
|
||||||
|
const MDBX_val ikey = dataview2iov(top->first);
|
||||||
|
const MDBX_val idata = dataview2iov(top->second);
|
||||||
|
printf("%+d) %20.20s %20.20s", offset,
|
||||||
|
mdbx_dump_val(&ikey, dump_key, sizeof(dump_key)),
|
||||||
|
mdbx_dump_val(&idata, dump_value, sizeof(dump_value)));
|
||||||
|
|
||||||
|
speculum_render_cursor(ikey, idata, speculum_cursors[prev_prev].get(), ref);
|
||||||
|
speculum_render_cursor(ikey, idata, speculum_cursors[prev].get(), ref);
|
||||||
|
speculum_render_cursor(ikey, idata, speculum_cursors[seek_check].get(),
|
||||||
|
ref);
|
||||||
|
speculum_render_cursor(ikey, idata, speculum_cursors[lowerbound].get(),
|
||||||
|
ref);
|
||||||
|
speculum_render_cursor(ikey, idata, speculum_cursors[next].get(), ref);
|
||||||
|
speculum_render_cursor(ikey, idata, speculum_cursors[next_next].get(), ref);
|
||||||
|
|
||||||
|
printf(" %s\n", "|");
|
||||||
|
++top;
|
||||||
|
++offset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool testcase::speculum_check_cursor(const char *where, const char *stage,
|
bool testcase::speculum_check_cursor(const char *where, const char *stage,
|
||||||
const testcase::SET::const_iterator &it,
|
const testcase::SET::const_iterator &it,
|
||||||
int cursor_err, const MDBX_val &cursor_key,
|
int cursor_err, const MDBX_val &cursor_key,
|
||||||
const MDBX_val &cursor_data) const {
|
const MDBX_val &cursor_data,
|
||||||
|
MDBX_cursor *cursor) const {
|
||||||
// verbose(where, stage, cursor_key, cursor_data, cursor_err);
|
// verbose(where, stage, cursor_key, cursor_data, cursor_err);
|
||||||
// verbose(where, stage, it);
|
// verbose(where, stage, it);
|
||||||
if (cursor_err != MDBX_SUCCESS && cursor_err != MDBX_NOTFOUND &&
|
if (cursor_err != MDBX_SUCCESS && cursor_err != MDBX_NOTFOUND &&
|
||||||
cursor_err != MDBX_RESULT_TRUE && cursor_err != MDBX_ENODATA)
|
cursor_err != MDBX_RESULT_TRUE && cursor_err != MDBX_ENODATA) {
|
||||||
|
speculum_render(it, cursor);
|
||||||
return failure("speculum-%s: %s %s %d %s", where, stage, "cursor-get",
|
return failure("speculum-%s: %s %s %d %s", where, stage, "cursor-get",
|
||||||
cursor_err, mdbx_strerror(cursor_err));
|
cursor_err, mdbx_strerror(cursor_err));
|
||||||
|
}
|
||||||
|
|
||||||
char dump_key[32], dump_value[32];
|
char dump_key[32], dump_value[32];
|
||||||
if (it == speculum.end() && cursor_err != MDBX_NOTFOUND)
|
if (it == speculum.end() && cursor_err != MDBX_NOTFOUND &&
|
||||||
|
cursor_err != MDBX_ENODATA) {
|
||||||
|
speculum_render(it, cursor);
|
||||||
return failure("speculum-%s: %s extra pair {%s, %s}", where, stage,
|
return failure("speculum-%s: %s extra pair {%s, %s}", where, stage,
|
||||||
mdbx_dump_val(&cursor_key, dump_key, sizeof(dump_key)),
|
mdbx_dump_val(&cursor_key, dump_key, sizeof(dump_key)),
|
||||||
mdbx_dump_val(&cursor_data, dump_value, sizeof(dump_value)));
|
mdbx_dump_val(&cursor_data, dump_value, sizeof(dump_value)));
|
||||||
else if (it != speculum.end() && cursor_err == MDBX_NOTFOUND) {
|
} else if (it != speculum.end() &&
|
||||||
|
(cursor_err == MDBX_NOTFOUND || cursor_err == MDBX_ENODATA)) {
|
||||||
|
speculum_render(it, cursor);
|
||||||
MDBX_val it_key = dataview2iov(it->first);
|
MDBX_val it_key = dataview2iov(it->first);
|
||||||
MDBX_val it_data = dataview2iov(it->second);
|
MDBX_val it_data = dataview2iov(it->second);
|
||||||
return failure("speculum-%s: %s lack pair {%s, %s}", where, stage,
|
return failure("speculum-%s: %s lack pair {%s, %s}", where, stage,
|
||||||
mdbx_dump_val(&it_key, dump_key, sizeof(dump_key)),
|
mdbx_dump_val(&it_key, dump_key, sizeof(dump_key)),
|
||||||
mdbx_dump_val(&it_data, dump_value, sizeof(dump_value)));
|
mdbx_dump_val(&it_data, dump_value, sizeof(dump_value)));
|
||||||
} else if (cursor_err == MDBX_SUCCESS || cursor_err == MDBX_RESULT_TRUE)
|
} else if (cursor_err == MDBX_SUCCESS || cursor_err == MDBX_RESULT_TRUE)
|
||||||
return speculum_check_iterator(where, stage, it, cursor_key, cursor_data);
|
return speculum_check_iterator(where, stage, it, cursor_key, cursor_data,
|
||||||
|
cursor);
|
||||||
else {
|
else {
|
||||||
assert(it == speculum.end() && cursor_err == MDBX_NOTFOUND);
|
assert(it == speculum.end() &&
|
||||||
|
(cursor_err == MDBX_NOTFOUND || cursor_err == MDBX_ENODATA));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -798,7 +909,8 @@ bool testcase::speculum_check_cursor(const char *where, const char *stage,
|
|||||||
MDBX_val cursor_key = {0, 0};
|
MDBX_val cursor_key = {0, 0};
|
||||||
MDBX_val cursor_data = {0, 0};
|
MDBX_val cursor_data = {0, 0};
|
||||||
int err = mdbx_cursor_get(cursor, &cursor_key, &cursor_data, op);
|
int err = mdbx_cursor_get(cursor, &cursor_key, &cursor_data, op);
|
||||||
return speculum_check_cursor(where, stage, it, err, cursor_key, cursor_data);
|
return speculum_check_cursor(where, stage, it, err, cursor_key, cursor_data,
|
||||||
|
cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
void testcase::speculum_prepare_cursors(const Item &item) {
|
void testcase::speculum_prepare_cursors(const Item &item) {
|
||||||
@ -822,6 +934,7 @@ void testcase::speculum_prepare_cursors(const Item &item) {
|
|||||||
guard.reset(cursor);
|
guard.reset(cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// mdbx_cursor_reset(speculum_cursors[seek_check].get());
|
||||||
const auto cursor_lowerbound = speculum_cursors[lowerbound].get();
|
const auto cursor_lowerbound = speculum_cursors[lowerbound].get();
|
||||||
const MDBX_val item_key = dataview2iov(item.first),
|
const MDBX_val item_key = dataview2iov(item.first),
|
||||||
item_data = dataview2iov(item.second);
|
item_data = dataview2iov(item.second);
|
||||||
@ -840,7 +953,7 @@ void testcase::speculum_prepare_cursors(const Item &item) {
|
|||||||
auto it_lowerbound = speculum.lower_bound(item);
|
auto it_lowerbound = speculum.lower_bound(item);
|
||||||
// verbose("prepare-cursors", "lowerbound", it_lowerbound);
|
// verbose("prepare-cursors", "lowerbound", it_lowerbound);
|
||||||
speculum_check_cursor("prepare-cursors", "lowerbound", it_lowerbound, err,
|
speculum_check_cursor("prepare-cursors", "lowerbound", it_lowerbound, err,
|
||||||
lowerbound_key, lowerbound_data);
|
lowerbound_key, lowerbound_data, cursor_lowerbound);
|
||||||
|
|
||||||
const auto cursor_prev = speculum_cursors[prev].get();
|
const auto cursor_prev = speculum_cursors[prev].get();
|
||||||
err = mdbx_cursor_copy(cursor_lowerbound, cursor_prev);
|
err = mdbx_cursor_copy(cursor_lowerbound, cursor_prev);
|
||||||
@ -916,6 +1029,7 @@ int testcase::insert(const keygen::buffer &akey, const keygen::buffer &adata,
|
|||||||
seek_check_data = adata->value;
|
seek_check_data = adata->value;
|
||||||
seek_check_err = mdbx_cursor_get(check_seek_cursor, &seek_check_key,
|
seek_check_err = mdbx_cursor_get(check_seek_cursor, &seek_check_key,
|
||||||
&seek_check_data, MDBX_SET_LOWERBOUND);
|
&seek_check_data, MDBX_SET_LOWERBOUND);
|
||||||
|
// speculum_render(speculum.find(item), check_seek_cursor);
|
||||||
if (seek_check_err != MDBX_SUCCESS && seek_check_err != MDBX_NOTFOUND &&
|
if (seek_check_err != MDBX_SUCCESS && seek_check_err != MDBX_NOTFOUND &&
|
||||||
seek_check_err != MDBX_RESULT_TRUE)
|
seek_check_err != MDBX_RESULT_TRUE)
|
||||||
failure("speculum-%s: %s pre-insert %d %s", "insert", "seek",
|
failure("speculum-%s: %s pre-insert %d %s", "insert", "seek",
|
||||||
@ -959,7 +1073,8 @@ int testcase::insert(const keygen::buffer &akey, const keygen::buffer &adata,
|
|||||||
mdbx_dump_val(&seek_check_key, dump_key, sizeof(dump_key)),
|
mdbx_dump_val(&seek_check_key, dump_key, sizeof(dump_key)),
|
||||||
mdbx_dump_val(&seek_check_data, dump_value, sizeof(dump_value)));
|
mdbx_dump_val(&seek_check_data, dump_value, sizeof(dump_value)));
|
||||||
speculum_check_iterator("insert", "pre-seek", insertion_result.first,
|
speculum_check_iterator("insert", "pre-seek", insertion_result.first,
|
||||||
seek_check_key, seek_check_data);
|
seek_check_key, seek_check_data,
|
||||||
|
check_seek_cursor);
|
||||||
rc = false;
|
rc = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -999,6 +1114,8 @@ int testcase::insert(const keygen::buffer &akey, const keygen::buffer &adata,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// speculum_render(insertion_result.first,
|
||||||
|
// speculum_cursors[seek_check].get());
|
||||||
#endif /* SPECULUM_CURSORS */
|
#endif /* SPECULUM_CURSORS */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1049,6 +1166,12 @@ int testcase::remove(const keygen::buffer &akey, const keygen::buffer &adata) {
|
|||||||
item.second = iov2dataview(adata);
|
item.second = iov2dataview(adata);
|
||||||
#if SPECULUM_CURSORS
|
#if SPECULUM_CURSORS
|
||||||
speculum_prepare_cursors(item);
|
speculum_prepare_cursors(item);
|
||||||
|
// MDBX_cursor *check_seek_cursor = speculum_cursors[seek_check].get();
|
||||||
|
// MDBX_val seek_check_key = akey->value;
|
||||||
|
// MDBX_val seek_check_data = adata->value;
|
||||||
|
// mdbx_cursor_get(check_seek_cursor, &seek_check_key, &seek_check_data,
|
||||||
|
// MDBX_SET_LOWERBOUND);
|
||||||
|
// speculum_render(speculum.find(item), check_seek_cursor);
|
||||||
#endif /* SPECULUM_CURSORS */
|
#endif /* SPECULUM_CURSORS */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1075,6 +1198,7 @@ int testcase::remove(const keygen::buffer &akey, const keygen::buffer &adata) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if SPECULUM_CURSORS
|
#if SPECULUM_CURSORS
|
||||||
|
speculum_render(it_found, speculum_cursors[seek_check].get());
|
||||||
if (it_found != speculum.begin()) {
|
if (it_found != speculum.begin()) {
|
||||||
const auto cursor_prev = speculum_cursors[prev].get();
|
const auto cursor_prev = speculum_cursors[prev].get();
|
||||||
auto it_prev = it_found;
|
auto it_prev = it_found;
|
||||||
|
@ -197,15 +197,19 @@ protected:
|
|||||||
bool speculum_check_cursor(const char *where, const char *stage,
|
bool speculum_check_cursor(const char *where, const char *stage,
|
||||||
const testcase::SET::const_iterator &it,
|
const testcase::SET::const_iterator &it,
|
||||||
int cursor_err, const MDBX_val &cursor_key,
|
int cursor_err, const MDBX_val &cursor_key,
|
||||||
const MDBX_val &cursor_data) const;
|
const MDBX_val &cursor_data,
|
||||||
|
MDBX_cursor *cursor) const;
|
||||||
bool speculum_check_cursor(const char *where, const char *stage,
|
bool speculum_check_cursor(const char *where, const char *stage,
|
||||||
const testcase::SET::const_iterator &it,
|
const testcase::SET::const_iterator &it,
|
||||||
MDBX_cursor *cursor,
|
MDBX_cursor *cursor,
|
||||||
const MDBX_cursor_op op) const;
|
const MDBX_cursor_op op) const;
|
||||||
|
void speculum_render(const testcase::SET::const_iterator &it,
|
||||||
|
const MDBX_cursor *ref) const;
|
||||||
#endif /* SPECULUM_CURSORS */
|
#endif /* SPECULUM_CURSORS */
|
||||||
bool speculum_check_iterator(const char *where, const char *stage,
|
bool speculum_check_iterator(const char *where, const char *stage,
|
||||||
const testcase::SET::const_iterator &it,
|
const testcase::SET::const_iterator &it,
|
||||||
const MDBX_val &k, const MDBX_val &v) const;
|
const MDBX_val &k, const MDBX_val &v,
|
||||||
|
MDBX_cursor *cursor) const;
|
||||||
|
|
||||||
void verbose(const char *where, const char *stage,
|
void verbose(const char *where, const char *stage,
|
||||||
const testcase::SET::const_iterator &it) const;
|
const testcase::SET::const_iterator &it) const;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user