Skip to content

Commit b080f74

Browse files
committed
FEATURE-ci-v3-runtime-green: complete first FreeBSD native make-check exposure
1 parent 021a00c commit b080f74

7 files changed

Lines changed: 63 additions & 3 deletions

File tree

‎.github/workflows/v3-release-acceptance.yml‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ jobs:
269269
freebsd:
270270
runs-on: ubuntu-24.04
271271
needs: prepare
272-
timeout-minutes: 240
272+
timeout-minutes: 300
273273
outputs:
274274
artifact_id: ${{ steps.proof.outputs.artifact-id }}
275275
artifact_digest: ${{ steps.proof.outputs.artifact-digest }}
@@ -332,6 +332,12 @@ jobs:
332332
fi
333333
test "$(node --version)" = v24.15.0
334334
python3 -c 'import subprocess; subprocess.run(["git","--version"],check=True)'
335+
# The native peer-policy runtime test binds 127.0.0.2 as its
336+
# admin source address; FreeBSD only configures 127.0.0.1 on
337+
# lo0 by default, so the alias must exist before make check.
338+
if ifconfig lo0 >/dev/null 2>&1; then
339+
ifconfig lo0 alias 127.0.0.2 2>/dev/null || ifconfig lo0 | grep -q '127\.0\.0\.2'
340+
fi
335341
python3 scripts/ci-freebsd-toolchain.py --output "$RUNNER_TEMP/platform-evidence/toolchain"
336342
. "$RUNNER_TEMP/platform-evidence/toolchain/toolchain.env"
337343
python3 scripts/prepare-v3-package-ci.py --output "$RUNNER_TEMP/prerequisites" --make gmake

‎ChangeLog‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
Version 3.0.0 - 2026-10-10
2+
Complete the first FreeBSD native make-check exposure: portable
3+
process-memory measurement, GNU-make gate selection, the
4+
loopback admin alias, per-test hang bounds and job budget.
25
Link the installed public TLS and HTTP/2 audit clients to Winsock on
36
Windows and name their executables with the platform suffix.
47
Resolve the Windows version-information system import in installed

‎scripts/run-v3-http3-full-gates.py‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@
2020

