Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions .github/workflows/freebsd.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: FreeBSD

on:
pull_request:
types:
- opened
- synchronize
- reopened
- ready_for_review
push:
branches: [master]
workflow_dispatch:

jobs:
test:
name: FreeBSD
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- name: Build and test
uses: vmactions/freebsd-vm@v1
with:
mem: 12288
copyback: false
cache-after-prepare: true
prepare: |
./ci/freebsd/prepare.sh
run: |
./ci/freebsd/build-and-test.sh
2 changes: 1 addition & 1 deletion SConstruct
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ else:
# check _mm_crc32_u64 (SSE4.2) support:
conf.check_mm_crc32_u64()

if IS_CLANG := any(cc in os.path.basename(conf.env['CC']) for cc in ('clang', 'include-what-you-use')):
if IS_CLANG := conf.CheckDeclaration("__clang__"):
conf.env.Append(CCFLAGS=['-fcolor-diagnostics']) # Colored warnings
conf.env.Append(CCFLAGS=['-Qunused-arguments']) # Hide wrong messages
conf.env.Append(CCFLAGS=['-Wno-bad-function-cast'])
Expand Down
14 changes: 14 additions & 0 deletions ci/freebsd/build-and-test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/bin/sh
set -eu

cd "$(dirname "$0")/../.."
echo "==> $(freebsd-version) $(uname -m), $(sysctl -n hw.ncpu) cpus, $(pwd)"

scons_ARGS="VERBOSE=1 DEBUG=1 O=release"
scons config $scons_ARGS
scons $scons_ARGS

mount -t tmpfs none /rt
RM_TS_DIR=/rt pytest -m "not slow"

echo "==> tests passed"
21 changes: 21 additions & 0 deletions ci/freebsd/prepare.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/bin/sh
set -eu

cd "$(dirname "$0")/../.."
export ASSUME_ALWAYS_YES=yes

PACKAGES="rsync git py312-sphinx"
PACKAGES_BUILD="scons-py312 pkgconf glib json-glib libblkid gettext py312-py-cpuinfo"
PACKAGES_TEST="bash dash py312-pip"

echo "==> pkg install: $PACKAGES"

pkg install -y $PACKAGES
pkg install -y $PACKAGES_BUILD
pkg install -y $PACKAGES_TEST
pip install -r tests/requirements.txt
pip install -r docs/requirements.txt

mkdir /rt

echo "==> prepare done"
2 changes: 1 addition & 1 deletion docs/testing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Testsuite
complete yet (and probably never will), but it's already a valuable boost of
confidence in ``rmlint's`` correctness.

The tests are based on ``pytest`` and are written in ``python>=3.6``.
The tests are based on ``pytest`` and are written in ``python>=3.9``.
Every testcase just runs the (previously built) ``rmlint`` binary a
and parses its json output. So they are technically blackbox-tests.

Expand Down
6 changes: 3 additions & 3 deletions lib/cmdline.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,13 +76,13 @@ static void rm_cmd_show_version(void) {
fprintf(stderr, " %c%s", (features[i].enabled) ? '+' : '-', features[i].name);
}

fprintf(stderr, RESET "\n\n");
fputs("\n\n", stderr);
fprintf(stderr, _("rmlint was written by Christopher <sahib> Pahl and Daniel "
"<SeeSpotRun> Thomas."));
fprintf(stderr, "\n");
fputc('\n', stderr);
fprintf(stderr, _("The code at https://github.com/sahib/rmlint is licensed under the "
"terms of the GPLv3."));
fprintf(stderr, "\n");
fputc('\n', stderr);
exit(0);
}

Expand Down
10 changes: 5 additions & 5 deletions lib/utilities.c
Original file line number Diff line number Diff line change
Expand Up @@ -689,7 +689,7 @@ static gchar rm_mounts_is_rotational_blockdev(const char *dev) {
fclose(sys_fdes);
#else
(void)dev;
#endif
#endif /* HAVE_SYSBLOCK */

return is_rotational;
}
Expand Down Expand Up @@ -1012,7 +1012,7 @@ void rm_mounts_table_destroy(RmMountTable *self) {
g_slice_free(RmMountTable, self);
}

#else /* probably FreeBSD */
#else

