Skip to content

Commit d00407c

Browse files
jameseh96daverigby
authored andcommitted
Reduce duration of eviction tests
`ReplicaEvictedBeforeActive` test was observed taking >60s on windows. Profiling indicated a large amount of time was spent flushing vbuckets. Change to avoid flushing for each item stored. Change-Id: I4bf3d7fa58c9acf55f57fb367005128dd4577a2d Reviewed-on: http://review.couchbase.org/c/kv_engine/+/135640 Tested-by: Build Bot <[email protected]> Reviewed-by: Dave Rigby <[email protected]>
1 parent 7734d83 commit d00407c

File tree

1 file changed

+72
-25
lines changed

1 file changed

+72
-25
lines changed

engines/ep/tests/module_tests/item_pager_test.cc

Lines changed: 72 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ class STBucketQuotaTest : public STParameterizedBucketTest {
207207
{
208208
auto key = makeStoredDocKey(std::string(keyPrefix) +
209209
std::to_string(count++));
210-
auto item = make_item(vbid, key, std::string(100, 'x'));
210+
auto item = make_item(vbid, key, std::string(5000, 'x'));
211211
// make the items have a range of MFU values
212212
// without this, no matter what percent of items should be
213213
// evicted, either all of them or none of them would be
@@ -220,8 +220,12 @@ class STBucketQuotaTest : public STParameterizedBucketTest {
220220
mfu = ht.generateFreqValue(mfu);
221221
}
222222
item.setFreqCounterValue(mfu);
223-
EXPECT_EQ(ENGINE_SUCCESS, storeItem(item));
224-
flushAndRemoveCheckpoints(vbid);
223+
auto result = storeItem(item);
224+
if (result != ENGINE_SUCCESS) {
225+
ADD_FAILURE() << "Failed storing an item before the "
226+
"predicate returned true";
227+
return count;
228+
}
225229
}
226230
populate = !predicate();
227231
if (!populate) {
@@ -909,12 +913,17 @@ TEST_P(STItemPagerTest, ReplicaEvictedBeforeActive) {
909913
// greater than the gap between high and low watermarks. With the default
910914
// quota, there's not enough "headroom" left after base memory usage to
911915
// populate vbs as desired.
912-
increaseQuota(2100000);
916+
increaseQuota(2200000);
913917

914918
auto& stats = engine->getEpStats();
915919

916920
auto watermarkDiff = stats.mem_high_wat.load() - stats.mem_low_wat.load();
917921

922+
// starting above the low water mark would mean that the replica pageable
923+
// memory will definitely not exceed the watermarkdiff when the high
924+
// watermark is reached.
925+
ASSERT_LT(stats.getPreciseTotalMemoryUsed(), stats.mem_low_wat.load());
926+
918927
// populate the replica vbs until its evictable memory _exceeds_ the gap
919928
// between the high and low water mark. When the mem usage later passes the
920929
// high water mark, evicting from the replica should reclaim enough memory.
@@ -934,8 +943,10 @@ TEST_P(STItemPagerTest, ReplicaEvictedBeforeActive) {
934943
// replicas, their total pageable memory must be at least the
935944
// watermark diff + a small excess to account for the final
936945
// inserted item _passing_ the high watermark.
937-
return pageableMem > watermarkDiff * 1.1;
946+
return pageableMem > watermarkDiff + 10000;
938947
});
948+
flushAndRemoveCheckpoints(replicaVBs[0]);
949+
flushAndRemoveCheckpoints(replicaVBs[1]);
939950

940951
// We don't care exactly how many were stored, just that it is a
941952
// "large enough" number for percentages to be somewhat useful
@@ -944,6 +955,20 @@ TEST_P(STItemPagerTest, ReplicaEvictedBeforeActive) {
944955
// Now fill the active VB until the high watermark is reached
945956
auto activeItemCount =
946957
populateVbsUntil(activeVBs, [&stats, &store = store] {
958+
return stats.getPreciseTotalMemoryUsed() >
959+
stats.mem_high_wat.load();
960+
});
961+
962+
flushAndRemoveCheckpoints(activeVBs[0]);
963+
flushAndRemoveCheckpoints(activeVBs[1]);
964+
965+
// Flushing and removing checkpoints frees some memory, "top up" the
966+
// active vbuckets back to the high watermark.
967+
activeItemCount += populateVbsUntil(
968+
activeVBs,
969+
[this, &stats, &activeVBs] {
970+
flushAndRemoveCheckpoints(activeVBs[0]);
971+
flushAndRemoveCheckpoints(activeVBs[1]);
947972
bool readyToEvict = stats.getPreciseTotalMemoryUsed() >
948973
stats.mem_high_wat.load();
949974
if (readyToEvict) {
@@ -954,7 +979,8 @@ TEST_P(STItemPagerTest, ReplicaEvictedBeforeActive) {
954979
store->attemptToFreeMemory();
955980
}
956981
return readyToEvict;
957-
});
982+
},
983+
"topup_keys");
958984

959985
EXPECT_GT(activeItemCount, 100);
960986

@@ -983,11 +1009,11 @@ TEST_P(STItemPagerTest, ReplicaEvictedBeforeActive) {
9831009
<< vbid << " not fully resident after eviction";
9841010
}
9851011
// Confirm the replica RR is "low"
986-
// the replica RR could be constrained further (around 5%) but checking
987-
// it is below 10% to avoid making the test too sensitive to small
1012+
// the replica RR could be constrained further, but checking
1013+
// it is below 20% to avoid making the test too sensitive to small
9881014
// changes in base memory usage.
9891015
for (const auto vbid : replicaVBs) {
990-
EXPECT_LT(getRRPercent(*store->getVBucket(vbid)), 10)
1016+
EXPECT_LT(getRRPercent(*store->getVBucket(vbid)), 20)
9911017
<< vbid << " has residency higher than expected";
9921018
}
9931019
}
@@ -1017,28 +1043,36 @@ TEST_P(STItemPagerTest, ActiveEvictedIfReplicaEvictionInsufficient) {
10171043
// Set replicaVB as active initially (so we can populate it).
10181044
setVBucketStateAndRunPersistTask(replicaVB, vbucket_state_active);
10191045

1020-
// We need total evictable data to comfortably exceed the gap between
1021-
// high and low watermarks. With the default quota, there's not enough
1022-
// "headroom" left after base memory usage to populate vbs as desired.
1023-
increaseQuota(1200000);
1024-
auto quota = engine->getConfiguration().getMaxSize();
1025-
1026-
// Set the water marks to 80% and 85%
1027-
engine->getConfiguration().setMemLowWat(quota * 0.80);
1028-
engine->getConfiguration().setMemHighWat(quota * 0.85);
1046+
// bump the quota up. We need total evictable data to comfortably exceed
1047+
// the gap between high and low watermarks. With the default
1048+
// quota, there's not enough "headroom" left after base memory usage to
1049+
// populate vbs as desired.
1050+
increaseQuota(20000000);
10291051

10301052
auto& stats = engine->getEpStats();
10311053

1032-
auto targetReplicaMem =
1033-
stats.getPreciseTotalMemoryUsed() +
1034-
double(stats.mem_high_wat.load() - stats.mem_low_wat.load()) * 0.9;
1054+
auto watermarkDiff = stats.mem_high_wat.load() - stats.mem_low_wat.load();
1055+
1056+
// starting above the low water mark would mean that the replica pageable
1057+
// memory will definitely not exceed the watermarkdiff when the high
1058+
// watermark is reached.
1059+
ASSERT_LT(stats.getPreciseTotalMemoryUsed(), stats.mem_low_wat.load());
10351060

10361061
// store items in the replica vb such that evicting everything in the
10371062
// replica when at the high watermark will _not_ reach the low watermark
1038-
auto replicaItemCount =
1039-
populateVbsUntil({replicaVB}, [&stats, targetReplicaMem] {
1040-
return stats.getPreciseTotalMemoryUsed() >= targetReplicaMem;
1063+
auto replicaItemCount = populateVbsUntil(
1064+
{replicaVB}, [&stats, &store = store, replicaVB, watermarkDiff] {
1065+
// sanity check - if this fails the quota is too low -
1066+
EXPECT_LT(stats.getPreciseTotalMemoryUsed(),
1067+
stats.mem_high_wat.load());
1068+
1069+
size_t pageableMem =
1070+
store->getVBucket(replicaVB)->getPageableMemUsage();
1071+
1072+
return pageableMem > watermarkDiff * 0.8;
10411073
});
1074+
flushAndRemoveCheckpoints(replicaVB);
1075+
10421076
setVBucketStateAndRunPersistTask(replicaVB, vbucket_state_replica);
10431077

10441078
// We don't care exactly how many were stored, just that it is a
@@ -1048,6 +1082,18 @@ TEST_P(STItemPagerTest, ActiveEvictedIfReplicaEvictionInsufficient) {
10481082
// Now fill the active VB until the high watermark is reached
10491083
auto activeItemCount =
10501084
populateVbsUntil({activeVB}, [&stats, &store = store] {
1085+
return stats.getPreciseTotalMemoryUsed() >
1086+
stats.mem_high_wat.load();
1087+
});
1088+
1089+
flushAndRemoveCheckpoints(activeVB);
1090+
1091+
// Flushing and removing checkpoints frees some memory, "top up" the
1092+
// active vbuckets back to the high watermark.
1093+
activeItemCount += populateVbsUntil(
1094+
{activeVB},
1095+
[this, &stats, &activeVB] {
1096+
flushAndRemoveCheckpoints(activeVB);
10511097
bool readyToEvict = stats.getPreciseTotalMemoryUsed() >
10521098
stats.mem_high_wat.load();
10531099
if (readyToEvict) {
@@ -1058,7 +1104,8 @@ TEST_P(STItemPagerTest, ActiveEvictedIfReplicaEvictionInsufficient) {
10581104
store->attemptToFreeMemory();
10591105
}
10601106
return readyToEvict;
1061-
});
1107+
},
1108+
"topup_keys");
10621109

10631110
EXPECT_GT(activeItemCount, 100);
10641111

0 commit comments

Comments
 (0)