Skip to content

Commit d3b343e

Browse files
committed
Add tests for eviction iter reset when eviction disabled
1 parent 9b3ce7b commit d3b343e

File tree

2 files changed

+120
-55
lines changed

2 files changed

+120
-55
lines changed

src/bucket/SearchableBucketList.cpp

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -51,15 +51,6 @@ SearchableLiveBucketListSnapshot::scanForEviction(
5151
auto startIter = evictionIter;
5252
auto scanSize = sas.evictionScanSize;
5353

54-
// exit scan early if there's nothing to scan. We still need to call
55-
// `updateStartingEvictionIterator` before exiting early in case the
56-
// underlying bucket has changed, since even when scanning is disabled, it's
57-
// important to maintain a valid iterator.
58-
if (scanSize == 0)
59-
{
60-
return result;
61-
}
62-
6354
for (;;)
6455
{
6556
auto const& b = getBucketFromIter(evictionIter);

src/bucket/test/BucketListTests.cpp

Lines changed: 120 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1550,61 +1550,135 @@ TEST_CASE_VERSIONS("eviction scan", "[bucketlist][archival][soroban]")
15501550
closeLedger(*app);
15511551
}
15521552

1553-
updateStateArchivalSettings(
1554-
[&](StateArchivalSettings& sa) {
1555-
// Scan meta entry + one other entry in initial scan
1556-
sa.evictionScanSize = metadataSize + 1;
1557-
// Reset eviction iter start of bucket being tested
1558-
sa.startingEvictionScanLevel = levelToTest;
1559-
},
1560-
[&](EvictionIterator& ei) {
1561-
ei.bucketFileOffset = 0;
1562-
ei.isCurrBucket = isCurr;
1563-
ei.bucketListLevel = 1;
1564-
});
1565-
1566-
// Advance until one ledger before bucket is updated
1567-
auto ledgersUntilUpdate =
1568-
LiveBucketList::bucketUpdatePeriod(levelToTest,
1569-
isCurr) -
1570-
1; // updateStateArchivalSettings closes a ledger that we
1571-
// need to count
1572-
REQUIRE(ledgersUntilUpdate >= 1);
1573-
for (uint32_t i = 0; i < ledgersUntilUpdate - 1; ++i)
1574-
{
1575-
auto startingIter = evictionIter();
1553+
auto f = [&](bool disableEviction) {
1554+
updateStateArchivalSettings(
1555+
[&](StateArchivalSettings& sa) {
1556+
// Scan meta entry + one other entry in initial
1557+
// scan, or disable scan entirely
1558+
sa.evictionScanSize =
1559+
disableEviction ? 0 : metadataSize + 1;
1560+
// Reset eviction iter start of bucket being tested
1561+
sa.startingEvictionScanLevel = levelToTest;
1562+
},
1563+
[&](EvictionIterator& ei) {
1564+
// If scanning is enabled, reset iterator to the
1565+
// start. Otherwise, set the iterator to some
1566+
// arbitrary location so we can see if it was
1567+
// changed properly.
1568+
ei.bucketFileOffset = disableEviction ? 10 : 0;
1569+
ei.isCurrBucket = isCurr;
1570+
ei.bucketListLevel = 1;
1571+
});
1572+
1573+
// Advance until one ledger before bucket is updated
1574+
auto ledgersUntilUpdate =
1575+
LiveBucketList::bucketUpdatePeriod(levelToTest,
1576+
isCurr) -
1577+
1; // updateStateArchivalSettings closes a ledger that
1578+
// we need to count
1579+
REQUIRE(ledgersUntilUpdate >= 1);
1580+
for (uint32_t i = 0; i < ledgersUntilUpdate - 1; ++i)
1581+
{
1582+
auto startingIter = evictionIter();
1583+
closeLedger(*app);
1584+
++ledgerSeq;
1585+
1586+
if (disableEviction)
1587+
{
1588+
// Make sure scan doesn't advance iterator when
1589+
// disabled
1590+
REQUIRE(evictionIter() == startingIter);
1591+
}
1592+
else
1593+
{
1594+
// Check that iterator is making progress correctly
1595+
REQUIRE(evictionIter().bucketFileOffset >
1596+
startingIter.bucketFileOffset);
1597+
REQUIRE(evictionIter().bucketListLevel ==
1598+
levelToTest);
1599+
REQUIRE(evictionIter().isCurrBucket == isCurr);
1600+
}
1601+
}
1602+
1603+
auto iterBeforeBucketChange = evictionIter();
1604+
1605+
// Next ledger close should update bucket
1606+
auto startingHash = bucket()->getHash();
1607+
closeLedger(*app);
1608+
++ledgerSeq;
1609+
1610+
// Check that bucket actually changed
1611+
REQUIRE(bucket()->getHash() != startingHash);
1612+
1613+
// The iterator retroactively checks if the Bucket has
1614+
// changed, so close one additional ledger to check if the
1615+
// iterator has reset. This is due to the scan using a
1616+
// BucketList snapshot of the lcl ledger.
15761617
closeLedger(*app);
15771618
++ledgerSeq;
15781619

1579-
// Check that iterator is making progress correctly
1580-
REQUIRE(evictionIter().bucketFileOffset >
1581-
startingIter.bucketFileOffset);
1620+
LiveBucketInputIterator in(bucket());
1621+
1622+
// Check that iterator has reset to beginning of bucket
1623+
if (disableEviction)
1624+
{
1625+
REQUIRE(evictionIter().bucketFileOffset == 0);
1626+
}
1627+
else
1628+
{
1629+
// If scan is enabled, we should reset then scan the
1630+
// first entry (not including meta)
1631+
REQUIRE(evictionIter().bucketFileOffset ==
1632+
metadataSize + xdr::xdr_size(*in) +
1633+
xdrOverheadBytes);
1634+
}
15821635
REQUIRE(evictionIter().bucketListLevel == levelToTest);
15831636
REQUIRE(evictionIter().isCurrBucket == isCurr);
1584-
}
15851637

1586-
// Next ledger close should update bucket
1587-
auto startingHash = bucket()->getHash();
1588-
closeLedger(*app);
1589-
++ledgerSeq;
1638+
// Check that the iterator actually changed
1639+
REQUIRE(!(iterBeforeBucketChange == evictionIter()));
15901640

1591-
// Check that bucket actually changed
1592-
REQUIRE(bucket()->getHash() != startingHash);
1593-
1594-
// The iterator retroactively checks if the Bucket has
1595-
// changed, so close one additional ledger to check if the
1596-
// iterator has reset
1597-
closeLedger(*app);
1598-
++ledgerSeq;
1641+
// If eviction was disabled, re-enable it and verify we
1642+
// start making progress again
1643+
if (disableEviction)
1644+
{
1645+
// Re-enable eviction scan
1646+
updateStateArchivalSettings(
1647+
[&](StateArchivalSettings& sa) {
1648+
sa.evictionScanSize = metadataSize + 1;
1649+
},
1650+
[](EvictionIterator&) {
1651+
// Don't modify iterator, let it continue from
1652+
// where it reset to
1653+
});
1654+
1655+
// Close a few ledgers and verify iterator advances
1656+
for (uint32_t i = 0; i < 2; ++i)
1657+
{
1658+
auto prevIter = evictionIter();
1659+
closeLedger(*app);
1660+
++ledgerSeq;
1661+
1662+
// Iterator should be making progress now that
1663+
// eviction is re-enabled
1664+
REQUIRE(evictionIter().bucketFileOffset >
1665+
prevIter.bucketFileOffset);
1666+
REQUIRE(evictionIter().bucketListLevel ==
1667+
levelToTest);
1668+
REQUIRE(evictionIter().isCurrBucket == isCurr);
1669+
}
1670+
}
1671+
};
15991672

1600-
LiveBucketInputIterator in(bucket());
1673+
SECTION("eviction disabled")
1674+
{
1675+
f(true);
1676+
}
16011677

1602-
// Check that iterator has reset to beginning of bucket and
1603-
// read meta entry + one additional entry
1604-
REQUIRE(evictionIter().bucketFileOffset ==
1605-
metadataSize + xdr::xdr_size(*in) + xdrOverheadBytes);
1606-
REQUIRE(evictionIter().bucketListLevel == levelToTest);
1607-
REQUIRE(evictionIter().isCurrBucket == isCurr);
1678+
SECTION("eviction enabled")
1679+
{
1680+
f(false);
1681+
}
16081682
};
16091683

16101684
SECTION("curr bucket")

0 commit comments

Comments
 (0)