From 1a39d6f29df207131316fc5e4f70f11ba9d96db5 Mon Sep 17 00:00:00 2001 From: Filip Leonarski Date: Sun, 8 Nov 2026 09:55:42 +0100 Subject: [PATCH] Tests: live stills with the image buffer full during the pre-pass Forty frames are all there before the pre-pass ends, with twelve slots in the image buffer. The collection does not deadlock and the end message goes out. The frames that found no free slot are not written; the collection reports them: images_collected stays at forty, images_sent (in the status and in the end message) counts only the frames written and analysed, and the writer-queue-full warning is set exactly when frames were lost. Efficiency stays 1.0, as every frame was received. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01HVeDQsU5a8AJUdJPgWevAK --- tests/JFJochReceiverRugnuxTest.cpp | 44 ++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/tests/JFJochReceiverRugnuxTest.cpp b/tests/JFJochReceiverRugnuxTest.cpp index 08b67257d..4acc7e11b 100644 --- a/tests/JFJochReceiverRugnuxTest.cpp +++ b/tests/JFJochReceiverRugnuxTest.cpp @@ -543,6 +543,50 @@ TEST_CASE("JFJochReceiverRugnux_Stills_ZMQWriterDown", "[JFJochReceiverRugnux]") REQUIRE_NOTHROW(writer_future.get()); } +TEST_CASE("JFJochReceiverRugnux_Stills_BufferFullDuringPrePass", "[JFJochReceiverRugnux]") { + // Forty frames, all there before the pre-pass ends, and twelve slots in the image buffer. + Logger logger(Catch::getResultCapture().getCurrentTestName()); + RegisterHDF5Filter(); + + const int64_t images = 40; + DiffractionExperiment x = StillsExperiment(images); + PixelMask mask(x); + Stream stream(x, images); + stream.Frames(0, images); + stream.End(); + + const size_t buffer_MiB = 12 * x.GetImageBufferLocationSize() / (1024 * 1024) + 1; + + RecordingPusher pusher; + AcquisitionDeviceGroup group; + JFJochReceiverService service(group, logger, pusher, buffer_MiB); + service.NumThreads(2); + service.Indexing(x.GetIndexingSettings()); + service.RugnuxLive(true, nullptr, 4, 60); + + service.Start(x, mask, nullptr, stream.puller); + const auto out = service.Stop(); + + // No deadlock, and the end message goes out. + CHECK(!out.status.cancelled); + CHECK(pusher.Events() == std::vector{"start", "image", "end"}); + + // A frame that finds no free slot is not written, and the collection says so. + CHECK(out.status.images_collected == images); + CHECK(out.efficiency == 1.0f); + CHECK(out.writer_queue_full_warning == (out.status.images_sent < images)); + CHECK(out.scan_result.images.size() == out.status.images_sent); + REQUIRE(pusher.End()); + CHECK(pusher.End()->images_collected_count == images); + CHECK(pusher.End()->images_sent_to_write_count == out.status.images_sent); + CHECK(pusher.Images().size() == out.status.images_sent); + + const auto live = service.GetRugnuxStatus(); + CHECK(live.state == RugnuxLiveState::Done); + REQUIRE(live.stills); + CHECK(live.stills->images_analysed == out.status.images_sent); +} + TEST_CASE("JFJochReceiverRugnux_Rotation", "[JFJochReceiverRugnux]") { // A scan stays with rugnux's own run: the start message goes out at once, and there are no stills results. Logger logger(Catch::getResultCapture().getCurrentTestName());