kit

kit
git clone https://git.ryansepassi.com/git/kit.git
Log | Files | Refs | README

run.sh (16820B)


      1 #!/bin/sh
      2 # Driver-level checks for `kit run` Wasm sandbox CLI behavior.
      3 
      4 set -u
      5 
      6 script_dir=$(cd "$(dirname "$0")" && pwd)
      7 repo_root=$(cd "$script_dir/../.." && pwd)
      8 
      9 KIT="${KIT:-$repo_root/build/kit}"
     10 
     11 if [ ! -x "$KIT" ]; then
     12     echo "driver-wasm: kit binary not found at $KIT" >&2
     13     exit 2
     14 fi
     15 
     16 work=$(mktemp -d "${TMPDIR:-/tmp}/kit-driver-wasm-test.XXXXXX")
     17 trap 'rm -rf "$work"' EXIT
     18 
     19 KIT_KIT_DIR="$repo_root/test/lib"
     20 . "$repo_root/test/lib/kit_sh_kit.sh"
     21 kit_report_init
     22 
     23 cat > "$work/return0.wat" <<'WAT'
     24 (module
     25   (func (export "test_main") (result i32)
     26     i32.const 0))
     27 WAT
     28 
     29 cat > "$work/host_add.wat" <<'WAT'
     30 (module
     31   (import "env" "host_add" (func $host_add (param i32 i32) (result i32)))
     32   (func (export "test_main") (result i32)
     33     i32.const 21
     34     i32.const 21
     35     call $host_add
     36     i32.const 42
     37     i32.sub))
     38 WAT
     39 
     40 cat > "$work/memory_2page_max.wat" <<'WAT'
     41 (module
     42   (memory 1 2)
     43   (func (export "test_main") (result i32)
     44     i32.const 0))
     45 WAT
     46 
     47 cat > "$work/memory_one.wat" <<'WAT'
     48 (module
     49   (memory 1)
     50   (func (export "test_main") (result i32)
     51     i32.const 0))
     52 WAT
     53 
     54 cat > "$work/wasi_exit.wat" <<'WAT'
     55 (module
     56   (import "wasi_snapshot_preview1" "proc_exit" (func $proc_exit (param i32)))
     57   (func (export "test_main") (result i32)
     58     i32.const 7
     59     call $proc_exit
     60     i32.const 0))
     61 WAT
     62 
     63 cat > "$work/wasi_stdout.wat" <<'WAT'
     64 (module
     65   (import "wasi_snapshot_preview1" "fd_write"
     66     (func $fd_write (param i32 i32 i32 i32) (result i32)))
     67   (memory 1)
     68   (data (i32.const 0) "\08\00\00\00\0b\00\00\00")
     69   (data (i32.const 8) "hello wasi\0a")
     70   (func (export "test_main") (result i32)
     71     i32.const 1
     72     i32.const 0
     73     i32.const 1
     74     i32.const 20
     75     call $fd_write
     76     i32.const 0
     77     i32.ne))
     78 WAT
     79 
     80 cat > "$work/wasi_env.wat" <<'WAT'
     81 (module
     82   (import "wasi_snapshot_preview1" "environ_sizes_get"
     83     (func $sizes (param i32 i32) (result i32)))
     84   (import "wasi_snapshot_preview1" "environ_get"
     85     (func $get (param i32 i32) (result i32)))
     86   (memory 1)
     87   (func (export "test_main") (result i32)
     88     (local $err i32)
     89     (local $p i32)
     90     i32.const 0
     91     i32.const 4
     92     call $sizes
     93     local.set $err
     94     (if (i32.ne (local.get $err) (i32.const 0))
     95       (then (return (local.get $err))))
     96     (if (i32.ne (i32.load (i32.const 0)) (i32.const 1))
     97       (then (return (i32.const 10))))
     98     i32.const 8
     99     i32.const 64
    100     call $get
    101     local.set $err
    102     (if (i32.ne (local.get $err) (i32.const 0))
    103       (then (return (local.get $err))))
    104     i32.const 8
    105     i32.load
    106     local.set $p
    107     (if (i32.ne (i32.load8_u (local.get $p)) (i32.const 75))
    108       (then (return (i32.const 11))))
    109     (if (i32.ne (i32.load8_u offset=13 (local.get $p)) (i32.const 61))
    110       (then (return (i32.const 12))))
    111     (if (i32.ne (i32.load8_u offset=14 (local.get $p)) (i32.const 111))
    112       (then (return (i32.const 13))))
    113     i32.const 0))
    114 WAT
    115 
    116 cat > "$work/wasi_args.wat" <<'WAT'
    117 (module
    118   (import "wasi_snapshot_preview1" "args_sizes_get"
    119     (func $sizes (param i32 i32) (result i32)))
    120   (import "wasi_snapshot_preview1" "args_get"
    121     (func $get (param i32 i32) (result i32)))
    122   (memory 1)
    123   (func (export "test_main") (result i32)
    124     (local $err i32)
    125     (local $p i32)
    126     i32.const 0
    127     i32.const 4
    128     call $sizes
    129     local.set $err
    130     (if (i32.ne (local.get $err) (i32.const 0))
    131       (then (return (local.get $err))))
    132     (if (i32.ne (i32.load (i32.const 0)) (i32.const 2))
    133       (then (return (i32.const 20))))
    134     i32.const 8
    135     i32.const 64
    136     call $get
    137     local.set $err
    138     (if (i32.ne (local.get $err) (i32.const 0))
    139       (then (return (local.get $err))))
    140     i32.const 12
    141     i32.load
    142     local.set $p
    143     (if (i32.ne (i32.load8_u (local.get $p)) (i32.const 97))
    144       (then (return (i32.const 21))))
    145     (if (i32.ne (i32.load8_u offset=4 (local.get $p)) (i32.const 97))
    146       (then (return (i32.const 22))))
    147     i32.const 0))
    148 WAT
    149 
    150 cat > "$work/wasi_fs_read.wat" <<'WAT'
    151 (module
    152   (import "wasi_snapshot_preview1" "path_open"
    153     (func $path_open
    154       (param i32 i32 i32 i32 i32 i64 i64 i32 i32) (result i32)))
    155   (import "wasi_snapshot_preview1" "fd_read"
    156     (func $fd_read (param i32 i32 i32 i32) (result i32)))
    157   (import "wasi_snapshot_preview1" "fd_close"
    158     (func $fd_close (param i32) (result i32)))
    159   (memory 1)
    160   (data (i32.const 0) "\80\00\00\00\05\00\00\00")
    161   (data (i32.const 64) "hello.txt")
    162   (func (export "test_main") (result i32)
    163     (local $fd i32)
    164     (local $err i32)
    165     i32.const 3
    166     i32.const 0
    167     i32.const 64
    168     i32.const 9
    169     i32.const 0
    170     i64.const 0
    171     i64.const 0
    172     i32.const 0
    173     i32.const 16
    174     call $path_open
    175     local.set $err
    176     (if (i32.ne (local.get $err) (i32.const 0))
    177       (then (return (local.get $err))))
    178     i32.const 16
    179     i32.load
    180     local.set $fd
    181     local.get $fd
    182     i32.const 0
    183     i32.const 1
    184     i32.const 20
    185     call $fd_read
    186     local.set $err
    187     (if (i32.ne (local.get $err) (i32.const 0))
    188       (then (return (local.get $err))))
    189     (if (i32.ne (i32.load (i32.const 20)) (i32.const 5))
    190       (then (return (i32.const 30))))
    191     (if (i32.ne (i32.load8_u (i32.const 128)) (i32.const 104))
    192       (then (return (i32.const 31))))
    193     (if (i32.ne (i32.load8_u offset=4 (i32.const 128)) (i32.const 111))
    194       (then (return (i32.const 32))))
    195     local.get $fd
    196     call $fd_close
    197     drop
    198     i32.const 0))
    199 WAT
    200 
    201 cat > "$work/wasi_seek.wat" <<'WAT'
    202 (module
    203   (import "wasi_snapshot_preview1" "path_open"
    204     (func $path_open (param i32 i32 i32 i32 i32 i64 i64 i32 i32) (result i32)))
    205   (import "wasi_snapshot_preview1" "fd_read"
    206     (func $fd_read (param i32 i32 i32 i32) (result i32)))
    207   (import "wasi_snapshot_preview1" "fd_seek"
    208     (func $fd_seek (param i32 i64 i32 i32) (result i32)))
    209   (import "wasi_snapshot_preview1" "fd_tell"
    210     (func $fd_tell (param i32 i32) (result i32)))
    211   (import "wasi_snapshot_preview1" "fd_close"
    212     (func $fd_close (param i32) (result i32)))
    213   (memory 1)
    214   (data (i32.const 64) "hello.txt")
    215   (func (export "test_main") (result i32)
    216     (local $fd i32) (local $err i32)
    217     ;; path_open(dirfd=3, ..., "hello.txt", oflags=0, ..., &fd=16)
    218     i32.const 3 i32.const 0 i32.const 64 i32.const 9
    219     i32.const 0 i64.const 0 i64.const 0 i32.const 0 i32.const 16
    220     call $path_open local.set $err
    221     (if (i32.ne (local.get $err) (i32.const 0)) (then (return (i32.const 1))))
    222     (i32.load (i32.const 16)) local.set $fd
    223     ;; read 2 bytes into buf=128; iov at [0]=128 [4]=2; nread at 8
    224     (i32.store (i32.const 0) (i32.const 128))
    225     (i32.store (i32.const 4) (i32.const 2))
    226     local.get $fd i32.const 0 i32.const 1 i32.const 8
    227     call $fd_read local.set $err
    228     (if (i32.ne (local.get $err) (i32.const 0)) (then (return (i32.const 2))))
    229     (if (i32.ne (i32.load (i32.const 8)) (i32.const 2)) (then (return (i32.const 3))))
    230     (if (i32.ne (i32.load8_u (i32.const 128)) (i32.const 104)) ;; 'h'
    231       (then (return (i32.const 4))))
    232     ;; fd_seek(fd, offset=3, whence=0/SET, &newpos=24)
    233     local.get $fd i64.const 3 i32.const 0 i32.const 24
    234     call $fd_seek local.set $err
    235     (if (i32.ne (local.get $err) (i32.const 0)) (then (return (i32.const 5))))
    236     (if (i64.ne (i64.load (i32.const 24)) (i64.const 3)) (then (return (i32.const 6))))
    237     ;; fd_tell(fd, &pos=32)
    238     local.get $fd i32.const 32
    239     call $fd_tell local.set $err
    240     (if (i32.ne (local.get $err) (i32.const 0)) (then (return (i32.const 7))))
    241     (if (i64.ne (i64.load (i32.const 32)) (i64.const 3)) (then (return (i32.const 8))))
    242     ;; read 1 byte from pos 3: expect 'l'=108
    243     (i32.store (i32.const 4) (i32.const 1))
    244     local.get $fd i32.const 0 i32.const 1 i32.const 8
    245     call $fd_read local.set $err
    246     (if (i32.ne (local.get $err) (i32.const 0)) (then (return (i32.const 9))))
    247     (if (i32.ne (i32.load8_u (i32.const 128)) (i32.const 108)) ;; 'l'
    248       (then (return (i32.const 10))))
    249     local.get $fd call $fd_close drop
    250     i32.const 0))
    251 WAT
    252 
    253 cat > "$work/wasi_filestat.wat" <<'WAT'
    254 (module
    255   (import "wasi_snapshot_preview1" "path_open"
    256     (func $path_open (param i32 i32 i32 i32 i32 i64 i64 i32 i32) (result i32)))
    257   (import "wasi_snapshot_preview1" "fd_filestat_get"
    258     (func $fd_filestat_get (param i32 i32) (result i32)))
    259   (import "wasi_snapshot_preview1" "fd_close"
    260     (func $fd_close (param i32) (result i32)))
    261   (memory 1)
    262   (data (i32.const 256) "hello.txt")
    263   (func (export "test_main") (result i32)
    264     (local $fd i32) (local $err i32)
    265     i32.const 3 i32.const 0 i32.const 256 i32.const 9
    266     i32.const 0 i64.const 0 i64.const 0 i32.const 0 i32.const 16
    267     call $path_open local.set $err
    268     (if (i32.ne (local.get $err) (i32.const 0)) (then (return (i32.const 1))))
    269     (i32.load (i32.const 16)) local.set $fd
    270     ;; fd_filestat_get(fd, filestat=64): 64-byte struct
    271     local.get $fd i32.const 64
    272     call $fd_filestat_get local.set $err
    273     (if (i32.ne (local.get $err) (i32.const 0)) (then (return (i32.const 2))))
    274     ;; filetype @ 64+16=80: expect 4 (regular file)
    275     (if (i32.ne (i32.load8_u (i32.const 80)) (i32.const 4))
    276       (then (return (i32.const 3))))
    277     ;; size @ 64+32=96 (u64 LE): expect 5
    278     (if (i64.ne (i64.load (i32.const 96)) (i64.const 5))
    279       (then (return (i32.const 4))))
    280     local.get $fd call $fd_close drop
    281     i32.const 0))
    282 WAT
    283 
    284 cat > "$work/wasi_path_filestat.wat" <<'WAT'
    285 (module
    286   (import "wasi_snapshot_preview1" "path_filestat_get"
    287     (func $path_filestat_get (param i32 i32 i32 i32 i32) (result i32)))
    288   (memory 1)
    289   (data (i32.const 256) "hello.txt")
    290   (func (export "test_main") (result i32)
    291     (local $err i32)
    292     ;; path_filestat_get(dirfd=3, flags=0, path=256, pathlen=9, filestat=64)
    293     i32.const 3 i32.const 0 i32.const 256 i32.const 9 i32.const 64
    294     call $path_filestat_get local.set $err
    295     (if (i32.ne (local.get $err) (i32.const 0)) (then (return (local.get $err))))
    296     ;; filetype @ 64+16=80: expect 4 (regular file)
    297     (if (i32.ne (i32.load8_u (i32.const 80)) (i32.const 4))
    298       (then (return (i32.const 10))))
    299     ;; size @ 64+32=96 (u64 LE): expect 5
    300     (if (i64.ne (i64.load (i32.const 96)) (i64.const 5))
    301       (then (return (i32.const 11))))
    302     i32.const 0))
    303 WAT
    304 
    305 cat > "$work/wasi_opendir_readdir.wat" <<'WAT'
    306 (module
    307   (import "wasi_snapshot_preview1" "path_open"
    308     (func $path_open (param i32 i32 i32 i32 i32 i64 i64 i32 i32) (result i32)))
    309   (import "wasi_snapshot_preview1" "fd_readdir"
    310     (func $fd_readdir (param i32 i32 i32 i64 i32) (result i32)))
    311   (import "wasi_snapshot_preview1" "fd_close"
    312     (func $fd_close (param i32) (result i32)))
    313   (memory 1)
    314   (data (i32.const 64) "subdir")
    315   (func (export "test_main") (result i32)
    316     (local $dir_fd i32) (local $err i32)
    317     ;; path_open(3, 0, "subdir", oflags=4/OFLAGS_DIRECTORY, ..., &fd=16)
    318     i32.const 3 i32.const 0 i32.const 64 i32.const 6
    319     i32.const 4 i64.const 0 i64.const 0 i32.const 0 i32.const 16
    320     call $path_open local.set $err
    321     (if (i32.ne (local.get $err) (i32.const 0)) (then (return (i32.const 1))))
    322     (i32.load (i32.const 16)) local.set $dir_fd
    323     ;; fd_readdir(dir_fd, buf=128, buflen=256, cookie=0, &bufused=32)
    324     local.get $dir_fd i32.const 128 i32.const 256 i64.const 0 i32.const 32
    325     call $fd_readdir local.set $err
    326     (if (i32.ne (local.get $err) (i32.const 0)) (then (return (i32.const 2))))
    327     ;; expect exactly one entry: "world.txt" (9 bytes) → bufused=24+9=33
    328     (if (i32.ne (i32.load (i32.const 32)) (i32.const 33))
    329       (then (return (i32.const 3))))
    330     ;; dirent namlen @ buf+16=144: expect 9
    331     (if (i32.ne (i32.load (i32.const 144)) (i32.const 9))
    332       (then (return (i32.const 4))))
    333     ;; dirent filetype @ buf+20=148: expect 4 (regular)
    334     (if (i32.ne (i32.load8_u (i32.const 148)) (i32.const 4))
    335       (then (return (i32.const 5))))
    336     local.get $dir_fd call $fd_close drop
    337     i32.const 0))
    338 WAT
    339 
    340 cat > "$work/wasi_unknown.wat" <<'WAT'
    341 (module
    342   (import "wasi_snapshot_preview1" "path_unlink_file"
    343     (func $unlink (param i32 i32 i32) (result i32)))
    344   (memory 1)
    345   (func (export "test_main") (result i32)
    346     i32.const 0
    347     i32.const 0
    348     i32.const 0
    349     call $unlink))
    350 WAT
    351 
    352 cat > "$work/main.c" <<'SRC'
    353 int main(void) { return 0; }
    354 SRC
    355 
    356 printf 'hello' > "$work/hello.txt"
    357 mkdir -p "$work/subdir"
    358 printf 'world' > "$work/subdir/world.txt"
    359 
    360 run_ok "wasm-default-runs-no-imports" \
    361   "$KIT" run -e test_main "$work/return0.wat"
    362 
    363 KIT_TEST_HOST_IMPORTS=1 "$KIT" run -e test_main "$work/host_add.wat" \
    364   > "$work/default-deny.out" 2> "$work/default-deny.err"
    365 if [ "$?" -ne 0 ]; then
    366   ok "wasm-default-denies-test-env-fallback"
    367 else
    368   not_ok "wasm-default-denies-test-env-fallback" "$work/default-deny.out"
    369 fi
    370 contains "wasm-default-deny-diag" "$work/default-deny.err" \
    371   "wasm host import unresolved"
    372 
    373 run_ok "wasm-explicit-test-import" \
    374   "$KIT" run --wasm-imports=test -e test_main "$work/host_add.wat"
    375 
    376 run_fail "wasm-memory-cap-fails" \
    377   "$KIT" run --wasm-memory-max=64K -e test_main "$work/memory_2page_max.wat"
    378 contains "wasm-memory-cap-diag" "$work/wasm-memory-cap-fails.err" \
    379   "wasm linear memory reservation exceeds 65536 bytes"
    380 
    381 run_ok "wasm-memory-cap-allows" \
    382   "$KIT" run --wasm-memory-max=128K -e test_main "$work/memory_2page_max.wat"
    383 
    384 run_fail "wasm-memories-cap-fails" \
    385   "$KIT" run --wasm-memories-max=0 -e test_main "$work/memory_one.wat"
    386 contains "wasm-memories-cap-diag" "$work/wasm-memories-cap-fails.err" \
    387   "wasm memory count exceeds 0"
    388 
    389 run_ok "wasm-policy-flags-parse" \
    390   "$KIT" run --wasm-env=inherit --wasm-env-pass=PATH \
    391     --wasm-env-set=KIT_TEST=1 --wasm-map-dir="$work=/work:ro" \
    392     --wasm-map-file="$work/return0.wat=/return0.wat:ro" --wasm-cwd=/work \
    393     --wasm-stdio=inherit --wasm-clock=monotonic --wasm-random=seed:abcd \
    394     -e test_main "$work/return0.wat"
    395 
    396 "$KIT" run --wasm-wasi -e test_main "$work/wasi_exit.wat" \
    397   > "$work/wasm-wasi-proc-exit.out" 2> "$work/wasm-wasi-proc-exit.err"
    398 if [ "$?" -eq 7 ]; then
    399   ok "wasm-wasi-proc-exit"
    400 else
    401   not_ok "wasm-wasi-proc-exit" "$work/wasm-wasi-proc-exit.err"
    402 fi
    403 
    404 "$KIT" run --wasm-wasi --wasm-stdio=inherit -e test_main \
    405   "$work/wasi_stdout.wat" > "$work/wasm-wasi-stdout.out" \
    406   2> "$work/wasm-wasi-stdout.err"
    407 if [ "$?" -eq 0 ]; then ok "wasm-wasi-stdout"; else
    408   not_ok "wasm-wasi-stdout" "$work/wasm-wasi-stdout.err"
    409 fi
    410 contains "wasm-wasi-stdout-text" "$work/wasm-wasi-stdout.out" "hello wasi"
    411 
    412 "$KIT" run --wasm-wasi --wasm-stdio=null -e test_main \
    413   "$work/wasi_stdout.wat" > "$work/wasm-wasi-stdout-null.out" \
    414   2> "$work/wasm-wasi-stdout-null.err"
    415 if [ "$?" -eq 0 ] && [ ! -s "$work/wasm-wasi-stdout-null.out" ]; then
    416   ok "wasm-wasi-stdout-null"
    417 else
    418   not_ok "wasm-wasi-stdout-null" "$work/wasm-wasi-stdout-null.err"
    419 fi
    420 
    421 run_ok "wasm-wasi-env-set" \
    422   "$KIT" run --wasm-wasi --wasm-env-set=KIT_WASM_TEST=ok \
    423     -e test_main "$work/wasi_env.wat"
    424 
    425 run_ok "wasm-wasi-args" \
    426   "$KIT" run --wasm-wasi -e test_main "$work/wasi_args.wat" -- alpha
    427 
    428 run_ok "wasm-wasi-fs-read" \
    429   "$KIT" run --wasm-wasi --wasm-map-dir="$work=/sandbox:ro" \
    430     -e test_main "$work/wasi_fs_read.wat"
    431 
    432 run_ok "wasm-wasi-fs-map-file-read" \
    433   "$KIT" run --wasm-wasi \
    434     --wasm-map-file="$work/hello.txt=/sandbox/hello.txt:ro" \
    435     -e test_main "$work/wasi_fs_read.wat"
    436 
    437 run_ok "wasm-wasi-seek-tell" \
    438   "$KIT" run --wasm-wasi --wasm-map-dir="$work=/sandbox:ro" \
    439     -e test_main "$work/wasi_seek.wat"
    440 
    441 run_ok "wasm-wasi-fd-filestat-get" \
    442   "$KIT" run --wasm-wasi --wasm-map-dir="$work=/sandbox:ro" \
    443     -e test_main "$work/wasi_filestat.wat"
    444 
    445 run_ok "wasm-wasi-path-filestat-get" \
    446   "$KIT" run --wasm-wasi --wasm-map-dir="$work=/sandbox:ro" \
    447     -e test_main "$work/wasi_path_filestat.wat"
    448 
    449 run_ok "wasm-wasi-opendir-readdir" \
    450   "$KIT" run --wasm-wasi --wasm-map-dir="$work=/sandbox:ro" \
    451     -e test_main "$work/wasi_opendir_readdir.wat"
    452 
    453 run_fail "wasm-wasi-unknown-import-fails" \
    454   "$KIT" run --wasm-wasi -e test_main "$work/wasi_unknown.wat"
    455 contains "wasm-wasi-unknown-import-diag" \
    456   "$work/wasm-wasi-unknown-import-fails.err" \
    457   "wasm host import unresolved"
    458 
    459 run_fail "wasm-flags-reject-native" \
    460   "$KIT" run --wasm-memory-max=1M "$work/main.c"
    461 contains "wasm-flags-reject-native-diag" "$work/wasm-flags-reject-native.err" \
    462   "wasm sandbox flags require a wasm input"
    463 
    464 run_fail "wasm-rejects-mixed-native-inputs" \
    465   "$KIT" run -e test_main "$work/return0.wat" "$work/main.c"
    466 contains "wasm-rejects-mixed-native-inputs-diag" \
    467   "$work/wasm-rejects-mixed-native-inputs.err" \
    468   "sandboxed wasm run does not support mixed native inputs"
    469 
    470 run_fail "wasm-import-mode-invalid" \
    471   "$KIT" run --wasm-imports=env -e test_main "$work/return0.wat"
    472 contains "wasm-import-mode-invalid-diag" \
    473   "$work/wasm-import-mode-invalid.err" \
    474   "unknown --wasm-imports value"
    475 
    476 run_fail "wasm-fs-invalid" \
    477   "$KIT" run --wasm-fs=host -e test_main "$work/return0.wat"
    478 contains "wasm-fs-invalid-diag" "$work/wasm-fs-invalid.err" \
    479   "unknown --wasm-fs value"
    480 
    481 kit_summary test-driver-wasm
    482 kit_exit