tree: d030b675209886b45f3f9c8f5f5e2be88ad86a52 [path history] [tgz]
  1. busybox.inc
  2. cactus.exp
  3. crash_panic.exp
  4. crash_roxlattables_unhandled_exception_at_el3.exp
  5. crash_test.exp
  6. disable_dyn_auth.inc
  7. disable_dyn_auth_tftf.exp
  8. el3-test-payload.exp
  9. fvp-r-yocto.exp
  10. hold_uart.exp
  11. ivy.exp
  12. linux-bl33.exp
  13. linux-oe-rst-bl31.exp
  14. linux-oe.exp
  15. linux-rd-busybox-aarch32.exp
  16. linux-rd-busybox.exp
  17. linux-tpm-384.exp
  18. linux-tpm.exp
  19. linux.inc
  20. openembedded.inc
  21. README.md
  22. readonly_el1_xlat_tables.exp
  23. spm-edk2-uart0.exp
  24. spm-edk2-uart2.exp
  25. spm-linux-uart0.exp
  26. spm-optee-sp-uart1.exp
  27. spm-uart2.exp
  28. tftf-aarch32.exp
  29. tftf.exp
  30. tftf_fault.exp
  31. timeout.exp
  32. timeout_spmin_roxlattables.exp
  33. timeout_test.exp
  34. tpm-logs.exp
  35. trusted-firmware-aarch32.inc
  36. trusted-firmware-load-error.exp
  37. trusted-firmware-rst-to-bl31.inc
  38. trusted-firmware.inc
  39. tsp.exp
  40. uart-hold.inc
  41. ubsan-test-trap.exp
  42. unhandled_exception_at_el3.exp
lava-expect/README.md

Expect Scripts

The project tracks two set of expect scripts under two different folders, expect and lava-expect, the former required for local (non-LAVA) or Internal CI (Arm CI) and the latter for Open CI (LAVA). Note that any contribution into the expect scripts must be done in both folders, otherwise expect test coverage will differ.

LAVA Test Actions

The lava-expect script does exactly the same as its counterpart under the expect folder. However, LAVA would use either Interactive Test Actions or Monitor Test Actions to support possible scenarios. In other words, expect scripts are transformed into either interactive or monitor test actions.

In the lava-expect scripts, both types of actions, interactive and monitor, are defined using the same array variable, expect_string but each array element would contain either a leading i indicating interactive actions or m indicating monitor actions.

Interactive actions are used in the following scenarios

  • Matching a literal and single-event string, i.e. matching Booting Trusted Firmware
  • Matching literal string in strict order of appearance, i.e. matching BL1: Booting BL31 after BL1: Booting BL2
  • Matching literal string, a prompt, following a pass/fail criteria
  • Input commands at the bootloader or command prompt

Monitor actions are used in the following scenario

  • regex matching through the log, i.e. 'Digest(\s|\w):\s(\w{2}\s){16}'.

The following sections go in detail providing syntactic details for each scenario.

Interactive Actions Strings

To better understand how expect scripts translates into lava-expect, we can compare similar scripts, i.e. expect/disable_dyn_auth_tftf.exp versus lava-expect/disable_dyn_auth_tftf.exp which only requires interactive actions. Let's compare these two:

  • expect/disable_dyn_auth_tftf.exp
source [file join [file dirname [info script]] disable_dyn_auth.inc]

expect_string "Booting trusted firmware test framework" "Starting TFTF"
expect_re "Running at NS-EL(1|2)"

expect {
	"Tests Failed  : 0" {
		expect_string "Exiting tests." "<<TFTF Success>>"
		exit_uart 0
	}
	"Tests Passed  : 0" {
		puts "<<TFTF no tests passed>>"
		exit_uart -1
	}
	-re "Tests Failed  : \[^0]" {
		puts "<<TFTF Fail>>"
		exit_uart -1
	}
	timeout {
		exit_timeout
	}
}

exit_uart -1
  • and its counterpart lava-expect/disable_dyn_auth_tftf.exp (note, the same filename but different folder)
source $ci_root/lava-expect/disable_dyn_auth.inc

prompt='Booting trusted firmware test framework'
expect_string+=("i;${prompt}")

