A work version of strict workload test
This commit is contained in:
parent
357ca88b4c
commit
6df92a8b8d
|
@ -207,7 +207,7 @@ public:
|
||||||
double detailedHealthMetricsLastUpdated;
|
double detailedHealthMetricsLastUpdated;
|
||||||
|
|
||||||
UniqueOrderedOptionList<FDBTransactionOptions> transactionDefaults;
|
UniqueOrderedOptionList<FDBTransactionOptions> transactionDefaults;
|
||||||
std::unique_ptr<SpecialKeySpace> specialKeySpace;
|
std::shared_ptr<SpecialKeySpace> specialKeySpace;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -531,7 +531,7 @@ DatabaseContext::DatabaseContext(Reference<AsyncVar<Reference<ClusterConnectionF
|
||||||
|
|
||||||
monitorMasterProxiesInfoChange = monitorMasterProxiesChange(clientInfo, &masterProxiesChangeTrigger);
|
monitorMasterProxiesInfoChange = monitorMasterProxiesChange(clientInfo, &masterProxiesChangeTrigger);
|
||||||
clientStatusUpdater.actor = clientStatusUpdateActor(this);
|
clientStatusUpdater.actor = clientStatusUpdateActor(this);
|
||||||
specialKeySpace = std::make_unique<SpecialKeySpace>(LiteralStringRef(""), LiteralStringRef("\xff\xff\xff\xff"));
|
specialKeySpace = std::make_shared<SpecialKeySpace>(LiteralStringRef(""), LiteralStringRef("\xff\xff\xff\xff"));
|
||||||
}
|
}
|
||||||
|
|
||||||
DatabaseContext::DatabaseContext(const Error& err)
|
DatabaseContext::DatabaseContext(const Error& err)
|
||||||
|
|
|
@ -32,6 +32,10 @@ ACTOR Future<Void> SpecialKeyRangeBaseImpl::normalizeKeySelectorActor(const Spec
|
||||||
.detail("SpecialKeyRangeEnd", pkrImpl->range.end);
|
.detail("SpecialKeyRangeEnd", pkrImpl->range.end);
|
||||||
|
|
||||||
Standalone<RangeResultRef> result = wait(pkrImpl->getRange(ryw, KeyRangeRef(startKey, endKey)));
|
Standalone<RangeResultRef> result = wait(pkrImpl->getRange(ryw, KeyRangeRef(startKey, endKey)));
|
||||||
|
if (result.size() == 0) {
|
||||||
|
TraceEvent("ZeroElementsIntheRange").detail("Start", startKey).detail("End", endKey);
|
||||||
|
return Void();
|
||||||
|
}
|
||||||
// TODO : KeySelector::setKey has byte limit according to the knobs, customize it if needed
|
// TODO : KeySelector::setKey has byte limit according to the knobs, customize it if needed
|
||||||
if (ks->offset < 1) {
|
if (ks->offset < 1) {
|
||||||
if (result.size() >= 1 - ks->offset) {
|
if (result.size() >= 1 - ks->offset) {
|
||||||
|
@ -71,26 +75,28 @@ ACTOR Future<Standalone<RangeResultRef>> SpecialKeySpace::getRangeAggregationAct
|
||||||
// make sure offset == 1
|
// make sure offset == 1
|
||||||
state RangeMap<Key, SpecialKeyRangeBaseImpl*, KeyRangeRef>::Iterator iter =
|
state RangeMap<Key, SpecialKeyRangeBaseImpl*, KeyRangeRef>::Iterator iter =
|
||||||
pks->impls.rangeContaining(begin.getKey());
|
pks->impls.rangeContaining(begin.getKey());
|
||||||
while (begin.offset != 1 && iter != pks->impls.ranges().begin() && iter != pks->impls.ranges().end()) {
|
while ((begin.offset < 1 && iter != pks->impls.ranges().begin()) || ( begin.offset > 1 && iter != pks->impls.ranges().end())) {
|
||||||
if (iter->value() != nullptr) wait(iter->value()->normalizeKeySelectorActor(iter->value(), ryw, &begin));
|
if (iter->value() != nullptr) wait(iter->value()->normalizeKeySelectorActor(iter->value(), ryw, &begin));
|
||||||
begin.offset < 1 ? --iter : ++iter;
|
begin.offset < 1 ? --iter : ++iter;
|
||||||
}
|
}
|
||||||
if (begin.offset != 1) {
|
if (begin.offset != 1) {
|
||||||
// The Key Selector points to key outside the whole special key space
|
// The Key Selector points to key outside the whole special key space
|
||||||
TraceEvent(SevError, "IllegalBeginKeySelector")
|
TraceEvent(SevWarn, "IllegalBeginKeySelector")
|
||||||
.detail("TerminateKey", begin.getKey())
|
.detail("TerminateKey", begin.getKey())
|
||||||
.detail("TerminateOffset", begin.offset);
|
.detail("TerminateOffset", begin.offset);
|
||||||
|
begin.offset = 1;
|
||||||
}
|
}
|
||||||
iter = pks->impls.rangeContaining(end.getKey());
|
iter = pks->impls.rangeContaining(end.getKey());
|
||||||
while (end.offset != 1 && iter != pks->impls.ranges().begin() && iter != pks->impls.ranges().end()) {
|
while ((end.offset < 1 && iter != pks->impls.ranges().begin()) || (end.offset > 1 && iter != pks->impls.ranges().end())) {
|
||||||
if (iter->value() != nullptr) wait(iter->value()->normalizeKeySelectorActor(iter->value(), ryw, &end));
|
if (iter->value() != nullptr) wait(iter->value()->normalizeKeySelectorActor(iter->value(), ryw, &end));
|
||||||
end.offset < 1 ? --iter : ++iter;
|
end.offset < 1 ? --iter : ++iter;
|
||||||
}
|
}
|
||||||
if (end.offset != 1) {
|
if (end.offset != 1) {
|
||||||
// The Key Selector points to key outside the whole special key space
|
// The Key Selector points to key outside the whole special key space
|
||||||
TraceEvent(SevError, "IllegalEndKeySelector")
|
TraceEvent(SevWarn, "IllegalEndKeySelector")
|
||||||
.detail("TerminateKey", end.getKey())
|
.detail("TerminateKey", end.getKey())
|
||||||
.detail("TerminateOffset", end.offset);
|
.detail("TerminateOffset", end.offset);
|
||||||
|
end.offset = 1;
|
||||||
}
|
}
|
||||||
// return if range inverted
|
// return if range inverted
|
||||||
if (begin.offset >= end.offset && begin.getKey() >= end.getKey()) {
|
if (begin.offset >= end.offset && begin.getKey() >= end.getKey()) {
|
||||||
|
|
|
@ -13,8 +13,12 @@ public:
|
||||||
virtual Future<Standalone<RangeResultRef>> getRange(Reference<ReadYourWritesTransaction> ryw,
|
virtual Future<Standalone<RangeResultRef>> getRange(Reference<ReadYourWritesTransaction> ryw,
|
||||||
KeyRangeRef kr) const {
|
KeyRangeRef kr) const {
|
||||||
ASSERT(range.contains(kr));
|
ASSERT(range.contains(kr));
|
||||||
auto result = ryw->getRange(kr, GetRangeLimits());
|
auto resultFuture = ryw->getRange(kr, CLIENT_KNOBS->TOO_MANY);
|
||||||
// ASSERT(resultFuture.isReady());
|
ASSERT(resultFuture.isReady());
|
||||||
|
auto result = resultFuture.getValue();
|
||||||
|
if (result.size() == 0) {
|
||||||
|
TraceEvent("DebugLLL");
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -22,13 +26,13 @@ public:
|
||||||
struct SpecialKeySpaceCorrectnessWorkload : TestWorkload {
|
struct SpecialKeySpaceCorrectnessWorkload : TestWorkload {
|
||||||
|
|
||||||
int actorCount, minKeysPerRange, maxKeysPerRange, rangeCount, keyBytes, valBytes;
|
int actorCount, minKeysPerRange, maxKeysPerRange, rangeCount, keyBytes, valBytes;
|
||||||
double testDuration, absoluteRandomProb;
|
double testDuration, absoluteRandomProb, transactionsPerSecond;
|
||||||
std::vector<Future<Void>> clients;
|
// std::vector<Future<Void>> clients;
|
||||||
|
|
||||||
PerfIntCounter wrongResults, keysCount;
|
PerfIntCounter wrongResults, keysCount;
|
||||||
|
|
||||||
Reference<ReadYourWritesTransaction> ryw; // used to store all populated data
|
Reference<ReadYourWritesTransaction> ryw; // used to store all populated data
|
||||||
std::vector<SPSCTestImpl> impls;
|
std::vector<SPSCTestImpl*> impls;
|
||||||
|
|
||||||
Standalone<VectorRef<KeyRangeRef>> keys;
|
Standalone<VectorRef<KeyRangeRef>> keys;
|
||||||
|
|
||||||
|
@ -40,14 +44,17 @@ struct SpecialKeySpaceCorrectnessWorkload : TestWorkload {
|
||||||
keyBytes = getOption(options, LiteralStringRef("keyBytes"), 16);
|
keyBytes = getOption(options, LiteralStringRef("keyBytes"), 16);
|
||||||
valBytes = getOption(options, LiteralStringRef("valueBytes"), 16);
|
valBytes = getOption(options, LiteralStringRef("valueBytes"), 16);
|
||||||
testDuration = getOption(options, LiteralStringRef("testDuration"), 10.0);
|
testDuration = getOption(options, LiteralStringRef("testDuration"), 10.0);
|
||||||
actorCount = getOption( options, LiteralStringRef("actorCount"), 50 );
|
transactionsPerSecond = getOption( options, LiteralStringRef("transactionsPerSecond"), 100.0 );
|
||||||
|
actorCount = getOption( options, LiteralStringRef("actorCount"), 1 );
|
||||||
absoluteRandomProb = getOption(options, LiteralStringRef("absoluteRandomProb"), 0.5);
|
absoluteRandomProb = getOption(options, LiteralStringRef("absoluteRandomProb"), 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual std::string description() { return "SpecialKeySpaceCorrectness"; }
|
virtual std::string description() { return "SpecialKeySpaceCorrectness"; }
|
||||||
virtual Future<Void> setup(Database const& cx) { return _setup(cx, this); }
|
virtual Future<Void> setup(Database const& cx) { return _setup(cx, this); }
|
||||||
virtual Future<Void> start(Database const& cx) { return _start(cx, this); }
|
virtual Future<Void> start(Database const& cx) { return _start(cx, this); }
|
||||||
virtual Future<bool> check(Database const& cx) { return wrongResults.getValue() == 0; }
|
virtual Future<bool> check(Database const& cx) {
|
||||||
|
return wrongResults.getValue() == 0;
|
||||||
|
}
|
||||||
virtual void getMetrics(std::vector<PerfMetric>& m) {}
|
virtual void getMetrics(std::vector<PerfMetric>& m) {}
|
||||||
|
|
||||||
// disable the default timeout setting
|
// disable the default timeout setting
|
||||||
|
@ -75,14 +82,15 @@ struct SpecialKeySpaceCorrectnessWorkload : TestWorkload {
|
||||||
}
|
}
|
||||||
ACTOR Future<Void> _start(Database cx, SpecialKeySpaceCorrectnessWorkload* self) {
|
ACTOR Future<Void> _start(Database cx, SpecialKeySpaceCorrectnessWorkload* self) {
|
||||||
self->ryw = Reference(new ReadYourWritesTransaction(cx));
|
self->ryw = Reference(new ReadYourWritesTransaction(cx));
|
||||||
|
self->ryw->clear(normalKeys);
|
||||||
// generate key ranges
|
// generate key ranges
|
||||||
for (int i = 0; i < self->rangeCount; ++i) {
|
for (int i = 0; i < self->rangeCount; ++i) {
|
||||||
std::string baseKey = deterministicRandom()->randomAlphaNumeric(i + 1);
|
std::string baseKey = deterministicRandom()->randomAlphaNumeric(i + 1);
|
||||||
Key startKey(baseKey + "/");
|
Key startKey(baseKey + "/");
|
||||||
Key endKey(baseKey + "/\xff");
|
Key endKey(baseKey + "/\xff");
|
||||||
self->keys.push_back_deep(self->keys.arena(), KeyRangeRef(startKey, endKey));
|
self->keys.push_back_deep(self->keys.arena(), KeyRangeRef(startKey, endKey));
|
||||||
self->impls.emplace_back(startKey, endKey);
|
self->impls.push_back(new SPSCTestImpl(startKey, endKey));
|
||||||
cx->specialKeySpace->registerKeyRange(self->keys.back(), &self->impls.back());
|
cx->specialKeySpace->registerKeyRange(self->keys.back(), self->impls.back());
|
||||||
// generate keys in each key range
|
// generate keys in each key range
|
||||||
int keysInRange = deterministicRandom()->randomInt(self->minKeysPerRange, self->maxKeysPerRange + 1);
|
int keysInRange = deterministicRandom()->randomInt(self->minKeysPerRange, self->maxKeysPerRange + 1);
|
||||||
self->keysCount += keysInRange;
|
self->keysCount += keysInRange;
|
||||||
|
@ -91,36 +99,45 @@ struct SpecialKeySpaceCorrectnessWorkload : TestWorkload {
|
||||||
Value(deterministicRandom()->randomAlphaNumeric(self->valBytes)));
|
Value(deterministicRandom()->randomAlphaNumeric(self->valBytes)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
self->ryw->setVersion(100);
|
||||||
std::vector<Future<Void>> clients;
|
std::vector<Future<Void>> clients;
|
||||||
for(int c = 0; c < self->actorCount; c++) {
|
for(int c = 0; c < self->actorCount; c++) {
|
||||||
clients.push_back(self->getRangeCallActor(cx, self));
|
clients.push_back(self->getRangeCallActor(cx, self));
|
||||||
}
|
}
|
||||||
wait(timeout(waitForAll(clients), self->testDuration, Void()));
|
wait(timeout(waitForAll(clients), self->testDuration, Void()));
|
||||||
|
// wait(delay(self->testDuration));
|
||||||
|
// printf("After start delay\n");
|
||||||
|
for (SPSCTestImpl* p : self->impls)
|
||||||
|
delete p;
|
||||||
return Void();
|
return Void();
|
||||||
}
|
}
|
||||||
|
|
||||||
ACTOR Future<Void> getRangeCallActor(Database cx, SpecialKeySpaceCorrectnessWorkload* self) {
|
ACTOR Future<Void> getRangeCallActor(Database cx, SpecialKeySpaceCorrectnessWorkload* self) {
|
||||||
|
state double lastTime = now();
|
||||||
loop {
|
loop {
|
||||||
|
wait( poisson( &lastTime, 1.0 / self->transactionsPerSecond ) );
|
||||||
state bool reverse = deterministicRandom()->random01() < 0.5;
|
state bool reverse = deterministicRandom()->random01() < 0.5;
|
||||||
state GetRangeLimits limit = self->randomLimits();
|
state GetRangeLimits limit = self->randomLimits();
|
||||||
state KeySelector begin = self->randomKeySelector();
|
state KeySelector begin = self->randomKeySelector();
|
||||||
state KeySelector end = self->randomKeySelector();
|
state KeySelector end = self->randomKeySelector();
|
||||||
KeyRange kr = KeyRangeRef(LiteralStringRef("test"), LiteralStringRef("test2"));
|
auto correctResultFuture = self->ryw->getRange(begin, end, limit, false, reverse);
|
||||||
// state Standalone<RangeResultRef> correctResult = wait(self->ryw->getRange(begin, end, limit, false, reverse));
|
ASSERT(correctResultFuture.isReady());
|
||||||
Standalone<RangeResultRef> tempResult = wait(self->ryw->getRange(kr, 1));
|
// TraceEvent("RANGECALLCOUNTER").detail("Counter", count);
|
||||||
// ASSERT(correctResultFuture.isReady());
|
// printf("DEBUG Counter: %d\n", count);
|
||||||
// auto correctResult = correctResultFuture.getValue();
|
// count++;
|
||||||
// auto testResultFuture = cx->specialKeySpace->getRange(self->ryw, begin, end, limit, false, reverse);
|
auto correctResult = correctResultFuture.getValue();
|
||||||
// ASSERT(testResultFuture.isReady());
|
auto testResultFuture = cx->specialKeySpace->getRange(self->ryw, begin, end, limit, false, reverse);
|
||||||
// auto testResult = testResultFuture.getValue();
|
ASSERT(testResultFuture.isReady());
|
||||||
|
auto testResult = testResultFuture.getValue();
|
||||||
|
|
||||||
// // check the same
|
// check the same
|
||||||
// if (!self->compareRangeResult(correctResult, testResult)) {
|
if (!self->compareRangeResult(correctResult, testResult)) {
|
||||||
// // TODO : log here
|
// TODO : log here
|
||||||
// // TraceEvent("WrongGetRangeResult"). detail("KeySeleco")
|
// TraceEvent("WrongGetRangeResult"). detail("KeySeleco")
|
||||||
// ++self->wrongResults;
|
auto temp1 = cx->specialKeySpace->getRange(self->ryw, begin, end, limit, false, reverse);
|
||||||
// }
|
auto temp2 = self->ryw->getRange(begin, end, limit, false, reverse);
|
||||||
|
++self->wrongResults;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,11 +155,11 @@ struct SpecialKeySpaceCorrectnessWorkload : TestWorkload {
|
||||||
prefix = Key(
|
prefix = Key(
|
||||||
deterministicRandom()->randomAlphaNumeric(deterministicRandom()->randomInt(1, rangeCount + 1)) + "/");
|
deterministicRandom()->randomAlphaNumeric(deterministicRandom()->randomInt(1, rangeCount + 1)) + "/");
|
||||||
else
|
else
|
||||||
prefix = keys[deterministicRandom()->randomInt(1, rangeCount + 1)].begin;
|
prefix = keys[deterministicRandom()->randomInt(0, rangeCount)].begin;
|
||||||
Key suffix;
|
Key suffix;
|
||||||
// TODO : add randomness to pickup existing keys
|
// TODO : add randomness to pickup existing keys
|
||||||
// if (deterministicRandom()->random01() < absoluteRandomProb)
|
if (deterministicRandom()->random01() < absoluteRandomProb)
|
||||||
suffix = Key(deterministicRandom()->randomAlphaNumeric(keyBytes));
|
suffix = Key(deterministicRandom()->randomAlphaNumeric(keyBytes));
|
||||||
// return Key(deterministicRandom()->randomAlphaNumeric(keyBytes)).withPrefix(prefix);
|
// return Key(deterministicRandom()->randomAlphaNumeric(keyBytes)).withPrefix(prefix);
|
||||||
// TODO : test corner case here if offset points out
|
// TODO : test corner case here if offset points out
|
||||||
int offset = deterministicRandom()->randomInt(-keysCount.getValue() - 1, keysCount.getValue() + 1);
|
int offset = deterministicRandom()->randomInt(-keysCount.getValue() - 1, keysCount.getValue() + 1);
|
||||||
|
@ -151,7 +168,8 @@ struct SpecialKeySpaceCorrectnessWorkload : TestWorkload {
|
||||||
}
|
}
|
||||||
|
|
||||||
GetRangeLimits randomLimits() {
|
GetRangeLimits randomLimits() {
|
||||||
if (deterministicRandom()->random01() < 0.5) return GetRangeLimits();
|
// TODO : fix knobs for row_unlimited
|
||||||
|
// if (deterministicRandom()->random01() < 0.5) return GetRangeLimits();
|
||||||
int rowLimits = deterministicRandom()->randomInt(1, keysCount.getValue() + 1);
|
int rowLimits = deterministicRandom()->randomInt(1, keysCount.getValue() + 1);
|
||||||
// TODO : add random bytes limit here
|
// TODO : add random bytes limit here
|
||||||
// TODO : setRequestLimits in RYW
|
// TODO : setRequestLimits in RYW
|
||||||
|
|
|
@ -123,6 +123,7 @@ if(WITH_PYTHON)
|
||||||
add_fdb_test(TEST_FILES fast/SelectorCorrectness.txt)
|
add_fdb_test(TEST_FILES fast/SelectorCorrectness.txt)
|
||||||
add_fdb_test(TEST_FILES fast/Sideband.txt)
|
add_fdb_test(TEST_FILES fast/Sideband.txt)
|
||||||
add_fdb_test(TEST_FILES fast/SidebandWithStatus.txt)
|
add_fdb_test(TEST_FILES fast/SidebandWithStatus.txt)
|
||||||
|
add_fdb_test(TEST_FILES fast/SpecialKeySpaceCorrectness.txt)
|
||||||
add_fdb_test(TEST_FILES fast/SwizzledRollbackSideband.txt)
|
add_fdb_test(TEST_FILES fast/SwizzledRollbackSideband.txt)
|
||||||
add_fdb_test(TEST_FILES fast/SystemRebootTestCycle.txt)
|
add_fdb_test(TEST_FILES fast/SystemRebootTestCycle.txt)
|
||||||
add_fdb_test(TEST_FILES fast/TaskBucketCorrectness.txt)
|
add_fdb_test(TEST_FILES fast/TaskBucketCorrectness.txt)
|
||||||
|
|
Loading…
Reference in New Issue