| #!/usr/bin/env bash |
| # |
| # Copyright (c) 2023, Arm Limited. All rights reserved. |
| # |
| # SPDX-License-Identifier: BSD-3-Clause |
| # |
| |
| gen_lava_job_def() { |
| local yaml_template_file="${yaml_template_file:?}" |
| local yaml_file="${yaml_file:?}" |
| local yaml_job_file="${yaml_job_file}" |
| |
| # Bash doesn't have array values, we have to create references to the |
| # array of artefacts and their urls. |
| declare -n artefacts="${1-null}" |
| declare -n artefact_urls="${2-null}" |
| |
| if [ -f "${lava_model_params}" ]; then |
| readarray -t boot_arguments < "${lava_model_params}" |
| fi |
| |
| # Source runtime environment variables now so that they are accessible from |
| # the LAVA job template. |
| local run_root="${archive}/run" |
| local run_env="${run_root}/env" |
| |
| if [ -f "${run_env}" ]; then |
| source "${run_env}" |
| fi |
| |
| # Generate the LAVA job definition, minus the test expectations |
| expand_template "${yaml_template_file}" > "${yaml_file}" |
| |
| gen_yaml_expect >> "$yaml_file" |
| |
| # create job.yaml |
| cp "$yaml_file" "$yaml_job_file" |
| |
| # archive both yamls |
| archive_file "$yaml_file" |
| archive_file "$yaml_job_file" |
| } |
| |
| gen_lava_model_params() { |
| local lava_model_params="${lava_model_params:?}" |
| declare -n macros="$1" |
| |
| # Derive LAVA model parameters from the non-LAVA ones |
| cp "${archive}/model_params" "${lava_model_params}" |
| |
| sed -i '/^[[:space:]]*$/d' $lava_model_params |
| |
| if [[ $model =~ "qemu" ]]; then |
| # Strip the model parameters of parameters already specified in the deploy |
| # overlay and job context. |
| sed -i '/-M/d;/kernel/d;/initrd/d;/bios/d;/cpu/d;/^[[:space:]]*$/d' \ |
| $lava_model_params |
| elif [[ ! $model =~ "qemu" ]]; then |
| # FIXME find a way to properly match FVP configurations. |
| # Ensure braces in the FVP model parameters are not accidentally |
| # interpreted as LAVA macros. |
| sed -i -e 's/{/{{/g' "${lava_model_params}" |
| sed -i -e 's/}/}}/g' "${lava_model_params}" |
| else |
| echo "Unsupported emulated platform $model." |
| fi |
| |
| # LAVA expects binary paths as macros, i.e. `{X}` instead of `x.bin`, so |
| # replace the file paths in our pre-generated model parameters. |
| for regex in "${!macros[@]}"; do |
| sed -i -e "s!${regex}!${macros[${regex}]}!" "${lava_model_params}" |
| done |
| } |
| |
| gen_yaml_template() { |
| local target="${target-fvp}" |
| local yaml_template_file="${yaml_template_file-$workspace/${target}_template.yaml}" |
| |
| local payload_type="${payload_type:?}" |
| |
| cp "${ci_root}/script/lava-templates/${target}-${payload_type:?}.yaml" \ |
| "${yaml_template_file}" |
| |
| archive_file "$yaml_template_file" |
| } |
| |
| gen_yaml_expect() { |
| # Loop through all uarts expect files |
| for expect_file in $(find $run_root -name expect); do |
| local uart_number=$(basename "$(dirname ${expect_file})") |
| |
| # Only handle the primary UART through LAVA. The remaining UARTs are |
| # validated after LAVA returns by the post-expect script. |
| if [ "${uart_number:?}" != "uart$(get_primary_uart "${archive}")" ]; then |
| continue |
| fi |
| |
| # Array containing "interactive" or "monitor" expect strings and populated during run config execution. |
| # Interactive expect scripts are converted into LAVA Interactive Test Actions (see |
| # https://tf.validation.linaro.org/static/docs/v2/interactive.html#writing-tests-interactive) and |
| # monitor expect scripts are converted into LAVA Monitor Test Actions (see |
| # https://validation.linaro.org/static/docs/v2/actions-test.html#monitor) |
| # |
| # Interactive Expect strings have the format 'i;<prompt>;<succeses>;<failures>;<commands>' |
| # where multiple successes or failures or commands are separated by @ |
| # |
| # Monitor Expect strings have the format 'm;<start>;<end>;<patterns>' |
| # where multiple patterns are separated by @ |
| # |
| expect_string=() |
| |
| # Get the real name of the expect file |
| expect_file=$(cat $expect_file) |
| |
| # Source the run_config enviroment variables |
| env=$run_root/$uart_number/env |
| if [ -e $env ]; then |
| source $env |
| fi |
| |
| # Get all expect strings |
| expect_dir="${ci_root}/expect-lava" |
| expect_file="${expect_dir}/${expect_file}" |
| |
| # Allow the expectations to be provided directly in LAVA's job YAML |
| # format, rather than converting it from a pseudo-Expect Bash script in |
| # the block below. |
| if [ -f "${expect_file/.exp/.yaml}" ]; then |
| pushd "${expect_dir}" |
| expand_template "${expect_file/.exp/.yaml}" |
| popd |
| |
| continue |
| else |
| source "${expect_file}" |
| fi |
| |
| if [ ${#expect_string[@]} -gt 0 ]; then |
| # expect loop |
| for key in "${!expect_string[@]}"; do |
| # single raw expect string |
| es="${expect_string[${key}]}" |
| |
| # action type: either m or i |
| action="$(echo "${es}" | awk -F ';' '{print $1}')" |
| |
| if [ "${action}" = "m" ]; then |
| start="$(echo "${es}" | awk -F ';' '{print $2}')" |
| end="$(echo "${es}" | awk -F ';' '{print $3}')" |
| patterns="$(echo "${es}" | awk -F ';' '{print $4}')" |
| |
| cat <<-EOF |
| - test: |
| monitors: |
| - name: tests |
| start: '${start}' |
| end: '${end}' |
| EOF |
| |
| # Patterns are separated by '@' |
| OLD_IFS=$IFS; IFS=$'@' |
| for p in ${patterns}; do |
| cat <<-EOF |
| pattern: '$p' |
| EOF |
| done |
| |
| IFS=$OLD_IFS |
| cat <<-EOF |
| fixupdict: |
| PASS: pass |
| FAIL: fail |
| EOF |
| fi # end of monitor action |
| |
| if [ "${action}" = "i" ]; then |
| prompts="$(echo "${es}" | awk -F ';' '{print $2}')" |
| success="$(echo "${es}" | awk -F ';' '{print $3}')" |
| failure="$(echo "${es}" | awk -F ';' '{print $4}')" |
| commands="$(echo "${es}" | awk -F ';' '{print $5}')" |
| |
| test_name="${uart_number}_${key}" |
| |
| cat <<-EOF |
| - test: |
| interactive: |
| EOF |
| OLD_IFS=$IFS; IFS=$'@' |
| |
| name="${test_name}" \ |
| commands=$commands \ |
| print_interactive_command |
| |
| if [[ -n "${success}" ]]; then |
| message="$success" \ |
| print_lava_result_msg |
| fi |
| |
| if [[ -n "${failure}" ]]; then |
| res="failures" \ |
| message="$failure" \ |
| print_lava_result_msg |
| fi |
| IFS=$OLD_IFS |
| fi # end of interactive action |
| |
| done # end of expect loop |
| fi |
| done # end of uart loop |
| } |
| |
| |
| print_interactive_command(){ |
| local name="${name:?}" |
| local prompt=${prompts:-} |
| local commands=${commands:-} |
| |
| cat <<-EOF |
| - name: interactive_${name} |
| prompts: ['${prompt}'] |
| script: |
| - name: interactive_command_${name} |
| EOF |
| |
| if [ -z "${commands}" ]; then |
| cat <<-EOF |
| command: |
| EOF |
| else |
| for c in ${commands}; do |
| cat <<-EOF |
| command: "$c" |
| EOF |
| done |
| fi |
| } |
| |
| print_lava_result_msg() { |
| local res="${res:-successes}" |
| local message=${message:?} |
| |
| cat <<-EOF |
| ${res}: |
| EOF |
| |
| for m in ${message}; do |
| cat <<-EOF |
| - message: '$m' |
| EOF |
| |
| if [ $res == "failures" ]; then |
| cat <<-EOF |
| exception: JobError |
| EOF |
| fi |
| done |
| } |