test: cover testChunkPipeline

This commit is contained in:
dualfroz committed 2026-09-11 14:23:15 +02:00
1 parent 2ad3e95a33
commit 38891ba723
1 file changed
+122
+122
View File
@@ -152,3 +152,125 @@ VF_TEST(readyChunksLandInTheCachePinnedInsideTheRadius) {
ChunkPipeline pipeline(baseConfig(4));
primePipeline(pipeline);
CHECK_EQ(pipeline.cache().size(), pipeline.results().size());
for (const ChunkTaskResult& produced : pipeline.results()) {
CHECK(pipeline.cache().contains(produced.coord));
CHECK(pipeline.cache().isPinned(produced.coord));
Chunk cached;
CHECK(pipeline.cache().peekChunk(produced.coord, cached));
CHECK_EQ(std::memcmp(cached.raw().data(), produced.chunk.raw().data(), chunkVolume), 0);
}
CHECK(pipeline.cache().bytesUsed() > 0);
CHECK_EQ(pipeline.cache().bytesUsed(), pipeline.stats().cachedBytes);
}
VF_TEST(pipelineStatsCountEveryStageAndCancellation) {
ChunkPipeline pipeline(baseConfig(4));
primePipeline(pipeline);
PipelineStats counted = pipeline.stats();
std::uint64_t ready = static_cast<std::uint64_t>(pipeline.results().size());
CHECK_EQ(counted.chunksReady, ready);
CHECK_EQ(counted.cancelled, static_cast<std::uint64_t>(0));
for (int stage = 0; stage < chunkStageCount; ++stage) {
CHECK_EQ(counted.stageCompleted[static_cast<std::size_t>(stage)], ready);
CHECK(counted.averageStageMs(static_cast<ChunkStage>(stage)) >= 0.0);
}
CHECK(counted.stageNanos[static_cast<std::size_t>(ChunkStage::Mesh)] > 0);
pipeline.resetStats();
CHECK_EQ(pipeline.stats().chunksReady, static_cast<std::uint64_t>(0));
}
VF_TEST(nearChunksOutrankFarOnesInThePendingQueue) {
PipelineConfig config = baseConfig(0);
config.viewRadius = 6;
config.verticalChunks = 1;
ChunkPipeline pipeline(config);
pipeline.setObserver({0, 0, 0});
pipeline.enqueueViewVolume();
std::vector<ChunkTask> tasks = pipeline.pendingTasks();
CHECK(tasks.size() > 20);
CHECK(tasks.front().coord == (Vec3i{0, 0, 0}));
CHECK(tasks.front().priority == JobPriority::High);
CHECK(tasks.back().priority == JobPriority::Low);
for (std::size_t i = 1; i < tasks.size(); ++i) {
CHECK(tasks[i - 1].distanceSq <= tasks[i].distanceSq);
CHECK(static_cast<int>(tasks[i - 1].priority) <= static_cast<int>(tasks[i].priority));
CHECK(tasks[i].inRange);
}
}
VF_TEST(pipelineBlocksMatchDirectWorldGenOutput) {
ChunkPipeline pipeline(baseConfig(8));
primePipeline(pipeline);
WorldGen reference(pipeline.settings().gen);
int compared = 0;
for (const ChunkTaskResult& produced : pipeline.results()) {
Chunk expected;
reference.generateChunk(expected, produced.coord);
CHECK_EQ(std::memcmp(expected.raw().data(), produced.chunk.raw().data(), chunkVolume), 0);
const Chunk* resident = pipeline.worldView().chunkAt(produced.coord);
CHECK(resident != nullptr);
CHECK_EQ(std::memcmp(expected.raw().data(), resident->raw().data(), chunkVolume), 0);
++compared;
}
CHECK(compared > 0);
CHECK(!pipeline.worldView().chunkAt({0, 0, 0})->empty());
}
VF_TEST(pipelineMeshMatchesDirectLitMeshing) {
ChunkPipeline pipeline(baseConfig(8));
primePipeline(pipeline);
const Vec3i probe{0, 1, 0};
const ChunkTaskResult* produced = pipeline.resultFor(probe);
CHECK(produced != nullptr);
Vec3i origin{probe.x * chunkSize - 1, probe.y * chunkSize - 1, probe.z * chunkSize - 1};
Vec3i dims{chunkSize + 2, chunkSize + 2, chunkSize + 2};
LightField expectedLight = computeLight(pipeline.worldView(), origin, dims);
CHECK_EQ(expectedLight.sun.size(), produced->light.sun.size());
CHECK_EQ(std::memcmp(expectedLight.sun.data(), produced->light.sun.data(),
expectedLight.sun.size()),
0);
CHECK_EQ(std::memcmp(expectedLight.block.data(), produced->light.block.data(),
expectedLight.block.size()),
0);
ChunkMesh expectedMesh = meshChunkLit(pipeline.worldView(), probe, expectedLight);
CHECK(sameMesh(expectedMesh.opaque, produced->mesh.opaque));
CHECK(sameMesh(expectedMesh.transparent, produced->mesh.transparent));
CHECK(!produced->mesh.opaque.empty());
}
VF_TEST(pipelineDrivesItsWorkThroughTheJobSystem) {
ChunkPipeline pipeline(baseConfig(4));
primePipeline(pipeline);
JobStats counted = pipeline.jobSystem().stats();
std::uint64_t nodes = static_cast<std::uint64_t>(pipeline.results().size()) * chunkStageCount;
CHECK_EQ(counted.executed, nodes);
CHECK_EQ(counted.submitted, nodes);
CHECK_EQ(counted.failed, static_cast<std::uint64_t>(0));
CHECK(counted.peakBusyWorkers >= 1u);
CHECK(counted.peakBusyWorkers <= 4u);
}
VF_TEST(secondRunAfterMovingTheObserverUnpinsWhatLeftTheRadius) {
ChunkPipeline pipeline(baseConfig(4));
primePipeline(pipeline);
const Vec3i edge{-2, 0, 0};
CHECK(pipeline.cache().isPinned(edge));
pipeline.setObserver({4, 0, 0});
pipeline.enqueueViewVolume();
pipeline.run();
CHECK(!pipeline.inViewVolume(edge));
CHECK(pipeline.cache().contains(edge));
CHECK(!pipeline.cache().isPinned(edge));
CHECK(pipeline.cache().isPinned({4, 0, 0}));
}