# Compare stdout and numeric statuses on one fixture tree. Run after the release build. def main [] { $env.LC_ALL = 'C' let repo = ($env.FILE_PWD | path dirname) let artifacts = ($repo | path join userland target tools wasm32-wasip2 release) let host = ($repo | path join target tools debug sausage) let world = (mktemp -d) let fixture = ($world | path join world) mkdir ($fixture | path join sub) ($fixture | path join bin) "alpha\nBeta alpha\nwords alphabet\nother\nalpha alpha\n" | save ($fixture | path join a.txt) "other\nalpha\n" | save ($fixture | path join sub b.txt) "different\n" | save ($fixture | path join c.log) mkdir ($fixture | path join left nested) ($fixture | path join right nested) "before\n" | save ($fixture | path join left nested a.txt) "after\n" | save ($fixture | path join right nested a.txt) "only left\n" | save ($fixture | path join left only.txt) '{"items":[1,2,3]}' | save ($fixture | path join data.json) for tool in [rg grep sed fd jaq find xargs env timeout] { cp ($artifacts | path join $"($tool).wasm") ($fixture | path join bin $tool) } for tool in [diff cmp] { cp ($artifacts | path join diffutils.wasm) ($fixture | path join bin $tool) } for tool in [echo wc printf printenv sleep] { cp ($repo | path join userland target wasm32-wasip2 release sausage-coreutils.wasm) ($fixture | path join bin $tool) } cp ($repo | path join userland brush source target wasm32-wasip2 release brush.wasm) ($fixture | path join bin sh) let cases = [ {tool: grep, args: [-rn alpha sub]} {tool: grep, args: [-i beta a.txt]} {tool: grep, args: [-v alpha a.txt]} {tool: grep, args: [-l alpha a.txt sub/b.txt]} {tool: grep, args: [-c alpha a.txt]} {tool: grep, args: [-w alpha a.txt]} {tool: grep, args: [-E 'alpha|Beta' a.txt]} {tool: grep, args: [-F 'alpha alpha' a.txt]} {tool: grep, args: [-o alpha a.txt]} {tool: grep, args: [-A 1 Beta a.txt]} {tool: grep, args: [-B 1 Beta a.txt]} {tool: grep, args: [-C 1 Beta a.txt]} {tool: grep, args: [-r '--include=*.txt' alpha sub]} {tool: grep, args: [absent a.txt]} {tool: grep, args: [alpha missing]} {tool: rg, args: [--sort path alpha a.txt]} {tool: rg, args: [--sort path -g '*.txt' alpha sub]} {tool: rg, args: [--sort path -l alpha sub]} {tool: find, args: [sub -name '*.txt']} {tool: find, args: [sub -type f]} {tool: find, args: [sub -path 'sub/*.txt']} {tool: find, args: [sub -maxdepth 0]} {tool: find, args: [sub -newer a.txt]} {tool: find, args: [sub -print0]} {tool: sed, args: [-n '2p' a.txt]} {tool: sed, args: ['s/alpha/ALPHA/g' a.txt]} {tool: sed, args: [-E 's/(alpha)/[\1]/g' a.txt]} {tool: sed, args: ['2,3d' a.txt]} {tool: diff, args: [-u a.txt a.txt]} {tool: diff, args: [-u a.txt c.log]} {tool: diff, args: [-r sub sub]} {tool: diff, args: [-r left right]} {tool: cmp, args: [a.txt a.txt]} {tool: cmp, args: [a.txt c.log]} {tool: fd, args: [b sub]} {tool: fd, args: [-e txt . sub]} {tool: jaq, args: ['.items | map(. * 2)' data.json]} ] for case in $cases { let native = if $case.tool == jaq { do { cd $fixture; ^nix shell nixpkgs#jq -c jq ...$case.args } | complete } else { do { cd $fixture; ^$case.tool ...$case.args } | complete } let guest = if $case.tool == find { let quoted = ($case.args | each {|a| $"'($a)'" } | str join ' ') do { ^$host sh $world -c $"find ($quoted)" } | complete } else { let name = if $case.tool in [diff cmp] { 'diffutils' } else { $case.tool } let wasm = ($artifacts | path join $"($name).wasm") let args = if $name == diffutils { [$case.tool] | append $case.args } else { $case.args } do { ^wasmtime run --dir $"($fixture)::/" --env PWD=/ $wasm ...$args } | complete } if $native.stdout != $guest.stdout or $native.exit_code != $guest.exit_code { error make {msg: $"Mismatch ($case): native=($native) guest=($guest). Fixture: ($fixture)"} } print $"PASS ($case.tool) ($case.args)" } # In-place editing changes the fixture. Reset it before the guest comparison. "alpha alpha\n" | save ($fixture | path join edit.txt) let native = (do { cd $fixture; ^sed -i 's/alpha/B/g' edit.txt } | complete) let expected = (open --raw ($fixture | path join edit.txt)) "alpha alpha\n" | save -f ($fixture | path join edit.txt) let guest = (do { ^wasmtime run --dir $"($fixture)::/" --env PWD=/ ($artifacts | path join sed.wasm) -i 's/alpha/B/g' edit.txt } | complete) if $guest.exit_code != $native.exit_code or (open --raw ($fixture | path join edit.txt)) != $expected { error make {msg: 'sed -i mismatch'} } print 'PASS sed -i' for case in [ {script: 'env FOO=1 printenv FOO', stdout: "1\n", code: 0} {script: 'timeout 1 sleep 5', stdout: '', code: 124} {script: 'cd sub && find . -name "*.txt" -exec wc -l {} \;', stdout: "2 ./b.txt\n", code: 0} {script: "printf 'a\nb\n' | xargs -n1 echo", stdout: "a\nb\n", code: 0} ] { let result = (do { ^$host sh $world -c $case.script } | complete) if $result.stdout != $case.stdout or $result.exit_code != $case.code { error make {msg: $"Spawn mismatch: ($case) got ($result)"} } print $"PASS ($case.script)" } rm -r $world }