Skip to content

Commit 02194de

Browse files
BenHuddlestondaverigby
authored andcommitted
MB-34017: Expand warmup tests to warmup multiple SyncWrites
Expand warmup tests to warmup mutltiple SyncWrites in phases to ensure that everything is warmed up correctly. Change-Id: I4e0d060ae2faf419d4ee39700da3ff8d690602db Reviewed-on: http://review.couchbase.org/109891 Reviewed-by: Dave Rigby <[email protected]> Tested-by: Build Bot <[email protected]>
1 parent 03c77b9 commit 02194de

File tree

1 file changed

+117
-83
lines changed

1 file changed

+117
-83
lines changed

engines/ep/tests/module_tests/evp_store_warmup_test.cc

Lines changed: 117 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -511,11 +511,14 @@ class DurabilityWarmupTest : public DurabilityKVBucketTest {
511511
protected:
512512
// Test that a pending SyncWrite/Delete not yet committed is correctly
513513
// warmed up when the bucket restarts.
514-
void testPendingSyncWrite(vbucket_state_t vbState, DocumentState docState);
514+
void testPendingSyncWrite(vbucket_state_t vbState,
515+
const std::vector<std::string>& keys,
516+
DocumentState docState);
515517

516518
// Test that a pending SyncWrite/Delete which was committed is correctly
517519
// warmed up when the bucket restarts (as a Committed item).
518520
void testCommittedSyncWrite(vbucket_state_t vbState,
521+
const std::vector<std::string>& keys,
519522
DocumentState docState);
520523

521524
// Test that a committed mutation followed by a pending SyncWrite to the
@@ -579,7 +582,6 @@ DurabilityWarmupTest::PrePostStateChecker::~PrePostStateChecker() {
579582
EXPECT_EQ(preHCS, vb->getHighCompletedSeqno())
580583
<< "PrePostStateChecker: Found that post warmup the HCS does not "
581584
"match the pre-warmup value";
582-
;
583585
}
584586

585587
DurabilityWarmupTest::PrePostStateChecker
@@ -604,124 +606,156 @@ GetValue DurabilityWarmupTest::getItemFetchFromDiskIfNeeded(
604606
return gv;
605607
}
606608

607-
void DurabilityWarmupTest::testPendingSyncWrite(vbucket_state_t vbState,
608-
DocumentState docState) {
609-
// Store a pending SyncWrite/Delete (without committing) and then restart
610-
auto key = makeStoredDocKey("key");
611-
auto item = makePendingItem(key, "pending_value");
612-
if (docState == DocumentState::Deleted) {
613-
item->setDeleted(DeleteSource::Explicit);
614-
}
615-
ASSERT_EQ(ENGINE_EWOULDBLOCK, store->set(*item, cookie));
616-
flush_vbucket_to_disk(vbid);
609+
void DurabilityWarmupTest::testPendingSyncWrite(
610+
vbucket_state_t vbState,
611+
const std::vector<std::string>& keys,
612+
DocumentState docState) {
613+
// Store the given pending SyncWrites/Deletes (without committing) and then
614+
// restart
617615

618-
if (vbState != vbucket_state_active) {
619-
setVBucketStateAndRunPersistTask(vbid, vbState);
620-
}
621-
resetEngineAndWarmup();
616+
auto vb = engine->getVBucket(vbid);
617+
auto numTracked = vb->getDurabilityMonitor().getNumTracked();
622618

623-
// Check that attempts to read this key via frontend are blocked.
624-
auto gv = store->get(key, vbid, cookie, {});
625-
EXPECT_EQ(ENGINE_SYNC_WRITE_RECOMMIT_IN_PROGRESS, gv.getStatus());
619+
for (const auto& k : keys) {
620+
// Previous runs could have left the VB into a non-active state - must
621+
// be active to perform set().
622+
if (vb->getState() != vbucket_state_active) {
623+
setVBucketToActiveWithValidTopology();
624+
}
626625

627-
// Check that the item is still pending with the correct CAS.
628-
auto vb = engine->getVBucket(vbid);
629-
auto handle = vb->lockCollections(item->getKey());
630-
auto prepared = vb->fetchPreparedValue(handle);
631-
EXPECT_TRUE(prepared.storedValue);
632-
EXPECT_TRUE(prepared.storedValue->isPending());
633-
EXPECT_EQ(item->isDeleted(), prepared.storedValue->isDeleted());
634-
EXPECT_EQ(item->getCas(), prepared.storedValue->getCas());
626+
const auto key = makeStoredDocKey(k);
627+
auto item = makePendingItem(key, "pending_value");
628+
if (docState == DocumentState::Deleted) {
629+
item->setDeleted(DeleteSource::Explicit);
630+
}
631+
ASSERT_EQ(ENGINE_EWOULDBLOCK, store->set(*item, cookie));
632+
flush_vbucket_to_disk(vbid);
635633

636-
// DurabilityMonitor be tracking the prepare.
637-
EXPECT_EQ(1, vb->getDurabilityMonitor().getNumTracked());
634+
// Set the state that we want to test
635+
if (vbState != vbucket_state_active) {
636+
setVBucketStateAndRunPersistTask(vbid, vbState);
637+
}
638+
639+
// About to destroy engine; reset vb shared_ptr.
640+
vb.reset();
641+
resetEngineAndWarmup();
642+
vb = engine->getVBucket(vbid);
643+
644+
// Check that attempts to read this key via frontend are blocked.
645+
auto gv = store->get(key, vbid, cookie, {});
646+
EXPECT_EQ(ENGINE_SYNC_WRITE_RECOMMIT_IN_PROGRESS, gv.getStatus());
647+
648+
// Check that the item is still pending with the correct CAS.
649+
auto handle = vb->lockCollections(item->getKey());
650+
auto prepared = vb->fetchPreparedValue(handle);
651+
EXPECT_TRUE(prepared.storedValue);
652+
EXPECT_TRUE(prepared.storedValue->isPending());
653+
EXPECT_EQ(item->isDeleted(), prepared.storedValue->isDeleted());
654+
EXPECT_EQ(item->getCas(), prepared.storedValue->getCas());
655+
656+
// DurabilityMonitor be tracking the prepare.
657+
EXPECT_EQ(++numTracked, vb->getDurabilityMonitor().getNumTracked());
658+
}
638659
}
639660

640661
TEST_P(DurabilityWarmupTest, ActivePendingSyncWrite) {
641-
testPendingSyncWrite(vbucket_state_active, DocumentState::Alive);
662+
testPendingSyncWrite(vbucket_state_active,
663+
{"key1", "key2", "key3"},
664+
DocumentState::Alive);
642665
}
643666

644667
TEST_P(DurabilityWarmupTest, ActivePendingSyncDelete) {
645-
testPendingSyncWrite(vbucket_state_active, DocumentState::Deleted);
668+
testPendingSyncWrite(vbucket_state_active,
669+
{"key1", "key2", "key3"},
670+
DocumentState::Deleted);
646671
}
647672

648673
TEST_P(DurabilityWarmupTest, ReplicaPendingSyncWrite) {
649-
testPendingSyncWrite(vbucket_state_replica, DocumentState::Alive);
674+
testPendingSyncWrite(vbucket_state_replica,
675+
{"key1", "key2", "key3"},
676+
DocumentState::Alive);
650677
}
651678

652679
TEST_P(DurabilityWarmupTest, ReplicaPendingSyncDelete) {
653-
testPendingSyncWrite(vbucket_state_replica, DocumentState::Deleted);
680+
testPendingSyncWrite(vbucket_state_replica,
681+
{"key1", "key2", "key3"},
682+
DocumentState::Deleted);
654683
}
655-
void DurabilityWarmupTest::testCommittedSyncWrite(vbucket_state_t vbState,
656-
DocumentState docState) {
657-
// prepare & commit a SyncWrite then restart.
658-
auto key = makeStoredDocKey("key");
659-
auto item = makePendingItem(key, "value");
660-
if (docState == DocumentState::Deleted) {
661-
item->setDeleted(DeleteSource::Explicit);
662-
}
663-
ASSERT_EQ(ENGINE_EWOULDBLOCK, store->set(*item, cookie));
664-
flush_vbucket_to_disk(vbid);
684+
void DurabilityWarmupTest::testCommittedSyncWrite(
685+
vbucket_state_t vbState,
686+
const std::vector<std::string>& keys,
687+
DocumentState docState) {
688+
// Prepare
689+
testPendingSyncWrite(vbState, keys, docState);
665690

666-
{ // scoping vb - is invalid once resetEngineAndWarmup() is called.
667-
auto vb = engine->getVBucket(vbid);
668-
EXPECT_EQ(ENGINE_SUCCESS,
669-
vb->seqnoAcknowledged(
670-
folly::SharedMutex::ReadHolder(vb->getStateLock()),
671-
"replica",
672-
vb->getHighPreparedSeqno()));
691+
auto vb = engine->getVBucket(vbid);
692+
auto numTracked = vb->getDurabilityMonitor().getNumTracked();
693+
ASSERT_EQ(keys.size(), numTracked);
694+
695+
auto prepareSeqno = 1;
696+
for (const auto& k : keys) {
697+
// Commit
698+
const auto key = makeStoredDocKey(k);
699+
if (vbState == vbucket_state_active) {
700+
// Commit on active is driven by the ADM so we need to drive our
701+
// commit via seqno ack
702+
EXPECT_EQ(ENGINE_SUCCESS,
703+
vb->seqnoAcknowledged(folly::SharedMutex::ReadHolder(
704+
vb->getStateLock()),
705+
"replica",
706+
prepareSeqno++));
707+
} else {
708+
// Commit on non-active is driven by VBucket::commit
709+
vb->commit(key, prepareSeqno++, {}, vb->lockCollections(key));
710+
}
673711

674712
flush_vbucket_to_disk(vbid, 1);
675-
}
676713

677-
if (vbState != vbucket_state_active) {
678-
setVBucketStateAndRunPersistTask(vbid, vbState);
679-
}
714+
if (vbState != vbucket_state_active) {
715+
setVBucketStateAndRunPersistTask(vbid, vbState);
716+
}
680717

681-
const auto expectedItem = getItemFetchFromDiskIfNeeded(key, docState);
682-
ASSERT_EQ(ENGINE_SUCCESS, expectedItem.getStatus());
718+
const auto expectedItem = getItemFetchFromDiskIfNeeded(key, docState);
719+
ASSERT_EQ(ENGINE_SUCCESS, expectedItem.getStatus());
683720

684-
resetEngineAndWarmup();
685-
686-
// Check that the item is CommittedviaPrepare.
687-
auto vb = engine->getVBucket(vbid);
688-
// @TODO: RocksDB currently only has an estimated item count in
689-
// full-eviction, so it fails this check. Skip if RocksDB && full_eviction.
690-
if ((std::get<0>(GetParam()).find("Rocksdb") == std::string::npos) ||
691-
std::get<0>(GetParam()) == "value_only") {
692-
const auto expectedNumItems = docState == DocumentState::Alive ? 1 : 0;
693-
EXPECT_EQ(expectedNumItems, vb->getNumItems());
694-
}
721+
// About to destroy engine; reset vb shared_ptr.
722+
vb.reset();
723+
resetEngineAndWarmup();
724+
vb = engine->getVBucket(vbid);
695725

696-
GetValue gv = getItemFetchFromDiskIfNeeded(item->getKey(), docState);
697-
EXPECT_EQ(ENGINE_SUCCESS, gv.getStatus());
698-
EXPECT_EQ(CommittedState::CommittedViaPrepare, gv.item->getCommitted());
699-
EXPECT_EQ(*expectedItem.item, *gv.item);
726+
// Check that the item is CommittedviaPrepare.
727+
GetValue gv = getItemFetchFromDiskIfNeeded(key, docState);
728+
EXPECT_EQ(ENGINE_SUCCESS, gv.getStatus());
729+
EXPECT_EQ(CommittedState::CommittedViaPrepare, gv.item->getCommitted());
730+
EXPECT_EQ(*expectedItem.item, *gv.item);
700731

701-
// DurabilityMonitor should be empty as no outstanding prepares.
702-
EXPECT_EQ(0, vb->getDurabilityMonitor().getNumTracked());
732+
// DurabilityMonitor should be empty as no outstanding prepares.
733+
EXPECT_EQ(--numTracked, vb->getDurabilityMonitor().getNumTracked());
734+
}
703735
}
704736

705737
TEST_P(DurabilityWarmupTest, ActiveCommittedSyncWrite) {
706-
testCommittedSyncWrite(vbucket_state_active, DocumentState::Alive);
707-
// Run the test again to verify that item counts are correct after we
708-
// overwrite the original prepare and commit
709-
testCommittedSyncWrite(vbucket_state_active, DocumentState::Alive);
738+
testCommittedSyncWrite(vbucket_state_active,
739+
{"key1", "key2", "key3"},
740+
DocumentState::Alive);
710741
}
711742

712743
TEST_P(DurabilityWarmupTest, ActiveCommittedSyncDelete) {
713-
testCommittedSyncWrite(vbucket_state_active, DocumentState::Deleted);
714-
// Run the test again to verify that item counts are correct after we
715-
// overwrite the original prepare and commit
716-
testCommittedSyncWrite(vbucket_state_active, DocumentState::Deleted);
744+
testCommittedSyncWrite(vbucket_state_active,
745+
{"key1", "key2", "key3"},
746+
DocumentState::Deleted);
717747
}
718748

719749
TEST_P(DurabilityWarmupTest, ReplicaCommittedSyncWrite) {
720-
testCommittedSyncWrite(vbucket_state_replica, DocumentState::Alive);
750+
testCommittedSyncWrite(vbucket_state_replica,
751+
{"key1", "key2", "key3"},
752+
DocumentState::Alive);
721753
}
722754

723755
TEST_P(DurabilityWarmupTest, ReplicaCommittedSyncDelete) {
724-
testCommittedSyncWrite(vbucket_state_replica, DocumentState::Deleted);
756+
testCommittedSyncWrite(vbucket_state_replica,
757+
{"key1", "key2", "key3"},
758+
DocumentState::Deleted);
725759
}
726760

727761
void DurabilityWarmupTest::testCommittedAndPendingSyncWrite(

0 commit comments

Comments
 (0)