Compare commits

...

4 commits

Author SHA1 Message Date
CismonX
ffa28a4091
test: fetch prng seed from environment variable
Tests that require PRNG are by default seeded from `/dev/urandom`.
However, the user should be able to override with a given seed
to reproduce a failing test.

Instead of messing with command-line arguments, a cleaner approach
is to fetch the seed from an environment variable.
2025-06-19 16:51:35 +08:00
CismonX
6c38779e78
prng: debug-print seed if fetched from getrandom() 2025-06-19 16:49:41 +08:00
CismonX
72d55ed68f
test: do not skip test if a backend is disabled
For `ATX_CHECK_FS()` and `ATX_CHECK_FS_NEW()`, do not skip the test
if a backend (or its "-write" feature) is disabled, since
`exit 77` skips the entire test group, not current `AT_CHECK()`.

Instead, silently pass the current test.
2025-06-19 08:02:03 +08:00
CismonX
dad1984d7f
build: move bookmarkfs_util.pc.in to ./src
Whatever pkg-config is interested in all lies within ./src.
2025-06-18 16:13:07 +08:00
18 changed files with 47 additions and 83 deletions

View file

@ -8,5 +8,3 @@
ACLOCAL_AMFLAGS = -I m4 ACLOCAL_AMFLAGS = -I m4
SUBDIRS = doc src tests SUBDIRS = doc src tests
pkgconfig_DATA = bookmarkfs_util.pc

View file

@ -9,7 +9,7 @@ dnl
AC_PREREQ([2.70]) AC_PREREQ([2.70])
AC_INIT([bookmarkfs], [0.1.2], [bug-bookmarkfs@nongnu.org]) AC_INIT([bookmarkfs], [0.1.2], [bug-bookmarkfs@nongnu.org])
AC_CONFIG_SRCDIR([bookmarkfs_util.pc.in]) AC_CONFIG_SRCDIR([src/bookmarkfs_util.pc.in])
AC_CONFIG_HEADERS([config.h]) AC_CONFIG_HEADERS([config.h])
AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_TESTDIR([tests]) AC_CONFIG_TESTDIR([tests])
@ -175,8 +175,7 @@ AC_DEFINE([BUILDING_BOOKMARKFS], [1], [Define to 1 if building BookmarkFS.])
AC_CONFIG_FILES([ AC_CONFIG_FILES([
Makefile Makefile
doc/Makefile doc/Makefile
src/Makefile src/Makefile src/bookmarkfs_util.pc
tests/Makefile tests/atlocal tests/Makefile tests/atlocal
bookmarkfs_util.pc
]) ])
AC_OUTPUT AC_OUTPUT

View file

@ -13,6 +13,7 @@ noinst_HEADERS = backend_util.h db.h defs.h frontend_util.h fs_ops.h \
xattr.h xstd.h xattr.h xstd.h
lib_LTLIBRARIES = lib_LTLIBRARIES =
pkglib_LTLIBRARIES = pkglib_LTLIBRARIES =
pkgconfig_DATA = bookmarkfs_util.pc
BASE_CPPFLAGS_ = BASE_CPPFLAGS_ =
if NO_FILE_NAME if NO_FILE_NAME

View file

@ -29,6 +29,7 @@
#include "prng.h" #include "prng.h"
#include <errno.h> #include <errno.h>
#include <inttypes.h>
#include <string.h> #include <string.h>
#include <sys/random.h> #include <sys/random.h>
@ -89,5 +90,8 @@ prng_seed (
// as many bytes as requested. // as many bytes as requested.
// This is guaranteed on both Linux and FreeBSD. // This is guaranteed on both Linux and FreeBSD.
debug_assert(nbytes == sizeof(state)); debug_assert(nbytes == sizeof(state));
debug_printf("prng seed: "
"%016" PRIx64 "%016" PRIx64 "%016" PRIx64 "%016" PRIx64,
state[0], state[1], state[2], state[3]);
return 0; return 0;
} }

View file

