enospc tests (not sure how useful)
Build Packages / build:rpm (rocky8_nocuda) (push) Successful in 9m14s
Build Packages / build:rpm (ubuntu2204_nocuda) (push) Successful in 8m23s
Build Packages / build:rpm (rocky9_nocuda) (push) Successful in 10m12s
Build Packages / build:rpm (ubuntu2404_nocuda) (push) Successful in 7m38s
Build Packages / build:rpm (rocky8_sls9) (push) Successful in 9m50s
Build Packages / build:rpm (rocky9_sls9) (push) Successful in 9m28s
Build Packages / build:rpm (rocky8) (push) Successful in 10m14s
Build Packages / build:rpm (ubuntu2204) (push) Successful in 9m54s
Build Packages / build:rpm (rocky9) (push) Successful in 11m41s
Build Packages / Generate python client (push) Successful in 24s
Build Packages / build:rpm (ubuntu2404) (push) Successful in 9m16s
Build Packages / Build documentation (push) Successful in 59s
Build Packages / Create release (push) Has been skipped
Build Packages / XDS test (durin plugin) (push) Successful in 8m2s
Build Packages / XDS test (JFJoch plugin) (push) Successful in 7m14s
Build Packages / DIALS test (push) Successful in 11m57s
Build Packages / XDS test (neggia plugin) (push) Successful in 8m10s
Build Packages / Unit tests (push) Successful in 56m13s

