Files
ternfs-XTXMarkets/ci.py
Francesco Mazzoli 01f9d5addf Improve FUSE, run all tests with it
The FUSE driver, up to now, had no way to know when the user had
"explicitly" closed a file. Instead it linked the TernFS file on
flush, which could cause nasty situation. The classic example
is a fork causing the FD to a TernFS file being present in the forked
process, and then the process dying causing a spurious flush.

This commit adds a way to detect when a flush is due to a close(),
which allows us to link the file only in the cases where that happened,
which is a much better heuristic and close to what we do in the kernel
module.

This commit also contains various other improvements to make all tests
pass under FUSE. The big remaining item is changing how files are read
(they're currently read all upfront and then kept in memory).
2025-09-18 18:09:43 +01:00

79 lines
4.4 KiB
Python
Executable File

#!/usr/bin/env python3
# Copyright 2025 XTX Markets Technologies Limited
#
# SPDX-License-Identifier: GPL-2.0-or-later
import os
import argparse
from common import *
parser = argparse.ArgumentParser()
parser.add_argument('--functional', action='store_true')
parser.add_argument('--integration', action='store_true')
parser.add_argument('--short', action='store_true')
parser.add_argument('--kmod', action='store_true')
parser.add_argument('--build', action='store_true')
parser.add_argument('--docker', action='store_true', help='Build and run in docker image')
parser.add_argument('--prepare-image', default=None, type=str, help='Build the kmod image given the provided base image')
parser.add_argument('--leader-only', action='store_true', help='Run only LogsDB leader with LEADER_NO_FOLLOWERS')
parser.add_argument('--close-tracker-object', default=None, type=str, help='Run fuse driver with the given close tracker object')
args = parser.parse_args()
script_dir = os.path.dirname(os.path.realpath(__file__))
os.chdir(script_dir)
if args.build:
bold_print('building')
for r in (['ubuntu', 'ubuntusanitized', 'ubuntuvalgrind'] if args.docker else ['release', 'sanitized', 'valgrind']):
wait_cmd(run_cmd(['./build.sh', r]))
wait_cmd(run_cmd(['make', 'bincode_tests'], cwd='kmod'))
if args.functional:
bold_print('functional tests')
if args.docker:
bold_print('starting functional tests in docker')
container = 'ghcr.io/xtxmarkets/ternfs-ubuntu-build:2025-09-18'
# See <https://groups.google.com/g/seastar-dev/c/r7W-Kqzy9O4>
# for motivation for `--security-opt seccomp=unconfined`,
# the `--pids-limit -1` is not something I hit but it seems
# like a good idea.
run_cmd_unbuffered(
['docker', 'run', '--pids-limit', '-1', '--security-opt', 'seccomp=unconfined', '--cap-add', 'SYS_ADMIN', '--privileged', '--rm', '-i', '--mount', f'type=bind,src={script_dir},dst={script_dir}', '-w', f'{script_dir}', '-e', f'UID={os.getuid()}', '-e', f'GID={os.getgid()}', container, './cpp/tests.sh']
)
run_cmd_unbuffered(
['docker', 'run', '--pids-limit', '-1', '--security-opt', 'seccomp=unconfined', '--cap-add', 'SYS_ADMIN', '--privileged', '--rm', '-i', '--mount', f'type=bind,src={script_dir},dst={script_dir}', '-w', f'{script_dir}/go', '-e', f'UID={os.getuid()}', '-e', f'GID={os.getgid()}', container, 'go', 'test', './...']
)
#run_cmd_unbuffered(
# ['docker', 'run', '--pids-limit', '-1', '--security-opt', 'seccomp=unconfined', '--cap-add', 'SYS_ADMIN', '-v', '/dev/fuse:/dev/fuse', '--privileged', '--rm', '-i', '--mount', f'type=bind,src={script_dir},dst={script_dir}', '-w', f'{script_dir}/kmod', '-e', f'UID={os.getuid()}', '-e', f'GID={os.getgid()}', container, './bincode_tests']
#)
# ToDo bincode_tests don't work in container mising libasan.so
wait_cmds(
[run_cmd(['./bincode_tests'], cwd='kmod')] + ([] if args.docker else [run_cmd(['./cpp/tests.sh']), run_cmd(['go', 'test', './...'], cwd='go')]),
)
if args.integration:
if args.docker:
bold_print('starting integration tests in docker')
container = 'ghcr.io/xtxmarkets/ternfs-ubuntu-build:2025-09-18'
# See <https://groups.google.com/g/seastar-dev/c/r7W-Kqzy9O4>
# for motivation for `--security-opt seccomp=unconfined`,
# the `--pids-limit -1` is not something I hit but it seems
# like a good idea.
run_cmd_unbuffered(
['docker', 'run', '--pids-limit', '-1', '--security-opt', 'seccomp=unconfined', '--cap-add', 'SYS_ADMIN', '-v', '/dev/fuse:/dev/fuse', '-v', '/sys/kernel:/sys/kernel', '--privileged', '--rm', '-i', '--mount', f'type=bind,src={script_dir},dst=/ternfs', '-e', f'UID={os.getuid()}', '-e', f'GID={os.getgid()}', container, '/ternfs/integration.py', '--docker'] + (['--short'] if args.short else []) + (['--leader-only'] if args.leader_only else []) + (['--close-tracker-object', args.close_tracker_object] if args.close_tracker_object else [])
)
else:
run_cmd_unbuffered(
['./integration.py'] + (['--short'] if args.short else []) + (['--leader-only'] if args.leader_only else [])
)
if args.prepare_image:
bold_print('prepare kmod image')
wait_cmd(run_cmd(['./kmod/ci_prepare.sh', args.prepare_image]))
if args.kmod:
bold_print('kmod tests')
wait_cmd(run_cmd(['./kmod/ci.sh'] + (['-short'] if args.short else []) + (['-leader-only'] if args.leader_only else [])))