test: extend coverage of testRegionCompact

This commit is contained in:
dualfroz committed 2026-09-12 20:01:28 +02:00
1 parent 65523d4755
commit 2e636110ef
1 file changed
+107
+107
View File
@@ -315,3 +315,110 @@ VF_TEST(repackingWithCompressionShrinksTheFileAndStillReadsBack) {
CHECK(out.size() < buffer.size()); CHECK(out.size() < buffer.size());
CHECK(isCanonicalSaveLayout(out.data(), out.size())); CHECK(isCanonicalSaveLayout(out.data(), out.size()));
SaveContainer reloaded;
CHECK(readSaveContainer(out.data(), out.size(), reloaded));
CHECK_EQ(reloaded.chunks.size(), static_cast<std::size_t>(3));
for (const SaveChunkRecord& original : container.chunks) {
const SaveChunkRecord* back = reloaded.find(original.coord);
CHECK(back != nullptr);
if (back == nullptr) continue;
for (std::size_t i = 0; i < original.blocks.raw().size(); ++i)
CHECK(original.blocks.raw()[i] == back->blocks.raw()[i]);
CHECK(original.light == back->light);
CHECK_EQ(original.meta.generationStage, back->meta.generationStage);
}
SaveScanner scanner;
CHECK(scanner.scan(out).clean());
}
VF_TEST(compactionRefusesAContainerTheScannerCallsDamaged) {
ByteBuffer buffer = writeSaveContainer(uniformContainer(3));
SaveHeader header;
CHECK(readSaveHeader(buffer.data(), buffer.size(), header));
std::vector<SaveTableEntry> entries;
CHECK(readSaveTable(buffer.data(), buffer.size(), header, entries));
std::size_t payloadAt = static_cast<std::size_t>(entries[1].sectorOffset) * header.sectorBytes;
saveWriteU32At(buffer.data(), buffer.size(), payloadAt + 8, 0u);
RegionCompactor compactor;
ByteBuffer out;
CompactionStats stats;
CHECK(!compactor.compact(buffer, out, stats));
CHECK(!stats.ok);
CHECK(stats.failure.find("integrity") != std::string::npos);
CHECK(out.empty());
}
VF_TEST(compactionAndRepairCooperateOnADamagedFragmentedContainer) {
ByteBuffer buffer = writeSaveContainer(uniformContainer(4));
CHECK(updateChunkInPlace(buffer, buildRecord(Vec3i{2, 0, 0}, busyChunk(6)), false));
SaveHeader header;
CHECK(readSaveHeader(buffer.data(), buffer.size(), header));
std::vector<SaveTableEntry> entries;
CHECK(readSaveTable(buffer.data(), buffer.size(), header, entries));
std::size_t payloadAt = static_cast<std::size_t>(entries[0].sectorOffset) * header.sectorBytes;
saveWriteU32At(buffer.data(), buffer.size(), payloadAt + 8, 0u);
RegionCompactor compactor;
ByteBuffer refused;
CompactionStats refusedStats;
CHECK(!compactor.compact(buffer, refused, refusedStats));
SaveScanner scanner;
RepairResult repaired = scanner.scanAndRepair(buffer);
CHECK(repaired.ok);
CHECK_EQ(repaired.chunksDropped, static_cast<std::size_t>(1));
ByteBuffer out;
CompactionStats stats;
CHECK(compactor.compact(repaired.output, out, stats));
CHECK(stats.ok);
CHECK_EQ(stats.fragmentationAfter, 0);
CHECK(isCanonicalSaveLayout(out.data(), out.size()));
}
VF_TEST(inPlaceUpdateRefusesAChunkThatIsNotInTheTable) {
ByteBuffer buffer = writeSaveContainer(uniformContainer(2));
ByteBuffer untouched = buffer;
CHECK(!updateChunkInPlace(buffer, buildRecord(Vec3i{9, 0, 0}, uniformChunk(Block::Sand)),
false));
CHECK(buffer == untouched);
ByteBuffer rubbish(40, 0);
CHECK(!updateChunkInPlace(rubbish, buildRecord(Vec3i{0, 0, 0}, uniformChunk(Block::Sand)),
false));
}
VF_TEST(inPlaceUpdateKeepsTheContainerReadableAndChecksummed) {
ByteBuffer buffer = writeSaveContainer(uniformContainer(3));
CHECK(updateChunkInPlace(buffer, buildRecord(Vec3i{1, 0, 0}, busyChunk(21)), true));
SaveScanner scanner;
CHECK(scanner.scan(buffer).clean());
SaveContainer reloaded;
CHECK(readSaveContainer(buffer.data(), buffer.size(), reloaded));
const SaveChunkRecord* updated = reloaded.find({1, 0, 0});
CHECK(updated != nullptr);
if (updated == nullptr) return;
Chunk expected = busyChunk(21);
for (std::size_t i = 0; i < expected.raw().size(); ++i)
CHECK(expected.raw()[i] == updated->blocks.raw()[i]);
}
VF_TEST(surveyAndFragmentationRejectBuffersThatAreNotContainers) {
RegionCompactor compactor;
ByteBuffer rubbish(500, 0x7F);
CHECK(compactor.survey(rubbish).empty());
CHECK_EQ(compactor.fragmentationPercent(rubbish), -1);
ByteBuffer stump(4, 0);
CHECK(compactor.survey(stump).empty());
CHECK_EQ(compactor.fragmentationPercent(stump), -1);
ByteBuffer out;
CompactionStats stats;
CHECK(!compactor.compact(rubbish, out, stats));
CHECK(stats.failure.find("readable save container") != std::string::npos);
}