This commit is contained in:
2026-05-05 16:08:23 +02:00
parent cae8577c85
commit 2dc9a043be
3 changed files with 209 additions and 2 deletions
+12 -2
View File
@@ -69,6 +69,16 @@ ADD_EXECUTABLE(jfjoch_test
XDSPluginTest.cpp
)
target_link_libraries(jfjoch_test Catch2WithMain JFJochBroker JFJochReceiver JFJochReader JFJochWriter JFJochImageAnalysis JFJochCommon JFJochHLSSimulation JFJochPreview
jfjoch_xds_plugin)
target_link_libraries(jfjoch_test Catch2WithMain JFJochBroker JFJochReceiver JFJochReader JFJochWriter
JFJochImageAnalysis JFJochCommon JFJochHLSSimulation JFJochPreview
jfjoch_xds_plugin)
target_include_directories(jfjoch_test PRIVATE .)
find_package(Threads REQUIRED)
add_library(enospc_shim MODULE enospc_shim.c)
target_link_libraries(enospc_shim PRIVATE Threads::Threads dl)
set_target_properties(enospc_shim PROPERTIES PREFIX "" POSITION_INDEPENDENT_CODE ON) # remove "lib"
ADD_EXECUTABLE(jfjoch_hdf5_enospc_test jfjoch_hdf5_enospc_test.cpp)
target_link_libraries(jfjoch_hdf5_enospc_test Catch2WithMain JFJochWriter)
+153
View File
@@ -0,0 +1,153 @@
// SPDX-FileCopyrightText: 2024 Filip Leonarski, Paul Scherrer Institute <filip.leonarski@psi.ch>
// SPDX-License-Identifier: GPL-3.0-only
#define _GNU_SOURCE
#include <dlfcn.h>
#include <errno.h>
#include <unistd.h>
#include <sys/uio.h>
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
// Function pointers to real syscalls
static ssize_t (*real_pwrite64) (int, const void *, size_t, __off64_t) = NULL;
// State
static size_t total_written = 0;
static size_t fail_after = 0;
// Thread safety (important in real tests)
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
// Initialize real symbols and config
__attribute__((constructor))
static void init(void) {
real_pwrite64 = dlsym(RTLD_NEXT, "pwrite64");
const char* env = getenv("ENOSPC_AFTER");
if (env) {
fail_after = strtoull(env, NULL, 10);
} else {
fail_after = 10ULL * 1024 * 1024; // default: 10 MB
}
printf("ENOSPC shim loaded with limit %lu bytes\n", fail_after);
}
/*
// Common helper
static int should_fail(size_t upcoming) {
if (fail_after == 0) return 0;
if (total_written >= fail_after) return 1;
if (total_written + upcoming > fail_after) {
// Simulate partial write exhaustion:
// allow some bytes, then next call fails
return 0;
}
return 0;
}
// ---- write ----
ssize_t write(int fd, const void *buf, size_t count) {
pthread_mutex_lock(&lock);
printf("write %lu bytes\n", count);
if (total_written >= fail_after) {
pthread_mutex_unlock(&lock);
errno = ENOSPC;
return -1;
}
pthread_mutex_unlock(&lock);
ssize_t ret = real_write(fd, buf, count);
if (ret > 0) {
pthread_mutex_lock(&lock);
total_written += ret;
pthread_mutex_unlock(&lock);
}
return ret;
}
// ---- pwrite ----
ssize_t pwrite(int fd, const void *buf, size_t count, off_t offset) {
pthread_mutex_lock(&lock);
printf("pwrite %lu bytes\n", count);
if (total_written >= fail_after) {
pthread_mutex_unlock(&lock);
errno = ENOSPC;
return -1;
}
pthread_mutex_unlock(&lock);
ssize_t ret = real_pwrite(fd, buf, count, offset);
if (ret > 0) {
pthread_mutex_lock(&lock);
total_written += ret;
pthread_mutex_unlock(&lock);
}
return ret;
}
// ---- writev ----
ssize_t writev(int fd, const struct iovec *iov, int iovcnt) {
size_t total = 0;
for (int i = 0; i < iovcnt; i++) {
total += iov[i].iov_len;
}
printf("writev %lu bytes\n", total);
pthread_mutex_lock(&lock);
if (total_written >= fail_after) {
pthread_mutex_unlock(&lock);
errno = ENOSPC;
return -1;
}
pthread_mutex_unlock(&lock);
ssize_t ret = real_writev(fd, iov, iovcnt);
if (ret > 0) {
pthread_mutex_lock(&lock);
total_written += ret;
pthread_mutex_unlock(&lock);
}
pwrite64()
return ret;
} */
ssize_t pwrite64(int fd, const void *buf, size_t count, off_t offset) {
pthread_mutex_lock(&lock);
printf("pwrite64 %lu bytes\n", count);
if (total_written >= fail_after) {
pthread_mutex_unlock(&lock);
errno = ENOSPC;
return -1;
}
pthread_mutex_unlock(&lock);
ssize_t ret = real_pwrite64(fd, buf, count, offset);
if (ret > 0) {
pthread_mutex_lock(&lock);
total_written += ret;
pthread_mutex_unlock(&lock);
}
return ret;
}
+44
View File
@@ -0,0 +1,44 @@
// SPDX-FileCopyrightText: 2026 Filip Leonarski, Paul Scherrer Institute <filip.leonarski@psi.ch>
// SPDX-License-Identifier: GPL-3.0-only
// Run with LD_PRELOAD=enospc_shim.so ./jfjoch_hdf5_enospc_test
#include <catch2/catch_all.hpp>
#include "../writer/HDF5Objects.h"
#include "../writer/FileWriter.h"
#include "../common/DiffractionExperiment.h"
TEST_CASE("HDF5File_enospc") {
auto file = std::make_unique<HDF5File>("enospc_test.h5");
std::vector<uint8_t> small_vector(2056), large_vector(40 * 1024 * 1024);
REQUIRE_NOTHROW(file->SaveVector("/small", small_vector));
REQUIRE_NOTHROW(file->SaveVector("/large1", large_vector));
REQUIRE_THROWS(file->SaveVector("/large2", large_vector));
REQUIRE_NOTHROW(file.reset());
}
TEST_CASE("FileWriter_enospc") {
{
RegisterHDF5Filter();
DiffractionExperiment x(DetJF4M());
x.FilePrefix("test02_1p10").ImagesPerTrigger(5).ImagesPerFile(2).Compression(CompressionAlgorithm::NO_COMPRESSION);
StartMessage start_message;
x.FillMessage(start_message);
FileWriter file_set(start_message);
std::vector<uint16_t> image(x.GetPixelsNum());
DataMessage message{};
message.image = CompressedImage(image, x.GetXPixelsNum(), x.GetYPixelsNum());
message.number = 0;
REQUIRE_NOTHROW(file_set.Write(message));
message.number = 1;
REQUIRE_THROWS(file_set.Write(message));
message.number = 2;
REQUIRE_THROWS(file_set.Write(message));
}
// No leftover HDF5 objects
REQUIRE (H5Fget_obj_count(H5F_OBJ_ALL, H5F_OBJ_ALL) == 0);
}