#!/usr/bin/expect -f # # This scripts starts QEMU, loads and boots Linux/OP-TEE, then runs # tests in the guest. The return code is 0 for success, >0 for error. # # Options: # -q Suppress output to stdout (quiet) # --tests Type of tests to run, values: all, xtest and trusted-keys # --timeout Timeout for each test (sub)case, in seconds [480] # --xtest-args Optional arguments to xtest set bios "../out/bios-qemu/bios.bin" set cmd1 "cd /mnt/host/build/qemu_v8/xen" if {[info exists ::env(XEN_FFA)] && $::env(XEN_FFA) == "y"} { set cmd2 "xl create guest_ffa.cfg" } else { set cmd2 "xl create guest.cfg" } set cmd3 "xl console domu" set quiet 0 set xtest_args "" if {[info exists ::env(RUST_ENABLE)] && $::env(RUST_ENABLE) == "y"} { set rust_enable 1 } else { set rust_enable 0 } # The time required to run some tests (e.g., key generation tests [4007.*]) # can be significant and vary widely -- typically, from about one minute to # several minutes depending on the host machine. # The value here should be sufficient to run the whole optee_test suite # ('xtest') with all testsuites enabled (regression+gp+pkcs11). set timeout 900 set tests "all" set basedir [file dirname $argv0] # Parse command line set myargs $argv while {[llength $myargs]} { set myargs [lassign $myargs arg] switch -exact -- $arg { "--tests" {set myargs [lassign $myargs ::tests]} "--timeout" {set myargs [lassign $myargs ::timeout]} "-q" {set ::quiet 1} "--xtest-args" {set myargs [lassign $myargs ::xtest_args]} } } set cmd "xtest $xtest_args" proc info arg { if {$::quiet==1} { return } puts -nonewline $arg flush stdout } proc check_test_result arg { set casenum "none" set star 0 set ncases 0 expect { # Exit with error status as soon as a test fails -re { ([^ ]+) FAIL} { info " $expect_out(1,string) FAIL\n" exit 1 } -re {rcu.*detected stalls} { info " Kernel error: '$expect_out(0,string)'\n" exit 1 } # Crude progress indicator: print one # when each test [sub]case starts -re {([\*o]) ([^ ]+) } { set casenum $expect_out(2,string) if {$expect_out(1,string) == "o"} { if {$star == 1} { # Do not count first subcase ('o') since start # of test ('*') was counted already set star 0 exp_continue } } else { set star 1 } info "#" incr ncases if {$ncases % 50 == 0} { info "\n" } exp_continue } # Exit when result separator is seen "+-----------------------------------------------------\r\r" {} # Handle errors in TEE core output -i $arg -re {(..TC:[^\n]*assertion[^\n]*failed at[^\n]*)} { info "!!! $expect_out(1,string)\n" exit 1 } -i $arg -re {(..TC:[^\n]*Panic at[^\n]*)} { info "!!! $expect_out(1,string)\n" exit 1 } timeout { info "!!! Timeout\n" info "TIMEOUT - test case too long or hung? (last test started: $casenum)\n" exit 2 } } info "\nStatus: PASS ($ncases test cases)\n" } # Disable echoing of guest output log_user 0 # Save guest console output to a file log_file -a -noappend "serial0.log" info "Starting QEMU..." open "serial1.log" "w+" spawn -open [open "|tail -f serial1.log"] set teecore $spawn_id spawn sh -c "$::env(QEMU) $::env(QEMU_CHECK_ARGS)" expect { "Kernel panic" { info "!!! Kernel panic\n" exit 1 } timeout { info "!!! Timeout\n" exit 1 } "ogin:" } send -- "root\r\r" expect "# " info " done, guest is booted" if {$::env(XEN_BOOT) == "y"} { info " (Xen Dom0)" } info ".\n" # Toolchain libraries might be here or there send -- "export LD_LIBRARY_PATH=/lib:/lib/arm-linux-gnueabihf\r" if {$tests == "all" || $tests == "xtest"} { info "Running: $cmd...\n" expect "# " send -- "$cmd\r" check_test_result $teecore } if {$::env(XEN_BOOT) == "y"} { info " Booting DomU.\n" expect "# " info "Running: $cmd1...\n" send -- "$cmd1\r" expect "# " info "Running: $cmd2...\n" send -- "$cmd2\r" expect "# " info "Running: $cmd3...\n" send -- "$cmd3\r" expect { "Kernel panic" { info "!!! Kernel panic\n" exit 1 } timeout { info "!!! Timeout\n" exit 1 } "login:" } send -- "root\r\r" expect "# " info " done, DomU is booted.\n" # Toolchain libraries might be here or there send -- "export LD_LIBRARY_PATH=/lib:/lib/arm-linux-gnueabihf\r" expect "# " if {$tests == "all" || $tests == "xtest"} { info "Running: $cmd...\n" send -- "$cmd\r" check_test_result $teecore } } if {$tests == "all" || $tests == "trusted-keys"} { # Invoke Trusted Keys tests source $basedir/trusted-keys.exp } if {($tests == "all" || $tests == "rust") && $::rust_enable == 1} { # Invoke Rust tests source $basedir/rust.exp }