diff options
Diffstat (limited to 'tests/config')
| -rw-r--r-- | tests/config | 187 |
1 files changed, 187 insertions, 0 deletions
diff --git a/tests/config b/tests/config new file mode 100644 index 0000000..2229bf5 --- /dev/null +++ b/tests/config @@ -0,0 +1,187 @@ +# The config parser, against hostile input. dryrun is the parser's only +# observable behaviour, so every case runs through it. + +"$VMM" create cfg1 64M >/dev/null 2>&1 + +: > "$VMMDIR/cfg1/config" +exits 0 "minimal config parses" dryrun cfg1 + +cfg cfg1 <<EOF +CPUS=2 # two of them +EOF +refuses 'config:1' "inline comment is rejected by line" dryrun cfg1 + +cfg cfg1 <<EOF +MEMORY=4096 +EOF +refuses 'unknown key' "a typo'd key is an error, not silence" dryrun cfg1 + +cfg cfg1 <<EOF +CPUS=1 +CPUS=2 +EOF +refuses 'duplicate key' "duplicate keys are an error" dryrun cfg1 + +cfg cfg1 <<EOF +IMAGE_FORMAT="qcow2,readonly=on" +EOF +refuses 'IMAGE_FORMAT must be' "IMAGE_FORMAT injection is refused" dryrun cfg1 + +cfg cfg1 <<EOF +GRAPHICS=bogus +EOF +refuses 'GRAPHICS must be' "an invalid GRAPHICS value is refused" dryrun cfg1 + +cfg cfg1 <<EOF +CPUS=abc +EOF +refuses 'CPUS must be' "non-numeric CPUS is refused" dryrun cfg1 + +cfg cfg1 <<EOF +HOSTFWD="70000:22" +EOF +refuses 'out of range' "out of range host port is refused" dryrun cfg1 + +cfg cfg1 <<EOF +HOSTFWD="0:22" +EOF +refuses 'out of range' "host port 0 is refused" dryrun cfg1 + +cfg cfg1 <<EOF +HOSTFWD="99999999999999999999:22" +EOF +refuses 'out of range' "a port too big for arithmetic is refused" dryrun cfg1 + +cfg cfg1 <<EOF +HOSTFWD=",,," +EOF +refuses 'no usable entries' "a HOSTFWD of only separators is refused" dryrun cfg1 + +# Only the dotted quad binds what it looks like: inet_aton reads 127.1 +# as 127.0.0.1 and 010.0.0.1 as octal for 8.0.0.1, and a host name is +# not an address at all. +cfg cfg1 <<EOF +HOSTFWD="localhost:2222:22" +EOF +refuses 'must be A.B.C.D' "a host name in HOSTFWD is refused" dryrun cfg1 + +cfg cfg1 <<EOF +HOSTFWD="127.0.0.256:2222:22" +EOF +refuses 'must be A.B.C.D' "an octet out of range is refused" dryrun cfg1 + +cfg cfg1 <<EOF +HOSTFWD="127.1:2222:22" +EOF +refuses 'must be A.B.C.D' "a short form address is refused" dryrun cfg1 + +cfg cfg1 <<EOF +HOSTFWD="010.0.0.1:2222:22" +EOF +refuses 'must be A.B.C.D' "an octal octet is refused" dryrun cfg1 + +cfg cfg1 <<EOF +HOSTFWD=":2222:22" +EOF +refuses 'must be A.B.C.D' "an entry with no address at all is refused" dryrun cfg1 + +# The address check runs inside the loop over entries and keeps its own +# scratch names, since the shell has no others to give it. +cfg cfg1 <<EOF +HOSTFWD="2222:22,localhost:8080:80" +EOF +refuses 'must be A.B.C.D' "a bad address in a later entry is refused" dryrun cfg1 + +# A forward the guest cannot receive is a config that lies, not a +# default. A restricted NIC is still a NIC. +cfg cfg1 <<EOF +NETWORK=no +HOSTFWD="2222:22" +EOF +refuses 'nothing to forward' "HOSTFWD without a NIC is refused" dryrun cfg1 + +cfg cfg1 <<EOF +NETWORK=hostonly +HOSTFWD="2222:22" +EOF +exits 0 "HOSTFWD with a restricted NIC is kept" dryrun cfg1 + +cfg cfg1 <<EOF +BOOT_ORDER=cc +EOF +refuses 'BOOT_ORDER must be' "a repeated BOOT_ORDER letter is refused" dryrun cfg1 + +# A boot list restricts nothing unless some device it names exists: with +# no bootindex anywhere, QEMU falls back and boots the disk the list +# left out. +cfg cfg1 <<EOF +BOOT_ORDER=d +EOF +refuses 'no device to boot' "a boot list of absent devices is refused" dryrun cfg1 + +cfg cfg1 <<EOF +BOOT_ORDER=n +NETWORK=no +EOF +refuses 'no device to boot' "netboot without a NIC is refused" dryrun cfg1 + +cfg cfg1 <<EOF +BOOT_ORDER=dc +EOF +exits 0 "a boot list that still names the disk is kept" dryrun cfg1 + +cfg cfg1 <<EOF +IMAGE="$WORK/shared.qcow2" +EOF +refuses 'unknown key: IMAGE' "the primary disk path cannot be configured" dryrun cfg1 + +cfg cfg1 <<EOF +CDROM="/tmp/install.iso +EOF +refuses 'unbalanced quote' "unbalanced quote is refused" dryrun cfg1 + +cfg cfg1 <<EOF +CPUS=$(printf '2\001') +EOF +refuses 'non-printable' "a non-printable byte is refused" dryrun cfg1 + +# Shell variables cannot carry NUL, so the parser must inspect the file +# before read(1) can silently remove it. +printf 'CPUS=2\nMEM=2\000\n' > "$VMMDIR/cfg1/config" +refuses 'config:2: NUL byte' "a NUL byte is refused on its own line" dryrun cfg1 + +# The parser is byte oriented whatever the caller's locale says, or a +# multibyte character passes for one printable character. +printf 'CDROM="/tmp/\303\251.iso"\n' > "$VMMDIR/cfg1/config" +out=$(env LANG=en_US.UTF-8 LC_CTYPE=en_US.UTF-8 "$VMM" dryrun cfg1 2>&1) && got=0 || got=$? +if [ "$got" != 0 ] && printf '%s' "$out" | grep -q 'non-printable'; then + ok "a UTF-8 byte is refused under a UTF-8 locale" +else + notok "a UTF-8 byte is refused under a UTF-8 locale" "exit $got: $out" +fi + +# A final line with no trailing newline must still be seen. +printf 'CPUS=3' > "$VMMDIR/cfg1/config" +outputs "-smp '3'" "final line without a newline is parsed" dryrun cfg1 + +# CRLF must not leak into a value. +printf 'CPUS=4\r\n' > "$VMMDIR/cfg1/config" +outputs "-smp '4'" "CRLF line endings are handled" dryrun cfg1 + +# An unreadable config must say so, not blame a key it never got to read. +chmod 000 "$VMMDIR/cfg1/config" +refuses 'not readable' "an unreadable config names the real problem" dryrun cfg1 +chmod 600 "$VMMDIR/cfg1/config" + +# edit exists to re-read the config once the editor has been through it, +# which is the only reason to run one from here. EDITOR=true is exported +# by the harness, so what is left of edit is the check. +: > "$VMMDIR/cfg1/config" +exits 0 "edit re-validates the config it just wrote" edit cfg1 +outputs 'config ok' "edit says so when the config parses" edit cfg1 + +cfg cfg1 <<EOF +MEMORY=4096 +EOF +refuses 'unknown key' "edit refuses to leave a broken config unreported" edit cfg1 +exits 2 "edit of an unknown VM exits 2" edit nosuchvm |