Skip to content

test(qemu): optional QEMU kernel-matrix binder round-trip harness (#664) - #665

Closed
Ulrond wants to merge 4 commits into
developfrom
feature/664-qemu-binder-test
Closed

test(qemu): optional QEMU kernel-matrix binder round-trip harness (#664)#665
Ulrond wants to merge 4 commits into
developfrom
feature/664-qemu-binder-test

Conversation

@Ulrond

@Ulrond Ulrond commented Jun 30, 2026

Copy link
Copy Markdown
Collaborator

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's BINDER_VERSION check catches the 7-vs-8 protocol mismatch), registers a service with servicemanager, fetches it, transacts (41→42). Sentinel line QEMU_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 — reuses build_binder.sh for 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 in tests/qemu/README.md and linked from tests/README.md.

Verification done in-tree

  • bash -n / sh -n clean on all scripts.
  • binder_roundtrip.cpp compiles + links against the staged binder SDK (needed the transitive -lbase -lcutils -llog).
  • The runner end-to-end builds the SDK, compiles the test, assembles the initramfs, and reports cleanly (validated with the boot step skipped).

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 of tests/.

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.
Copilot AI review requested due to automatic review settings June 30, 2026 19:00
@github-project-automation github-project-automation Bot moved this to Architecture Review Required in halif_aidl Jun 30, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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, start servicemanager, 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.md and tests/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 thread tests/qemu/run-qemu-test.sh Outdated
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 thread tests/qemu/run-qemu-test.sh Outdated
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 thread tests/qemu/guest-init.sh Outdated
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
Ulrond added 2 commits June 30, 2026 22:43
- 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.
Copilot AI review requested due to automatic review settings June 30, 2026 22:01

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated 3 comments.

Comment thread tests/qemu/guest-init.sh
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 thread tests/qemu/run-qemu-test.sh Outdated
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.
@Ulrond Ulrond self-assigned this Jul 3, 2026
@Ulrond Ulrond added this to the Next Release milestone Jul 3, 2026
@Ulrond

Ulrond commented Jul 4, 2026

Copy link
Copy Markdown
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.

@Ulrond Ulrond closed this Jul 4, 2026
@Ulrond
Ulrond deleted the feature/664-qemu-binder-test branch July 4, 2026 08:02
@github-project-automation github-project-automation Bot moved this from Architecture Review Required to Resolved in halif_aidl Jul 4, 2026
@github-actions github-actions Bot locked and limited conversation to collaborators Jul 4, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

Status: Resolved

Development

Successfully merging this pull request may close these issues.

test: optional QEMU kernel-matrix binder round-trip harness

2 participants