Phase 2 of iterator stress test
Summary: Using an iterator instead of the Get method, each thread goes through a portion of the database and verifies values by comparing to the shared state. Test Plan: ./db_stress --db=/tmp/tmppp --max_key=10000 --ops_per_thread=10000 To test some basic cases, the following lines can be added (each set in turn) to the verifyDb method with the following expected results: // Should abort with "Unexpected value found" shared.Delete(start); // Should abort with "Value not found" WriteOptions write_opts; db_->Delete(write_opts, Key(start)); // Should succeed WriteOptions write_opts; shared.Delete(start); db_->Delete(write_opts, Key(start)); // Should abort with "Value not found" WriteOptions write_opts; db_->Delete(write_opts, Key(start + (end-start)/2)); // Should abort with "Value not found" db_->Delete(write_opts, Key(end-1)); // Should abort with "Unexpected value" shared.Delete(end-1); // Should abort with "Unexpected value" shared.Delete(start + (end-start)/2); // Should abort with "Value not found" db_->Delete(write_opts, Key(start)); shared.Delete(start); db_->Delete(write_opts, Key(end-1)); db_->Delete(write_opts, Key(end-2)); To test the out of range abort, change the key in the for loop to Key(i+1), so that the key defined by the index i is now outside of the supposed range of the database. Reviewers: emayanke Reviewed By: emayanke CC: dhruba, xjin Differential Revision: https://reviews.facebook.net/D13071
This commit is contained in:
parent
22bb7c754b
commit
7edb92b843
@ -1023,7 +1023,15 @@ class StressTest {
|
|||||||
if (!FLAGS_test_batches_snapshots) {
|
if (!FLAGS_test_batches_snapshots) {
|
||||||
MutexLock l(thread->shared->GetMutexForKey(rand_key));
|
MutexLock l(thread->shared->GetMutexForKey(rand_key));
|
||||||
if (FLAGS_verify_before_write) {
|
if (FLAGS_verify_before_write) {
|
||||||
VerifyValue(rand_key, read_opts, *(thread->shared), &from_db, true);
|
std::string keystr = Key(rand_key);
|
||||||
|
Slice k = keystr;
|
||||||
|
Status s = db_->Get(read_opts, k, &from_db);
|
||||||
|
VerifyValue(rand_key,
|
||||||
|
read_opts,
|
||||||
|
*(thread->shared),
|
||||||
|
from_db,
|
||||||
|
s,
|
||||||
|
true);
|
||||||
}
|
}
|
||||||
thread->shared->Put(rand_key, value_base);
|
thread->shared->Put(rand_key, value_base);
|
||||||
if (FLAGS_use_merge_put) {
|
if (FLAGS_use_merge_put) {
|
||||||
@ -1056,13 +1064,37 @@ class StressTest {
|
|||||||
thread->stats.Stop();
|
thread->stats.Stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void VerifyDb(const SharedState &shared, long start) const {
|
void VerifyDb(const SharedState &shared, long tid) const {
|
||||||
ReadOptions options(FLAGS_verify_checksum, true);
|
ReadOptions options(FLAGS_verify_checksum, true);
|
||||||
long max_key = shared.GetMaxKey();
|
long max_key = shared.GetMaxKey();
|
||||||
long step = shared.GetNumThreads();
|
static const long keys_per_thread = max_key / shared.GetNumThreads();
|
||||||
for (long i = start; i < max_key; i+= step) {
|
long start = keys_per_thread * tid;
|
||||||
|
long end = start + keys_per_thread;
|
||||||
|
if (tid == shared.GetNumThreads() - 1) {
|
||||||
|
end = max_key;
|
||||||
|
}
|
||||||
|
unique_ptr<Iterator> iter(db_->NewIterator(options));
|
||||||
|
iter->Seek(Key(start));
|
||||||
|
for (long i = start; i < end; i++) {
|
||||||
std::string from_db;
|
std::string from_db;
|
||||||
VerifyValue(i, options, shared, &from_db, true);
|
std::string keystr = Key(i);
|
||||||
|
Slice k = keystr;
|
||||||
|
Status s = iter->status();
|
||||||
|
if (iter->Valid()) {
|
||||||
|
if (iter->key().compare(k) > 0) {
|
||||||
|
s = Status::NotFound(Slice());
|
||||||
|
} else if (iter->key().compare(k) == 0) {
|
||||||
|
from_db = iter->value().ToString();
|
||||||
|
iter->Next();
|
||||||
|
} else if (iter->key().compare(k) < 0) {
|
||||||
|
VerificationAbort("An out of range key was found", i);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// The iterator found no value for the key in question, so do not
|
||||||
|
// move to the next item in the iterator
|
||||||
|
s = Status::NotFound(Slice());
|
||||||
|
}
|
||||||
|
VerifyValue(i, options, shared, from_db, s, true);
|
||||||
if (from_db.length()) {
|
if (from_db.length()) {
|
||||||
PrintKeyValue(i, from_db.data(), from_db.length());
|
PrintKeyValue(i, from_db.data(), from_db.length());
|
||||||
}
|
}
|
||||||
@ -1075,25 +1107,28 @@ class StressTest {
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VerifyValue(long key, const ReadOptions &opts, const SharedState &shared,
|
void VerifyValue(long key,
|
||||||
std::string *value_from_db, bool strict=false) const {
|
const ReadOptions &opts,
|
||||||
std::string keystr = Key(key);
|
const SharedState &shared,
|
||||||
Slice k = keystr;
|
const std::string &value_from_db,
|
||||||
|
Status s,
|
||||||
|
bool strict=false) const {
|
||||||
|
// compare value_from_db with the value in the shared state
|
||||||
char value[100];
|
char value[100];
|
||||||
uint32_t value_base = shared.Get(key);
|
uint32_t value_base = shared.Get(key);
|
||||||
if (value_base == SharedState::SENTINEL && !strict) {
|
if (value_base == SharedState::SENTINEL && !strict) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (db_->Get(opts, k, value_from_db).ok()) {
|
if (s.ok()) {
|
||||||
if (value_base == SharedState::SENTINEL) {
|
if (value_base == SharedState::SENTINEL) {
|
||||||
VerificationAbort("Unexpected value found", key);
|
VerificationAbort("Unexpected value found", key);
|
||||||
}
|
}
|
||||||
size_t sz = GenerateValue(value_base, value, sizeof(value));
|
size_t sz = GenerateValue(value_base, value, sizeof(value));
|
||||||
if (value_from_db->length() != sz) {
|
if (value_from_db.length() != sz) {
|
||||||
VerificationAbort("Length of value read is not equal", key);
|
VerificationAbort("Length of value read is not equal", key);
|
||||||
}
|
}
|
||||||
if (memcmp(value_from_db->data(), value, sz) != 0) {
|
if (memcmp(value_from_db.data(), value, sz) != 0) {
|
||||||
VerificationAbort("Contents of value read don't match", key);
|
VerificationAbort("Contents of value read don't match", key);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
Reference in New Issue
Block a user