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
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:
+12
-2
@@ -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)
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
Reference in New Issue
Block a user