From f4953b86fc7bc7447dc8cfe9da2d342a86d7f766 Mon Sep 17 00:00:00 2001 From: Julian Noble Date: Sun, 9 Aug 2026 02:55:56 +1000 Subject: [PATCH] test suites: lib-tier package deps probed to constraints (json, sha1, struct::stack) Seven suites hard-required packages that only a lib-tier-provisioned runner interpreter supplies (the suite-built/runtime-store tclsh carry tcllib in their own library tree; runtests deliberately propagates the runner's [info library] into the child auto_path). On unprovisioned hosts (e.g. a PATH tclsh86 without tcllib) each such file died wholesale: load-time requires errored the file (pathcmd, argparsingtest_compare, maketcllibfetch, offsetstyle - the struct::stack cases via vendored tomlish's own require) and scriptwrap's lazy 'package require tomlish' (_read_scriptset_wrap_tomlfile) errored tests mid-body (runtimecmd_roundtrip, multishell sentinel, dtplite checkfile tests). All are now feature-probe constraints in the established have_tclcoredocs style: - pathcmd.test: jsonAvailable probe wired (was hardcoded 1 and attached to no test) gating the json round-trip test - argparsingtest_compare.test: jsonAvailable gating compare_json - maketcllibfetch.test: have_sha1 gating the artifact+sha1sums+server fixture portion (the config/env scaffolding still builds, so the trustgate and no-config tests run) and the file:// mirror test - offsetstyle.test: have_tomlish gating the build-baseline test (its G-165 exemption logic reads mapvfs.toml); the six probe tests keep running, the file-level mapvfs read already catch-degrades - runtimecmd_roundtrip.test / multishell.test: have_tomlish gating the wrap tests (multishell's wrapok fixture already catch-degrades; the sentinel keeps failing loudly on provisioned runners) - dtplite.test: tomlish folded into the existing havescriptwrap probe Verified: provisioned runners unchanged (86ts/90s green, only pre-existing isunix/parser-availability skips); PATH mingw tclsh86 (json-less, struct::stack-less) runs all seven files with visible constraint skips and zero failures; sha1-less behaviour proven via a package-unknown-cleared harness (trustgate+no-config pass, 6 fixture skips); testbody_lint clean. Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com --- .../argparsingtest_compare.test | 9 ++- .../mix/testsuites/scriptwrap/multishell.test | 10 ++++ .../scriptwrap/runtimecmd_roundtrip.test | 8 +++ .../pathcmd/testsuites/tests/pathcmd.test | 10 +++- .../utils/testsuites/utils/offsetstyle.test | 11 +++- .../shell/testsuites/binscripts/dtplite.test | 6 ++ .../testsuites/punkexe/maketcllibfetch.test | 57 ++++++++++++------- 7 files changed, 83 insertions(+), 28 deletions(-) diff --git a/src/tests/modules/argparsingtest/testsuites/argparsingtest/argparsingtest_compare.test b/src/tests/modules/argparsingtest/testsuites/argparsingtest/argparsingtest_compare.test index 38e9404d..6d409a76 100644 --- a/src/tests/modules/argparsingtest/testsuites/argparsingtest/argparsingtest_compare.test +++ b/src/tests/modules/argparsingtest/testsuites/argparsingtest/argparsingtest_compare.test @@ -1,7 +1,12 @@ package require tcltest package require argparsingtest -package require json + +#2026-08-09 Agent-Updated: json (tcllib, supplied by the runner interpreter's own library - +#the suite-built and runtime-store tclsh carry the punkbin lib tier) probed to a constraint +#instead of a bare require, so json-less hosts skip compare_json visibly rather than +#erroring the whole file at load. +tcltest::testConstraint jsonAvailable [expr {![catch {package require json}]}] namespace eval ::testspace { namespace import ::tcltest::* @@ -37,7 +42,7 @@ namespace eval ::testspace { } -result 1 #added 2026-07-18 (agent) - test compare_json {Test that compare -format json round-trips with style-keyed unsupported and first_call structure} -body { + test compare_json {Test that compare -format json round-trips with style-keyed unsupported and first_call structure} -constraints jsonAvailable -body { set r [argparsingtest::compare -style tkstyle -iterations 20 -parsers {manual_switch cmdline_typed} -format json] set ok 1 if {[catch {set d [json::json2dict $r]} _err]} { set ok "json parse: $_err" } diff --git a/src/tests/modules/punk/mix/testsuites/scriptwrap/multishell.test b/src/tests/modules/punk/mix/testsuites/scriptwrap/multishell.test index 42ee3fc5..9873e705 100644 --- a/src/tests/modules/punk/mix/testsuites/scriptwrap/multishell.test +++ b/src/tests/modules/punk/mix/testsuites/scriptwrap/multishell.test @@ -3,6 +3,15 @@ package require tcltest package require Thread ;#punk::fileline textinfo (used by scriptwrap checkfile) calls thread::id package require punk::mix::commandset::scriptwrap +#2026-08-09 Agent-Updated: multishell parses the fixture's _wrap.toml via a lazy +#'package require tomlish' inside scriptwrap (_read_scriptset_wrap_tomlfile), and tomlish +#(vendored) needs struct::stack from the runner interpreter's own library (tcllib lib tier - +#the suite-built and runtime-store tclsh carry it). Probed to a constraint gating the +#wrap-produces-output sentinel test: on lib-tier-less hosts the wrap-once fixture below +#catch-degrades (wrapok 0 -> structure tests skip) and the sentinel skips too; on +#provisioned runners have_tomlish is 1, so a genuine wrap regression still fails loudly. +tcltest::testConstraint have_tomlish [expr {![catch {package require tomlish}]}] + #Characterization of the punk MULTISHELL polyglot build machinery #(punk::mix::commandset::scriptwrap::multishell + checkfile) - added 2026-07-10 at the #user's direction: the polyglot technique is deliberately maintained despite its @@ -92,6 +101,7 @@ namespace eval ::testspace { } test scriptwrap_multishell_wrap_produces_output {wrapping a scriptset with payloads + _wrap.toml produces the polyglot output file}\ + -constraints have_tomlish\ -setup $common -body { variable wrapresult variable outfile diff --git a/src/tests/modules/punk/mix/testsuites/scriptwrap/runtimecmd_roundtrip.test b/src/tests/modules/punk/mix/testsuites/scriptwrap/runtimecmd_roundtrip.test index 7b3a390c..dfa0a812 100644 --- a/src/tests/modules/punk/mix/testsuites/scriptwrap/runtimecmd_roundtrip.test +++ b/src/tests/modules/punk/mix/testsuites/scriptwrap/runtimecmd_roundtrip.test @@ -3,6 +3,13 @@ package require tcltest package require Thread ;#punk::fileline textinfo (used by scriptwrap machinery) calls thread::id package require punk::mix::commandset::scriptwrap +#2026-08-09 Agent-Updated: multishell parses the scriptset's _wrap.toml via a lazy +#'package require tomlish' inside scriptwrap (_read_scriptset_wrap_tomlfile), and tomlish +#(vendored) needs struct::stack from the runner interpreter's own library (tcllib lib tier - +#the suite-built and runtime-store tclsh carry it). Probed to a constraint so lib-tier-less +#hosts skip the round-trip test visibly instead of erroring it mid-body. +tcltest::testConstraint have_tomlish [expr {![catch {package require tomlish}]}] + #Characterization of the punk MULTISHELL polyglot build machinery #(punk::mix::commandset::scriptwrap::multishell + checkfile) - added 2026-07-10 at the #user's direction: the polyglot technique is deliberately maintained despite its @@ -43,6 +50,7 @@ namespace eval ::testspace { } test scriptwrap_runtime_cmd_roundtrip_no_drift {re-wrapping the punk-runtime scriptset from src/scriptapps/bin reproduces the committed bin/punk-runtime.cmd byte for byte - the artifact is in sync with its sources and un-hand-edited}\ + -constraints have_tomlish\ -setup $common -body { variable projectroot variable startdir diff --git a/src/tests/modules/punk/pathcmd/testsuites/tests/pathcmd.test b/src/tests/modules/punk/pathcmd/testsuites/tests/pathcmd.test index 12ff47af..33b2a2fc 100644 --- a/src/tests/modules/punk/pathcmd/testsuites/tests/pathcmd.test +++ b/src/tests/modules/punk/pathcmd/testsuites/tests/pathcmd.test @@ -18,9 +18,13 @@ package require tcltest package require punk -package require json -tcltest::testConstraint jsonAvailable 1 +#2026-08-09 Agent-Updated: probe wired (was a bare 'package require json' plus a constraint +#hardcoded to 1 and attached to no test - a runner without json errored the whole file at +#load). json is tcllib, supplied by the runner interpreter's own library tree - the +#suite-built and runtime-store tclsh carry the punkbin lib tier (tcllib2.0), so the +#round-trip test always runs there; on unprovisioned hosts it skips visibly instead. +tcltest::testConstraint jsonAvailable [expr {![catch {package require json}]}] namespace eval ::testspace { namespace import ::tcltest::* @@ -120,7 +124,7 @@ namespace eval ::testspace { } -result {1 1 1 0} #added 2026-08-07 (agent, G-173 - punk::path machine-parsable returns) - test pathcmd-json-1.2 {-return json is ansi-free and round-trips the dict} -setup setup_fixture -cleanup cleanup_fixture -body { + test pathcmd-json-1.2 {-return json is ansi-free and round-trips the dict} -constraints jsonAvailable -setup setup_fixture -cleanup cleanup_fixture -body { set d [::punk::path -return dict] set j [::punk::path -return json] set facts [list] diff --git a/src/tests/modules/punkboot/utils/testsuites/utils/offsetstyle.test b/src/tests/modules/punkboot/utils/testsuites/utils/offsetstyle.test index d135a1e2..f297fe85 100644 --- a/src/tests/modules/punkboot/utils/testsuites/utils/offsetstyle.test +++ b/src/tests/modules/punkboot/utils/testsuites/utils/offsetstyle.test @@ -21,7 +21,14 @@ package require tcltest package require punkboot::utils package require punk::zip -package require tomlish + +#2026-08-09 Agent-Updated: tomlish (vendored) needs struct::stack from the runner +#interpreter's own library (tcllib lib tier - the suite-built and runtime-store tclsh +#carry it); probed to a constraint instead of a bare require so lib-tier-less hosts run +#the offsetstyle probe tests and skip only the build-baseline test, whose G-165 exemption +#logic reads mapvfs.toml via tomlish (the file-level read below already catch-degrades to +#an empty exemption list when tomlish is absent). +tcltest::testConstraint have_tomlish [expr {![catch {package require tomlish}]}] #added 2026-07-29 (agent, G-134) @@ -118,7 +125,7 @@ namespace eval ::testspace { } } - test kit_offsetstyle_build_baseline {every assembled kit image in src/_bake probes archive or none - never file; kits declaring the offsetstyle="file" opt-in (G-165) are exempt and must probe file} -constraints {builtkitsavailable} -body { + test kit_offsetstyle_build_baseline {every assembled kit image in src/_bake probes archive or none - never file; kits declaring the offsetstyle="file" opt-in (G-165) are exempt and must probe file} -constraints {builtkitsavailable have_tomlish} -body { variable bakefolder variable mapvfs_declared_file set bad [list] diff --git a/src/tests/shell/testsuites/binscripts/dtplite.test b/src/tests/shell/testsuites/binscripts/dtplite.test index b719c22e..4b94ccf0 100644 --- a/src/tests/shell/testsuites/binscripts/dtplite.test +++ b/src/tests/shell/testsuites/binscripts/dtplite.test @@ -43,6 +43,12 @@ namespace eval ::testspace { testConstraint havescriptwrap [expr {![catch { package require Thread ;#punk::fileline textinfo (used by checkfile) calls thread::id package require punk::mix::commandset::scriptwrap + #2026-08-09 Agent-Updated: the checkfile machinery parses wrap toml via a lazy + #'package require tomlish' inside scriptwrap, and tomlish (vendored) needs + #struct::stack from the runner interpreter's own library (tcllib lib tier - the + #suite-built and runtime-store tclsh carry it). Folded into this probe so + #lib-tier-less hosts skip instead of erroring mid-test. + package require tomlish }]}] proc readbytes {path} { diff --git a/src/tests/shell/testsuites/punkexe/maketcllibfetch.test b/src/tests/shell/testsuites/punkexe/maketcllibfetch.test index ea830b25..c65d4113 100644 --- a/src/tests/shell/testsuites/punkexe/maketcllibfetch.test +++ b/src/tests/shell/testsuites/punkexe/maketcllibfetch.test @@ -1,6 +1,14 @@ package require tcltest package require punk::zip -package require sha1 + +#2026-08-09 Agent-Updated: sha1 (tcllib, supplied by the runner interpreter's own library - +#the suite-built and runtime-store tclsh carry the punkbin lib tier) probed to a constraint +#instead of a bare require, so lib-tier-less hosts don't error the whole file at load. +#sha1 is consumed only by the fixture build (hashing the served artifacts into the server's +#sha1sums.txt): without it the artifact/server fixture is not built and fixtureserver-gated +#tests skip, while the config/env scaffolding still supports the punkexeavailable-only +#trustgate test. +tcltest::testConstraint have_sha1 [expr {![catch {package require sha1}]}] #Piped characterization of 'make.tcl libfetch' (G-139): the punkbin lib-tier #fetch/verify/materialize entrypoint, driven ONLY against fixture origins - a @@ -220,26 +228,31 @@ namespace eval ::testspace { set tplat [file join $serverroot lib $plat] file mkdir $tplat set zipstage [file normalize [makeDirectory lf_zipstage]] - #two immutable revisions of the same package folder (r2 = new bytes, new - #embedded record) + a corrupt-served artifact for the mismatch case - build_fixture_zip $zipstage fixturepkg fixturepkg-tcl9-r1.zip \ - "proc fixturepkg::rev {} {return r1}\n" [file join $tplat fixturepkg-tcl9-r1.zip] - build_fixture_zip $zipstage fixturepkg fixturepkg-tcl9-r2.zip \ - "proc fixturepkg::rev {} {return r2}\n" [file join $tplat fixturepkg-tcl9-r2.zip] - writefile_raw [file join $tplat fixturepkg-tcl9-r1.toml] [fixture_record fixturepkg-tcl9-r1.zip] - writefile_raw [file join $tplat badpkg-tcl9-r1.zip] "these served bytes do not match the sha1 the server sha1sums promises\n" - #server sha1sums: r1 zip + r1 sidecar listed with true hashes; r2 zip - #listed with a true hash but its sidecar deliberately NOT listed (the - #sidecar-skipped note lane); badpkg listed with a WRONG hash (mismatch - #lane). ghostpkg-tcl9-r1.zip is declared by a config but never listed. - set sums [list] - foreach fname [list fixturepkg-tcl9-r1.zip fixturepkg-tcl9-r1.toml fixturepkg-tcl9-r2.zip] { - lappend sums "[string tolower [sha1::sha1 -hex -file [file join $tplat $fname]]] *$fname" - } - lappend sums "[string repeat 0 40] *badpkg-tcl9-r1.zip" - writefile_raw [file join $tplat sha1sums.txt] "[join $sums \n]\n" + #artifact + sha1sums + server portion gated on have_sha1 (see the constraint note + #at the top of the file) - fixtureok keeps its 0 default when skipped, so + #fixtureserver tests skip; the dirs/config/env scaffolding above and below stays + if {[testConstraint have_sha1]} { + #two immutable revisions of the same package folder (r2 = new bytes, new + #embedded record) + a corrupt-served artifact for the mismatch case + build_fixture_zip $zipstage fixturepkg fixturepkg-tcl9-r1.zip \ + "proc fixturepkg::rev {} {return r1}\n" [file join $tplat fixturepkg-tcl9-r1.zip] + build_fixture_zip $zipstage fixturepkg fixturepkg-tcl9-r2.zip \ + "proc fixturepkg::rev {} {return r2}\n" [file join $tplat fixturepkg-tcl9-r2.zip] + writefile_raw [file join $tplat fixturepkg-tcl9-r1.toml] [fixture_record fixturepkg-tcl9-r1.zip] + writefile_raw [file join $tplat badpkg-tcl9-r1.zip] "these served bytes do not match the sha1 the server sha1sums promises\n" + #server sha1sums: r1 zip + r1 sidecar listed with true hashes; r2 zip + #listed with a true hash but its sidecar deliberately NOT listed (the + #sidecar-skipped note lane); badpkg listed with a WRONG hash (mismatch + #lane). ghostpkg-tcl9-r1.zip is declared by a config but never listed. + set sums [list] + foreach fname [list fixturepkg-tcl9-r1.zip fixturepkg-tcl9-r1.toml fixturepkg-tcl9-r2.zip] { + lappend sums "[string tolower [sha1::sha1 -hex -file [file join $tplat $fname]]] *$fname" + } + lappend sums "[string repeat 0 40] *badpkg-tcl9-r1.zip" + writefile_raw [file join $tplat sha1sums.txt] "[join $sums \n]\n" - variable fixtureok [server_start] + variable fixtureok [server_start] + } #shield the runs from ambient state, then point the seams at the fixture #config + packages tier (restored at end of file) foreach v {PUNKBIN_URL PUNK_LIBFETCH_CONFIG PUNK_LIBFETCH_PACKAGES} { @@ -419,7 +432,9 @@ namespace eval ::testspace { set ::env(PUNK_LIBFETCH_CONFIG) $::testspace::configfile } -result {timedout 0 exitcode 0 noop_stated 1} - test maketcl_libfetch_file_origin {a consented file:// mirror origin fetches and materializes via the native copy transport (no server process involved)} -constraints {punkexeavailable} -setup { + #2026-08-09 Agent-Updated: have_sha1 added - no server involved, but the file:// mirror + #serves the artifact + sha1sums fixture built under the have_sha1 gate + test maketcl_libfetch_file_origin {a consented file:// mirror origin fetches and materializes via the native copy transport (no server process involved)} -constraints {punkexeavailable have_sha1} -setup { reset_packages write_config {{fixture fixturepkg-tcl9-r1.zip testplat-x86_64}} unset -nocomplain ::env(PUNKBIN_URL)