RmMountTable *rm_mounts_table_new(_UNUSED bool force_fiemap) {
return NULL;
Expand Down Expand Up @@ -1105,7 +1105,7 @@ dev_t rm_mounts_get_disk_id(RmMountTable *self, _UNUSED dev_t dev,
(void)dev;
(void)path;
return 0;
#endif
#endif /* RM_MOUNTTABLE_IS_USABLE */
}

dev_t rm_mounts_get_disk_id_by_path(RmMountTable *self, const char *path) {
Expand Down Expand Up @@ -1290,7 +1290,7 @@ RmOff rm_offset_get_from_path(const char *path, RmOff file_offset,
return result;
}

#else /* Probably FreeBSD */
#else /* FreeBSD */

RmOff rm_offset_get_from_fd(_UNUSED int fd, _UNUSED RmOff file_offset,
_UNUSED RmOff *file_offset_next, _UNUSED RmOff *logical_offset,
Expand All @@ -1303,7 +1303,7 @@ RmOff rm_offset_get_from_path(_UNUSED const char *path, _UNUSED RmOff file_offse
return 0;
}

#endif
#endif /* HAVE_FIEMAP */

static gboolean rm_util_is_path_double(const char *path1, const char *path2) {
const char *basename1 = rm_util_basename(path1);
Expand Down
9 changes: 6 additions & 3 deletions site_scons/rm_build_checks.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,12 @@
def check_pkgconfig(context, version):
context.Message('Checking for pkg-config... ')
command = PKG_CONFIG + ' --atleast-pkgconfig-version=' + version
ret = context.TryAction(command)[0]
context.Result(ret)
return ret
rc, _ = context.TryAction(command)
if not rc:
print("Error: pkg-config not found (or too old).")
Exit(1)
context.Result(rc)
return rc


def check_pkg(context, name, varname, required=True):
Expand Down
5 changes: 3 additions & 2 deletions tests/test_formatters/test_sh.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@ def run_shell_script(shell, sh_path, *args):

return subprocess.check_output(
[shell_path, sh_path] + list(args),
shell=False
).decode("utf-8")
shell=False,
text=True
)


def filter_part_of_directory(data):
Expand Down
5 changes: 5 additions & 0 deletions tests/test_mains/test_is_reflink.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,15 @@
create_file,
create_link,
get_testdir,
has_feature,
run_rmlint,
run_rmlint_once,
)

if not has_feature('fiemap'):
pytest.skip("rmlint was compiled without fiemap support",
allow_module_level=True)


def check_is_reflink_status(status_code, *paths):
with assert_exit_code(status_code):
Expand Down
25 changes: 16 additions & 9 deletions tests/test_robustness/test_manylongpathfiles.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,32 @@
import os

import pytest

from tests.utils import create_dirs, create_file, run_rmlint
from tests.utils import create_dirs, create_file, get_testdir, run_rmlint


@pytest.mark.slow
def test_manylongpathfiles():
path_max = os.pathconf(get_testdir(), "PC_PATH_MAX")
path_max = path_max if 0 < path_max <= 1024 else 1024
prefix = os.path.abspath(get_testdir()) + os.sep
budget = path_max - len(prefix) - 12

# four equally-sized path components, up to min(1024, PATH_MAX)
component_len = (budget - 4) // 4
component = "l" * component_len
longpath = (component + "/") * 4

#create ~1000 character path, 4 dirs deep
longpath = ("long" * (1000//4//4) + "/") * 4
create_dirs(longpath)

# create heaps of identical files:
numfiles = 1024 * 32 + 1
for i in range(numfiles):
create_file('xxx', longpath + 'file' + str(i).zfill(7))
create_file("xxx", longpath + f"file{i:07d}")

# create heaps of identical pairs:
numpairs = 1024 * 32 + 1
for i in range(numpairs):
create_file(str(i), longpath + 'a' + str(i).zfill(7))
create_file(str(i), longpath + 'b' + str(i).zfill(7))
create_file(str(i), longpath + f"a{i:07d}")
create_file(str(i), longpath + f"b{i:07d}")

_, *data, _ = run_rmlint('')
_, *data, _ = run_rmlint("")
assert len(data) == numfiles + numpairs * 2
36 changes: 28 additions & 8 deletions tests/test_types/test_baduids.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,36 @@
import subprocess
import sys

import pytest

from tests.utils import create_file, get_testdir, run_rmlint, runs_as_root

RMLINT_DUMMY_GROUP = '__rmlint_dummy_group'
RMLINT_DUMMY_USER = '__rmlint_dummy_user'

if sys.platform.startswith('linux'):
ADD_ID_CMDS = (
'groupadd {g}',
'useradd -M -N {u}',
)
DEL_ID_CMDS = (
'userdel -r {u}',
'groupdel {g}',
)
elif sys.platform.startswith('freebsd'):
ADD_ID_CMDS = (
'pw groupadd -n {g}',
'pw useradd -n {u}',
)
DEL_ID_CMDS = (
'pw userdel -n {u}',
'pw groupdel -n {g}',
)
else:
ADD_ID_CMDS = DEL_ID_CMDS = None
pytest.skip(f"uid/gid: {sys.platform} not implemented/supported",
allow_module_level=True)


def exec_cmds(cmds):
for cmd in cmds:
Expand All @@ -24,10 +50,7 @@ def test_bad_ids():
if not runs_as_root():
return

exec_cmds([
'groupadd {g}',
'useradd -M -N {u}',
])
exec_cmds(ADD_ID_CMDS)

try:
create_file('x', '1_bad_uid')
Expand All @@ -40,10 +63,7 @@ def test_bad_ids():
'chown {u}:{g} {t}/3_bad_gid_and_uid'
])
finally:
exec_cmds([
'userdel -r {u}',
'groupdel {g}'
])
exec_cmds(DEL_ID_CMDS)

_, *data, footer = run_rmlint('-S a')

Expand Down
4 changes: 2 additions & 2 deletions tests/test_types/test_duplicate.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from tests.utils import create_dirs, create_file, create_link, get_testdir, run_rmlint, use_valgrind
from tests.utils import create_dirs, create_file, create_link, get_env_flag, get_testdir, run_rmlint


def test_small_diffs():
Expand All @@ -8,7 +8,7 @@ def create_data(length, flips=()):
data[flip] = '1'
return ''.join(data)

if use_valgrind():
if get_env_flag('use_valgrind'):
size = 32
else:
# Takes horribly long elsewhise
Expand Down
2 changes: 1 addition & 1 deletion tests/test_types/test_nonstripped.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def create_binary(path, stripped=False):
full_path = os.path.join(get_testdir(), path)

command = '{cc} -o {path} {option} -std=c99 -xc -'.format(
cc=os.environ.get('CC', 'gcc'), path=full_path, option='-s' if stripped else '-ggdb3',
cc=os.environ.get('CC', 'cc'), path=full_path, option='-s' if stripped else '-g3',
)
subprocess.run(command, input=SOURCE, shell=True, text=True, check=True)

Expand Down
Loading