test(qemu): optional QEMU kernel-matrix binder round-trip harness (#664) - #665
Closed
Ulrond wants to merge 4 commits into
Closed
test(qemu): optional QEMU kernel-matrix binder round-trip harness (#664)#665Ulrond wants to merge 4 commits into
Ulrond wants to merge 4 commits into
Conversation
Add an on-demand, optional test that boots a target kernel under QEMU and runs a Binder round-trip against that kernel's driver — the runtime gate for the kernel-floor / protocol / bitness work (#662, linux_binder_idl#35). Docker can't do this (containers share the host kernel), so it boots real kernels. - binder_roundtrip.cpp: open /dev/binder (catches the BINDER_VERSION protocol mismatch), servicemanager register/fetch/transact (41->42); HALIF hook. - guest-init.sh: provision binder device (binderfs >=5.0 / static node), run the test, emit a sentinel, poweroff. - run-qemu-test.sh: reuse build_binder.sh for the guest userspace, assemble a busybox initramfs (libbinder/utils/base/cutils/log + servicemanager + test), boot each kernel, parse the sentinel. Skips cleanly when QEMU/busybox/ compiler/kernels are absent. - build-kernels.sh: Buildroot matrix builder (4.9 -> 5.16) with a binder kconfig fragment (+ protocol-7 ipc32 variant). Verified in-tree: scripts pass bash/sh -n; the test compiles+links against the staged binder SDK; the runner builds the SDK, compiles the test, assembles the initramfs, and reports cleanly. The actual multi-kernel boots require built target kernels (build-kernels.sh) and are run on demand.
Contributor
There was a problem hiding this comment.
Pull request overview
Adds an optional, on-demand QEMU-based harness under tests/qemu/ to boot real kernels and run a minimal Binder round-trip, intended to validate binder runtime compatibility across a kernel matrix (where Docker/container testing can’t vary the kernel).
Changes:
- Add host-side runner to build a minimal initramfs (binder SDK + servicemanager + test), boot kernels in QEMU, and parse a PASS/FAIL sentinel.
- Add guest init (PID 1) to provision
/dev/binder, startservicemanager, run the round-trip, and power off. - Add Buildroot-based kernel matrix builder and kernel config fragments for binder protocol variants; document usage in
tests/README.mdandtests/qemu/README.md.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/README.md | Links and briefly documents the new optional tests/qemu/ harness. |
| tests/qemu/run-qemu-test.sh | Host runner: builds test binary, assembles initramfs, boots kernels under QEMU, parses sentinel. |
| tests/qemu/README.md | Detailed documentation for the harness, matrix variants, and extension hook. |
| tests/qemu/kconfig/binder.fragment | Kernel config fragment enabling binder/binderfs for protocol 8 (default). |
| tests/qemu/kconfig/binder-ipc32.fragment | Overlay fragment enabling legacy protocol-7 (IPC32) variant. |
| tests/qemu/guest-init.sh | Guest PID 1: mounts pseudo-fs, provisions binder device, runs test, powers off. |
| tests/qemu/build-kernels.sh | Buildroot-based builder for the kernel matrix used by the QEMU harness. |
| tests/qemu/binder_roundtrip.cpp | In-guest minimal binder round-trip test emitting PASS/FAIL sentinel. |
Comment on lines
+46
to
+53
| while [ $# -gt 0 ]; do | ||
| case "$1" in | ||
| --kernel) KERNEL_ARG="$2"; shift 2 ;; | ||
| --keep) KEEP=true; shift ;; | ||
| -h|--help) sed -n '20,33p' "${BASH_SOURCE[0]}" | sed 's/^# \{0,1\}//'; exit 0 ;; | ||
| *) echo "Unknown option: $1" >&2; exit 2 ;; | ||
| esac | ||
| done |
Comment on lines
+79
to
+82
| if [ ! -f "${REPO_ROOT}/out/target/.sdk_ready" ]; then | ||
| echo " building binder SDK (build_binder.sh) ..." | ||
| (cd "${REPO_ROOT}" && ./build_binder.sh) >/dev/null 2>&1 || skip "build_binder.sh failed" | ||
| fi |
Comment on lines
+95
to
+100
| echo " compiling binder_roundtrip ..." | ||
| "${CXX}" -std=c++17 -O1 -Wno-attributes -Wno-write-strings -Wno-return-type \ | ||
| "${HERE}/binder_roundtrip.cpp" \ | ||
| -I"${SDK_INC}" -L"${SDK_LIB}" -lbinder -lutils -lbase -lcutils -llog \ | ||
| -Wl,-rpath,/opt/binder/lib -o "${WORK}/binder_roundtrip" \ | ||
| || skip "binder_roundtrip failed to compile against the SDK" |
Comment on lines
+58
to
+63
| command -v "${QEMU}" >/dev/null 2>&1 || skip "${QEMU} not installed" | ||
| BUSYBOX="$(command -v busybox || true)" | ||
| [ -n "${BUSYBOX}" ] || skip "busybox not installed (need a static-ish busybox for the initramfs)" | ||
| command -v cpio >/dev/null 2>&1 || skip "cpio not installed" | ||
| CXX="${CXX:-g++}" | ||
| command -v "${CXX}" >/dev/null 2>&1 || skip "${CXX} not installed" |
Comment on lines
+44
to
+48
| # servicemanager must own the context before the test calls defaultServiceManager(). | ||
| /opt/binder/bin/servicemanager >/dev/null 2>&1 & | ||
| i=0 | ||
| while [ ! -e /dev/binder ] && [ "$i" -lt 10 ]; do i=$((i + 1)); sleep 1; done | ||
| sleep 1 |
Comment on lines
+51
to
+54
| # Buildroot needs a normal build toolchain + the usual fetchers. | ||
| for t in make gcc g++ wget cpio rsync bc flex bison; do | ||
| have "$t" || die "missing build dependency: $t (Buildroot prerequisite)" | ||
| done |
- run-qemu-test.sh: guard `--kernel` against a missing value; add timeout/ gzip/ldd to the skip-prereq check; treat binder-SDK build and binder_roundtrip compile/link FAILURES as hard errors (fail, exit 1) rather than clean SKIPs, so real breakage isn't masked once the harness is opted in. - guest-init.sh: drop the misleading /dev/binder re-check loop; give servicemanager a brief settle instead (it has no readiness file to poll). - build-kernels.sh: add tar to the dependency preflight.
Install the QEMU binder test prerequisites via the system package manager (apt/dnf/pacman, sudo when needed). Two groups: RUN (qemu, busybox, cpio, g++, gzip) and BUILD (Buildroot kernel-build deps: toolchain + wget/tar/rsync/bc/ flex/bison/unzip/ncurses/openssl/elf headers). --minimal installs RUN only (bring-your-own kernels); --dry-run prints the package list. Referenced as step 0 from tests/qemu/README.md.
Comment on lines
+39
to
+42
| if [ ! -e /dev/binder ]; then | ||
| echo "QEMU_BINDER_RESULT: FAIL no /dev/binder on kernel $(uname -r)" | ||
| poweroff -f | ||
| fi |
Comment on lines
+111
to
+121
| # Copy each binary's shared-lib closure + the ELF interpreter into the rootfs, | ||
| # preserving paths, so the guest userspace resolves at runtime. | ||
| copy_deps() { | ||
| local bin="$1" dep | ||
| LD_LIBRARY_PATH="${SDK_LIB}" ldd "${bin}" 2>/dev/null | awk '{for(i=1;i<=NF;i++) if($i ~ /^\//) print $i}' \ | ||
| | while read -r dep; do | ||
| [ -f "${dep}" ] || continue | ||
| mkdir -p "${ROOT}$(dirname "${dep}")" | ||
| cp -n "${dep}" "${ROOT}${dep}" 2>/dev/null || true | ||
| done | ||
| } |
Comment on lines
+63
to
+68
| echo "[buildroot] fetching ${BR_VERSION} ..." | ||
| wget -qO "${HERE}/.buildroot/br.tar.gz" \ | ||
| "https://buildroot.org/downloads/buildroot-${BR_VERSION}.tar.gz" \ | ||
| || die "failed to download Buildroot ${BR_VERSION}" | ||
| tar -xzf "${HERE}/.buildroot/br.tar.gz" -C "${HERE}/.buildroot" | ||
| fi |
- guest-init.sh: exit after the FAIL sentinel + poweroff so the failure mode is deterministic even if poweroff is delayed. - run-qemu-test.sh: copy_deps skips SDK libs (already staged at /opt/binder/lib via rpath) — avoids copying them under host repo paths and bloating the initramfs. - build-kernels.sh: fail fast if the Buildroot tarball extraction fails.
Collaborator
Author
|
Relocated to linux_binder_idl — the QEMU harness tests the binder driver/runtime (not any HAL AIDL) and validates the kernel-floor work that lives there. Superseded by rdkcentral/linux_binder_idl#41 (issue rdkcentral/linux_binder_idl#40), on the linux_binder_idl 2.5.0 milestone. Closing here. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #664.
Adds an optional, on-demand QEMU test under
tests/qemu/that boots a target kernel and runs a Binder round-trip against its driver — the runtime gate for the kernel-floor / protocol / bitness work (#662, linux_binder_idl#35). Docker can't do this (containers share the host kernel), so it boots real kernels.Pieces
binder_roundtrip.cpp— opens/dev/binder(libbinder'sBINDER_VERSIONcheck catches the 7-vs-8 protocol mismatch), registers a service withservicemanager, fetches it, transacts (41→42). Sentinel lineQEMU_BINDER_RESULT: PASS/FAIL. Carries a marked hook to extend to a generated HALIF interface.guest-init.sh— guest PID 1: provisions the binder device (binderfs ≥5.0 / static node <5.0), runs the test, powers off.run-qemu-test.sh— reusesbuild_binder.shfor the guest userspace, assembles a busybox initramfs (libbinder/utils/base/cutils/log + servicemanager + test + their lib closure), boots each kernel, parses the sentinel. Skips cleanly when QEMU/busybox/compiler/kernels are absent — the default suite is unaffected.build-kernels.sh— Buildroot matrix builder (4.9 → 5.16) applying a binder kconfig fragment, plus a protocol-7 (ipc32) variant.Standalone (not wired into
smoke_test.sh) so QEMU testing is purely opt-in; documented intests/qemu/README.mdand linked fromtests/README.md.Verification done in-tree
bash -n/sh -nclean on all scripts.binder_roundtrip.cppcompiles + links against the staged binder SDK (needed the transitive-lbase -lcutils -llog).The actual multi-kernel boots need built target kernels (
build-kernels.sh, heavy/Buildroot) and are run on demand — not CI-wired, consistent with the rest oftests/.