From 9e00195788931589a691e897c53e8cba28e11340 Mon Sep 17 00:00:00 2001 From: Artur Kowalski Date: Fri, 3 Nov 2023 18:10:27 +0100 Subject: [PATCH] Extend CI to automatically run tests on select MSI platforms --- .github/workflows/build.yml | 58 +++++++++++++++- ci/ci.sh | 131 ++++++++++++++++++++++++++++++++++++ ci/scp.py | 22 ++++++ ci/smmstore-serial-enabled | Bin 0 -> 262144 bytes ci/ssh.py | 42 ++++++++++++ 5 files changed, 252 insertions(+), 1 deletion(-) create mode 100755 ci/ci.sh create mode 100755 ci/scp.py create mode 100644 ci/smmstore-serial-enabled create mode 100755 ci/ssh.py diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 6ea284a3641..be05c7415a3 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -45,7 +45,7 @@ jobs: strategy: matrix: vendor: [ msi ] - model: [ ms7d25_ddr4, ms7d25_ddr5, ms7e06_ddr4, ms7e06_ddr5 ] + model: [ ms7d25_ddr5 ] steps: - name: Checkout repository uses: actions/checkout@v3 @@ -62,12 +62,17 @@ jobs: cp configs/config.${{ matrix.vendor }}_${{ matrix.model }} .config make olddefconfig make + - name: Create patched binary with pre-enabled serial output + run: | + cp build/coreboot.rom build/coreboot_serial_enabled.rom + build/util/cbfstool/cbfstool build/coreboot_serial_enabled.rom write -r SMMSTORE -f ci/smmstore-serial-enabled - name: Save artifacts uses: actions/upload-artifact@v2 with: name: "dasharo-${{ matrix.vendor }}-${{ matrix.model }}-${{ matrix.build }}" path: | build/coreboot.rom + build/coreboot_serial_enabled.rom retention-days: 30 build_protectli: environment: Protectli @@ -100,3 +105,54 @@ jobs: - name: Build Dasharo run: | ./build.sh ${{ matrix.model }} + test_msi: + runs-on: self-hosted + strategy: + matrix: + vendor: [ msi ] + model: [ ms7d25_ddr5 ] + needs: [build_msi] + steps: + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: '3.11' + + - name: Fetch CI script + uses: actions/checkout@v4 + with: + sparse-checkout: ci + sparse-checkout-cone-mode: false + + - name: Checkout test repository + uses: actions/checkout@v4 + with: + repository: Dasharo/open-source-firmware-validation + path: validation + submodules: true + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -r validation/requirements.txt + + - name: Fetch latest firmware + uses: actions/download-artifact@v3 + with: + name: dasharo-${{ matrix.vendor }}-${{ matrix.model }}-${{ matrix.build }} + path: firmware + + - name: Flash firmware + shell: bash + run: ./ci/ci.sh -r validation -v "${{ matrix.vendor }}" -m "${{ matrix.model }}" -f firmware/coreboot_serial_enabled.rom flash + + - name: Run tests + shell: bash + run: ./ci/ci.sh -r validation -v "${{ matrix.vendor }}" -m "${{ matrix.model }}" -f firmware/coreboot_serial_enabled.rom test + + - name: Upload test results + uses: actions/upload-artifact@v3 + with: + name: test-results-${{ matrix.vendor }}-${{ matrix.model }} + path: test-results-${{ matrix.vendor }}-${{ matrix.model }} + if: always() diff --git a/ci/ci.sh b/ci/ci.sh new file mode 100755 index 00000000000..05d65a4b032 --- /dev/null +++ b/ci/ci.sh @@ -0,0 +1,131 @@ +#!/usr/bin/env bash + +set -euo pipefail + +script_dir="$(dirname "${BASH_SOURCE[0]}")" + +vendor="" +model="" + +usage() { + echo "Usage: ci.sh -v vendor -m model -f firmware command" 1>&2 + exit 1 +} + +while getopts "r:v:m:f:" o; do + case "${o}" in + r) root="${OPTARG}" ;; + v) vendor="${OPTARG}" ;; + m) model="${OPTARG}" ;; + f) fw_file="${OPTARG}" ;; + *) usage ;; + esac +done +shift $((OPTIND-1)) + +[ -n "$vendor" ] || usage +[ -n "$model" ] || usage +[ $# -eq 1 ] || usage + +command="$1" +[[ "$command" =~ ^(flash|test)$ ]] || usage +shift 1 + +options=( + -L TRACE + -v snipeit:none +) + +compatibility_tests=() +performance_tests=() +security_tests=() +stability_tests=() + +case "$vendor" in + msi) + case "$model" in + ms7d25_ddr5) + device_ip="192.168.10.93" + rte_ip="192.168.10.188" + pikvm_ip="192.168.10.45" + config="msi-pro-z690-a-ddr5" + ;; + *) + echo unknown board: $model + exit 1 + ;; + esac + ;; + *) + echo unknown vendor: $vendor + exit 1 + ;; +esac + +options+=( + -v device_ip:$device_ip + -v rte_ip:$rte_ip + -v pikvm_ip:$pikvm_ip + -v config:$config + -v snipeit:no +) + +if [ "$command" == "flash" ]; then + "$script_dir/scp.py" "$rte_ip" "$fw_file" /tmp/dasharo.rom + "$script_dir/ssh.py" "$rte_ip" /home/root/flash.sh /tmp/dasharo.rom + exit 0 +fi + +case "$vendor" in + msi) + case "$model" in + ms7d25_ddr5) + compatibility_tests+=( + custom-boot-menu-key + ) + + security_tests+=( + me-neuter + ) + ;; + *) + echo unknown board: $model + exit 1 + ;; + esac + ;; + *) + echo unknown vendor: $vendor + exit 1 + ;; +esac + +mkdir -p "test-results-$vendor-$model" + +run_robot() { + local category="$1" + local test="$2" + + robot -l "test-results-$vendor-$model/dasharo-${category}.log.html" \ + -r "test-results-$vendor-$model/dasharo-${category}.html" \ + -o "test-results-$vendor-$model/dasharo-${category}.xml" \ + ${options[@]} "$root/dasharo-${category}/$test.robot" +} + +if [ "$command" == "test" ]; then + for test in "${compatibility_tests[@]}"; do + run_robot compatibility "$test" + done + + for test in "${performance_tests[@]}"; do + run_robot performance "$test" + done + + for test in "${security_tests[@]}"; do + run_robot security "$test" + done + + for test in "${stability_tests[@]}"; do + run_robot stability "$test" + done +fi diff --git a/ci/scp.py b/ci/scp.py new file mode 100755 index 00000000000..1c57d7484b2 --- /dev/null +++ b/ci/scp.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python3 + +from argparse import ArgumentParser +import paramiko + +def main(): + parser = ArgumentParser() + parser.add_argument("host") + parser.add_argument("local") + parser.add_argument("remote") + args = parser.parse_args() + + client = paramiko.client.SSHClient() + client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) + client.connect(args.host, username="root", password="meta-rte") + + ftp = client.open_sftp() + ftp.put(args.local, args.remote) + ftp.close() + +if __name__ == '__main__': + main() diff --git a/ci/smmstore-serial-enabled b/ci/smmstore-serial-enabled new file mode 100644 index 0000000000000000000000000000000000000000..76eefc9d761a40d4153ef520bed4c67fe1c111cd GIT binary patch literal 262144 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 zKmY_l00ck)1V8`;KmY_l00ck)1V8`;KmY_l00ck)1V8`;KmY_l00ck)1V8`;KmY_l z00ck)1V8`;KmY_l00ck)1V8`;KmY_l00ck)1V8`;KmY_l00ck)1V8`;KmY_l00ck) z1V8`;KmY_l00ck)1V8`;KmY_l00ck)1V8`;KmY_l00ck)1V8`;KmY_l00ck)1V8`; zKmY_l00ck)1V8`;KmY_l00ck)1V8`;KmY_l00ck)1V8`;KmY_l00ck)1V8`;KmY_l z00ck)1V8`;KmY_l00ck)1V8`;KmY_l00ck)1V8`;KmY_l00ck)1V8`;KmY_l00ck) z1V8`;KmY_l00ck)1V8`;KmY_l00ck)1V8`;KmY_l00ck)1V8`;KmY_l00ck)1V8`; zKmY_l00ck)1V8`;KmY_l00ck)1V8`;KmY_l00ck)1V8`;KmY_l00ck)1V8`;KmY_l z00ck)1V8`;KmY_l00ck)1V8`;KmY_l00ck)1V8`;KmY_l00ck)1V8`;KmY_l00ck) z1V8`;KmY_l00ck)1V8`;KmY_l00ck)1V8`;KmY_l00ck)1V8`;KmY_l00ck)1V8`; zKmY_l00ck)1V8`;KmY_l00ck)1V8`;KmY_l00ck)1V8`;KmY_l00ck)1V8`;KmY_l z00ck)1V8`;KmY_l00ck)1V8`;KmY_l00ck)1V8`;KmY_l00ck)1V8`;KmY_l00ck) z1V8`;KmY_l00ck)1V8`;KmY_l00ck)1V8`;KmY_l00ck)1V8`;KmY_l00ck)1V8`; zKmY_l00ck)1V8`;KmY_l00ck)1V8`;KmY_l00ck)1V8`;KmY_l00ck)1V8`;KmY_l z00ck)1V8`;KmY_l00ck)1V8`;KmY_l00ck)1V8`;KmY_l00ck)1V8`;KmY_l00ck) z1V8`;KmY_l00ck)1V8`;KmY_l00ck)1V8`;KmY_l00ck)1V8`;KmY_l00ck)1V8`; yKmY_l00ck)1V8`;KmY_l00ck)1V8`;KmY_l00ck)1V8`;KmY_l00jQu6Zk(e&_Rp< literal 0 HcmV?d00001 diff --git a/ci/ssh.py b/ci/ssh.py new file mode 100755 index 00000000000..4dc30d75142 --- /dev/null +++ b/ci/ssh.py @@ -0,0 +1,42 @@ +#!/usr/bin/env python3 + +from argparse import ArgumentParser, REMAINDER +from select import select +import paramiko +import sys +import os + +def main(): + parser = ArgumentParser() + parser.add_argument("host") + parser.add_argument("command") + parser.add_argument("args", nargs=REMAINDER) + args = parser.parse_args() + + client = paramiko.client.SSHClient() + client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) + client.connect(args.host, username="root", password="meta-rte") + + cmd = f"{args.command} " + for arg in args.args: + cmd += f'\'{arg}\' ' + + transport = client.get_transport() + channel = transport.open_session() + channel.exec_command(cmd) + + while True: + if channel.exit_status_ready(): + break + rl, _wl, _xl = select([channel], [], []) + if len(rl) > 0: + if channel.recv_ready(): + data = channel.recv(1024) + os.write(sys.stdout.fileno(), data) + + if channel.recv_stderr_ready(): + data = channel.recv_stderr(1024) + os.write(sys.stderr.fileno(), data) + +if __name__ == '__main__': + main()