summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorJulian Andres Klode <julian.klode@canonical.com>2025-01-07 17:39:32 +0100
committerJulian Andres Klode <jak@debian.org>2025-10-25 18:42:14 +0000
commit9d62eef571ffd1fd2df8b97884d3689fced27fb1 (patch)
tree100d5321f364b389100928e927639e852c52ff48 /test
parent50d8703c785898d06463513896e37cbe7cedd471 (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/framework11
-rwxr-xr-xtest/integration/test-architecture-variants244
-rw-r--r--test/integration/varianttable5
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