mirror of
https://git.sr.ht/~cismonx/bookmarkfs
synced 2025-06-07 11:48:51 +00:00
test: add test harness for filesystem
This commit is contained in:
parent
9da346753d
commit
44100f8852
4 changed files with 229 additions and 0 deletions
|
@ -25,6 +25,13 @@ if BOOKMARKFS_UTIL
|
|||
check_hashmap.c
|
||||
endif # BOOKMARKFS_UTIL
|
||||
|
||||
if BOOKMARKFS_MOUNT
|
||||
check_PROGRAMS += check-fs
|
||||
|
||||
check_fs_CPPFLAGS = -I$(top_srcdir)/src
|
||||
check_fs_SOURCES = check_fs.c
|
||||
endif # BOOKMARKFS_MOUNT
|
||||
|
||||
# Autotest setup
|
||||
|
||||
AUTOTEST = $(AUTOM4TE) --language=autotest
|
||||
|
|
|
@ -6,6 +6,11 @@
|
|||
# this notice are preserved. This file is offered as-is, without any warranty.
|
||||
#
|
||||
|
||||
# -- Paths --
|
||||
top_builddir="@abs_top_builddir@"
|
||||
buildsrcdir="$top_builddir/src"
|
||||
|
||||
# -- Features --
|
||||
@BOOKMARKFS_UTIL_TRUE@ feat_bookmarkfs_util=y
|
||||
@BOOKMARKCTL_TRUE@ feat_bookmarkctl=y
|
||||
@BOOKMARKFS_FSCK_TRUE@ feat_bookmarkfs_fsck=y
|
||||
|
|
145
tests/check_fs.c
Normal file
145
tests/check_fs.c
Normal file
|
@ -0,0 +1,145 @@
|
|||
/**
|
||||
* bookmarkfs/tests/check_fs.c
|
||||
* ----
|
||||
*
|
||||
* Copyright (C) 2025 CismonX <admin@cismon.net>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "frontend_util.h"
|
||||
|
||||
// Forward declaration start
|
||||
static int dispatch_subcmds (int, char *[]);
|
||||
static int subcmd_ismount (int, char *[]);
|
||||
static int subcmd_sleep (int, char *[]);
|
||||
// Forward declaration end
|
||||
|
||||
static int
|
||||
dispatch_subcmds (
|
||||
int argc,
|
||||
char *argv[]
|
||||
) {
|
||||
if (--argc < 1) {
|
||||
log_puts("subcmd not given");
|
||||
return -1;
|
||||
}
|
||||
char const *cmd = *(++argv);
|
||||
|
||||
int status = -1;
|
||||
if (0 == strcmp("ismount", cmd)) {
|
||||
status = subcmd_ismount(argc, argv);
|
||||
} else if (0 == strcmp("sleep", cmd)) {
|
||||
status = subcmd_sleep(argc, argv);
|
||||
} else {
|
||||
log_printf("bad subcmd '%s'", cmd);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
static int
|
||||
subcmd_ismount (
|
||||
int argc,
|
||||
char *argv[]
|
||||
) {
|
||||
if (--argc < 1) {
|
||||
log_puts("path not given");
|
||||
return -1;
|
||||
}
|
||||
char const *path = *(++argv);
|
||||
|
||||
int flags = O_RDONLY | O_DIRECTORY;
|
||||
#ifdef O_PATH
|
||||
flags |= O_PATH;
|
||||
#endif
|
||||
int fd = open(path, flags);
|
||||
if (fd < 0) {
|
||||
log_printf("open: %s: %s", path, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
int status = -1;
|
||||
|
||||
struct stat stat_buf;
|
||||
if (0 != fstat(fd, &stat_buf)) {
|
||||
log_printf("fstat(): %s", strerror(errno));
|
||||
goto end;
|
||||
}
|
||||
dev_t dev = stat_buf.st_dev;
|
||||
|
||||
if (0 != fstatat(fd, "..", &stat_buf, 0)) {
|
||||
log_printf("fstatat(): %s", strerror(errno));
|
||||
goto end;
|
||||
}
|
||||
if (dev != stat_buf.st_dev) {
|
||||
status = 0;
|
||||
}
|
||||
|
||||
end:
|
||||
close(fd);
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sleep milliseconds.
|
||||
*
|
||||
* This sub-command exists because we cannot portably do so in POSIX shell.
|
||||
*/
|
||||
static int
|
||||
subcmd_sleep (
|
||||
int argc,
|
||||
char *argv[]
|
||||
) {
|
||||
if (--argc < 1) {
|
||||
log_puts("duration not given");
|
||||
return -1;
|
||||
}
|
||||
char const *duration = *(++argv);
|
||||
|
||||
int millis = atoi(duration);
|
||||
if (millis <= 0) {
|
||||
log_printf("bad duration %d", millis);
|
||||
return -1;
|
||||
}
|
||||
struct timespec ts = {
|
||||
.tv_sec = millis / 1000,
|
||||
.tv_nsec = (millis % 1000) * 1000000
|
||||
};
|
||||
return clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, NULL);
|
||||
}
|
||||
|
||||
int
|
||||
main (
|
||||
int argc,
|
||||
char *argv[]
|
||||
) {
|
||||
int status = EXIT_FAILURE;
|
||||
if (0 != dispatch_subcmds(argc, argv)) {
|
||||
goto end;
|
||||
}
|
||||
status = EXIT_SUCCESS;
|
||||
|
||||
end:
|
||||
return status;
|
||||
}
|
|
@ -16,6 +16,14 @@ dnl Repeat string n times.
|
|||
dnl
|
||||
m4_define([ATX_REPEAT], [m4_for([unused_], [1], [$1], , [$2])])
|
||||
|
||||
dnl
|
||||
dnl ATX_OPT_MODULE(name)
|
||||
dnl
|
||||
dnl Expands to a string which can be used for `-o backend=NAME`
|
||||
dnl or `-o handler=NAME` options of a BookmarkFS program.
|
||||
dnl
|
||||
m4_define([ATX_OPT_MODULE], [$buildsrcdir/.libs/$1.so:bookmarkfs_$1])
|
||||
|
||||
dnl
|
||||
dnl ATX_FEAT_VAR(feature)
|
||||
dnl
|
||||
|
@ -63,6 +71,16 @@ m4_define([ATX_RUN_REPEAT], [
|
|||
done
|
||||
])
|
||||
|
||||
dnl
|
||||
dnl ATX_RUN_IN_DIR(pathname, script)
|
||||
dnl
|
||||
m4_define([ATX_RUN_IN_DIR], [
|
||||
atx_pwd=$(pwd)
|
||||
cd "$1" || exit 1
|
||||
$2
|
||||
cd "$atx_pwd"
|
||||
])
|
||||
|
||||
dnl
|
||||
dnl ATX_RUN_ONE(cmd)
|
||||
dnl
|
||||
|
@ -100,6 +118,60 @@ m4_define([ATX_CHECK_LIB], [
|
|||
])
|
||||
])
|
||||
|
||||
dnl
|
||||
dnl ATX_CHECK_FS(backend, [options], src, target, [prepare], [check])
|
||||
dnl
|
||||
dnl Check for a BookmarkFS filesystem.
|
||||
dnl
|
||||
m4_define([ATX_CHECK_FS], [
|
||||
ATX_CHECK_SIMPLE([
|
||||
ATX_FEAT_PREREQ([bookmarkfs-mount], [backend-$1])
|
||||
$5
|
||||
"$buildsrcdir/mount.bookmarkfs" -F \
|
||||
-o "backend=ATX_OPT_MODULE([backend_$1])" \
|
||||
-o "fsname=check-$1,no_sandbox,$2" \
|
||||
"$3" "$4" 2>mount.bookmarkfs.stderr &
|
||||
while ! check-fs ismount "$4"; do
|
||||
check-fs sleep 100
|
||||
if ! jobs %%; then
|
||||
echo 'fs daemon terminated unexpectedly'
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
$6
|
||||
], [
|
||||
umount "$4"
|
||||
])
|
||||
])
|
||||
|
||||
dnl
|
||||
dnl ATX_CHECK_FS_NEW(backend, [options], target, [check])
|
||||
dnl
|
||||
dnl Perform filesystem checks using a new bookmark storage
|
||||
dnl created with mkfs.bookmarkfs.
|
||||
dnl
|
||||
m4_define([ATX_CHECK_FS_NEW], [
|
||||
ATX_CHECK_FS([$1], [rw,$2], [bookmarks-$1], [$3], [
|
||||
ATX_FEAT_PREREQ([bookmarkfs-mkfs], [backend-$1-write])
|
||||
"$buildsrcdir/mkfs.bookmarkfs" \
|
||||
-o "backend=ATX_OPT_MODULE([backend_$1]),force" \
|
||||
"bookmarks-$1" || exit 1
|
||||
mkdir -p "$3"
|
||||
], [$4])
|
||||
])
|
||||
|
||||
dnl
|
||||
dnl ATX_CHECK_FS_NEW_ANY([options], [check])
|
||||
dnl
|
||||
m4_define([ATX_CHECK_FS_NEW_ANY], [
|
||||
ATX_CHECK_FS_NEW([firefox], [$1], [mnt.tmp], [
|
||||
ATX_RUN_IN_DIR([mnt.tmp/bookmarks/unfiled], [$2])
|
||||
])
|
||||
ATX_CHECK_FS_NEW([chromium], [$1], [mnt.tmp], [
|
||||
ATX_RUN_IN_DIR([mnt.tmp/bookmarks/Other bookmarks], [$2])
|
||||
])
|
||||
])
|
||||
|
||||
dnl -- Helper functions --
|
||||
|
||||
AT_TEST_HELPER_FN([rand_u64_hex], , , [
|
||||
|
|
Loading…
Add table
Reference in a new issue