From fe22b52b8d1e88efc34320d30998cac8beee5f4c Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 2 Aug 2026 23:04:27 +0800 Subject: [PATCH 1/4] [ci]: run the test suite on FreeBSD The FreeBSD entries in lint.yml only cross-compile, so no gopsutil test has ever executed on a FreeBSD kernel. Refs #1898 --- .github/workflows/test_freebsd.yml | 44 ++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 .github/workflows/test_freebsd.yml diff --git a/.github/workflows/test_freebsd.yml b/.github/workflows/test_freebsd.yml new file mode 100644 index 0000000000..9dfa505cd4 --- /dev/null +++ b/.github/workflows/test_freebsd.yml @@ -0,0 +1,44 @@ +name: Test FreeBSD + +on: + push: + branches: + - master + pull_request: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +permissions: + contents: read + +jobs: + freebsd: + name: FreeBSD + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout code + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + + - name: Test + uses: vmactions/freebsd-vm@77ed28d336d03fe19a3f4f7266c1d2c4714dd79d # v1.5.2 + with: + usesh: true + cache-after-prepare: true + # lsof: process.TestConnections shells out to it. + prepare: | + pkg install -y go lsof + run: | + set -e + go version + # The image does not run /etc/rc.d/dmesg, so cpu.TestInfo finds no + # /var/run/dmesg.boot. A booted FreeBSD system always has one. + dmesg > /var/run/dmesg.boot + # devfs materialises /dev/pts only while a pty is open, and this + # runs over a non-interactive ssh session. process.TestTerminal + # reads that directory, so keep one pty allocated for the run. + script -q /dev/null sleep 900 & + sleep 1 + go test ./... From 6ade1674bf6bc5cb5568775f00572c02c2bf1933 Mon Sep 17 00:00:00 2001 From: neil Date: Mon, 10 Aug 2026 16:51:38 +0800 Subject: [PATCH 2/4] probe: time the fix, and prove the job can still fail --- .github/workflows/zz-probe.yml | 84 ++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 .github/workflows/zz-probe.yml diff --git a/.github/workflows/zz-probe.yml b/.github/workflows/zz-probe.yml new file mode 100644 index 0000000000..90e1154562 --- /dev/null +++ b/.github/workflows/zz-probe.yml @@ -0,0 +1,84 @@ +name: probe + +on: + push: + branches: ['*'] + +jobs: + real: + name: real + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout code + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + + - name: Test + uses: vmactions/freebsd-vm@77ed28d336d03fe19a3f4f7266c1d2c4714dd79d # v1.5.2 + with: + release: "15.1" + usesh: true + copyback: false + prepare: | + pkg install -y go lsof + run: | + set -e + go version + # Everything below runs as root, so paths that depend on being + # unprivileged are not exercised here. + # + # The image does not run /etc/rc.d/dmesg, so cpu.TestInfo finds no + # /var/run/dmesg.boot. A booted FreeBSD system always has one. + dmesg > /var/run/dmesg.boot + # devfs materialises /dev/pts only while a pty is open, and this + # runs over a non-interactive ssh session. process.TestTerminal + # reads that directory, so keep one pty allocated for the run. + # Its descriptors are detached: holding the ssh session's stdout + # would keep the step open until the sleep expired, whatever go + # test did. + script -q /dev/null sleep 3600 /dev/null 2>&1 & + pty_pid=$! + trap 'kill "$pty_pid" 2>/dev/null' EXIT + sleep 1 + date +'PROBE tests start %H:%M:%S' + go test ./... + date +'PROBE tests done %H:%M:%S' + + must_fail: + name: must_fail + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout code + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + + - name: A failure after the trap is installed must still fail the job + uses: vmactions/freebsd-vm@77ed28d336d03fe19a3f4f7266c1d2c4714dd79d # v1.5.2 + with: + release: "15.1" + usesh: true + copyback: false + prepare: | + pkg install -y go lsof + run: | + set -e + go version + # Everything below runs as root, so paths that depend on being + # unprivileged are not exercised here. + # + # The image does not run /etc/rc.d/dmesg, so cpu.TestInfo finds no + # /var/run/dmesg.boot. A booted FreeBSD system always has one. + dmesg > /var/run/dmesg.boot + # devfs materialises /dev/pts only while a pty is open, and this + # runs over a non-interactive ssh session. process.TestTerminal + # reads that directory, so keep one pty allocated for the run. + # Its descriptors are detached: holding the ssh session's stdout + # would keep the step open until the sleep expired, whatever go + # test did. + script -q /dev/null sleep 3600 /dev/null 2>&1 & + pty_pid=$! + trap 'kill "$pty_pid" 2>/dev/null' EXIT + sleep 1 + echo "PROBE now failing on purpose" + false + echo "PROBE THIS LINE MUST NOT APPEAR" From a2152dc4f0d39835b81c80b9ed6d2e7c53df1552 Mon Sep 17 00:00:00 2001 From: neil Date: Mon, 10 Aug 2026 16:54:41 +0800 Subject: [PATCH 3/4] probe: also fire on pull_request --- .github/workflows/zz-probe.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/zz-probe.yml b/.github/workflows/zz-probe.yml index 90e1154562..9375ab8bd7 100644 --- a/.github/workflows/zz-probe.yml +++ b/.github/workflows/zz-probe.yml @@ -3,6 +3,7 @@ name: probe on: push: branches: ['*'] + pull_request: jobs: real: From 2d1305f4836fa7f67a8dda32d6bccb02c93c515d Mon Sep 17 00:00:00 2001 From: neil Date: Mon, 10 Aug 2026 17:14:19 +0800 Subject: [PATCH 4/4] probe: run the exact file from the PR branch --- .github/workflows/test_freebsd.yml | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test_freebsd.yml b/.github/workflows/test_freebsd.yml index 9dfa505cd4..4ede248ddf 100644 --- a/.github/workflows/test_freebsd.yml +++ b/.github/workflows/test_freebsd.yml @@ -25,20 +25,29 @@ jobs: - name: Test uses: vmactions/freebsd-vm@77ed28d336d03fe19a3f4f7266c1d2c4714dd79d # v1.5.2 with: + release: "15.1" usesh: true - cache-after-prepare: true + copyback: false # lsof: process.TestConnections shells out to it. prepare: | pkg install -y go lsof run: | set -e go version + # Everything below runs as root, so paths that depend on being + # unprivileged are not covered by this job. + # # The image does not run /etc/rc.d/dmesg, so cpu.TestInfo finds no # /var/run/dmesg.boot. A booted FreeBSD system always has one. dmesg > /var/run/dmesg.boot # devfs materialises /dev/pts only while a pty is open, and this # runs over a non-interactive ssh session. process.TestTerminal # reads that directory, so keep one pty allocated for the run. - script -q /dev/null sleep 900 & + # Its descriptors are detached: holding the ssh session's stdout + # keeps the step open until the sleep expires, whatever go test + # does. The trap bounds the holder's lifetime instead. + script -q /dev/null sleep 3600 /dev/null 2>&1 & + pty_pid=$! + trap 'kill "$pty_pid" 2>/dev/null' EXIT sleep 1 go test ./...