# v2-test.sh: boot contract v2 checks, run by dash (milestone M3). # The self-test runs it as `dash /scripts/v2-test.sh`. Each check prints # "v2-test: ok NAME" or "v2-test: FAIL NAME"; the exit status is the # number of failures. What "contract v2" promises is in docs/boot-contract.md. fails=0 checks=0 check() { # check NAME COMMAND... (passes when COMMAND succeeds) name=$1; shift checks=$((checks + 1)) if "$@"; then echo "v2-test: ok $name" else echo "v2-test: FAIL $name"; fails=$((fails + 1)); fi } eq() { [ "$1" = "$2" ] || { echo " got '$1', want '$2'"; return 1; }; } # roundtrip FILE: write two lines, read them back, delete, check it's gone. roundtrip() { printf 'line one\nline two\n' > "$1" || return 1 { read a; read b; } < "$1" [ "$a/$b" = "line one/line two" ] || { echo " read back '$a/$b'"; return 1; } rm "$1" && [ ! -e "$1" ] } # The environment the kernel gives pid 1, passed on by init. check env-PATH eq "$PATH" "/sbin:/bin:/usr/bin:/mnt/disk0/bin" check env-HOME eq "$HOME" "/" check env-TERM eq "$TERM" "linux" # The root file system (A:, ext2): layout and writable. layout() { [ -x /sbin/init ] && [ -x /bin/rbsh ] && [ -d /etc ] && [ -d /usr/bin ] && [ -d /home/tyler ]; } check root-layout layout read first < /etc/passwd # (our Rust grep has no ^ anchors or -c, so plain sh) check etc-passwd eq "$first" "root:x:0:0:root:/root:/bin/rbsh" check root-writable roundtrip /v2-test-root.txt # /bin/sh is dash; the Rust tools come first on PATH, the kernel's ABI # test programs (on B:) last. check sh-is-dash [ -L /bin/sh ] check sh-runs eq "$(sh -c 'echo $((6 * 7))')" 42 check rust-tools-first eq "$(command -v ls)" /bin/ls check fixtures-on-B eq "$(command -v forktest)" /mnt/disk0/bin/forktest # The data disk (B:, FAT32) at /mnt/disk0. check B-readme [ -f /mnt/disk0/readme.txt ] check B-writable roundtrip /mnt/disk0/v2-test-b.txt # The share (C:, exFAT) at /mnt/share: write, read back, delete; a # directory too; and the README that `make image` put there. read first < /mnt/share/README.TXT check share-readme eq "$first" "This is the Foundry OS share (drive C:, /mnt/share)." check share-write-read-delete roundtrip /mnt/share/v2-test.txt mkdir /mnt/share/v2dir && echo inside > /mnt/share/v2dir/f.txt check share-subdir eq "$(cat /mnt/share/v2dir/f.txt)" inside rm /mnt/share/v2dir/f.txt /mnt/share/v2dir # this rm also removes empty directories check share-subdir-deleted [ ! -e /mnt/share/v2dir ] # A file left on the share for the host to read after the run # (make test checks it with scripts/exfat.py and fsck.exfat). echo "written on Foundry OS by dash" > /mnt/share/from-foundry.txt check share-keep-file [ -s /mnt/share/from-foundry.txt ] # An orphan for init: the subshell exits at once, its `sleep` lives on and # is adopted by init, which must reap it (the self-test's memory check # waits for every process to be gone). (sleep 1 &) check left-an-orphan true if [ $fails = 0 ]; then echo "v2-test: all $checks checks passed" else echo "v2-test: $fails of $checks checks FAILED"; fi exit $fails