Files
sausage/userland/curl/test.nu
T

114 lines
6.5 KiB
Nu

#!/usr/bin/env nu
# Compare curl transfers with native curl and check standard WASI imports.
use std/assert
def guest [component: path, root: path, args: list, input: string = ''] {
$input | ^wasmtime run -S http -S cli-exit-with-code=y --dir $'($root)::/' --env HOME=/ $component ...$args | complete
}
def compare [name: string, component: path, root: path, url: string, args: list, input: string = '', stderr: bool = false] {
let native = ($input | ^curl ...$args $url | complete)
let wasi = (guest $component $root ($args | append $url) $input)
assert equal $wasi.exit_code $native.exit_code $name
assert equal $wasi.stdout $native.stdout $name
if $stderr { assert equal $wasi.stderr $native.stderr $name }
print $'($name): PASS'
}
def main [component: path = '/tmp/p1-curl/target/wasm32-wasip2/release/curl.wasm'] {
let component = ($component | path expand)
mkdir /tmp/p1-curl
let root = (^mktemp -d -p /tmp/p1-curl comparison.XXXXXX | str trim)
let manifest = ($env.FILE_PWD | path join tests/server/Cargo.toml)
let build = (with-env {CARGO_BUILD_JOBS: '2', CARGO_TARGET_DIR: '/tmp/p1-curl/server-target'} { ^cargo build --manifest-path $manifest --locked } | complete)
if $build.exit_code != 0 { error make {msg: ($build | to json)} }
let readiness = ($root | path join port)
let server = job spawn { ^/tmp/p1-curl/server-target/debug/curl-test-server $readiness out> ($root | path join server.out) err> ($root | path join server.err) }
try {
let deadline = (date now) + 5sec
while not ($readiness | path exists) {
if (date now) >= $deadline { error make {msg: $'Fixture did not start. Inspect ($root)/server.err'} }
}
let port = (open --raw $readiness | str trim)
run-tests $component $root $port
} catch {|failure|
job kill $server
error make {msg: $failure.msg}
}
job kill $server
print 'Fixture stopped: PASS'
}
def run-tests [component: path, root: path, port: string] {
let base = $'http://127.0.0.1:($port)'
let wit = (^wasm-tools component wit $component | complete)
assert equal $wit.exit_code 0
let imports = ($wit.stdout | lines | str trim | where {|line| $line | str starts-with 'import '})
assert (not ($imports | is-empty))
assert ($imports | all {|line| $line | str starts-with 'import wasi:'})
print 'Imports: PASS (WASI only)'
print ($imports | str join (char newline))
let cases = [
{name: GET, path: /echo, args: [-sS -A Agent]}
{name: method, path: /echo, args: [-sS -A Agent -X DELETE]}
{name: headers, path: /echo, args: [-sS -A Agent -H 'X-Test: one' -H 'X-Test: two' -H 'Accept: custom']}
{name: suppress-header, path: /echo, args: [-sS -A Agent -H 'Accept:']}
{name: data, path: /echo, args: [-sS -A Agent -d a=1 --data b=2]}
{name: empty-data, path: /echo, args: [-sS -A Agent -d '' -d x]}
{name: raw, path: /echo, args: [-sS -A Agent --data-raw '@literal']}
{name: mixed-data, path: /echo, args: [-sS -A Agent --data-raw a -d b --data-binary c]}
{name: explicit-GET-data, path: /echo, args: [-sS -A Agent -X GET -d text]}
{name: JSON, path: /echo, args: [-sS -A Agent --json '{"a":1}']}
{name: JSON-headers, path: /echo, args: [-sS -A Agent --json '{}' -H 'Content-Type: custom']}
{name: basic, path: /echo, args: [-sS -A Agent -u 'user:pass']}
{name: redirect-no-follow, path: /redirect, args: [-sS -A Agent]}
{name: redirect, path: /redirect, args: [-sS -A Agent -L]}
{name: redirect-POST-GET, path: /303, args: [-sS -A Agent -L -d x]}
{name: redirect-preserve-POST, path: /307, args: [-sS -A Agent -L -d x]}
{name: redirect-limit, path: /loop, args: [-s -L --max-redirs 1]}
{name: fail, path: /404, args: [-sS -f]}
{name: fail-body, path: /404, args: [-sS --fail-with-body]}
{name: silent-fail, path: /404, args: [-s -f]}
{name: fail-headers-size, path: /404, args: [-sS -fi -w '%{size_download}']}
{name: write-out, path: /plain, args: [-sS -w '%{http_code}|%{url_effective}|%{content_type}|%{size_download}\n']}
{name: head, path: /plain, args: [-sS -I]}
{name: include, path: /plain, args: [-sS -i]}
{name: ignored-insecure, path: /plain, args: [-sS -k]}
{name: timeout, path: /slow, args: [-s -m 0.01]}
]
for case in $cases { compare $case.name $component $root $'($base)($case.path)' $case.args '' ($case.name in [fail fail-body silent-fail]) }
let text = $"line1\nline2\r\n"
$text | save ($root | path join input)
for flag in [-d --data-binary --json] {
let native = (^curl -sS -A Agent $flag $'@($root)/input' $'($base)/echo' | complete)
let wasi = (guest $component $root [-sS -A Agent $flag '@/input' $'($base)/echo'])
assert equal $wasi.exit_code $native.exit_code
assert equal $wasi.stdout $native.stdout
print $'($flag) @file: PASS'
compare $'($flag) @-' $component $root $'($base)/echo' [-sS -A Agent $flag '@-'] $text
}
let native = (^curl -sS -o ($root | path join native.out) $'($base)/plain' | complete)
let wasi = (guest $component $root [-sS -o /guest.out $'($base)/plain'])
assert equal $wasi.exit_code $native.exit_code
assert equal $wasi.stdout $native.stdout
assert equal (open --raw ($root | path join guest.out)) (open --raw ($root | path join native.out))
print '-o: PASS'
let wasi = (guest $component $root [-sS -O $'($base)/plain'])
assert equal $wasi.exit_code 0
assert equal (open --raw ($root | path join plain)) $"hello\n"
print '-O: PASS'
let native = (^curl --no-such-option | complete)
let wasi = (guest $component $root [--no-such-option])
assert equal $wasi.exit_code 2
assert equal $wasi.stderr $native.stderr
print 'Unknown option: PASS'
let verbose = (guest $component $root [-sS -v -H 'X-Test: visible' $'($base)/plain'])
assert equal $verbose.exit_code 0
assert ($verbose.stderr | str contains '> X-Test: visible')
assert ($verbose.stderr | str contains '< HTTP/1.1 200 OK')
assert (not ($verbose.stderr | str contains 'Authorization'))
print 'Verbose request and response headers: PASS'
let https = (guest $component $root [-sS -w '%{http_code}' https://example.com])
assert equal $https.exit_code 0
assert ($https.stdout | str contains 'Example Domain')
assert ($https.stdout | str ends-with '200')
print 'Public HTTPS GET: PASS'
print $'Fixture retained: ($root)'
}