Browse Source
- punk_main.tcl captures the runtime static baseline at kit boot: empty-filename [info loaded] prefixes probe-loaded in a throwaway interp (configurable denylist tk*/vfs/mk4tcl/vlerq/tdbc* for side-effecting/composite inits), recording only packages a load actually PROVIDES (diff on provides, not package names - probe loads can trigger index scans) into ::punkboot::static_packages/static_prefixes; the boot interp is seeded with ifneeded {load {} <prefix>} mappings
- punk::lib interp_sync_package_paths/snapshot_package_paths propagate the baseline and seed fabricated interps/threads; punk::repl codethread init (new %staticprefixes%/%staticpackages% scriptmap) and shellthread worker init do the same - the repl code interp on a static runtime resolves Thread again (punk91 = tclsfe-x64 + punk9win.vfs failed with "can't find package Thread"; the appended vfs replaces the stub's //zipfs:/app mount taking its static pkgIndex files with it, and the tclsfe PostInit hook seeds per-interp auto_path only)
- punk::packagepreference static-vs-bundled policy: requiring a baseline package ensures the static mapping and triggers the package unknown scan BEFORE resolution so bundled copies register and the highest version wins (newer bundled reachable, static not masked by older bundled); static registrations excluded from the loaded-shared-object same-version pinning
- composite statics defer correctly: static twapi provides nothing under the probe (script layer lived in the replaced stub zip) so the bundled complete twapi is the resolution; punk91 vfs/vfs::zip warning re-diagnosed as kit content (tclsfe bundles no tclvfs) - recorded in the goal detail, not a seeding defect
- tests: staticseed.test (4) + staticpolicy.test (4) un-gated simulated-baseline units (green 9.0.3 + 8.7); staticruntime.test (4) kit integration behind the capability-probed statickitavailable constraint (probes ::punkboot baseline incl Thread; env PUNK_STATICKIT_TEST_EXE override, default bin/punk91.exe) - 4/4 against the rebuilt punk91; punk902z/full shell tree/full source-tree suite baselines unchanged (exec-14.3 only)
- verification runtime tclsfe-x64.exe pinned in the punkbin artifact repo (separate repo, commit b2dbbe6) with sha1sums + new AGENTS.md scaffolding
- punkshell 0.6.0: CHANGELOG entry; AGENTS updates (src/vfs capture contract, tests indexes incl new punk/lib + punk/packagepreference entries, shell staticruntime contract)
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
master
19 changed files with 715 additions and 9 deletions
@ -1,3 +1,3 @@
|
||||
[project] |
||||
name = "punkshell" |
||||
version = "0.5.0" |
||||
version = "0.6.0" |
||||
|
||||
@ -1,4 +1,5 @@
|
||||
0.1.1 |
||||
0.2.0 |
||||
#First line must be a semantic version number |
||||
#all other lines are ignored. |
||||
#0.2.0 - G-058 static-vs-bundled policy: on require of a package in the runtime static baseline (::punkboot::static_packages), ensure the static ifneeded mapping exists and trigger the package unknown index scan so bundled vfs/module copies register BEFORE resolution - version comparison then applies (highest wins; identical versions resolve to the bundled copy). Static REGISTRATIONS (empty-filename info loaded entries) are now excluded from the loaded-shared-object same-version forcing, which would otherwise pin resolution to the static version even when a bundled copy is genuinely newer. |
||||
#0.1.1 - moduledoc auto-load success notice moved from stdout to stderr (stdout must stay clean for script/exec contexts e.g the punk 'script' subcommand; failure branch already used stderr) |
||||
|
||||
@ -1,4 +1,5 @@
|
||||
1.6.3 |
||||
1.7.0 |
||||
#First line must be a semantic version number |
||||
#all other lines are ignored. |
||||
#1.7.0 - G-058: worker thread init script seeds the runtime static/builtin package baseline (::punkboot::static_prefixes/static_packages captured at kit boot) with ifneeded {load {} <prefix>} mappings before packagepreference install, so workers can require statically-linked runtime packages |
||||
#1.6.3 - manager teardown must not block on a wedged worker (G-036: Tcl 9 console+udp worker event-loop wedge): unsubscribe's settings-reset thread::send is now -async (was bare synchronous - froze exit/quit when the shellfilter-run syslog worker had wedged); shutdown_free_threads keeps its timeout timer armed across all vwait iterations (was cancelled on first response, leaving later waits unbounded); get_tag_config's bare synchronous send flagged as the same hazard class (needs a result - convert to async+vwait-with-timeout if it shows in a hang) |
||||
|
||||
@ -0,0 +1,131 @@
|
||||
package require tcltest |
||||
|
||||
package require punk::lib |
||||
|
||||
#G-058 unit coverage: propagation/seeding of the runtime static/builtin package baseline |
||||
#(::punkboot::static_prefixes / ::punkboot::static_packages, captured at kit boot by |
||||
#punk_main.tcl) through punk::lib::interp_sync_package_paths and |
||||
#punk::lib::snapshot_package_paths. These tests run un-gated under plain tclsh using a |
||||
#SIMULATED baseline - the ifneeded entries they assert reference a fake static prefix |
||||
#that is never actually loaded. Kit-level integration (real static runtime) is covered |
||||
#by src/tests/shell/testsuites/punkexe/staticruntime.test behind a capability constraint. |
||||
|
||||
namespace eval ::testspace { |
||||
namespace import ::tcltest::* |
||||
variable common { |
||||
set result "" |
||||
} |
||||
|
||||
#save/restore any real ::punkboot baseline around each test (shared test interp) |
||||
proc baseline_save {} { |
||||
variable saved |
||||
set saved [dict create] |
||||
foreach v {static_prefixes static_packages} { |
||||
if {[info exists ::punkboot::$v]} { |
||||
dict set saved $v [set ::punkboot::$v] |
||||
} |
||||
} |
||||
} |
||||
proc baseline_restore {} { |
||||
variable saved |
||||
foreach v {static_prefixes static_packages} { |
||||
if {[dict exists $saved $v]} { |
||||
set ::punkboot::$v [dict get $saved $v] |
||||
} else { |
||||
catch {unset ::punkboot::$v} |
||||
} |
||||
} |
||||
} |
||||
proc baseline_fake {} { |
||||
namespace eval ::punkboot {} |
||||
set ::punkboot::static_prefixes [list Fakestat] |
||||
set ::punkboot::static_packages [dict create {*}{ |
||||
fakestatic {version 1.2 prefix Fakestat} |
||||
Fakestatic {version 1.2 prefix Fakestat} |
||||
}] |
||||
} |
||||
proc baseline_none {} { |
||||
catch {unset ::punkboot::static_prefixes} |
||||
catch {unset ::punkboot::static_packages} |
||||
} |
||||
|
||||
test staticseed_interp_sync_seeds {interp_sync_package_paths seeds baseline ifneeded mappings and copies the ::punkboot vars into the child}\ |
||||
-setup { |
||||
set result "" |
||||
baseline_save |
||||
baseline_fake |
||||
interp create staticseed_child |
||||
}\ |
||||
-body { |
||||
punk::lib::interp_sync_package_paths staticseed_child |
||||
lappend result [interp eval staticseed_child {package ifneeded fakestatic 1.2}] |
||||
lappend result [interp eval staticseed_child {package ifneeded Fakestatic 1.2}] |
||||
lappend result [interp eval staticseed_child {dict keys $::punkboot::static_packages}] |
||||
lappend result [interp eval staticseed_child {set ::punkboot::static_prefixes}] |
||||
}\ |
||||
-cleanup { |
||||
interp delete staticseed_child |
||||
baseline_restore |
||||
}\ |
||||
-result [list {load {} Fakestat} {load {} Fakestat} {fakestatic Fakestatic} Fakestat] |
||||
|
||||
test staticseed_interp_sync_no_overwrite_provided {a package already provided in the child is not re-mapped; other baseline entries still seed}\ |
||||
-setup { |
||||
set result "" |
||||
baseline_save |
||||
baseline_fake |
||||
interp create staticseed_child |
||||
}\ |
||||
-body { |
||||
interp eval staticseed_child {package provide fakestatic 9.9} |
||||
punk::lib::interp_sync_package_paths staticseed_child |
||||
lappend result [interp eval staticseed_child {package ifneeded fakestatic 1.2}] |
||||
lappend result [interp eval staticseed_child {package ifneeded Fakestatic 1.2}] |
||||
}\ |
||||
-cleanup { |
||||
interp delete staticseed_child |
||||
baseline_restore |
||||
}\ |
||||
-result [list {} {load {} Fakestat}] |
||||
|
||||
test staticseed_snapshot_script_seeds {snapshot_package_paths returns a script that reproduces the baseline and seeding in a fresh interp}\ |
||||
-setup { |
||||
set result "" |
||||
baseline_save |
||||
baseline_fake |
||||
interp create staticseed_child |
||||
}\ |
||||
-body { |
||||
set scr [punk::lib::snapshot_package_paths] |
||||
lappend result [string match "*::punkboot::static_packages*" $scr] |
||||
interp eval staticseed_child $scr |
||||
lappend result [interp eval staticseed_child {package ifneeded fakestatic 1.2}] |
||||
lappend result [interp eval staticseed_child {dict get $::punkboot::static_packages fakestatic prefix}] |
||||
}\ |
||||
-cleanup { |
||||
interp delete staticseed_child |
||||
baseline_restore |
||||
}\ |
||||
-result [list 1 {load {} Fakestat} Fakestat] |
||||
|
||||
test staticseed_noop_without_baseline {with no captured baseline (plain tclsh) neither helper adds punkboot state or ifneeded entries}\ |
||||
-setup { |
||||
set result "" |
||||
baseline_save |
||||
baseline_none |
||||
interp create staticseed_child |
||||
}\ |
||||
-body { |
||||
punk::lib::interp_sync_package_paths staticseed_child |
||||
lappend result [interp eval staticseed_child {info exists ::punkboot::static_packages}] |
||||
lappend result [interp eval staticseed_child {package ifneeded fakestatic 1.2}] |
||||
set scr [punk::lib::snapshot_package_paths] |
||||
lappend result [string match "*static_packages*" $scr] |
||||
}\ |
||||
-cleanup { |
||||
interp delete staticseed_child |
||||
baseline_restore |
||||
}\ |
||||
-result [list 0 {} 0] |
||||
} |
||||
tcltest::cleanupTests ;#needed to produce test summary line. |
||||
@ -0,0 +1,119 @@
|
||||
package require tcltest |
||||
|
||||
package require punk::lib |
||||
|
||||
#G-058 unit coverage: punk::packagepreference static-vs-bundled resolution policy. |
||||
#On 'package require' of a package present in the runtime static baseline |
||||
#(::punkboot::static_packages), the overloaded require ensures the static ifneeded |
||||
#mapping exists and triggers the package unknown index scan so bundled copies register |
||||
#BEFORE resolution - then standard version comparison applies (highest acceptable wins). |
||||
#Without the scan trigger, a seeded static version would satisfy the require immediately |
||||
#and a genuinely newer bundled copy would never be seen. |
||||
# |
||||
#These tests run un-gated under plain tclsh: the "static" package is simulated with a |
||||
#pre-registered working ifneeded script (the policy block only adds its own |
||||
#'load {} <prefix>' mapping when the baseline version is absent from package versions), |
||||
#and the "bundled" copies are pkgIndex.tcl fixtures on the child interp's auto_path. |
||||
#Real static runtime integration: src/tests/shell/testsuites/punkexe/staticruntime.test. |
||||
|
||||
namespace eval ::testspace { |
||||
namespace import ::tcltest::* |
||||
variable common { |
||||
set result "" |
||||
} |
||||
|
||||
variable fixdir_new [makeDirectory staticpolicy_newer] |
||||
variable fixdir_old [makeDirectory staticpolicy_older] |
||||
makeFile {package ifneeded fakestatic 1.5 {package provide fakestatic 1.5}} pkgIndex.tcl $fixdir_new |
||||
makeFile {package ifneeded fakestatic 1.0 {package provide fakestatic 1.0}} pkgIndex.tcl $fixdir_old |
||||
|
||||
#child interp with punk::packagepreference installed, a simulated static baseline for |
||||
#'fakestatic 1.2', and auto_path pointing at the given bundled-fixture dir |
||||
proc policy_child {name bundledir} { |
||||
interp create $name |
||||
#tm paths so the child can require punk::packagepreference from the source tree |
||||
punk::lib::interp_sync_package_paths $name |
||||
interp eval $name {package require punk::packagepreference} |
||||
interp eval $name {punk::packagepreference::install} |
||||
interp eval $name [list set ::auto_path [list $bundledir]] |
||||
interp eval $name { |
||||
namespace eval ::punkboot {} |
||||
set ::punkboot::static_prefixes [list Fakestat] |
||||
set ::punkboot::static_packages [dict create fakestatic {version 1.2 prefix Fakestat}] |
||||
#simulate a WORKING static loader for the baseline version (a real runtime |
||||
#would satisfy this via 'load {} Fakestat') |
||||
package ifneeded fakestatic 1.2 {package provide fakestatic 1.2} |
||||
} |
||||
} |
||||
|
||||
test staticpolicy_newer_bundled_wins {a bundled copy newer than the static baseline version is found (scan triggered before resolution) and wins}\ |
||||
-setup { |
||||
set result "" |
||||
variable fixdir_new |
||||
policy_child pol_child $fixdir_new |
||||
}\ |
||||
-body { |
||||
lappend result [interp eval pol_child {package require fakestatic}] |
||||
lappend result [interp eval pol_child {package provide fakestatic}] |
||||
}\ |
||||
-cleanup { |
||||
interp delete pol_child |
||||
}\ |
||||
-result [list 1.5 1.5] |
||||
|
||||
test staticpolicy_static_beats_older_bundled {the static baseline version wins over an older bundled copy}\ |
||||
-setup { |
||||
set result "" |
||||
variable fixdir_old |
||||
policy_child pol_child $fixdir_old |
||||
}\ |
||||
-body { |
||||
lappend result [interp eval pol_child {package require fakestatic}] |
||||
lappend result [interp eval pol_child {package provide fakestatic}] |
||||
}\ |
||||
-cleanup { |
||||
interp delete pol_child |
||||
}\ |
||||
-result [list 1.2 1.2] |
||||
|
||||
test staticpolicy_exact_older_bundled_reachable {an exact require of the older bundled version still resolves (scan applies to exact requires too)}\ |
||||
-setup { |
||||
set result "" |
||||
variable fixdir_old |
||||
policy_child pol_child $fixdir_old |
||||
}\ |
||||
-body { |
||||
lappend result [interp eval pol_child {package require -exact fakestatic 1.0}] |
||||
}\ |
||||
-cleanup { |
||||
interp delete pol_child |
||||
}\ |
||||
-result [list 1.0] |
||||
|
||||
test staticpolicy_seeds_missing_mapping {when the baseline version has no ifneeded entry the policy block adds the 'load {} <prefix>' mapping}\ |
||||
-setup { |
||||
set result "" |
||||
variable fixdir_old |
||||
interp create pol_child |
||||
punk::lib::interp_sync_package_paths pol_child |
||||
interp eval pol_child {package require punk::packagepreference} |
||||
interp eval pol_child {punk::packagepreference::install} |
||||
interp eval pol_child [list set ::auto_path [list $fixdir_old]] |
||||
interp eval pol_child { |
||||
namespace eval ::punkboot {} |
||||
set ::punkboot::static_prefixes [list Fakestat] |
||||
set ::punkboot::static_packages [dict create fakestatic {version 1.2 prefix Fakestat}] |
||||
#no working ifneeded for 1.2 - the require will fail at load time |
||||
#(no real static Fakestat exists) but must have REGISTERED the mapping |
||||
} |
||||
}\ |
||||
-body { |
||||
catch {interp eval pol_child {package require fakestatic 1.2}} |
||||
lappend result [interp eval pol_child {package ifneeded fakestatic 1.2}] |
||||
}\ |
||||
-cleanup { |
||||
interp delete pol_child |
||||
}\ |
||||
-result [list {load {} Fakestat}] |
||||
} |
||||
tcltest::cleanupTests ;#needed to produce test summary line. |
||||
@ -0,0 +1,209 @@
|
||||
package require tcltest |
||||
|
||||
#G-058 integration: a punkshell kit built on a runtime with statically-linked packages |
||||
#(e.g punk91 = tclsfe-x64.exe + punk9win.vfs: static Thread/twapi/sqlite3/tdbc) must keep |
||||
#those packages resolvable in the interps/threads punkshell fabricates - the repl's |
||||
#codethread/code interp, punk::lib::interp_sync_package_paths children, and |
||||
#snapshot_package_paths threads. Seeding/policy logic has un-gated unit coverage in |
||||
#modules/punk/lib/.../staticseed.test and modules/punk/packagepreference/.../staticpolicy.test; |
||||
#these tests exercise the real kit end to end. |
||||
# |
||||
#CONSTRAINT (capability-probed, not filename-hardcoded): the target executable is resolved |
||||
#from env(PUNK_STATICKIT_TEST_EXE) if set, else <projectroot>/bin/punk91.exe - and is only |
||||
#used if a probe run shows a captured static baseline including Thread |
||||
#(::punkboot::static_packages populated by the kit boot). Tests skip cleanly otherwise. |
||||
#To make the constraint satisfiable on other machines the verification runtime |
||||
#(tclsfe-x64.exe) is pinned in the punkbin artifact repository (win32-x86_64/ + |
||||
#sha1sums.txt) - retrieve to bin/runtime/<platform>/ and rebuild. |
||||
# |
||||
#NOTE: tests exercise the BUILT executable - after changing punk_main.tcl or the seeding |
||||
#modules, rebuild with 'make.tcl modules', 'make.tcl vfscommonupdate', 'make.tcl project' |
||||
#or these tests will run against a stale binary. |
||||
|
||||
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 statickitexe "" |
||||
if {[info exists ::env(PUNK_STATICKIT_TEST_EXE)] && $::env(PUNK_STATICKIT_TEST_EXE) ne ""} { |
||||
set statickitexe [file normalize $::env(PUNK_STATICKIT_TEST_EXE)] |
||||
} else { |
||||
set candidate [file join $projectroot bin punk91.exe] |
||||
if {[file exists $candidate]} { |
||||
set statickitexe $candidate |
||||
} |
||||
} |
||||
|
||||
variable punk_run_timeout_ms 30000 |
||||
variable runstate |
||||
array set runstate {} |
||||
|
||||
proc punk_run_read {chan} { |
||||
variable runstate |
||||
append runstate(output) [read $chan] |
||||
if {[chan eof $chan]} { |
||||
chan event $chan readable {} |
||||
set runstate(done) eof |
||||
} |
||||
} |
||||
#Run the target executable with args, feed stdin_data via pipe then half-close. |
||||
#Returns dict: timedout 0|1, exitcode <int|kill-info|"">, output <combined stdout+stderr> |
||||
proc punk_run {exe cmdargs stdin_data} { |
||||
variable runstate |
||||
variable punk_run_timeout_ms |
||||
array unset runstate |
||||
set runstate(output) "" |
||||
set runstate(done) "" |
||||
set env_had [info exists ::env(PUNK_PIPE_EOF)] |
||||
if {$env_had} { |
||||
set env_save $::env(PUNK_PIPE_EOF) |
||||
} |
||||
set ::env(PUNK_PIPE_EOF) exit |
||||
set chan [open |[list $exe {*}$cmdargs 2>@1] r+] |
||||
if {$env_had} { |
||||
set ::env(PUNK_PIPE_EOF) $env_save |
||||
} else { |
||||
unset ::env(PUNK_PIPE_EOF) |
||||
} |
||||
set pids [pid $chan] |
||||
chan configure $chan -blocking 0 -translation binary |
||||
catch { |
||||
puts -nonewline $chan $stdin_data |
||||
flush $chan |
||||
chan close $chan write |
||||
} |
||||
set timerid [after $punk_run_timeout_ms [list set [namespace current]::runstate(done) timeout]] |
||||
chan event $chan readable [list [namespace current]::punk_run_read $chan] |
||||
vwait [namespace current]::runstate(done) |
||||
after cancel $timerid |
||||
set timedout [expr {$runstate(done) eq "timeout"}] |
||||
set exitcode "" |
||||
if {$timedout} { |
||||
foreach p $pids { |
||||
catch {exec {*}[auto_execok taskkill] /F /T /PID $p} killres |
||||
lappend exitcode [list killed $p] |
||||
} |
||||
catch {chan close $chan} |
||||
} else { |
||||
chan configure $chan -blocking 1 |
||||
if {[catch {chan close $chan} errM errOpts]} { |
||||
set details [dict get $errOpts -errorcode] |
||||
if {[lindex $details 0] eq "CHILDSTATUS"} { |
||||
set exitcode [lindex $details 2] |
||||
} else { |
||||
set exitcode [list error $errM] |
||||
} |
||||
} else { |
||||
set exitcode 0 |
||||
} |
||||
} |
||||
return [dict create timedout $timedout exitcode $exitcode output $runstate(output)] |
||||
} |
||||
|
||||
#capability probe: run the candidate with a script that reports the captured baseline. |
||||
#Constraint requires a non-empty ::punkboot::static_packages including Thread. |
||||
variable probe_ok 0 |
||||
if {$statickitexe ne "" && [file exists $statickitexe]} { |
||||
variable probescript [makeFile { |
||||
if {[info exists ::punkboot::static_packages]} { |
||||
puts "STATICBASELINE=[dict keys $::punkboot::static_packages]" |
||||
} else { |
||||
puts "STATICBASELINE=" |
||||
} |
||||
exit 0 |
||||
} staticruntime_probe.tcl] |
||||
#kit script exec requires forward slashes (the shellspy dispatch mangles backslashes) |
||||
set proberesult [punk_run $statickitexe [list [string map {\\ /} $probescript]] ""] |
||||
if {![dict get $proberesult timedout] && [regexp {STATICBASELINE=([^\r\n]*)} [dict get $proberesult output] -> blkeys]} { |
||||
if {"Thread" in $blkeys} { |
||||
set probe_ok 1 |
||||
} |
||||
} |
||||
} |
||||
testConstraint statickitavailable $probe_ok |
||||
|
||||
test staticruntime_shell_boot_no_thread_error {the repl boots on the static kit without the codethread Thread resolution failure}\ |
||||
-constraints statickitavailable\ |
||||
-setup { |
||||
set result "" |
||||
}\ |
||||
-body { |
||||
variable statickitexe |
||||
set r [punk_run $statickitexe [list shell] "exit\n"] |
||||
lappend result [dict get $r timedout] |
||||
lappend result [string match "*can't find package Thread*" [dict get $r output]] |
||||
lappend result [string match "*failed to load punk::console*" [dict get $r output]] |
||||
}\ |
||||
-cleanup { |
||||
}\ |
||||
-result [list 0 0 0] |
||||
|
||||
test staticruntime_codeinterp_thread_and_baseline {the code interp resolves Thread (static version) and can introspect the captured baseline}\ |
||||
-constraints statickitavailable\ |
||||
-setup { |
||||
set result "" |
||||
}\ |
||||
-body { |
||||
variable statickitexe |
||||
set stdin_data "puts THREADVER=\[package require Thread\]\nputs BASELINE=\[expr {\[dict size \$::punkboot::static_packages\] > 0}\]\nexit\n" |
||||
set r [punk_run $statickitexe [list shell] $stdin_data] |
||||
lappend result [dict get $r timedout] |
||||
lappend result [regexp {THREADVER=[0-9][0-9.abp]*} [dict get $r output]] |
||||
lappend result [regexp {BASELINE=1} [dict get $r output]] |
||||
}\ |
||||
-cleanup { |
||||
}\ |
||||
-result [list 0 1 1] |
||||
|
||||
test staticruntime_fabricated_interp_and_thread {a fabricated child interp and a snapshot-seeded worker thread resolve Thread inside the kit}\ |
||||
-constraints statickitavailable\ |
||||
-setup { |
||||
set result "" |
||||
variable fabscript [makeFile { |
||||
package require punk::lib |
||||
interp create fab |
||||
punk::lib::interp_sync_package_paths fab |
||||
puts "FABINTERP=[interp eval fab {catch {package require Thread} r; set r}]" |
||||
interp delete fab |
||||
package require Thread |
||||
#worker must stay alive for the sends (a bare create waits in its event loop) |
||||
set wid [thread::create] |
||||
thread::send $wid [punk::lib::snapshot_package_paths] |
||||
thread::send $wid {catch {package require Thread} r; set r} wr |
||||
puts "FABTHREAD=$wr" |
||||
thread::release $wid |
||||
exit 0 |
||||
} staticruntime_fab.tcl] |
||||
}\ |
||||
-body { |
||||
variable statickitexe |
||||
variable fabscript |
||||
set r [punk_run $statickitexe [list [string map {\\ /} $fabscript]] ""] |
||||
lappend result [dict get $r timedout] |
||||
lappend result [regexp {FABINTERP=[0-9][0-9.abp]*} [dict get $r output]] |
||||
lappend result [regexp {FABTHREAD=[0-9][0-9.abp]*} [dict get $r output]] |
||||
}\ |
||||
-cleanup { |
||||
}\ |
||||
-result [list 0 1 1] |
||||
|
||||
test staticruntime_twapi_resolves {twapi resolves in the kit per the static-vs-bundled policy (composite static twapi defers to the bundled complete copy)}\ |
||||
-constraints statickitavailable\ |
||||
-setup { |
||||
set result "" |
||||
}\ |
||||
-body { |
||||
variable statickitexe |
||||
set stdin_data "puts TWAPIVER=\[package require twapi\]\nexit\n" |
||||
set r [punk_run $statickitexe [list shell] $stdin_data] |
||||
lappend result [dict get $r timedout] |
||||
lappend result [regexp {TWAPIVER=[0-9][0-9.abp]*} [dict get $r output]] |
||||
}\ |
||||
-cleanup { |
||||
}\ |
||||
-result [list 0 1] |
||||
} |
||||
tcltest::cleanupTests ;#needed to produce test summary line. |
||||
Loading…
Reference in new issue