2121
ROOT = Path(__file__).resolve().parents[1]
2222
INVENTORY = ROOT / 'test/conformance/http3/full-gates.json'
23+
# Generated Makefiles need GNU make; FreeBSD's default `make` is BSD
24+
# make, so prefer gmake where it exists and fall back to `make`.
25+
MAKE = shutil.which('gmake') or 'make'
2326
OFF_SUITES = '''http3_frame http3_settings http3_connection http3_headers http3_exchange
2427
http3_streaming http3_cancellation http3_qpack http3_qpack_scheduling http3_drain
2528
http3_fuzz_replay qpack_primitives qpack_field_section qpack_dynamic_table
@@ -374,10 +377,10 @@ def build_configuration(build, tls, sanitized):
374377

375378
def native_stage(build, suites, directory, fixtures=False):
376379
directory.mkdir(mode=0o700)
377-
commands = [checked(['make', '-j4', '-C', build / 'src'], ROOT, directory / 'build')]
380+
commands = [checked([MAKE, '-j4', '-C', build / 'src'], ROOT, directory / 'build')]
378381
targets = suites + (['http3_udp_fixture', 'http3_semantic_parity_fixture', 'quic_interop_endpoint'] if fixtures else [])
379382
selection = [name + '=' + ' '.join(targets) for name in ('TESTS', 'check_PROGRAMS', 'noinst_PROGRAMS')]
380-
commands.append(checked(['make', '-j4', '-C', build / 'test', *selection, *targets], ROOT, directory / 'test-build'))
383+
commands.append(checked([MAKE, '-j4', '-C', build / 'test', *selection, *targets], ROOT, directory / 'test-build'))
381384
results = run_native_suites(build, suites, directory / 'tests')
382385
results['commands'] = commands
383386
tls = '#define NATIVE_V3_TLS' in (build / 'config.h').read_text()

‎specs/tasks/FEATURE-ci-v3-runtime-green.md‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,3 +163,13 @@ Full local `make check -j1` (TLS=no, g++ 15.2, WSL2): 232/235 pass, 2 platform s
163163
- [x] Repair in `scripts/check-v3-public-tls.py`: the independent client is named with the platform `.exe` suffix and linked with `-lws2_32` on `os.name == 'nt'` (POSIX targets unchanged), and the provider `openssl` tool is invoked with its explicit `.exe` name on Windows, matching `run-v3-release-ci.py`.
164164
- [x] Same-class parity repair in `scripts/check-v3-public-http2.py` (preemptive, code-audit driven, not yet exercised on Windows): consumers and examples get the `.exe` suffix and the `ws2_32/mswsock/bcrypt` system libraries replace the POSIX-only `-pthread`/`-rpath` line, matching the `check-v3-installed-consumer.py`/`check-v3-public-tls.py` convention; runtime DLL resolution stays on the `runtime_environment` PATH/V3_PACKAGE_DLL_DIRS mechanism. Local gates: `test-v3-public-http2.py` 6/6, `py_compile` on both scripts.
165165
- [ ] Full mingw64/Windows CI evidence past the public TLS client link.
166+
167+
## Stage 11: first FreeBSD native make-check exposure (2026-10-30)
168+
169+
- [x] Evidence (5.1GB failure artifact 12993618134, run 41055662147, analyzed in full): the FreeBSD acceptance lane passed the entire installed matrix (both TLS lanes incl. public-tls and public-http2) in ~18 minutes, then reached `gmake check` for the first time ever (every earlier acceptance run died earlier: the Oct-26 runs at the http2 stale flake/copyback, the Oct-28 runs at the 180-min timeout). The first `make check` ran the full 7200s command deadline and was killed with only `response_sources` still unfinished: test 24 `threaded_pipe_sends_single_winner` started and never printed a result. Four real test failures were also recorded: `response_definition` (checks 846/847, `file_send_truncated_mid_send_fails`, completed in 2.58ms with `done==0`), `native_protocol_memory` ("process memory measurement unavailable" — no FreeBSD branch), `consumer_v3_peer_policy_runtime` (line 86 = bind/connect of the 127.0.0.2 admin source: FreeBSD has no 127/8 loopback alias by default), and `integ/http3_full_gate_runner_test.py` (`make -j4` in the gate runner is BSD make on FreeBSD; needs gmake).
170+
- [x] Repairs with proven causes: `native_protocol_memory_test.cpp` gains FreeBSD (kinfo_proc sysctl) and Windows (GetProcessMemoryInfo) resident-memory branches — the Windows acceptance make check needs the same branch; `run-v3-http3-full-gates.py` selects gmake when present (GNU-make Makefiles, BSD default make); the freebsd acceptance VM run script adds-or-verifies the `lo0` 127.0.0.2 alias (no-op where `ifconfig lo0` is absent, e.g. the Linux workflow tests).
171+
- [x] Hang bound: `test/timeout-wrapper.sh` (EXTRA_DIST, `LOG_COMPILER`) wraps every native test with `timeout -k 60 600` where timeout(1) exists, so a recurrence cannot consume a whole CI make-check budget; hosts without timeout (macOS default) run exactly as before.
172+
- [x] Budget: freebsd acceptance `timeout-minutes` 240 → 300 (observed: ~95 min prepare with the pinned-Node source build + ~18 min matrix + make check ×2 + evidence recovery).
173+
- [x] Local gates: fresh worktree configure/build; `native_protocol_memory` passes under the new LOG_COMPILER wrapper; `test-v3-ci-workflows.py` 31/31, `test-v3-platform-ci.py` 20/20, `test-v3-http3-full-gates.py` 1/1; changed-file cpplint and YAML parse pass.
174+
- [ ] Open flakes (no repair without a recurrence, per the standing http2-stale precedent): `response_sources` test 24 hang (one occurrence; the claim/close guard is a single atomic CAS and `pull_handle`'s fread cannot block on a pipe whose write end is closed — mechanism unexplained) and `response_definition` checks 846/847 (coroutine did not complete after the mid-send truncation). Both pass on Linux/macOS; the next FreeBSD run with bounded hangs decides.
175+
- [ ] Full FreeBSD acceptance CI evidence.

‎test/Makefile.am‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -727,6 +727,12 @@ consumer_v3_features_CPPFLAGS = -I$(top_srcdir)/src
727727
consumer_v3_features_LDADD = $(top_builddir)/src/libhttpserver_v3core.la
728728
AM_TESTS_ENVIRONMENT = V3_TLS_MODE="$(enable_v3_tls)"; export V3_TLS_MODE;
729729

730+
# Bound every native test program so one hung binary cannot consume a
731+
# whole CI make-check command budget; the wrapper degrades to a plain
732+
# exec where timeout(1) is unavailable (macOS by default).
733+
LOG_COMPILER = $(top_srcdir)/test/timeout-wrapper.sh
734+
EXTRA_DIST += timeout-wrapper.sh
735+
730736
basic_auth_corpus_LDFLAGS = $(V3_TLS_LDFLAGS) $(AM_LDFLAGS)
731737

732738
body_reader_LDFLAGS = $(V3_TLS_LDFLAGS) $(AM_LDFLAGS)

‎test/integ/native_protocol_memory_test.cpp‎

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,14 @@
2121

2222
#if defined(__APPLE__)
2323
#include <mach/mach.h>
24+
#elif defined(__FreeBSD__)
25+
#include <sys/types.h>
26+
#include <sys/sysctl.h>
27+
#include <sys/user.h>
28+
#include <unistd.h>
29+
#elif defined(_WIN32)
30+
#include <windows.h>
31+
#include <psapi.h>
2432
#else
2533
#include <unistd.h>
2634
#include <fstream>
@@ -46,6 +54,22 @@ std::size_t resident_bytes() {
4654
check(task_info(mach_task_self(), MACH_TASK_BASIC_INFO, reinterpret_cast<task_info_t>(&info), &count) == KERN_SUCCESS,
4755
"process memory measurement unavailable");
4856
return info.resident_size;
57+
#elif defined(__FreeBSD__)
58+
// FreeBSD ships no procfs by default; the native source is the
59+
// per-process sysctl MIB (kinfo_proc's resident page count).
60+
int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, static_cast<int>(::getpid())};
61+
kinfo_proc info{};
62+
size_t size = sizeof info;
63+
check(::sysctl(mib, 4, &info, &size, nullptr, 0) == 0
64+
&& size >= offsetof(kinfo_proc, ki_rssize) + sizeof info.ki_rssize,
65+
"process memory measurement unavailable");
66+
return static_cast<std::size_t>(info.ki_rssize)
67+
* static_cast<std::size_t>(::sysconf(_SC_PAGESIZE));
68+
#elif defined(_WIN32)
69+
PROCESS_MEMORY_COUNTERS counters{};
70+
check(::GetProcessMemoryInfo(::GetCurrentProcess(), &counters, sizeof counters) != 0,
71+
"process memory measurement unavailable");
72+
return counters.WorkingSetSize;
4973
#else
5074
std::ifstream stat("/proc/self/statm");
5175
std::size_t total = 0, resident = 0;

‎test/timeout-wrapper.sh‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#!/bin/sh
2+
# Bound one native test program so a single hung binary cannot consume
3+
# a whole CI make-check command budget. Hosts without timeout(1)
4+
# (macOS by default) run tests exactly as before.
5+
if command -v timeout >/dev/null 2>&1; then
6+
exec timeout -k 60 600 "$@"
7+
fi
8+
exec "$@"

0 commit comments

Comments
 (0)