[PATCH] Gitlab: Add a "sage-lab" stage to access a board farm
Tom Rini
trini at konsulko.com
Mon Nov 10 16:42:31 CET 2025
This is the Gitlab side of adding support for the board lab connected to
the "konsulko-sage" runner. On the software side, this lab uses only
upstream labgrid. On the hardware side, each device under test is
connected to its own exporter (typically a Raspberry Pi 4) that must be
turned on (and cleanly turned off) as part of a given test cycle.
Add support for testing on a SolidRun Hummingboard 2 (imx6), Raspberry
Pi 3 and Raspberry Pi 4. In all cases, we enable additional options to
run more tests on the board. As we have some networking tests, we test
both the legacy network stack and lwIP. In the case of Pi platforms, we
test all of 32bit configuration, plain configuration and rpi_arm64, and
again with and without lwIP.
Signed-off-by: Tom Rini <trini at konsulko.com>
---
Note that for the Pi platforms we enable/disable CMD_BOOTEFI_SELFTEST
based on overall binary size. I've created
https://source.denx.de/u-boot/custodians/u-boot-raspberrypi/-/issues/2
to track addressing that issue.
---
.gitlab-ci-sage-lab.yml | 182 ++++++++++++++++++++++++++++++++++++++++
.gitlab-ci.yml | 5 ++
2 files changed, 187 insertions(+)
create mode 100644 .gitlab-ci-sage-lab.yml
diff --git a/.gitlab-ci-sage-lab.yml b/.gitlab-ci-sage-lab.yml
new file mode 100644
index 000000000000..26a055f93121
--- /dev/null
+++ b/.gitlab-ci-sage-lab.yml
@@ -0,0 +1,182 @@
+# Definition for the lab connected to the "sage" host and managed with labgrid
+
+.sage_lab_template: &sage_lab_dfn
+ stage: sage-lab
+ rules:
+ - if: $SAGE_LAB == "1"
+ when: always
+ - if: $SAGE_LAB != "1"
+ when: manual
+ allow_failure: true
+ # USB can be unreliable.
+ retry: 2
+ dependencies: []
+ needs: [ "sandbox test.py" ]
+ tags: [ 'konsulko-sage-labgrid' ]
+ before_script:
+ # Clone uboot-test-hooks
+ - git config --global --add safe.directory "${CI_PROJECT_DIR}"
+ - git clone --depth=1 -b sage-labgrid https://github.com/trini/u-boot-test-hooks.git /tmp/uboot-test-hooks
+ - ln -s sage /tmp/uboot-test-hooks/bin/`hostname`
+ - ln -s sage /tmp/uboot-test-hooks/py/`hostname`
+ - export LG_ENV="/tmp/uboot-test-hooks/bin/sage/labgrid-sage-env.yaml"
+ # Prepare python environment
+ - python3 -m venv /tmp/venv;
+ . /tmp/venv/bin/activate;
+ pip install -r test/py/requirements.txt -r tools/binman/requirements.txt
+ -r tools/buildman/requirements.txt -r tools/u_boot_pylib/requirements.txt
+ labgrid
+ # Add more tools
+ - sudo apt-get update && sudo apt-get -y install snmp rsync
+ # Acquire and turn on the exporter.
+ - labgrid-client -p ${LABGRID_EXPORTER} acquire &&
+ labgrid-client -p ${LABGRID_EXPORTER} power on
+ # Prepare ssh
+ - mkdir --mode=0700 ~/.ssh;
+ printf 'Host sage-exporter-*\n\tUser labgrid\n' > ~/.ssh/config
+ script:
+ - export UBOOT_TRAVIS_BUILD_DIR=/tmp/${TEST_PY_BD}
+ # Sage is 16 threads and has 3 devices attached, so 6 builder threads.
+ - tools/buildman/buildman -o ${UBOOT_TRAVIS_BUILD_DIR} -w -E -W -e
+ --board ${TEST_PY_BD} ${OVERRIDE} -T 6
+ # Wait for the exporter to have the device ready
+ - while test `labgrid-client resources |
+ grep -q ${LABGRID_EXPORTER}/${LG_PLACE}/; echo $?` -ne 0; do sleep 1;
+ done
+ # Fingerprint the exporter
+ - ssh-keyscan ${LABGRID_EXPORTER} > ~/.ssh/known_hosts 2>/dev/null
+ # Don't stop on non-zero exit codes now, to provide as much chance as
+ # possible to ensure we don't leave lab resources acquired.
+ - set +e;
+ # Run the tests, save the results.
+ - export PATH=/tmp/uboot-test-hooks/bin:${PATH};
+ export PYTHONPATH=/tmp/uboot-test-hooks/py/sage;
+ labgrid-client -p ${LG_PLACE} acquire;
+ ./test/py/test.py -ra --bd ${TEST_PY_BD} ${TEST_PY_ID}
+ ${TEST_PY_EXTRA:-"--capture=tee-sys"}
+ ${TEST_PY_TEST_SPEC:+"-k ${TEST_PY_TEST_SPEC}"}
+ --build-dir "$UBOOT_TRAVIS_BUILD_DIR"
+ --junitxml=/tmp/${TEST_PY_BD}/results.xml;
+ RC=`echo $?`;
+ cp -v /tmp/${TEST_PY_BD}/*.{html,css,xml} .;
+ # Release and power off everything.
+ - labgrid-client -p ${LG_PLACE} power off
+ - labgrid-client -p ${LG_PLACE} release
+ - labgrid-client -p ${LABGRID_EXPORTER} ssh sudo poweroff && sleep 15 &&
+ labgrid-client -p ${LABGRID_EXPORTER} power off
+ - labgrid-client -p ${LABGRID_EXPORTER} release
+ - exit $RC
+ artifacts:
+ when: always
+ paths:
+ - "*.html"
+ - "*.css"
+ - results.xml
+ reports:
+ junit: results.xml
+ expire_in: 1 week
+
+SolidRun Hummingboard 2:
+ <<: *sage_lab_dfn
+ variables:
+ LABGRID_EXPORTER: "sage-exporter-hb-1"
+ LG_PLACE: "hb-1"
+ TEST_PY_BD: "mx6cuboxi"
+ OVERRIDE: "-a UNIT_TEST -a ~CMD_EFIDEBUG -a CMD_BOOTMENU -a CMD_LOG"
+
+SolidRun Hummingboard 2 (lwIP):
+ <<: *sage_lab_dfn
+ needs: [ "SolidRun Hummingboard 2" ]
+ variables:
+ LABGRID_EXPORTER: "sage-exporter-hb-1"
+ LG_PLACE: "hb-1"
+ TEST_PY_BD: "mx6cuboxi"
+ OVERRIDE: "-a UNIT_TEST -a ~CMD_EFIDEBUG -a CMD_BOOTMENU -a CMD_LOG -a NET_LWIP"
+
+Raspberry Pi 4:
+ <<: *sage_lab_dfn
+ variables:
+ LABGRID_EXPORTER: "sage-exporter-rpi4-1"
+ LG_PLACE: "rpi4-1"
+ TEST_PY_BD: "rpi_4"
+ OVERRIDE: "-a UNIT_TEST -a ~CMD_EFIDEBUG -a CMD_BOOTMENU -a CMD_LOG -a ~CMD_BOOTEFI_SELFTEST -a IPV6 -a IPV6_ROUTER_DISCOVERY -a CMD_TFTPPUT -a FIT -a FIT_SIGNATURE -a FIT_BEST_MATCH -a SYS_BOOTM_LEN=0x4000000 -a BOOTSTAGE -a BOOTSTAGE_STASH -a CMD_BOOTSTAGE -a BOOTSTAGE_STASH_ADDR=0x02400000"
+
+Raspberry Pi 4 (rpi_arm64):
+ <<: *sage_lab_dfn
+ needs: [ "Raspberry Pi 4" ]
+ variables:
+ LABGRID_EXPORTER: "sage-exporter-rpi4-1"
+ LG_PLACE: "rpi4-1"
+ TEST_PY_BD: "rpi_arm64"
+ OVERRIDE: "-a UNIT_TEST -a ~CMD_EFIDEBUG -a CMD_BOOTMENU -a CMD_LOG -a ~CMD_BOOTEFI_SELFTEST -a IPV6 -a IPV6_ROUTER_DISCOVERY -a CMD_TFTPPUT -a FIT -a FIT_SIGNATURE -a FIT_BEST_MATCH -a SYS_BOOTM_LEN=0x4000000 -a BOOTSTAGE -a BOOTSTAGE_STASH -a CMD_BOOTSTAGE -a BOOTSTAGE_STASH_ADDR=0x02400000"
+
+Raspberry Pi 4 (rpi_arm64, lwIP):
+ <<: *sage_lab_dfn
+ needs: [ "Raspberry Pi 4 (rpi_arm64)" ]
+ variables:
+ LABGRID_EXPORTER: "sage-exporter-rpi4-1"
+ LG_PLACE: "rpi4-1"
+ TEST_PY_BD: "rpi_arm64"
+ OVERRIDE: "-a UNIT_TEST -a ~CMD_EFIDEBUG -a CMD_BOOTMENU -a CMD_LOG -a ~CMD_BOOTEFI_SELFTEST -a FIT -a FIT_SIGNATURE -a FIT_BEST_MATCH -a SYS_BOOTM_LEN=0x4000000 -a BOOTSTAGE -a BOOTSTAGE_STASH -a CMD_BOOTSTAGE -a BOOTSTAGE_STASH_ADDR=0x02400000 -a NET_LWIP"
+
+Raspberry Pi 4 (rpi_4_32b):
+ <<: *sage_lab_dfn
+ needs: [ "Raspberry Pi 4 (rpi_arm64, lwIP)" ]
+ variables:
+ LABGRID_EXPORTER: "sage-exporter-rpi4-1"
+ LG_PLACE: "rpi4-1"
+ TEST_PY_BD: "rpi_4_32b"
+ OVERRIDE: "-a UNIT_TEST -a ~CMD_EFIDEBUG -a CMD_BOOTMENU -a CMD_LOG -a CMD_BOOTEFI_SELFTEST -a IPV6 -a IPV6_ROUTER_DISCOVERY -a CMD_TFTPPUT -a FIT -a FIT_SIGNATURE -a FIT_BEST_MATCH -a SYS_BOOTM_LEN=0x4000000 -a BOOTSTAGE -a BOOTSTAGE_STASH -a CMD_BOOTSTAGE -a BOOTSTAGE_STASH_ADDR=0x02400000"
+
+Raspberry Pi 4 (rpi_4_32b, lwIP):
+ <<: *sage_lab_dfn
+ needs: [ "Raspberry Pi 4 (rpi_4_32b)" ]
+ variables:
+ LABGRID_EXPORTER: "sage-exporter-rpi4-1"
+ LG_PLACE: "rpi4-1"
+ TEST_PY_BD: "rpi_4_32b"
+ OVERRIDE: "-a UNIT_TEST -a ~CMD_EFIDEBUG -a CMD_BOOTMENU -a CMD_LOG -a CMD_BOOTEFI_SELFTEST -a FIT -a FIT_SIGNATURE -a FIT_BEST_MATCH -a SYS_BOOTM_LEN=0x4000000 -a BOOTSTAGE -a BOOTSTAGE_STASH -a CMD_BOOTSTAGE -a BOOTSTAGE_STASH_ADDR=0x02400000 -a NET_LWIP"
+
+Raspberry Pi 3:
+ <<: *sage_lab_dfn
+ variables:
+ LABGRID_EXPORTER: "sage-exporter-rpi3-1"
+ LG_PLACE: "rpi3-1"
+ TEST_PY_BD: "rpi_3"
+ OVERRIDE: "-a UNIT_TEST -a ~CMD_EFIDEBUG -a CMD_BOOTMENU -a CMD_LOG -a CMD_BOOTEFI_SELFTEST -a IPV6 -a IPV6_ROUTER_DISCOVERY -a CMD_TFTPPUT -a FIT -a FIT_SIGNATURE -a FIT_BEST_MATCH -a SYS_BOOTM_LEN=0x4000000 -a BOOTSTAGE -a BOOTSTAGE_STASH -a CMD_BOOTSTAGE -a BOOTSTAGE_STASH_ADDR=0x02400000"
+
+Raspberry Pi 3 (rpi_arm64):
+ <<: *sage_lab_dfn
+ needs: [ "Raspberry Pi 3" ]
+ variables:
+ LABGRID_EXPORTER: "sage-exporter-rpi3-1"
+ LG_PLACE: "rpi3-1"
+ TEST_PY_BD: "rpi_arm64"
+ OVERRIDE: "-a UNIT_TEST -a ~CMD_EFIDEBUG -a CMD_BOOTMENU -a CMD_LOG -a ~CMD_BOOTEFI_SELFTEST -a IPV6 -a IPV6_ROUTER_DISCOVERY -a CMD_TFTPPUT -a FIT -a FIT_SIGNATURE -a FIT_BEST_MATCH -a SYS_BOOTM_LEN=0x4000000 -a BOOTSTAGE -a BOOTSTAGE_STASH -a CMD_BOOTSTAGE -a BOOTSTAGE_STASH_ADDR=0x02400000"
+
+Raspberry Pi 3 (rpi_arm64, lwIP):
+ <<: *sage_lab_dfn
+ needs: [ "Raspberry Pi 3 (rpi_arm64)" ]
+ variables:
+ LABGRID_EXPORTER: "sage-exporter-rpi3-1"
+ LG_PLACE: "rpi3-1"
+ TEST_PY_BD: "rpi_arm64"
+ OVERRIDE: "-a UNIT_TEST -a ~CMD_EFIDEBUG -a CMD_BOOTMENU -a CMD_LOG -a ~CMD_BOOTEFI_SELFTEST -a FIT -a FIT_SIGNATURE -a FIT_BEST_MATCH -a SYS_BOOTM_LEN=0x4000000 -a BOOTSTAGE -a BOOTSTAGE_STASH -a CMD_BOOTSTAGE -a BOOTSTAGE_STASH_ADDR=0x02400000 -a NET_LWIP"
+
+Raspberry Pi 3 (rpi_3_32b):
+ <<: *sage_lab_dfn
+ needs: [ "Raspberry Pi 3 (rpi_arm64, lwIP)" ]
+ variables:
+ LABGRID_EXPORTER: "sage-exporter-rpi3-1"
+ LG_PLACE: "rpi3-1"
+ TEST_PY_BD: "rpi_3_32b"
+ OVERRIDE: "-a UNIT_TEST -a ~CMD_EFIDEBUG -a CMD_BOOTMENU -a CMD_LOG -a CMD_BOOTEFI_SELFTEST -a IPV6 -a IPV6_ROUTER_DISCOVERY -a CMD_TFTPPUT -a FIT -a FIT_SIGNATURE -a FIT_BEST_MATCH -a SYS_BOOTM_LEN=0x4000000 -a BOOTSTAGE -a BOOTSTAGE_STASH -a CMD_BOOTSTAGE -a BOOTSTAGE_STASH_ADDR=0x02400000"
+
+Raspberry Pi 3 (rpi_3_32b, lwIP):
+ <<: *sage_lab_dfn
+ needs: [ "Raspberry Pi 3 (rpi_3_32b)" ]
+ variables:
+ LABGRID_EXPORTER: "sage-exporter-rpi3-1"
+ LG_PLACE: "rpi3-1"
+ TEST_PY_BD: "rpi_3_32b"
+ OVERRIDE: "-a UNIT_TEST -a ~CMD_EFIDEBUG -a CMD_BOOTMENU -a CMD_LOG -a CMD_BOOTEFI_SELFTEST -a FIT -a FIT_SIGNATURE -a FIT_BEST_MATCH -a SYS_BOOTM_LEN=0x4000000 -a BOOTSTAGE -a BOOTSTAGE_STASH -a CMD_BOOTSTAGE -a BOOTSTAGE_STASH_ADDR=0x02400000 -a NET_LWIP"
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 6a36513c3b75..b32e6ade230d 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -5,6 +5,7 @@ variables:
DEFAULT_AMD64_TAG: "amd64"
DEFAULT_FAST_TAG: "fast"
MIRROR_DOCKER: docker.io
+ SAGE_LAB: ""
SJG_LAB: ""
PLATFORM: linux/amd64,linux/arm64
@@ -24,6 +25,7 @@ image: ${MIRROR_DOCKER}/trini/u-boot-gitlab-ci-runner:jammy-20251001-04Nov2025
stages:
- testsuites
- test.py
+ - sage-lab
- sjg-lab
- world build
@@ -597,6 +599,9 @@ coreboot test.py:
TEST_PY_ID: "--id qemu"
<<: *buildman_and_testpy_dfn
+# Add sage-lab stage
+include: .gitlab-ci-sage-lab.yml
+
.sjg_lab_template: &sjg_lab_dfn
stage: sjg-lab
rules:
--
2.43.0
More information about the U-Boot
mailing list