db_stress to cover SeekForPrev() (#6022)

Summary:
Right now, db_stress doesn't cover SeekForPrev(). Add the coverage, which mirrors what we do for Seek().
Pull Request resolved: https://github.com/facebook/rocksdb/pull/6022

Test Plan: Run "make crash_test". Do some manual source code hack to simular iterator wrong results and see it caught.

Differential Revision: D18442193

fbshipit-source-id: 879b79000d5e33c625c7e970636de191ccd7776c
main
sdong 5 years ago committed by Facebook Github Bot
parent 03ce7fb292
commit a19de78da5
  1. 35
      tools/db_stress_tool.cc

@ -2479,10 +2479,18 @@ class StressTest {
std::unique_ptr<Iterator> cmp_iter(db_->NewIterator(cmp_ro, cmp_cfh));
bool diverged = false;
iter->Seek(key);
cmp_iter->Seek(key);
LastIterateOp last_op;
if (thread->rand.OneIn(8)) {
iter->SeekForPrev(key);
cmp_iter->SeekForPrev(key);
last_op = kLastOpSeekForPrev;
} else {
iter->Seek(key);
cmp_iter->Seek(key);
last_op = kLastOpSeek;
}
VerifyIterator(thread, cmp_cfh, readoptionscopy, iter.get(),
cmp_iter.get(), key, &diverged);
cmp_iter.get(), last_op, key, &diverged);
bool no_reverse =
(FLAGS_memtablerep == "prefix_hash" && !read_opts.total_order_seek &&
@ -2501,8 +2509,9 @@ class StressTest {
cmp_iter->Prev();
}
}
last_op = kLastOpNextOrPrev;
VerifyIterator(thread, cmp_cfh, readoptionscopy, iter.get(),
cmp_iter.get(), key, &diverged);
cmp_iter.get(), last_op, key, &diverged);
}
if (s.ok()) {
@ -2518,6 +2527,9 @@ class StressTest {
return s;
}
// Enum used by VerifyIterator() to identify the mode to validate.
enum LastIterateOp { kLastOpSeek, kLastOpSeekForPrev, kLastOpNextOrPrev };
// Compare the two iterator, iter and cmp_iter are in the same position,
// unless iter might be made invalidate or undefined because of
// upper or lower bounds, or prefix extractor.
@ -2526,12 +2538,12 @@ class StressTest {
// True if verification passed, false if not.
void VerifyIterator(ThreadState* thread, ColumnFamilyHandle* cmp_cfh,
const ReadOptions& ro, Iterator* iter, Iterator* cmp_iter,
const Slice& seek_key, bool* diverged) {
LastIterateOp op, const Slice& seek_key, bool* diverged) {
if (*diverged) {
return;
}
if (ro.iterate_lower_bound != nullptr &&
if (op == kLastOpSeek && ro.iterate_lower_bound != nullptr &&
(options_.comparator->Compare(*ro.iterate_lower_bound, seek_key) >= 0 ||
(ro.iterate_upper_bound != nullptr &&
options_.comparator->Compare(*ro.iterate_lower_bound,
@ -2542,6 +2554,17 @@ class StressTest {
return;
}
if (op == kLastOpSeekForPrev && ro.iterate_upper_bound != nullptr &&
(options_.comparator->Compare(*ro.iterate_upper_bound, seek_key) <= 0 ||
(ro.iterate_lower_bound != nullptr &&
options_.comparator->Compare(*ro.iterate_lower_bound,
*ro.iterate_upper_bound) >= 0))) {
// Uppder bound behavior is not well defined if it is smaller than
// seek key or lower bound. Disable the check for now.
*diverged = true;
return;
}
if (iter->Valid() && !cmp_iter->Valid()) {
fprintf(stderr,
"Control interator is invalid but iterator has key %s seek key "

Loading…
Cancel
Save