mirror of https://github.com/facebook/rocksdb.git
Verify columns in NonBatchedOpsStressTest::VerifyDb (#10783)
Summary: As the first step of covering the wide-column functionality of iterators in our stress tests, the patch adds verification logic to `NonBatchedOpsStressTest::VerifyDb` that checks whether the iterator's value and columns are in sync. Note: I plan to update the other types of stress tests and add similar verification for prefix scans etc. in separate PRs. Pull Request resolved: https://github.com/facebook/rocksdb/pull/10783 Test Plan: Ran some simple blackbox crash tests. Reviewed By: riversand963 Differential Revision: D40152370 Pulled By: riversand963 fbshipit-source-id: 8f9d17d7af5da58ccf1bd2057cab53cc9645ac35
This commit is contained in:
parent
b205c6d029
commit
d6d8c007ff
|
@ -15,10 +15,6 @@
|
|||
|
||||
namespace ROCKSDB_NAMESPACE {
|
||||
|
||||
const Slice kDefaultWideColumnName;
|
||||
|
||||
const WideColumns kNoWideColumns;
|
||||
|
||||
Status WideColumnSerialization::Serialize(const WideColumns& columns,
|
||||
std::string& output) {
|
||||
if (columns.size() >
|
||||
|
|
|
@ -9,6 +9,10 @@
|
|||
|
||||
namespace ROCKSDB_NAMESPACE {
|
||||
|
||||
const Slice kDefaultWideColumnName;
|
||||
|
||||
const WideColumns kNoWideColumns;
|
||||
|
||||
Status PinnableWideColumns::CreateIndexForWideColumns() {
|
||||
Slice value_copy = value_;
|
||||
|
||||
|
|
|
@ -263,6 +263,11 @@ WideColumns GenerateWideColumns(uint32_t value_base, const Slice& slice) {
|
|||
|
||||
WideColumns GenerateExpectedWideColumns(uint32_t value_base,
|
||||
const Slice& slice) {
|
||||
if (FLAGS_use_put_entity_one_in == 0 ||
|
||||
(value_base % FLAGS_use_put_entity_one_in) != 0) {
|
||||
return WideColumns{{kDefaultWideColumnName, slice}};
|
||||
}
|
||||
|
||||
WideColumns columns = GenerateWideColumns(value_base, slice);
|
||||
|
||||
std::sort(columns.begin(), columns.end(),
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
// found in the LICENSE file. See the AUTHORS file for names of contributors.
|
||||
//
|
||||
|
||||
#include <ios>
|
||||
|
||||
#include "util/compression.h"
|
||||
#ifdef GFLAGS
|
||||
#include "cache/fast_lru_cache.h"
|
||||
|
@ -438,6 +440,53 @@ void StressTest::VerificationAbort(SharedState* shared, std::string msg, int cf,
|
|||
shared->SetVerificationFailure();
|
||||
}
|
||||
|
||||
void StressTest::VerificationAbort(SharedState* shared, int cf, int64_t key,
|
||||
const Slice& value,
|
||||
const WideColumns& columns,
|
||||
const WideColumns& expected_columns) const {
|
||||
assert(shared);
|
||||
|
||||
auto key_str = Key(key);
|
||||
|
||||
fprintf(stderr,
|
||||
"Verification failed for column family %d key %s (%" PRIi64
|
||||
"): Value and columns inconsistent: %s\n",
|
||||
cf, Slice(key_str).ToString(/* hex */ true).c_str(), key,
|
||||
DebugString(value, columns, expected_columns).c_str());
|
||||
|
||||
shared->SetVerificationFailure();
|
||||
}
|
||||
|
||||
std::string StressTest::DebugString(const Slice& value,
|
||||
const WideColumns& columns,
|
||||
const WideColumns& expected_columns) {
|
||||
std::ostringstream oss;
|
||||
|
||||
oss << "value: " << value.ToString(/* hex */ true);
|
||||
|
||||
auto dump = [](const WideColumns& cols, std::ostream& os) {
|
||||
if (cols.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
os << std::hex;
|
||||
|
||||
auto it = cols.begin();
|
||||
os << *it;
|
||||
for (++it; it != cols.end(); ++it) {
|
||||
os << ' ' << *it;
|
||||
}
|
||||
};
|
||||
|
||||
oss << ", columns: ";
|
||||
dump(columns, oss);
|
||||
|
||||
oss << ", expected_columns: ";
|
||||
dump(expected_columns, oss);
|
||||
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
void StressTest::PrintStatistics() {
|
||||
if (dbstats) {
|
||||
fprintf(stdout, "STATISTICS:\n%s\n", dbstats->ToString().c_str());
|
||||
|
|
|
@ -9,6 +9,9 @@
|
|||
|
||||
#ifdef GFLAGS
|
||||
#pragma once
|
||||
|
||||
#include <ostream>
|
||||
|
||||
#include "db_stress_tool/db_stress_common.h"
|
||||
#include "db_stress_tool/db_stress_shared_state.h"
|
||||
|
||||
|
@ -231,6 +234,13 @@ class StressTest {
|
|||
int64_t key, Slice value_from_db,
|
||||
Slice value_from_expected) const;
|
||||
|
||||
void VerificationAbort(SharedState* shared, int cf, int64_t key,
|
||||
const Slice& value, const WideColumns& columns,
|
||||
const WideColumns& expected_columns) const;
|
||||
|
||||
static std::string DebugString(const Slice& value, const WideColumns& columns,
|
||||
const WideColumns& expected_columns);
|
||||
|
||||
void PrintEnv() const;
|
||||
|
||||
void Open(SharedState* shared);
|
||||
|
|
|
@ -101,6 +101,15 @@ class NonBatchedOpsStressTest : public StressTest {
|
|||
if (diff > 0) {
|
||||
s = Status::NotFound();
|
||||
} else if (diff == 0) {
|
||||
const WideColumns expected_columns = GenerateExpectedWideColumns(
|
||||
GetValueBase(iter->value()), iter->value());
|
||||
if (iter->columns() != expected_columns) {
|
||||
VerificationAbort(shared, static_cast<int>(cf), i,
|
||||
iter->value(), iter->columns(),
|
||||
expected_columns);
|
||||
break;
|
||||
}
|
||||
|
||||
from_db = iter->value().ToString();
|
||||
iter->Next();
|
||||
} else {
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <ostream>
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
@ -70,6 +71,14 @@ inline bool operator!=(const WideColumn& lhs, const WideColumn& rhs) {
|
|||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& os, const WideColumn& column) {
|
||||
const bool hex =
|
||||
(os.flags() & std::ios_base::basefield) == std::ios_base::hex;
|
||||
os << column.name().ToString(hex) << ':' << column.value().ToString(hex);
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
// A collection of wide columns.
|
||||
using WideColumns = std::vector<WideColumn>;
|
||||
|
||||
|
|
Loading…
Reference in New Issue