Skip to content

Commit aa8072e

Browse files
committed
Extend CI to automatically run tests on select MSI platforms
1 parent fd4ea51 commit aa8072e

File tree

5 files changed

+251
-1
lines changed

5 files changed

+251
-1
lines changed

.github/workflows/build.yml

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ jobs:
4545
strategy:
4646
matrix:
4747
vendor: [ msi ]
48-
model: [ ms7d25_ddr4, ms7d25_ddr5, ms7e06_ddr4, ms7e06_ddr5 ]
48+
model: [ ms7d25_ddr5 ]
4949
steps:
5050
- name: Checkout repository
5151
uses: actions/checkout@v3
@@ -62,12 +62,17 @@ jobs:
6262
cp configs/config.${{ matrix.vendor }}_${{ matrix.model }} .config
6363
make olddefconfig
6464
make
65+
- name: Create patched binary with pre-enabled serial output
66+
run: |
67+
cp build/coreboot.rom build/coreboot_serial_enabled.rom
68+
build/util/cbfstool/cbfstool build/coreboot_serial_enabled.rom write -r SMMSTORE -f ci/smmstore-serial-enabled
6569
- name: Save artifacts
6670
uses: actions/upload-artifact@v2
6771
with:
6872
name: "dasharo-${{ matrix.vendor }}-${{ matrix.model }}-${{ matrix.build }}"
6973
path: |
7074
build/coreboot.rom
75+
build/coreboot_serial_enabled.rom
7176
retention-days: 30
7277
build_protectli:
7378
environment: Protectli
@@ -100,3 +105,53 @@ jobs:
100105
- name: Build Dasharo
101106
run: |
102107
./build.sh ${{ matrix.model }}
108+
test_msi:
109+
runs-on: self-hosted
110+
strategy:
111+
matrix:
112+
vendor: [ msi ]
113+
model: [ ms7d25_ddr5 ]
114+
needs: [build_msi]
115+
steps:
116+
- name: Set up Python
117+
uses: actions/setup-python@v2
118+
with:
119+
python-version: '3.11'
120+
121+
- name: Fetch CI script
122+
uses: actions/checkout@v4
123+
with:
124+
sparse-checkout: ci
125+
sparse-checkout-cone-mode: false
126+
127+
- name: Checkout test repository
128+
uses: actions/checkout@v4
129+
with:
130+
repository: Dasharo/open-source-firmware-validation
131+
path: validation
132+
submodules: true
133+
134+
- name: Install dependencies
135+
run: |
136+
python -m pip install --upgrade pip
137+
pip install -r validation/requirements.txt
138+
139+
- name: Fetch latest firmware
140+
uses: actions/download-artifact@v3
141+
with:
142+
name: dasharo-${{ matrix.vendor }}-${{ matrix.model }}-${{ matrix.build }}
143+
path: firmware
144+
145+
- name: Flash firmware
146+
shell: bash
147+
run: ./ci/ci.sh -r validation -v "${{ matrix.vendor }}" -m "${{ matrix.model }}" -f firmware/coreboot_serial_enabled.rom flash
148+
149+
- name: Run tests
150+
shell: bash
151+
run: ./ci/ci.sh -r validation -v "${{ matrix.vendor }}" -m "${{ matrix.model }}" -f firmware/coreboot_serial_enabled.rom test
152+
153+
- name: Upload test results
154+
uses: actions/upload-artifact@v3
155+
with:
156+
name: test-results-${{ matrix.vendor }}-${{ matrix.model }}
157+
if: always()

