Files
sausage/userland/search-test.nu
T
surma b9e3e3677d userland: search and exec tools, spawn library (T14)
rg (ripgrep 15.2), grep (ours, on ripgrep's regex crates), find and xargs
(ours), sed (uutils 0.3 wrapper), diff and cmp (uutils diffutils 0.6 with -r),
fd 10.5, jaq 2.3, env and timeout. userland/spawn is a small Command-like
client of the process interface. search-test.nu: 42 cases match native tools.
2026-11-06 17:21:51 +00:00

103 lines
5.5 KiB
Nu

# 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
}