From 0769dce63f81b9690624a945ee187caf414381cb Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Thu, 2 Apr 2026 00:05:59 +0200 Subject: [PATCH] More CI pipeline fixes - Use apt instead of apt-get - Use libgcrypt20-dev on Debian - Fix CFLAGS on macOS - Skip ATTR_DEALLOCATOR when using Clang to avoid warnings - Use tempfile.mkstemp() in test scripts - Don't explicitly specify MPC_FAMILY - Re-add forward-declarations of wrapped functions to avoid warnings --- .ci/deps.sh | 16 ++++----- .ci/package/deb/build.sh | 2 +- .github/workflows/test.yml | 8 ++--- src/have.h | 2 +- test/integration/cmd_sign_verify.py | 34 +++++++++---------- test/integration/device_fd.py | 2 +- test/integration/systemd.py | 2 +- test/integration/testlib/const.py | 3 -- test/integration/testlib/notification.py | 3 +- .../testlib/template/script.py.tpl | 3 +- test/integration/testlib/util.py | 6 ++-- test/unit/test_fs.c | 1 - test/unit/test_net.c | 4 +++ 13 files changed, 42 insertions(+), 44 deletions(-) diff --git a/.ci/deps.sh b/.ci/deps.sh index 9c35f07b..9cbd115f 100755 --- a/.ci/deps.sh +++ b/.ci/deps.sh @@ -18,7 +18,7 @@ deps_linux_alpine() { } deps_linux_debian_mingw() { - apt-get install -y \ + apt install -y \ mingw-w64 mingw-w64-tools \ wine wine-binfmt \ libgcrypt-mingw-w64-dev \ @@ -30,9 +30,9 @@ deps_linux_debian_linux() { dpkg --add-architecture "$HOST" fi - apt-get update + apt update - apt-get install -y \ + apt install -y \ binfmt-support binutils gcc make pkgconf \ zlib1g-dev:"$HOST" \ libssl-dev:"$HOST" \ @@ -40,7 +40,7 @@ deps_linux_debian_linux() { liblz4-dev:"$HOST" \ libncurses-dev:"$HOST" \ libreadline-dev:"$HOST" \ - libgcrypt-dev:"$HOST" \ + libgcrypt20-dev:"$HOST" \ libminiupnpc-dev:"$HOST" \ libvdeplug-dev:"$HOST" \ libcmocka-dev:"$HOST" \ @@ -48,16 +48,16 @@ deps_linux_debian_linux() { "$@" if [ -n "$HOST" ]; then - apt-get install -y crossbuild-essential-"$HOST" qemu-user + apt install -y crossbuild-essential-"$HOST" qemu-user fi } deps_linux_debian() { export DEBIAN_FRONTEND=noninteractive - apt-get update - apt-get upgrade -y - apt-get install -y git pkgconf sudo texinfo meson + apt update + apt upgrade -y + apt install -y git pkgconf sudo texinfo meson HOST=${HOST:-} if [ "$HOST" = mingw ]; then diff --git a/.ci/package/deb/build.sh b/.ci/package/deb/build.sh index 61396f1e..261375dc 100755 --- a/.ci/package/deb/build.sh +++ b/.ci/package/deb/build.sh @@ -15,7 +15,7 @@ find_tag() { export DEBIAN_FRONTEND=noninteractive -apt-get install -y devscripts git-buildpackage dh-make +apt install -y devscripts git-buildpackage dh-make export USER=${USER:-$(whoami)} export EMAIL=ci@tinc-vpn.org diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index c8741740..0e69f2f2 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -90,7 +90,7 @@ jobs: - name: Install tools run: | - sudo apt-get install -y astyle clang-tidy-$CLANG shellcheck shfmt black pylint mypy + sudo apt install -y astyle clang-tidy-$CLANG shellcheck shfmt black pylint mypy sudo update-alternatives --install /usr/bin/clang-tidy clang-tidy /usr/bin/clang-tidy-$CLANG 100 sudo update-alternatives --install /usr/bin/run-clang-tidy run-clang-tidy /usr/bin/run-clang-tidy-$CLANG 100 python3 -m venv /tmp/venv @@ -302,14 +302,14 @@ jobs: run: sh .ci/deps.sh - name: Run tests with default settings - run: CFLAGS=/opt/homebrew/include sh .ci/test/run.sh default + run: CFLAGS=-I/opt/homebrew/include sh .ci/test/run.sh default - name: Run tests without legacy protocol - run: CFLAGS=/opt/homebrew/include sh .ci/test/run.sh nolegacy + run: CFLAGS=-I/opt/homebrew/include sh .ci/test/run.sh nolegacy if: always() - name: Run tests with libgcrypt - run: CFLAGS=/opt/homebrew/include sh .ci/test/run.sh gcrypt + run: CFLAGS=-I/opt/homebrew/include sh .ci/test/run.sh gcrypt if: always() - name: Upload test results diff --git a/src/have.h b/src/have.h index a155b04b..186c5f7a 100644 --- a/src/have.h +++ b/src/have.h @@ -63,7 +63,7 @@ #endif #endif -#if defined(HAVE_ATTR_MALLOC_WITH_ARG) +#if defined(HAVE_ATTR_MALLOC_WITH_ARG) && !defined(__clang__) #define ATTR_DEALLOCATOR(dealloc) __attribute__((__malloc__(dealloc))) #else #define ATTR_DEALLOCATOR(dealloc) diff --git a/test/integration/cmd_sign_verify.py b/test/integration/cmd_sign_verify.py index 2e695990..e9677b78 100755 --- a/test/integration/cmd_sign_verify.py +++ b/test/integration/cmd_sign_verify.py @@ -28,9 +28,9 @@ fake testing data\n\ hello there\n\ """.encode("utf-8") -RAW_DATA = tempfile.mktemp() +raw_fd, raw_path = tempfile.mkstemp() -with open(RAW_DATA, "wb") as raw_file: +with os.fdopen(raw_fd, "wb") as raw_file: raw_file.write(util.random_string(64).encode("utf-8")) @@ -53,19 +53,19 @@ def test_sign_errors(foo: Tinc) -> None: check.is_in("Could not open", err) os.truncate(foo.sub("ed25519_key.priv"), 0) - _, err = foo.cmd("sign", RAW_DATA, code=1) + _, err = foo.cmd("sign", raw_path, code=1) check.is_in("Could not read private key from", err) os.remove(foo.sub("ed25519_key.priv")) - _, err = foo.cmd("sign", RAW_DATA, code=1) + _, err = foo.cmd("sign", raw_path, code=1) check.is_in("Could not open", err) def test_verify(foo: Tinc) -> None: """Test `verify` of data known to work.""" - signed_file = tempfile.mktemp() - with open(signed_file, "wb") as f: + fd, path = tempfile.mkstemp() + with os.fdopen(fd, "wb") as f: f.write(SIGNED_BYTES) foo.name = "foo" @@ -75,13 +75,13 @@ def test_verify(foo: Tinc) -> None: for name in ".", foo.name: foo.cmd("verify", name, stdin=SIGNED_BYTES) - foo.cmd("verify", name, signed_file) + foo.cmd("verify", name, path) if os.name != "nt": foo.cmd("verify", "*", stdin=SIGNED_BYTES) - foo.cmd("verify", "*", signed_file) + foo.cmd("verify", "*", path) - os.remove(signed_file) + os.remove(path) def test_verify_errors(foo: Tinc) -> None: @@ -129,30 +129,30 @@ def test_verify_errors(foo: Tinc) -> None: def test_sign_verify(foo: Tinc, bar: Tinc) -> None: """Test `sign` and pass its result to `verify`.""" - signed, _ = foo.cmd("sign", RAW_DATA, stdin=b"") + signed, _ = foo.cmd("sign", raw_path, stdin=b"") assert isinstance(signed, bytes) - signed_file = tempfile.mktemp() - with open(signed_file, "wb") as f: + fd, path = tempfile.mkstemp() + with os.fdopen(fd, "wb") as f: f.write(signed) for name in ".", foo.name: - foo.cmd("verify", name, signed_file) + foo.cmd("verify", name, path) foo.cmd("verify", name, stdin=signed) if os.name != "nt": - foo.cmd("verify", "*", signed_file) + foo.cmd("verify", "*", path) foo.cmd("verify", "*", stdin=signed) - os.remove(signed_file) + os.remove(path) cmd.exchange(foo, bar) if os.name != "nt": - signed, _ = foo.cmd("sign", RAW_DATA) + signed, _ = foo.cmd("sign", raw_path) bar.cmd("verify", "*", stdin=signed) - signed, _ = bar.cmd("sign", RAW_DATA) + signed, _ = bar.cmd("sign", raw_path) foo.cmd("verify", bar.name, stdin=signed) diff --git a/test/integration/device_fd.py b/test/integration/device_fd.py index 70b5072e..1788b0d9 100755 --- a/test/integration/device_fd.py +++ b/test/integration/device_fd.py @@ -60,7 +60,7 @@ def test_device_fd(ctx: Test) -> None: log.info("create a UNIX socket to transfer FD") unix = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) - unix_path = tempfile.mktemp() + unix_path = tempfile.mkstemp()[1] + ".socket" unix.bind(unix_path) unix.listen(1) diff --git a/test/integration/systemd.py b/test/integration/systemd.py index ccf2f23b..9993a0da 100755 --- a/test/integration/systemd.py +++ b/test/integration/systemd.py @@ -77,7 +77,7 @@ def recv_until(sock: socket.socket, want: bytes) -> None: def test_watchdog(foo: Tinc) -> None: """Test systemd watchdog.""" - address = tempfile.mktemp() + address = tempfile.mkstemp()[1] + ".socket" foo_log = foo.sub("log") log.info("watchdog is disabled if no env vars are passed") diff --git a/test/integration/testlib/const.py b/test/integration/testlib/const.py index 65a66a0a..b8d7697f 100755 --- a/test/integration/testlib/const.py +++ b/test/integration/testlib/const.py @@ -5,9 +5,6 @@ import os # Exit code to skip current test EXIT_SKIP = 77 -# Family name for multiprocessing Listener/Connection -MPC_FAMILY = "AF_PIPE" if os.name == "nt" else "AF_UNIX" - # Do access checks on files. Disabled when not available or not applicable. RUN_ACCESS_CHECKS = os.name != "nt" and os.geteuid() != 0 diff --git a/test/integration/testlib/notification.py b/test/integration/testlib/notification.py index 7813bf01..5a421a3c 100755 --- a/test/integration/testlib/notification.py +++ b/test/integration/testlib/notification.py @@ -9,7 +9,6 @@ import typing as T from .log import log from .event import Notification -from .const import MPC_FAMILY def _get_key(name, script) -> str: @@ -78,7 +77,7 @@ class NotificationServer: os.kill(0, signal.SIGTERM) def _listen(self) -> None: - with mp.Listener(family=MPC_FAMILY, authkey=self.authkey) as listener: + with mp.Listener(authkey=self.authkey) as listener: assert not isinstance(listener.address, tuple) self.address = listener.address self._ready.set() diff --git a/test/integration/testlib/template/script.py.tpl b/test/integration/testlib/template/script.py.tpl index 59e229a4..d542b5b1 100644 --- a/test/integration/testlib/template/script.py.tpl +++ b/test/integration/testlib/template/script.py.tpl @@ -22,7 +22,6 @@ sys.path.append(r'$SRC_ROOT') from testlib.proc import Tinc from testlib.event import Notification from testlib.log import new_logger -from testlib.const import MPC_FAMILY this = Tinc('$NODE_NAME') log = new_logger(this.name) @@ -39,7 +38,7 @@ def notify_test(args: T.Dict[str, T.Any] = {}, error: T.Optional[Exception] = No for retry in range(1, 10): try: - with mpc.Client($NOTIFICATIONS_ADDR, family=MPC_FAMILY, authkey=$AUTH_KEY) as conn: + with mpc.Client($NOTIFICATIONS_ADDR, authkey=$AUTH_KEY) as conn: conn.send(evt) log.debug(f'sent notification') break diff --git a/test/integration/testlib/util.py b/test/integration/testlib/util.py index fdba760e..38aaffff 100755 --- a/test/integration/testlib/util.py +++ b/test/integration/testlib/util.py @@ -35,10 +35,10 @@ def random_port() -> int: def temp_file(content: str) -> str: """Create a temporary file and write text content into it.""" - file = tempfile.mktemp() - with open(file, "w", encoding="utf-8") as f: + fd, path = tempfile.mkstemp() + with os.fdopen(fd, "w", encoding="utf-8") as f: f.write(content) - return file + return path def remove_file(path: T.Union[str, Path]) -> bool: diff --git a/test/unit/test_fs.c b/test/unit/test_fs.c index 37a4a7e6..579efa3f 100644 --- a/test/unit/test_fs.c +++ b/test/unit/test_fs.c @@ -194,7 +194,6 @@ static void test_fopenmask_new(void **state) { struct stat st; strcpy(tmp, tmp_template); - // mktemp() nags about safety and using better alternatives int fd = mkstemp(tmp); assert_int_not_equal(-1, fd); close(fd); diff --git a/test/unit/test_net.c b/test/unit/test_net.c index 9e56ee30..0320a9e4 100644 --- a/test/unit/test_net.c +++ b/test/unit/test_net.c @@ -5,6 +5,10 @@ static environment_t *device_env = NULL; // NOLINTBEGIN(misc-use-internal-linkage) +void __wrap_environment_init(environment_t *env); +void __wrap_environment_exit(environment_t *env); +bool __wrap_execute_script(const char *name, environment_t *env); + void __wrap_environment_init(environment_t *env) { assert_non_null(env); assert_null(device_env); -- 2.47.3