ci/ci.sh

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
#!/usr/bin/env bash
2+
3+
set -euo pipefail
4+
5+
script_dir="$(dirname "${BASH_SOURCE[0]}")"
6+
7+
vendor=""
8+
model=""
9+
10+
usage() {
11+
echo "Usage: ci.sh -v vendor -m model -f firmware command" 1>&2
12+
exit 1
13+
}
14+
15+
while getopts "r:v:m:f:" o; do
16+
case "${o}" in
17+
r) root="${OPTARG}" ;;
18+
v) vendor="${OPTARG}" ;;
19+
m) model="${OPTARG}" ;;
20+
f) fw_file="${OPTARG}" ;;
21+
*) usage ;;
22+
esac
23+
done
24+
shift $((OPTIND-1))
25+
26+
[ -n "$vendor" ] || usage
27+
[ -n "$model" ] || usage
28+
[ $# -eq 1 ] || usage
29+
30+
command="$1"
31+
[[ "$command" =~ ^(flash|test)$ ]] || usage
32+
shift 1
33+
34+
options=(
35+
-L TRACE
36+
-v snipeit:none
37+
)
38+
39+
compatibility_tests=()
40+
performance_tests=()
41+
security_tests=()
42+
stability_tests=()
43+
44+
case "$vendor" in
45+
msi)
46+
case "$model" in
47+
ms7d25_ddr5)
48+
device_ip="192.168.10.93"
49+
rte_ip="192.168.10.188"
50+
pikvm_ip="192.168.10.45"
51+
config="msi-pro-z690-a-ddr5"
52+
;;
53+
*)
54+
echo unknown board: $model
55+
exit 1
56+
;;
57+
esac
58+
;;
59+
*)
60+
echo unknown vendor: $vendor
61+
exit 1
62+
;;
63+
esac
64+
65+
options+=(
66+
-v device_ip:$device_ip
67+
-v rte_ip:$rte_ip
68+
-v pikvm_ip:$pikvm_ip
69+
-v config:$config
70+
-v snipeit:no
71+
)
72+
73+
if [ "$command" == "flash" ]; then
74+
"$script_dir/scp.py" "$rte_ip" "$fw_file" /tmp/dasharo.rom
75+
"$script_dir/ssh.py" "$rte_ip" /home/root/flash.sh /tmp/dasharo.rom
76+
exit 0
77+
fi
78+
79+
case "$vendor" in
80+
msi)
81+
case "$model" in
82+
ms7d25_ddr5)
83+
compatibility_tests+=(
84+
custom-boot-menu-key
85+
)
86+
87+
security_tests+=(
88+
me-neuter
89+
)
90+
;;
91+
*)
92+
echo unknown board: $model
93+
exit 1
94+
;;
95+
esac
96+
;;
97+
*)
98+
echo unknown vendor: $vendor
99+
exit 1
100+
;;
101+
esac
102+
103+
mkdir -p "test-results-$vendor-$model"
104+
105+
run_robot() {
106+
local category="$1"
107+
local test="$2"
108+
109+
robot -l "test-results-$vendor-$model/dasharo-${category}.log.html" \
110+
-r "test-results-$vendor-$model/dasharo-${category}.html" \
111+
-o "test-results-$vendor-$model/dasharo-${category}.xml" \
112+
${options[@]} "$root/dasharo-${category}/$test.robot"
113+
}
114+
115+
if [ "$command" == "test" ]; then
116+
for test in "${compatibility_tests[@]}"; do
117+
run_robot compatibility "$test"
118+
done
119+
120+
for test in "${performance_tests[@]}"; do
121+
run_robot performance "$test"
122+
done
123+
124+
for test in "${security_tests[@]}"; do
125+
run_robot security "$test"
126+
done
127+
128+
for test in "${stability_tests[@]}"; do
129+
run_robot stability "$test"
130+
done
131+
fi

ci/scp.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#!/usr/bin/env python3
2+
3+
from argparse import ArgumentParser
4+
import paramiko
5+
6+
def main():
7+
parser = ArgumentParser()
8+
parser.add_argument("host")
9+
parser.add_argument("local")
10+
parser.add_argument("remote")
11+
args = parser.parse_args()
12+
13+
client = paramiko.client.SSHClient()
14+
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
15+
client.connect(args.host, username="root", password="meta-rte")
16+
17+
ftp = client.open_sftp()
18+
ftp.put(args.local, args.remote)
19+
ftp.close()
20+
21+
if __name__ == '__main__':
22+
main()

ci/smmstore-serial-enabled

256 KB
Binary file not shown.

ci/ssh.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#!/usr/bin/env python3
2+
3+
from argparse import ArgumentParser, REMAINDER
4+
from select import select
5+
import paramiko
6+
import sys
7+
import os
8+
9+
def main():
10+
parser = ArgumentParser()
11+
parser.add_argument("host")
12+
parser.add_argument("command")
13+
parser.add_argument("args", nargs=REMAINDER)
14+
args = parser.parse_args()
15+
16+
client = paramiko.client.SSHClient()
17+
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
18+
client.connect(args.host, username="root", password="meta-rte")
19+
20+
cmd = f"{args.command} "
21+
for arg in args.args:
22+
cmd += f'\'{arg}\' '
23+
24+
transport = client.get_transport()
25+
channel = transport.open_session()
26+
channel.exec_command(cmd)
27+
28+
while True:
29+
if channel.exit_status_ready():
30+
break
31+
rl, _wl, _xl = select([channel], [], [])
32+
if len(rl) > 0:
33+
if channel.recv_ready():
34+
data = channel.recv(1024)
35+
os.write(sys.stdout.fileno(), data)
36+
37+
if channel.recv_stderr_ready():
38+
data = channel.recv_stderr(1024)
39+
os.write(sys.stderr.fileno(), data)
40+
41+
if __name__ == '__main__':
42+
main()

0 commit comments

Comments
 (0)