@ -239,18 +239,13 @@ check_fs_dents (
int argc, int argc,
char *argv[] char *argv[]
) { ) {
char const *seed = NULL;
int n = -1; int n = -1;
OPT_START(argc, argv, "n:s:") OPT_START(argc, argv, "n:")
OPT_OPT('n') { OPT_OPT('n') {
n = atoi(optarg); n = atoi(optarg);
break; break;
} }
OPT_OPT('s') {
seed = optarg;
break;
}
OPT_END OPT_END
if (n <= 0) { if (n <= 0) {
@ -263,7 +258,7 @@ check_fs_dents (
} }
char const *path = argv[0]; char const *path = argv[0];
if (0 != prng_seed_from_hex(seed)) { if (0 != prng_seed_from_env()) {
return -1; return -1;
} }
int dirfd = open(path, O_RDONLY | O_DIRECTORY); int dirfd = open(path, O_RDONLY | O_DIRECTORY);

View file

@ -167,18 +167,13 @@ check_fs_regrw (
int argc, int argc,
char *argv[] char *argv[]
) { ) {
char const *seed = NULL;
int file_max = -1; int file_max = -1;
OPT_START(argc, argv, "n:s:") OPT_START(argc, argv, "n:")
OPT_OPT('n') { OPT_OPT('n') {
file_max = atoi(optarg); file_max = atoi(optarg);
break; break;
} }
OPT_OPT('s') {
seed = optarg;
break;
}
OPT_END OPT_END
if (file_max <= 0 || file_max % sizeof(uint64_t) != 0) { if (file_max <= 0 || file_max % sizeof(uint64_t) != 0) {
@ -191,7 +186,7 @@ check_fs_regrw (
} }
char const *path = argv[0]; char const *path = argv[0];
if (0 != prng_seed_from_hex(seed)) { if (0 != prng_seed_from_env()) {
return -1; return -1;
} }
return do_check_fs_regrw(path, file_max); return do_check_fs_regrw(path, file_max);

View file

@ -160,18 +160,13 @@ check_fs_times (
int argc, int argc,
char *argv[] char *argv[]
) { ) {
char const *seed = NULL;
int rounds = -1; int rounds = -1;
OPT_START(argc, argv, "r:s:") OPT_START(argc, argv, "r:")
OPT_OPT('r') { OPT_OPT('r') {
rounds = atoi(optarg); rounds = atoi(optarg);
break; break;
} }
OPT_OPT('s') {
seed = optarg;
break;
}
OPT_END OPT_END
if (rounds < 0) { if (rounds < 0) {
@ -184,7 +179,7 @@ check_fs_times (
} }
char const *path = argv[0]; char const *path = argv[0];
if (0 != prng_seed_from_hex(seed)) { if (0 != prng_seed_from_env()) {
return -1; return -1;
} }
int dirfd = open(path, O_RDONLY | O_DIRECTORY); int dirfd = open(path, O_RDONLY | O_DIRECTORY);

View file

@ -168,15 +168,10 @@ check_hashmap (
int argc, int argc,
char *argv[] char *argv[]
) { ) {
char const *seed = NULL;
int size_exp = -1; int size_exp = -1;
int rounds = -1; int rounds = -1;
OPT_START(argc, argv, "s:n:r:") OPT_START(argc, argv, "n:r:")
OPT_OPT('s') {
seed = optarg;
break;
}
OPT_OPT('n') { OPT_OPT('n') {
size_exp = atoi(optarg); size_exp = atoi(optarg);
break; break;
@ -196,7 +191,7 @@ check_hashmap (
return -1; return -1;
} }
if (0 != prng_seed_from_hex(seed)) { if (0 != prng_seed_from_env()) {
return -1; return -1;
} }
return do_check_hashmap(1u << size_exp, rounds); return do_check_hashmap(1u << size_exp, rounds);

View file

@ -104,21 +104,16 @@ subcmd_prng (
int argc, int argc,
char *argv[] char *argv[]
) { ) {
char const *seed = NULL;
int n = 0; int n = 0;
OPT_START(argc, argv, "s:n:") OPT_START(argc, argv, "n:")
OPT_OPT('s') {
seed = optarg;
break;
}
OPT_OPT('n') { OPT_OPT('n') {
n = atoi(optarg); n = atoi(optarg);
break; break;
} }
OPT_END OPT_END
if (0 != prng_seed_from_hex(seed)) { if (0 != prng_seed_from_env()) {
return -1; return -1;
} }
for (; n > 0; --n) { for (; n > 0; --n) {

View file

@ -26,25 +26,25 @@
#include <inttypes.h> #include <inttypes.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include "prng.h" #include "prng.h"
int int
prng_seed_from_hex ( prng_seed_from_env (void)
char const *str {
) { char const *seed_str = getenv("BOOKMARKFS_TEST_PRNG_SEED");
uint64_t buf[4], *seed = NULL; if (seed_str == NULL) {
return prng_seed(NULL);
}
if (str != NULL) { uint64_t seed[4];
int cnt = sscanf(str, int cnt = sscanf(seed_str,
"%16" SCNx64 "%16" SCNx64 "%16" SCNx64 "%16" SCNx64, "%16" SCNx64 "%16" SCNx64 "%16" SCNx64 "%16" SCNx64,
&buf[0], &buf[1], &buf[2], &buf[3]); &seed[0], &seed[1], &seed[2], &seed[3]);
if (cnt != 4) { if (cnt != 4) {
log_puts("bad prng seed"); log_puts("bad prng seed");
return -1; return -1;
} }
seed = buf;
log_printf("prng seed: '%s'", str);
}
return prng_seed(seed); return prng_seed(seed);
} }

View file

@ -72,8 +72,6 @@ check_watcher (
); );
int int
prng_seed_from_hex ( prng_seed_from_env (void);
char const *str
);
#endif /* !defined(BOOKMARKFS_CHECK_UTIL_H_) */ #endif /* !defined(BOOKMARKFS_CHECK_UTIL_H_) */

View file

@ -13,11 +13,10 @@ AT_KEYWORDS([fs dents])
ATX_CHECK_FS_NEW_ANY(, , [ ATX_CHECK_FS_NEW_ANY(, , [
ATX_RUN_REPEAT([8], [ ATX_RUN_REPEAT([8], [
name=$(ath_fn_rand_u64_hex) name=$(ath_fn_rand_u64_hex)
seed=$(ath_fn_prng_seed)
mkdir $name mkdir $name
ATX_RUN([ ATX_RUN([
check-fs dents -n 1024 -s "$seed" $name check-fs dents -n 1024 $name
]) ])
]) ])
]) ])

View file

@ -12,10 +12,9 @@ AT_KEYWORDS([fs regrw])
ATX_CHECK_FS_NEW_ANY([file_max=524288], , [ ATX_CHECK_FS_NEW_ANY([file_max=524288], , [
name=$(ath_fn_rand_u64_hex) name=$(ath_fn_rand_u64_hex)
seed=$(ath_fn_prng_seed)
ATX_RUN([ ATX_RUN([
check-fs regrw -n 524288 -s "$seed" $name check-fs regrw -n 524288 $name
]) ])
]) ])

View file

@ -12,11 +12,10 @@ AT_KEYWORDS([fs times])
ATX_CHECK_FS_NEW_ANY(, , [ ATX_CHECK_FS_NEW_ANY(, , [
name=$(ath_fn_rand_u64_hex) name=$(ath_fn_rand_u64_hex)
seed=$(ath_fn_prng_seed)
mkdir $name mkdir $name
ATX_RUN([ ATX_RUN([
check-fs times -s "$seed" -r 512 $name check-fs times -r 512 $name
]) ])
]) ])

View file

@ -11,11 +11,6 @@ AT_SETUP([util lib: hashmap])
AT_KEYWORDS([lib hashmap]) AT_KEYWORDS([lib hashmap])
ATX_CHECK_LIB([ ATX_CHECK_LIB([
seed="${CHECK_HASHMAP_PRNG_SEED}"
if test -z "$seed"; then
seed=$(ath_fn_prng_seed)
fi
size="${CHECK_HASHMAP_DATA_SIZE}" size="${CHECK_HASHMAP_DATA_SIZE}"
if test -z "$size"; then if test -z "$size"; then
# Requires at least 128 MiB of memory on a 64-bit platform. # Requires at least 128 MiB of memory on a 64-bit platform.
@ -28,7 +23,7 @@ ATX_CHECK_LIB([
fi fi
ATX_RUN([ ATX_RUN([
check-util-lib hashmap -s "$seed" -n "$size" -r "$rounds" check-util-lib hashmap -n "$size" -r "$rounds"
]) ])
]) ])

View file

@ -15,11 +15,15 @@ AT_KEYWORDS([lib prng])
# For reliable testing of PRNGs, see <https://prng.di.unimi.it/#quality>. # For reliable testing of PRNGs, see <https://prng.di.unimi.it/#quality>.
ATX_CHECK_LIB([ ATX_CHECK_LIB([
gen_num() { gen_num() {
check-util-lib prng -s$1 -n$2 env BOOKMARKFS_TEST_PRNG_SEED=$1 check-util-lib prng -n$2
} }
ATX_RUN_REPEAT([16], [ repeat=1
seed=$(ath_fn_prng_seed) if test -z "$BOOKMARKFS_TEST_PRNG_SEED"; then
repeat=16
fi
ATX_RUN_REPEAT([$repeat], [
seed=$(check-util-lib prng -n4 | tr -d '\n')
count=32 count=32
num_1=$(gen_num $seed $count) num_1=$(gen_num $seed $count)

View file

@ -125,8 +125,9 @@ dnl Check for a BookmarkFS filesystem.
dnl dnl
m4_define([ATX_CHECK_FS], [ m4_define([ATX_CHECK_FS], [
ATX_CHECK_SIMPLE([ ATX_CHECK_SIMPLE([
ATX_FEAT_PREREQ([bookmarkfs-mount], [backend-$1]) ATX_FEAT_PREREQ([bookmarkfs-mount])
$5 $5
ATX_FEAT_IF([backend-$1], , [exit])
"$buildsrcdir/mount.bookmarkfs" -F \ "$buildsrcdir/mount.bookmarkfs" -F \
-o "backend=ATX_OPT_MODULE([backend_$1])" \ -o "backend=ATX_OPT_MODULE([backend_$1])" \
-o "fsname=check-$1,no_sandbox,$2" \ -o "fsname=check-$1,no_sandbox,$2" \
@ -153,8 +154,9 @@ dnl created with mkfs.bookmarkfs.
dnl dnl
m4_define([ATX_CHECK_FS_NEW], [ m4_define([ATX_CHECK_FS_NEW], [
ATX_CHECK_FS([$1], [rw,$2], [bookmarks-$1], [$3], [ ATX_CHECK_FS([$1], [rw,$2], [bookmarks-$1], [$3], [
ATX_FEAT_PREREQ([bookmarkfs-mkfs], [backend-$1-write]) ATX_FEAT_PREREQ([bookmarkfs-mkfs])
$4 $4
ATX_FEAT_IF([backend-$1-write], , [exit])
"$buildsrcdir/mkfs.bookmarkfs" \ "$buildsrcdir/mkfs.bookmarkfs" \
-o "backend=ATX_OPT_MODULE([backend_$1]),force" \ -o "backend=ATX_OPT_MODULE([backend_$1]),force" \
"bookmarks-$1" || exit 1 "bookmarks-$1" || exit 1
@ -197,15 +199,6 @@ AT_TEST_HELPER_FN([rand_base64], , , [
echo $(head -c$1 /dev/urandom | base64 -w0) echo $(head -c$1 /dev/urandom | base64 -w0)
]) ])
AT_TEST_HELPER_FN([prng_seed], , , [
seed_1=$(ath_fn_rand_u64_hex)
seed_2=$(ath_fn_rand_u64_hex)
seed_3=$(ath_fn_rand_u64_hex)
seed_4=$(ath_fn_rand_u64_hex)
echo $seed_1$seed_2$seed_3$seed_4
])
dnl -- Test groups -- dnl -- Test groups --
AT_BANNER([The Utility Library]) AT_BANNER([The Utility Library])