diff options
| author | Julian Andres Klode <julian.klode@canonical.com> | 2025-01-07 17:39:32 +0100 |
|---|---|---|
| committer | Julian Andres Klode <jak@debian.org> | 2025-10-25 18:42:14 +0000 |
| commit | 9d62eef571ffd1fd2df8b97884d3689fced27fb1 (patch) | |
| tree | 100d5321f364b389100928e927639e852c52ff48 /test | |
| parent | 50d8703c785898d06463513896e37cbe7cedd471 (diff) | |
Implement architecture variants
Architecture variants are children of an architecture that share
the same ABI but are optimized for different ISA levels. They
are available in Ubuntu 25.10 and newer, and not supported in
Debian or other distributions.
A deb built for a variant contains the Architecture-Variant field,
and the Architecture field points to the baseline, for example:
Architecture: amd64
Architecture-Variant: amd64v3
However, the apt-get indextargets command reports the variant in the
Architecture: field, and most of the code in APT presents the variant
as the architecture.
There are two types of variants:
1. Standalone variants are recorded in the Architectures field of the
Release file as if they were a real architecture:
Architectures: amd64 amd64v3
Standalone architecture variants only fetch the standalone
architecture variant's Packages file. To do this, this patch
changes the code such that the variants indextargets "supplant"
the base targets.
This may have complicated outcomes on the apt-get indextargets
command.
2. Other variants can only be identified by their files being recorded
with hashes in the Release file.
APT fetches both the base architecture's as well as the variant's
Packages file.
Variants are configured in the
APT::Architecture-Variants
list.
Image builders may want to build specific variant images using
APT::Architecture-Variants { "amd64v3"; }
But this commit also implements an automatic discovery mechanism
using the varianttable and /proc/cpuinfo.
APT::Architecture-Variants "auto";
Diffstat (limited to 'test')
| -rw-r--r-- | test/integration/framework | 11 | ||||
| -rwxr-xr-x | test/integration/test-architecture-variants | 244 | ||||
| -rw-r--r-- | test/integration/varianttable | 5 |
3 files changed, 258 insertions, 2 deletions
diff --git a/test/integration/framework b/test/integration/framework index d95a1799a..7780ef835 100644 --- a/test/integration/framework +++ b/test/integration/framework @@ -547,6 +547,7 @@ exec fakeroot gdb --quiet -ex run '${DPKG:-dpkg}' --args '${DPKG:-dpkg}' --root= EOF chmod +x "${TMPWORKINGDIRECTORY}/rootdir/usr/bin/dpkg" "${TMPWORKINGDIRECTORY}/rootdir/usr/bin/gdb-dpkg" echo "Dir::Bin::dpkg \"${TMPWORKINGDIRECTORY}/rootdir/usr/bin/dpkg\";" > rootdir/etc/apt/apt.conf.d/99dpkg + echo "Dir::dpkg::varianttable \"${TESTDIRECTORY}/varianttable\";" > rootdir/etc/apt/apt.conf.d/99variants # Set the solver for the test case. if [ "$APT_SOLVER" ]; then echo "APT::Solver \"$APT_SOLVER\";" >> aptconfig.conf @@ -1033,10 +1034,12 @@ insertpackage() { continue fi for arch in $(getarchitecturesfromcommalist "$ARCH"); do + local variant="${arch#*:}" + arch="${arch%:*}" if [ "$arch" = 'none' ]; then ARCHS="$(getarchitectures)" else - ARCHS="$arch" + ARCHS="$variant" fi for BUILDARCH in $ARCHS; do local PPATH="aptarchive/dists/${RELEASE}/${DISTSECTION}/binary-${BUILDARCH}" @@ -1054,8 +1057,9 @@ Size: 42" fi echo "Maintainer: Joe Sixpack <joe@example.org>" test "$arch" = 'none' || echo "Architecture: $arch" + test "$arch" = "$variant" || echo "Architecture-Variant: $variant" echo "Version: $VERSION -Filename: pool/${DISTSECTION}/${NAME}/${NAME}_${VERSION}_${arch}.deb" +Filename: pool/${DISTSECTION}/${NAME}/${NAME}_${VERSION}_${variant}.deb" test -z "$DEPENDENCIES" || printf "%b\n" "$DEPENDENCIES" echo "Description: $(printf '%s' "$DESCRIPTION" | head -n 1)" echo "Description-md5: $(printf '%s' "$DESCRIPTION" | md5sum | cut -d' ' -f 1)" @@ -1118,6 +1122,8 @@ insertinstalledpackage() { local FILE='rootdir/var/lib/dpkg/status' local INFO='rootdir/var/lib/dpkg/info' for arch in $(getarchitecturesfromcommalist "$ARCH"); do + local variant="${arch#*:}" + arch="${arch%:*}" echo "Package: $NAME Status: $STATUS Priority: $PRIORITY" >> "$FILE" @@ -1128,6 +1134,7 @@ Priority: $PRIORITY" >> "$FILE" Maintainer: Joe Sixpack <joe@example.org> Version: $VERSION" >> "$FILE" test "$arch" = 'none' || echo "Architecture: $arch" >> "$FILE" + test "$arch" = "$variant" || echo "Architecture-Variant: $variant" >> "$FILE" test -z "$DEPENDENCIES" || printf "%b\n" "$DEPENDENCIES" >> "$FILE" printf "%b\n" "Description: $DESCRIPTION" >> "$FILE" echo >> "$FILE" diff --git a/test/integration/test-architecture-variants b/test/integration/test-architecture-variants new file mode 100755 index 000000000..e116720c9 --- /dev/null +++ b/test/integration/test-architecture-variants @@ -0,0 +1,244 @@ +#!/bin/sh +set -e + +TESTDIR="$(readlink -f "$(dirname "$0")")" +. "$TESTDIR/framework" +setupenvironment +configarchitecture 'amd64' + +msgmsg "Test basic ordering scenarios" + +echo 'APT::Architecture-Variants { "amd64v3"; "amd64v2" }' > 'rootdir/etc/apt/apt.conf.d/variants' +insertpackage 'unstable' 'foo' 'amd64:amd64v2' '1' +insertpackage 'unstable' 'foo' 'amd64' '1' +insertpackage 'unstable' 'foo' 'amd64:amd64v3' '1' +setupaptarchive --no-update + +testsuccessequal "" aptget update -qq + +testsuccessequal "foo: + Installed: (none) + Candidate: 1 + Version table: + 1 500 + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main amd64v3 Packages + 1 500 + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main amd64v2 Packages + 1 500 + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main amd64 Packages" aptcache policy foo +testsuccessequal "'file:${TMPWORKINGDIRECTORY}/aptarchive/pool/main/foo/foo_1_amd64v3.deb' foo_1_amd64v3.deb 42 " apt install --print-uris -qqq foo + +echo 'APT::Architecture-Variants { "amd64v2"; "amd64v3" }' > 'rootdir/etc/apt/apt.conf.d/variants' +testsuccessequal "foo: + Installed: (none) + Candidate: 1 + Version table: + 1 500 + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main amd64v2 Packages + 1 500 + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main amd64v3 Packages + 1 500 + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main amd64 Packages" aptcache policy foo +testsuccessequal "'file:${TMPWORKINGDIRECTORY}/aptarchive/pool/main/foo/foo_1_amd64v2.deb' foo_1_amd64v2.deb 42 " apt install --print-uris -qqq foo +echo 'APT::Architecture-Variants { "amd64v3" }' > 'rootdir/etc/apt/apt.conf.d/variants' +testsuccessequal "foo: + Installed: (none) + Candidate: 1 + Version table: + 1 500 + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main amd64v3 Packages + 1 500 + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main amd64 Packages" aptcache policy foo +testsuccessequal "'file:${TMPWORKINGDIRECTORY}/aptarchive/pool/main/foo/foo_1_amd64v3.deb' foo_1_amd64v3.deb 42 " apt install --print-uris -qqq foo + + +echo 'APT::Architecture-Variants { "amd64v3"; "amd64v2" }' > 'rootdir/etc/apt/apt.conf.d/variants' + +msgmsg "Test upgrade calculation: amd64v3 updates to amd64" + +insertpackage 'unstable' 'foo' 'amd64' '2' +insertinstalledpackage 'foo' 'amd64:amd64v3' '1' +setupaptarchive --no-update + +testsuccessequal "" aptget update -qq +testsuccessequal "foo: + Installed: 1 + Candidate: 2 + Version table: + 2 500 + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main amd64 Packages + *** 1 500 + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main amd64v3 Packages + 100 ${TMPWORKINGDIRECTORY}/rootdir/var/lib/dpkg/status + 1 500 + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main amd64v2 Packages + 1 500 + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main amd64 Packages" aptcache policy foo +testsuccessequal "'file:${TMPWORKINGDIRECTORY}/aptarchive/pool/main/foo/foo_2_amd64.deb' foo_2_amd64.deb 42 " apt dist-upgrade --print-uris -qqq + +msgmsg "Test upgrade calculation: amd64v3 updates to amd64v3 now" +insertpackage 'unstable' 'foo' 'amd64:amd64v3' '2' +setupaptarchive --no-update + +testsuccessequal "" aptget update -qq +testsuccessequal "foo: + Installed: 1 + Candidate: 2 + Version table: + 2 500 + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main amd64v3 Packages + 2 500 + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main amd64 Packages + *** 1 500 + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main amd64v3 Packages + 100 ${TMPWORKINGDIRECTORY}/rootdir/var/lib/dpkg/status + 1 500 + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main amd64v2 Packages + 1 500 + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main amd64 Packages" aptcache policy foo +testsuccessequal "'file:${TMPWORKINGDIRECTORY}/aptarchive/pool/main/foo/foo_2_amd64v3.deb' foo_2_amd64v3.deb 42 " apt dist-upgrade --print-uris -qqq + +msgmsg "Test standalone architecture variants" +sed -i 's/^Architectures:.*/Architectures: all amd64 amd64v3/' aptarchive/dists/unstable/Release +signreleasefiles +testsuccessequal "" aptget update -qq +testsuccessequal "foo: + Installed: 1 + Candidate: 2 + Version table: + 2 500 + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main amd64v3 Packages + *** 1 500 + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main amd64v3 Packages + 100 ${TMPWORKINGDIRECTORY}/rootdir/var/lib/dpkg/status" aptcache policy foo -o standalone=v3 +testsuccessequal "'file:${TMPWORKINGDIRECTORY}/aptarchive/pool/main/foo/foo_2_amd64v3.deb' foo_2_amd64v3.deb 42 " apt dist-upgrade --print-uris -qqq -o standalone=v3 + +sed -i 's/^Architectures:.*/Architectures: all amd64 amd64v3 amd64v2/' aptarchive/dists/unstable/Release +signreleasefiles +testsuccessequal "" aptget update -qq +testsuccessequal "foo: + Installed: 1 + Candidate: 2 + Version table: + 2 500 + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main amd64v3 Packages + *** 1 500 + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main amd64v3 Packages + 100 ${TMPWORKINGDIRECTORY}/rootdir/var/lib/dpkg/status" aptcache policy foo -o standalone=v3,v2 +testsuccessequal "'file:${TMPWORKINGDIRECTORY}/aptarchive/pool/main/foo/foo_2_amd64v3.deb' foo_2_amd64v3.deb 42 " apt dist-upgrade --print-uris -qqq -o standalone=v3,v2 + +sed -i 's/^Architectures:.*/Architectures: all amd64 amd64v2/' aptarchive/dists/unstable/Release +signreleasefiles +testsuccessequal "" aptget update -qq +# Notably v2 is now the standalone architecture so we need to fetch v3 and v2. +testsuccessequal "foo: + Installed: 1 + Candidate: 2 + Version table: + 2 500 + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main amd64v3 Packages + *** 1 500 + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main amd64v3 Packages + 100 ${TMPWORKINGDIRECTORY}/rootdir/var/lib/dpkg/status + 1 500 + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main amd64v2 Packages" aptcache policy foo -o standalone=v2 +testsuccessequal "'file:${TMPWORKINGDIRECTORY}/aptarchive/pool/main/foo/foo_2_amd64v3.deb' foo_2_amd64v3.deb 42 " apt dist-upgrade --print-uris -qqq -o standalone=v2 + +# amd64v2 is preferred now +sed -i 's/^Architectures:.*/Architectures: all amd64 amd64v3 amd64v2/' aptarchive/dists/unstable/Release +echo 'APT::Architecture-Variants { "amd64v2"; "amd64v3" }' > 'rootdir/etc/apt/apt.conf.d/variants' +signreleasefiles +testsuccessequal "" aptget update -qq +testsuccessequal "foo: + Installed: 1 + Candidate: 2 + Version table: + 2 500 + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main amd64v3 Packages + 1 500 + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main amd64v2 Packages + *** 1 500 + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main amd64v3 Packages + 100 ${TMPWORKINGDIRECTORY}/rootdir/var/lib/dpkg/status" aptcache policy foo -o standalone=v3,v2 -o pref=v2 +msgtest 'Test that amd64v2 is the candidate of the version 1' +testsuccessequal --nomsg "'file:${TMPWORKINGDIRECTORY}/aptarchive/pool/main/foo/foo_1_amd64v2.deb' foo_1_amd64v2.deb 42 " apt dist-upgrade --print-uris -qqq -o standalone=v3,v2 -o pref=v2 foo=1 + +msgmsg "Test automatic detection" +echo "flags : lm" > rootdir/cpuinfo +echo "flags : lm cmov cx8 fpu fxsr mmx syscall sse2 cx16 lahf_lm popcnt sse4_1 sse4_2 ssse3" >> rootdir/cpuinfo +echo 'APT::Architecture-Variants "auto";' > 'rootdir/etc/apt/apt.conf.d/variants' +echo 'Dir::Proc::CpuInfo "cpuinfo";'>> 'rootdir/etc/apt/apt.conf.d/variants' +testsuccessequal "" aptget update -qq +testsuccessequal "foo: + Installed: 1 + Candidate: 2 + Version table: + 2 500 + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main amd64 Packages + 1 500 + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main amd64 Packages + *** 1 100 + 100 ${TMPWORKINGDIRECTORY}/rootdir/var/lib/dpkg/status" aptcache policy foo -o auto=intersection + +echo "flags : lm cmov cx8 fpu fxsr mmx syscall sse2 cx16 lahf_lm popcnt sse4_1 sse4_2 ssse3" > rootdir/cpuinfo +echo 'APT::Architecture-Variants "auto";' > 'rootdir/etc/apt/apt.conf.d/variants' +echo 'Dir::Proc::CpuInfo "cpuinfo";'>> 'rootdir/etc/apt/apt.conf.d/variants' +testsuccessequal "" aptget update -qq +testsuccessequal "foo: + Installed: 1 + Candidate: 1 + Version table: + 1 500 + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main amd64v2 Packages + *** 1 100 + 100 ${TMPWORKINGDIRECTORY}/rootdir/var/lib/dpkg/status" aptcache policy foo -o auto=v2 + +# Not a valid value for the auto field. +echo 'APT::Architecture-Variants "invalid";' > 'rootdir/etc/apt/apt.conf.d/variants' +echo 'Dir::Proc::CpuInfo "cpuinfo";'>> 'rootdir/etc/apt/apt.conf.d/variants' +testwarningequal "W: Invalid value for APT::Architecture-Variants: invalid" aptget update -qq +testwarningequal "foo: + Installed: 1 + Candidate: 2 + Version table: + 2 500 + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main amd64 Packages + 1 500 + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main amd64 Packages + *** 1 100 + 100 ${TMPWORKINGDIRECTORY}/rootdir/var/lib/dpkg/status +W: Invalid value for APT::Architecture-Variants: invalid" aptcache policy foo -o auto=invalid + +# The unqualified one takes precedent +echo 'APT::Architecture-Variants "invalid";' > 'rootdir/etc/apt/apt.conf.d/variants' +echo 'APT::Architecture-Variants:: "amd64v2";' >> 'rootdir/etc/apt/apt.conf.d/variants' +echo 'Dir::Proc::CpuInfo "cpuinfo";'>> 'rootdir/etc/apt/apt.conf.d/variants' +testwarningequal "Variants enabled: +W: Invalid value for APT::Architecture-Variants: invalid" aptget update -qq -o debug::acquire::variants=1 +testwarningequal "foo: + Installed: 1 + Candidate: 2 + Version table: + 2 500 + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main amd64 Packages + 1 500 + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main amd64 Packages + *** 1 100 + 100 ${TMPWORKINGDIRECTORY}/rootdir/var/lib/dpkg/status +W: Invalid value for APT::Architecture-Variants: invalid" aptcache policy foo -o auto=invalid+v2 + + +echo 'APT::Architecture-Variants "auto,amd64v2";' > 'rootdir/etc/apt/apt.conf.d/variants' +echo 'Dir::Proc::CpuInfo "cpuinfo";'>> 'rootdir/etc/apt/apt.conf.d/variants' +testwarningequal "Variants enabled: amd64v2 +Variant target file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main amd64v2 Packages supplants target file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main amd64 Packages +W: Invalid value for APT::Architecture-Variants: auto cannot be combined with explicit variants" aptget update -qq -o debug::acquire::variants=1 +testwarningequal "foo: + Installed: 1 + Candidate: 1 + Version table: + 1 500 + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main amd64v2 Packages + *** 1 100 + 100 ${TMPWORKINGDIRECTORY}/rootdir/var/lib/dpkg/status +W: Invalid value for APT::Architecture-Variants: auto cannot be combined with explicit variants" aptcache policy foo -o auto=auto,v2 diff --git a/test/integration/varianttable b/test/integration/varianttable new file mode 100644 index 000000000..29cccba93 --- /dev/null +++ b/test/integration/varianttable @@ -0,0 +1,5 @@ +# <variant> <arch> <flags> +amd64v4 amd64 lm,cmov,cx8,fpu,fxsr,mmx,syscall,sse2,cx16,lahf_lm,popcnt,sse4_1,sse4_2,ssse3,avx,avx2,bmi1,bmi2,f16c,fma,abm,movbe,xsave,avx512f,avx512bw,avx512cd,avx512dq,avx512vl +amd64v3 amd64 lm,cmov,cx8,fpu,fxsr,mmx,syscall,sse2,cx16,lahf_lm,popcnt,sse4_1,sse4_2,ssse3,avx,avx2,bmi1,bmi2,f16c,fma,abm,movbe,xsave +amd64v2 amd64 lm,cmov,cx8,fpu,fxsr,mmx,syscall,sse2,cx16,lahf_lm,popcnt,sse4_1,sse4_2,ssse3 +amd64v1 amd64 lm,cmov,cx8,fpu,fxsr,mmx,syscall,sse2 |