prompt='Running at NS-EL(1|2)'
expect_string+=("i;${prompt}")

prompt='Tests Failed  : 0'
expect_string+=("i;${prompt}")

prompt='Exiting tests.'
failures='Tests Passed  : 0'
expect_string+=("i;${prompt};;${failures}")

The first thing to notice is that all strings are literal (no regex is required) and each are expected just once, so interactive actions are the choice.

As seen, the same expect strings appears in both, but in case of lava-expect/disable_dyn_auth_tftf.exp, is it written in bash language and appending elements into expect_string, which is the variable that ultimately is transformed into interactive test actions by CI scripts.

It is worth noting that each expect string must be appended += as an array element of expect_string, otherwise, and assignment operator = would remove previous defined expect strings. Also note the leading i character in the array element, indicating a interactive actions.

As indicated above, interactive actions match strings in a specific order. For the above example, expect strings are matched setting the prompt and an optional failures value, the latter indicating a possible failure string.

Interactive action strings should follow the following syntax

expect_string+=("i;<prompts>[;<successes>;<failures>;<commands>]")

Indicating the prompts to match, which can be one or several separated by the @ char and optional successeses, failures and commands strings.

One good way to explain (or at least understand it) is: If expect_string has a format of i;<expected>, then output will be matched for <expected> (until the end of output or timeout, lack of match is a failure in either case). Otherwise, the format is: i;<prompts>;[<successeses>];[<failures>];[<commands>]; a <command> will be sent to DUT, if specified; any output will be matched until next <prompts>; if <successes> is specified, it must be matched before appearance of prompt for this testcase to be successful (if <successes> is not matched before prompt, it's a failure); alternatively, if <failures> is matched, it's a fast-track failure (otherwise the lack of success output is enough to record a failure).

Again, this prompts/successes/failures form makes a good sense if actively sending a <command> and much less sense if not sending any <command>. Between these 2 main forms: passively matching output vs actively sending a command to a shell and checking its results, there can be other use cases which can be encoded with the full form, but then those would be corner/niche cases most of the cases.

Monitor Action Strings

If the corresponding expect string is a regular expression, a regex and/or input commands, one should use LAVA Monitor Test Actions. Besides the regex strings, monitors requires a start and end strings.

As in the previous section, it is best if understood with a real example, the expect/linux-tpm.exp

set non_zero_pcr "(?!(\\s00){16})((\\s(\[0-9a-f\]){2}){16}\\s)"

expect {

        -re "Digest(\\s|\\w)*:\\s(\\w{2}\\s){16}|\
        : (\\w{2}\\s){16}|\
        Event(\\s|\\w)*:\\s\\w+\\s" {
                puts $digest_log $expect_out(0,string)
                exp_continue
        }

        -exact "Booting BL31" {
                close $digest_log
        }

        timeout {
                exit_timeout
        }
}

expect {
        "login" {
                send "root\n"
        }

        timeout {
                exit_timeout
        }
}

expect {
        "#" {
                # Load the fTPM driver and retrieves PCR0
                send "ftpm\n"
        }

        timeout {
                exit_timeout
        }
}

for {set i 1} {$i < 11} {incr i} {
        send "pcrread -ha $i\n"

        expect {
                -re "(\\s00){16}\\s+(00\\s){16}" { }

                -re $non_zero_pcr {
                        exit_uart -1
                }

                timeout {
                        exit_timeout
                }
        }
}

which is translated into lava-expect/linux-tpm.exp

non_zero_pcr='(?!(\s00){16})((\s([0-9a-f]){2}){16}\s)'

expect_string+=('m;Booting Trusted Firmware;Booting BL31;Digest(\s|\w)*:\s(\w{2}\s){16}@: (\w{2}\s){16}@Event(\s|\w)*:\s\w+\s')

expect_string+=('i;buildroot login:')

expect_string+=("i;#;${non_zero_pcr};;root@ftpm")

zero_pcr="(\s00){16}\s+(00\s){16}"
for i in $(seq 1 11); do
    expect_string+=("i;#;${zero_pcr};;pcrread -ha $i")
done

In this case, translation required monitor and interactive strings. For the monitor strings, this is the syntax

expect_string+=('<start match>;<end match>;<regex 1>@<regex 2>@...')