Skip to content

tests: cross-build for arm64 and actually run it - #290

Merged
pierre-warnier merged 1 commit into
mainfrom
test/arm64-smoke
Sep 6, 2026
Merged

tests: cross-build for arm64 and actually run it#290
pierre-warnier merged 1 commit into
mainfrom
test/arm64-smoke

Conversation

@pierre-warnier

Copy link
Copy Markdown
Collaborator

The release has published an arm64 archive since 0.3.0 and nothing had ever
executed one
. CI builds it on a native arm64 runner and ships it, so a binary
broken on that architecture would reach a user before anyone ran it. My checks
until now went as far as the ELF header and the linked libraries — which says
the file is arm64, not that it works.

make test-arm64 cross-compiles the multicall binary and runs it under qemu
user-mode emulation against a prefixed tree:

=== the binary is arm64 and runs ===
  PASS: cross-compiled for ARM aarch64
  PASS: runs: shadow-rs (uutils shadow-rs) 0.4.0
  PASS: carries 15 applets
=== account operations ===
  PASS: useradd -m -G staff
  PASS: the account is in passwd
  PASS: and in shadow, with aging from login.defs
  PASS: and in the supplementary group
  PASS: the home directory was created
  PASS: chpasswd wrote a SHA-512 hash
  PASS: chage sets the aging fields
  PASS: chage -l computes the dates correctly
  PASS: gpasswd adds a member
  PASS: gshadow carries the member
  PASS: usermod renames the account
  PASS: the rename reached group
  PASS: userdel -r removes it
  PASS: the account is gone from passwd
  PASS: pwck reads the files it just wrote (exit 0)

  PASS: 18   FAIL: 0

Emulation is enough for what actually differs across architectures — integer
widths, struct layouts, and the crypt and PAM FFI boundaries — and it needs
neither an arm64 machine nor a binfmt handler on the host, which rootless
Docker cannot register anyway.

The cross toolchain is installed by the target rather than baked into the
image: it is 32 packages, and every other job would carry them for a check that
runs occasionally.

I also confirmed the published 0.4.0 arm64 archive runs, by the same route:
--version and all fifteen applets.

The release has published an arm64 archive since 0.3.0 and nothing had
ever executed one. CI builds it on a native arm64 runner and ships it, so
a binary that was broken on that architecture would reach a user before
anyone ran it; the checks so far went as far as the ELF header and the
linked libraries.

make test-arm64 cross-compiles the multicall binary and runs it under
qemu user-mode emulation against a prefixed tree: useradd with a home and
a supplementary group, chpasswd producing a SHA-512 hash, chage
computing its dates, gpasswd adding a member, usermod renaming across
files, userdel -r, and pwck reading back what the others wrote. Eighteen
assertions, all passing on the current tree.

Emulation is enough for what actually differs across architectures --
integer widths, struct layouts, and the crypt and PAM FFI boundaries --
and it needs no arm64 machine and no binfmt handler on the host, which
rootless Docker cannot register anyway.

The cross toolchain is installed by the target rather than baked into the
image: it is 32 packages, and every other job would carry them for a
check that runs occasionally.

Also confirmed the published 0.4.0 arm64 archive runs, by the same route.
@pierre-warnier
pierre-warnier merged commit 604b96a into main Sep 6, 2026
18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant