Browse Source
- new punkexe/maketclkitlocations.test (PUNK_MAPVFS_CONFIG fixtures, nothing built): two-target one-vfs distinct locations (flat vs kits/<platform>/), same-name two-non-native coexistence without runtime-rename, same-target duplicate keeps <name>_<runtime>; mismatch clause referenced as G-133 regression pin (binaryarch.test + maketclpayloadcheck.test) - mapvfs_match_outputs: a plain kit name now selects ALL matching records (one per target) instead of the first hit - pre-G-127 uniqueness assumption removed; filtered bakelist + selective bake cover every target of a shared name - full punkexe subtree pass: 15 files, 101 tests, 0 failed (4 constraint skips) Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.commaster
3 changed files with 213 additions and 10 deletions
@ -0,0 +1,183 @@
|
||||
package require tcltest |
||||
|
||||
#Piped characterization of the G-127 target-keyed kit OUTPUT LOCATION model, through |
||||
#the make.tcl bakelist report against fixture kit mappings (PUNK_MAPVFS_CONFIG env |
||||
#seam - the real mapping is never edited, nothing is built). Runs the WORKING TREE's |
||||
#src/make.tcl under the built punk executable's 'script' subcommand and pins: |
||||
# - one vfs definition paired with two different targets resolves to DISTINCT |
||||
# output locations in one report: the default-target kit at the flat |
||||
# src/_build/<kit> + bin/<kit> every launcher expects, the non-default-target kit |
||||
# under the kits/<platform>/ tier in both, with the row carrying target= and |
||||
# out= notes (location is a pure function of (name, target), which is what makes |
||||
# the pre-G-127 cross-run overwrite impossible by construction) |
||||
# - two NON-NATIVE targets sharing one kit name coexist as two rows whose locations |
||||
# differ by platform tier (and by target-driven .exe suffixing) with NO |
||||
# runtime-name disambiguation rename |
||||
# - a same-NAME same-TARGET duplicate still gets the historical <name>_<runtime> |
||||
# disambiguation - the guard's remaining job after G-127 scoped it per target |
||||
#The payload/target MISMATCH clause of G-127's Acceptance is a regression pin on |
||||
#G-133 behaviour characterized elsewhere: the scan verdict in |
||||
#modules/punkboot/utils/testsuites/utils/binaryarch.test, the advisory contract in |
||||
#maketclpayloadcheck.test. Real cross-target ARTIFACT evidence (bake punkshell902 -> |
||||
#bin/kits/linux-x86_64/punkshell902, per-platform %platform% payload selection) is |
||||
#recorded in goals/G-127-crosstarget-vfs-bake.md Progress - a full bake is too heavy |
||||
#for this suite by design (see the G-125 precedent note in maketclbootgate.test). |
||||
# |
||||
#Target executable resolved from env(PUNK_SHELL_TEST_EXE), else <projectroot>/bin/punk902z.exe |
||||
#then <projectroot>/bin/punkshell902. Skipped (constraint punkexeavailable) if none found. |
||||
|
||||
namespace eval ::testspace { |
||||
namespace import ::tcltest::* |
||||
|
||||
variable testdir [file dirname [file normalize [info script]]] |
||||
#<projectroot>/src/tests/shell/testsuites/punkexe -> 5 levels up to <projectroot> |
||||
variable projectroot [file normalize [file join $testdir .. .. .. .. ..]] |
||||
variable maketcl [file join $projectroot src make.tcl] |
||||
|
||||
variable punkexe "" |
||||
if {[info exists ::env(PUNK_SHELL_TEST_EXE)] && $::env(PUNK_SHELL_TEST_EXE) ne ""} { |
||||
set punkexe [file normalize $::env(PUNK_SHELL_TEST_EXE)] |
||||
} else { |
||||
foreach candidate [list [file join $projectroot bin punk902z.exe] [file join $projectroot bin punkshell902]] { |
||||
if {[file exists $candidate]} { |
||||
set punkexe $candidate |
||||
break |
||||
} |
||||
} |
||||
} |
||||
testConstraint punkexeavailable [expr {$punkexe ne "" && [file exists $punkexe]}] |
||||
|
||||
variable maketcl_run_timeout_ms 60000 |
||||
|
||||
variable runstate |
||||
array set runstate {} |
||||
|
||||
proc maketcl_run_read {chan} { |
||||
variable runstate |
||||
append runstate(output) [read $chan] |
||||
if {[chan eof $chan]} { |
||||
chan event $chan readable {} |
||||
set runstate(done) eof |
||||
} |
||||
} |
||||
|
||||
#Run <punkexe> script src/make.tcl <subcommand...> with output captured through a |
||||
#pipe (stdin half-closed for immediate EOF - make.tcl must never wait on stdin for |
||||
#these subcommands). Returns dict: timedout 0|1, exitcode <int|"">, output |
||||
#<combined stdout+stderr>. |
||||
proc maketcl_run {cmdargs} { |
||||
variable runstate |
||||
variable maketcl_run_timeout_ms |
||||
variable punkexe |
||||
variable maketcl |
||||
array unset runstate |
||||
set runstate(output) "" |
||||
set runstate(done) "" |
||||
|
||||
set chan [open |[list $punkexe script $maketcl {*}$cmdargs 2>@1] r+] |
||||
chan configure $chan -blocking 0 -translation binary |
||||
catch {chan close $chan write} ;#no stdin for the child - immediate EOF |
||||
set timerid [after $maketcl_run_timeout_ms [list set [namespace current]::runstate(done) timeout]] |
||||
chan event $chan readable [list [namespace current]::maketcl_run_read $chan] |
||||
while {$runstate(done) eq ""} { |
||||
vwait [namespace current]::runstate(done) |
||||
} |
||||
after cancel $timerid |
||||
set timedout [expr {$runstate(done) eq "timeout"}] |
||||
set exitcode "" |
||||
if {$timedout} { |
||||
catch {exec {*}[auto_execok taskkill] /F /T /PID [lindex [pid $chan] 0]} |
||||
catch {chan close $chan} |
||||
} else { |
||||
chan configure $chan -blocking 1 |
||||
if {[catch {chan close $chan} errdata errdict]} { |
||||
set exitcode [lindex [dict get $errdict -errorcode] end] |
||||
} else { |
||||
set exitcode 0 |
||||
} |
||||
} |
||||
return [dict create timedout $timedout exitcode $exitcode output $runstate(output)] |
||||
} |
||||
|
||||
#Fixture kit mappings through the PUNK_MAPVFS_CONFIG env seam (fixture files in |
||||
#the tcltest temp dir - the real mapping is never edited). Same helper shape as |
||||
#maketclbakelist.test. |
||||
proc maketcl_run_mapseam {fixturename fixturelines cmdargs} { |
||||
set fixture [tcltest::makeFile [join $fixturelines \n] $fixturename] |
||||
set ::env(PUNK_MAPVFS_CONFIG) [file normalize $fixture] |
||||
try { |
||||
return [maketcl_run $cmdargs] |
||||
} finally { |
||||
unset -nocomplain ::env(PUNK_MAPVFS_CONFIG) |
||||
tcltest::removeFile $fixturename |
||||
} |
||||
} |
||||
|
||||
#added 2026-07-31 (agent, G-127) |
||||
test maketcl_bakelist_twotarget_onevfs_distinct_locations {one vfs definition under two targets: default-target kit keeps flat locations (no target=/out= notes), non-default-target kit resolves under kits/<platform>/ in both src/_build and bin} -constraints {punkexeavailable} -body { |
||||
set r [maketcl_run_mapseam fixture_twotarget.toml { |
||||
{[kit.fixnat]} |
||||
{runtime = "tclsfe-x64"} |
||||
{vfs = "punk9wintk903.vfs"} |
||||
{type = "zip"} |
||||
{} |
||||
{[kit.fixlin]} |
||||
{runtime = "tclkit-902-Linux64-intel-dyn"} |
||||
{vfs = "punk9wintk903.vfs"} |
||||
{type = "kit"} |
||||
{target = "linux-x86_64"} |
||||
} {bakelist fixnat fixlin}] |
||||
set out [dict get $r output] |
||||
set result [list] |
||||
lappend result timedout [dict get $r timedout] exitcode [dict get $r exitcode] |
||||
#default-target row: flat locations, no target=/out= notes (runtime=missing may |
||||
#legitimately appear on a host without the runtime - only the location notes matter) |
||||
lappend result natrow [regexp {(?n)^fixnat\s+zip\s+tclsfe-x64\s+punk9wintk903\.vfs\s} $out] |
||||
lappend result natnonotes [expr {![regexp {(?n)^fixnat\s.*(target=|out=)} $out]}] |
||||
lappend result natbuild [regexp {(?n)^\s+build product: src/_build/fixnat\.exe } $out] |
||||
lappend result natdeploy [regexp {(?n)^\s+deployed:\s+bin/fixnat\.exe } $out] |
||||
#non-default-target row: kits/<platform>/ tier both sides, suffixless for linux |
||||
lappend result linrow [regexp {(?n)^fixlin\s+kit\s+tclkit-902-Linux64-intel-dyn\s+punk9wintk903\.vfs\s+\S+\s.*target=linux-x86_64 out=kits/linux-x86_64/} $out] |
||||
lappend result linbuild [regexp {(?n)^\s+build product: src/_build/kits/linux-x86_64/fixlin } $out] |
||||
lappend result lindeploy [regexp {(?n)^\s+deployed:\s+bin/kits/linux-x86_64/fixlin } $out] |
||||
set result |
||||
} -result {timedout 0 exitcode 0 natrow 1 natnonotes 1 natbuild 1 natdeploy 1 linrow 1 linbuild 1 lindeploy 1} |
||||
|
||||
#added 2026-07-31 (agent, G-127) |
||||
test maketcl_bakelist_same_name_two_nonnative_coexist {two NON-NATIVE targets sharing one kit name: two rows, locations split by platform tier (and target-driven .exe suffix), no runtime-name rename} -constraints {punkexeavailable} -body { |
||||
#legacy line format carries an explicit kitname element, letting two entries |
||||
#declare the SAME output name for different targets |
||||
set r [maketcl_run_mapseam fixture_samename.config { |
||||
{tclkit-902-Linux64-intel-dyn {punk9wintk903.vfs fixsame kit linux-x86_64}} |
||||
{tclsh8.6.10-luck-zip.exe {punk9wintk903.vfs fixsame zip win32-ix86}} |
||||
} {bakelist fixsame}] |
||||
set out [dict get $r output] |
||||
set result [list] |
||||
lappend result timedout [dict get $r timedout] exitcode [dict get $r exitcode] |
||||
lappend result linrow [regexp {(?n)^fixsame\s+kit\s+tclkit-902-Linux64-intel-dyn\s+punk9wintk903\.vfs\s+\S+\s.*out=kits/linux-x86_64/} $out] |
||||
lappend result ixrow [regexp {(?n)^fixsame\s+zip\s+tclsh8\.6\.10-luck-zip\s+punk9wintk903\.vfs\s+\S+\s.*out=kits/win32-ix86/} $out] |
||||
#the pre-G-127 behaviour disambiguated the second row by RUNTIME name - pin its absence |
||||
lappend result norename [expr {![regexp {(?n)^fixsame_} $out]}] |
||||
#distinct artifacts by construction: same name, two tiers, suffix follows target |
||||
lappend result linbuild [regexp {(?n)^\s+build product: src/_build/kits/linux-x86_64/fixsame } $out] |
||||
lappend result ixbuild [regexp {(?n)^\s+build product: src/_build/kits/win32-ix86/fixsame\.exe } $out] |
||||
set result |
||||
} -result {timedout 0 exitcode 0 linrow 1 ixrow 1 norename 1 linbuild 1 ixbuild 1} |
||||
|
||||
#added 2026-07-31 (agent, G-127) |
||||
test maketcl_bakelist_same_name_same_target_still_renamed {a same-name SAME-target duplicate keeps the historical <name>_<runtime> disambiguation} -constraints {punkexeavailable} -body { |
||||
set r [maketcl_run_mapseam fixture_sametarget.config { |
||||
{tclsfe-x64.exe {punk9wintk903.vfs fixdup zip}} |
||||
{tclsh905.exe {punk9wintk905.vfs fixdup zip}} |
||||
} {bakelist}] |
||||
set out [dict get $r output] |
||||
set result [list] |
||||
lappend result timedout [dict get $r timedout] exitcode [dict get $r exitcode] |
||||
lappend result firstrow [regexp {(?n)^fixdup\s+zip\s+tclsfe-x64\s} $out] |
||||
lappend result renamedrow [regexp {(?n)^fixdup_tclsh905\s+zip\s+tclsh905\s} $out] |
||||
set result |
||||
} -result {timedout 0 exitcode 0 firstrow 1 renamedrow 1} |
||||
|
||||
cleanupTests |
||||
} |
||||
namespace delete ::testspace |
||||
Loading…
Reference in new issue