summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/integration/framework140
-rwxr-xr-xtest/integration/test-apt-get-build-dep-barbarian140
-rwxr-xr-xtest/integration/test-apt-get-build-dep-file14
-rwxr-xr-xtest/integration/test-bug-632221-cross-dependency-satisfaction35
-rwxr-xr-xtest/integration/test-bug-992993-marked-cycles30
-rwxr-xr-xtest/integration/test-multiarch-allowed51
-rwxr-xr-xtest/integration/test-multiarch-barbarian243
-rwxr-xr-xtest/integration/test-prevent-markinstall-multiarch-same-versionscrew3
-rw-r--r--test/interactive-helper/CMakeLists.txt3
-rw-r--r--test/interactive-helper/longest-dependency-chain.cc72
-rw-r--r--test/libapt/getarchitectures_test.cc28
11 files changed, 689 insertions, 70 deletions
diff --git a/test/integration/framework b/test/integration/framework
index 8c9abfbe4..d8fd6ba95 100644
--- a/test/integration/framework
+++ b/test/integration/framework
@@ -204,6 +204,9 @@ aptinternalplanner() { runapt "${APTINTERNALPLANNER}" "$@"; }
dpkg() {
"${TMPWORKINGDIRECTORY}/rootdir/usr/bin/dpkg" "$@"
}
+dpkgquery() {
+ command dpkg-query --admindir="${TMPWORKINGDIRECTORY}/rootdir/var/lib/dpkg" "$@"
+}
dpkg_version() {
command perl -MDpkg -E 'say $Dpkg::PROGVERSION'
}
@@ -290,7 +293,6 @@ escape_shell() {
}
find_project_binary_dir() {
- local TESTDIRECTORY="$(readlink -f "$(dirname $0)")"
if [ -z "$PROJECT_BINARY_DIR" ]; then
PROJECT_BINARY_DIR=
for dir in ${TESTDIRECTORY}/../../ ${TESTDIRECTORY}/../../*; do
@@ -307,7 +309,24 @@ find_project_binary_dir() {
export PROJECT_BINARY_DIR
fi
}
+_removetmpworkingdirectory() {
+ cd /
+ if [ -n "$TMPWORKINGDIRECTORY" -a -d "$TMPWORKINGDIRECTORY" ]; then
+ rm -rf "$TMPWORKINGDIRECTORY"
+ fi
+ TMPWORKINGDIRECTORY=''
+}
setupenvironment() {
+ # cleanup the environment a bit
+ export LC_ALL=C
+ unset LANGUAGE COLUMNS NLSPATH
+ unset APT_CONFIG DPKG_ADMINDIR DPKG_COLORS
+ unset DEB_CHECK_COMMAND DEB_SIGN_KEYID DEB_BUILD_OPTIONS DEB_BUILD_PROFILES
+ unset DH_VERBOSE DH_QUIET DH_COMPAT DH_NO_ACT DH_OPTIONS DH_EXTRA_ADDONS
+ unset GREP_OPTIONS POSIXLY_CORRECT
+ unset http_proxy HTTP_PROXY https_proxy HTTPS_PROXY no_proxy
+ export GCOV_ERROR_FILE=/dev/null
+
# Next check needs a gnu stat, let's figure that out early.
stat=stat
if command -v gnustat >/dev/null 2>&1; then
@@ -317,8 +336,10 @@ setupenvironment() {
if [ -n "$TMPDIR" ] && [ "$(id -u)" = '0' ] && [ "$($stat --format '%a' "$TMPDIR")" != '1777' ]; then
unset TMPDIR
fi
- TMPWORKINGDIRECTORY="$(mktemp -d)"
- addtrap "cd /; rm -rf '$(escape_shell "$TMPWORKINGDIRECTORY")';"
+ if [ -z "$TMPWORKINGDIRECTORY" ]; then
+ addtrap '_removetmpworkingdirectory;'
+ TMPWORKINGDIRECTORY="$(mktemp -d)"
+ fi
if [ -n "$TMPDIR_ADD" ]; then
TMPWORKINGDIRECTORY="${TMPWORKINGDIRECTORY}/${TMPDIR_ADD}"
mkdir -p "$TMPWORKINGDIRECTORY"
@@ -338,18 +359,40 @@ setupenvironment() {
done
export PATH="${TMPWORKINGDIRECTORY}/bin/:$PATH"
+ if [ -z "$TESTDIRECTORY" ]; then
+ TESTDIRECTORY="$(readlink -f "$(dirname $0)")"
+ fi
+ cd "$TMPWORKINGDIRECTORY"
- mkdir -m 700 "${TMPWORKINGDIRECTORY}/downloaded"
+ mkdir -m 700 'downloaded'
if [ "$(id -u)" = '0' ]; then
# relax permissions so that running as root with user switching works
umask 022
chmod 711 "$TMPWORKINGDIRECTORY"
chown _apt:$(id -gn) "${TMPWORKINGDIRECTORY}/downloaded"
fi
+ mkdir -p 'rootdir/usr/bin' 'rootdir/var/cache' 'rootdir/var/lib' 'rootdir/var/log' 'rootdir/var/crash' 'rootdir/tmp'
- TESTDIRECTORY="$(readlink -f "$(dirname $0)")"
# Find the newest build directory (sets PROJECT_BINARY_DIR)
find_project_binary_dir
+
+ _setupprojectenvironment
+
+ # create some files in /tmp and look at user/group to get what this means
+ TEST_DEFAULT_USER="$(id -un)"
+ touch "${TMPWORKINGDIRECTORY}/test-file"
+ TEST_DEFAULT_GROUP=$(stat --format '%G' "${TMPWORKINGDIRECTORY}/test-file")
+
+ # prefer our apt binaries over the system apt binaries
+ export PATH="${BUILDDIRECTORY}:${PATH}:/usr/local/sbin:/usr/sbin:/sbin"
+
+ if [ -r "${TESTDIRECTORY}/extra-environment" ]; then
+ . "${TESTDIRECTORY}/extra-environment"
+ fi
+
+ msgdone "info"
+}
+_setupprojectenvironment() {
# allow overriding the default BUILDDIR location
SOURCEDIRECTORY="${APT_INTEGRATION_TESTS_SOURCE_DIR:-"${TESTDIRECTORY}/../../"}"
BUILDDIRECTORY="${APT_INTEGRATION_TESTS_BUILD_DIR:-"${PROJECT_BINARY_DIR}/cmdline"}"
@@ -361,18 +404,17 @@ setupenvironment() {
APTINTERNALSOLVER="${APT_INTEGRATION_TESTS_INTERNAL_SOLVER:-"${BUILDDIRECTORY}/solvers/apt"}"
APTDUMPSOLVER="${APT_INTEGRATION_TESTS_DUMP_SOLVER:-"${BUILDDIRECTORY}/solvers/dump"}"
APTINTERNALPLANNER="${APT_INTEGRATION_TESTS_INTERNAL_PLANNER:-"${BUILDDIRECTORY}/planners/apt"}"
+ ARTIFACTSDIR="${APT_INTEGRATION_TESTS_ARTIFACTS_DIR:-"${BUILDDIRECTORY}/artifacts"}"
test -x "${BUILDDIRECTORY}/apt-get" || msgdie "You need to build tree first"
- # -----
- cd "$TMPWORKINGDIRECTORY"
echo "#x-apt-configure-index \"${SOURCEDIRECTORY}/doc/examples/configure-index\";" > aptconfig.conf
- mkdir rootdir aptarchive keys
+ mkdir aptarchive keys
cd rootdir
mkdir -p etc/apt/apt.conf.d etc/apt/sources.list.d etc/apt/trusted.gpg.d etc/apt/preferences.d
- mkdir -p usr/bin var/cache var/lib var/log var/crash tmp
mkdir -p var/lib/dpkg/info var/lib/dpkg/updates var/lib/dpkg/triggers
mkdir -p usr/lib/apt/solvers usr/lib/apt/planners
- touch var/lib/dpkg/available
+ touch var/lib/dpkg/available var/lib/dpkg/lock
+ echo '1' > var/lib/dpkg/info/format
ln -s "${METHODSDIR}" usr/lib/apt/methods
ln -s "${APTDUMPSOLVER}" usr/lib/apt/solvers/dump
ln -s "${APTDUMPSOLVER}" usr/lib/apt/planners/dump
@@ -489,29 +531,10 @@ EOF
configcompression '.' 'gz' #'bz2' 'lzma' 'xz'
confighashes 'SHA256' # these are tests, not security best-practices
- # create some files in /tmp and look at user/group to get what this means
- TEST_DEFAULT_USER="$(id -un)"
- touch "${TMPWORKINGDIRECTORY}/test-file"
- TEST_DEFAULT_GROUP=$(stat --format '%G' "${TMPWORKINGDIRECTORY}/test-file")
-
- # cleanup the environment a bit
- # prefer our apt binaries over the system apt binaries
- export PATH="${BUILDDIRECTORY}:${PATH}:/usr/local/sbin:/usr/sbin:/sbin"
- export LC_ALL=C
- unset LANGUAGE COLUMNS NLSPATH
- unset APT_CONFIG DPKG_ADMINDIR DPKG_COLORS
- unset DEB_CHECK_COMMAND DEB_SIGN_KEYID DEB_BUILD_OPTIONS DEB_BUILD_PROFILES
- unset DH_VERBOSE DH_QUIET DH_COMPAT DH_NO_ACT DH_OPTIONS DH_EXTRA_ADDONS
- unset GREP_OPTIONS POSIXLY_CORRECT
- unset http_proxy HTTP_PROXY https_proxy HTTPS_PROXY no_proxy
-
# Make dpkg inherit testing path
echo 'DPkg::Path "";' >> aptconfig.conf
echo 'Dir::Bin::ischroot "/bin/false";' >> aptconfig.conf
- # Make gcov shut up
- export GCOV_ERROR_FILE=/dev/null
-
# If gpgv supports --weak-digest, pass it to make sure we can disable SHA1
if aptkey verify --weak-digest SHA1 --help 2>/dev/null >/dev/null; then
echo 'Acquire::gpgv::Options { "--weak-digest"; "sha1"; };' > rootdir/etc/apt/apt.conf.d/no-sha1
@@ -519,12 +542,6 @@ EOF
# most tests just need one signed Release file, not both
export APT_DONT_SIGN='Release.gpg'
-
- if [ -r "${TESTDIRECTORY}/extra-environment" ]; then
- . "${TESTDIRECTORY}/extra-environment"
- fi
-
- msgdone "info"
}
getarchitecture() {
@@ -1049,10 +1066,12 @@ Version: $VERSION" >> "$FILE"
test -z "$DEPENDENCIES" || printf "%b\n" "$DEPENDENCIES" >> "$FILE"
printf "%b\n" "Description: $DESCRIPTION" >> "$FILE"
echo >> "$FILE"
- if [ "$(dpkg-query -W --showformat='${Multi-Arch}')" = 'same' ]; then
+ if [ "$(dpkgquery -W --showformat='${Multi-Arch}' "${NAME}:${arch}" 2>/dev/null)" = 'same' ]; then
echo -n > "${INFO}/${NAME}:${arch}.list"
+ echo -n > "${INFO}/${NAME}:${arch}.md5sums"
else
echo -n > "${INFO}/${NAME}.list"
+ echo -n > "${INFO}/${NAME}.md5sums"
fi
done
}
@@ -1778,6 +1797,52 @@ msgfailoutput() {
ls -l
fi
catfile "$OUTPUT"
+ if [ "$CMD" != 'echo' ] && tail -n 1 "$OUTPUT" | grep -q '(core dumped)$'; then
+ local COREDUMP="${TMPWORKINGDIRECTORY}/rootdir/tmp/core.dump"
+ local COREEXE=''
+ for CORENAME in 'core' 'core.pid'; do
+ if [ -s "$CORENAME" ]; then
+ cp -a ${CORENAME} "$COREDUMP"
+ elif [ -s "${TMPWORKINGDIRECTORY}/${CORENAME}" ]; then
+ cp -a "${TMPWORKINGDIRECTORY}/${CORENAME}" "$COREDUMP"
+ else
+ continue
+ fi
+ break
+ done
+ if [ -s "$COREDUMP" ]; then
+ true # found already as a file
+ elif dpkg-checkbuilddeps -d 'systemd-coredump' /dev/null >/dev/null 2>&1; then
+ COREEXE="$(coredumpctl -1 --no-legend list | sed -e 's#^.* \([^ ]\+\)$#\1#')"
+ coredumpctl -1 dump "$COREEXE" -o "$COREDUMP" 2>/dev/null >&2 || true
+ else
+ echo '### core dump not found ###'
+ cat /proc/sys/kernel/core_pattern
+ fi
+ if [ -s "$COREDUMP" ]; then
+ if [ -z "$COREEXE" ]; then
+ case "$CMD" in
+ apt) COREEXE="${BUILDDIRECTORY}/${CMD}";;
+ aptftparchive) COREEXE="${APTFTPARCHIVEBINDIR}/apt-ftparchive";;
+ apthelper) COREEXE="${APTHELPERBINDIR}/apt-helper";;
+ aptwebserver) COREEXE="${APTTESTHELPERSBINDIR}/aptwebserver";;
+ apt*) COREEXE="${BUILDDIRECTORY}/apt-${CMD##*apt}";;
+ *) COREEXE="${BUILDDIRECTORY}/${CMD}";;
+ esac
+ fi
+
+ if [ -d "${ARTIFACTSDIR}" ]; then
+ local ARTIFACT_COREDUMP="$(mktemp --suffix=.coredump -p "${ARTIFACTSDIR}" "${COREEXE##*/}-XXXXXX")"
+ cp -a "$COREDUMP" "$ARTIFACT_COREDUMP"
+ echo "#### coredump in $ARTIFACT_COREDUMP for $COREEXE ####"
+ fi
+ if [ -n "$COREEXE" -a -s "$COREEXE" ] && dpkg-checkbuilddeps -d 'gdb' /dev/null >/dev/null 2>&1; then
+ echo "#### gdb backtrace ####"
+ command gdb --batch -n -ex 'set pagination off' --ex 'thread apply all bt full' "$COREEXE" "$COREDUMP" || true
+ fi
+ fi
+ rm -f "$COREDUMP"
+ fi
msgfail "$MSG"
}
@@ -1801,6 +1866,9 @@ testsuccesswithglobalerror() {
if echo 'E: Can not write log (Is /dev/pts mounted?) - posix_openpt (2: No such file or directory)' \
| cmp - "${TMPWORKINGDIRECTORY}/rootdir/tmp/checkforwarnings.output" >/dev/null 2>&1; then
msgpass
+ elif echo 'E: Can not write log (Is /dev/pts mounted?) - posix_openpt (13: Permission denied)' \
+ | cmp - "${TMPWORKINGDIRECTORY}/rootdir/tmp/checkforwarnings.output" >/dev/null 2>&1; then
+ msgpass
else
msgfailoutput 'successful run, but output contains warnings/errors' "$OUTPUT" "$@"
fi
diff --git a/test/integration/test-apt-get-build-dep-barbarian b/test/integration/test-apt-get-build-dep-barbarian
new file mode 100755
index 000000000..688f7a54b
--- /dev/null
+++ b/test/integration/test-apt-get-build-dep-barbarian
@@ -0,0 +1,140 @@
+#!/bin/sh
+set -e
+
+TESTDIR="$(readlink -f "$(dirname "$0")")"
+. "$TESTDIR/framework"
+setupenvironment
+configarchitecture 'amd64' 'i386' 'armel' 'mipsel'
+
+insertinstalledpackage 'build-essential' 'all' '1'
+insertpackage 'unstable' 'samey' 'amd64,i386,armel,mipsel' '1' 'Multi-Arch: same'
+insertinstalledpackage 'samey' 'unknown' '1' 'Multi-Arch: same'
+
+insertsource 'unstable' 'cool-foo' 'any' '1' 'Build-Depends: foo, samey'
+insertsource 'unstable' 'bad-amd64-foo' 'any' '1' 'Build-Depends: foo, samey
+Build-Conflicts: foo:amd64'
+insertsource 'unstable' 'bad-armel-foo' 'any' '1' 'Build-Depends: foo, samey
+Build-Conflicts: foo:armel'
+insertsource 'unstable' 'bad-amd64-armel-foo' 'any' '1' 'Build-Depends: foo, samey
+Build-Conflicts: foo:amd64, foo:armel'
+insertsource 'unstable' 'bad-amd64-i386-foo' 'any' '1' 'Build-Depends: foo, samey
+Build-Conflicts: foo:amd64, foo:i386'
+insertsource 'unstable' 'bad-amd64-i386-armel-foo' 'any' '1' 'Build-Depends: foo, samey
+Build-Conflicts: foo:amd64, foo:i386, foo:armel'
+insertpackage 'unstable' 'foo' 'amd64,i386,armel,mipsel' '1' 'Multi-Arch: foreign'
+
+setupaptarchive
+
+installsfoosamey() {
+ local FOO="foo:$1"
+ local SAMEY="samey:$2"
+ if [ "$1" = 'amd64' ]; then FOO='foo'; fi
+ if [ "$2" = 'amd64' ]; then SAMEY='samey'; fi
+ echo "Reading package lists...
+Reading package lists...
+Building dependency tree...
+The following NEW packages will be installed:
+ $FOO $SAMEY
+0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
+Inst $FOO (1 unstable [$1])
+Inst $SAMEY (1 unstable [$2])
+Conf $FOO (1 unstable [$1])
+Conf $SAMEY (1 unstable [$2])"
+}
+
+testdpkginstalled 'samey:unknown'
+
+testsuccessequal "$(installsfoosamey 'amd64' 'amd64')" apt build-dep cool-foo -s
+testsuccessequal "$(installsfoosamey 'amd64' 'amd64')" apt build-dep cool-foo -s -a amd64
+testsuccessequal "$(installsfoosamey 'amd64' 'i386')" apt build-dep cool-foo -s -a i386
+testsuccessequal "$(installsfoosamey 'amd64' 'armel')" apt build-dep cool-foo -s -a armel
+
+testsuccessequal "$(installsfoosamey 'i386' 'amd64')" apt build-dep bad-amd64-foo -s
+testsuccessequal "$(installsfoosamey 'i386' 'amd64')" apt build-dep bad-amd64-foo -s -a amd64
+testsuccessequal "$(installsfoosamey 'i386' 'i386')" apt build-dep bad-amd64-foo -s -a i386
+testsuccessequal "$(installsfoosamey 'i386' 'armel')" apt build-dep bad-amd64-foo -s -a armel
+
+testsuccessequal "$(installsfoosamey 'amd64' 'amd64')" apt build-dep bad-armel-foo -s
+testsuccessequal "$(installsfoosamey 'amd64' 'amd64')" apt build-dep bad-armel-foo -s -a amd64
+testsuccessequal "$(installsfoosamey 'amd64' 'i386')" apt build-dep bad-armel-foo -s -a i386
+testsuccessequal "$(installsfoosamey 'amd64' 'armel')" apt build-dep bad-armel-foo -s -a armel
+
+testsuccessequal "$(installsfoosamey 'i386' 'amd64')" apt build-dep bad-amd64-armel-foo -s
+testsuccessequal "$(installsfoosamey 'i386' 'amd64')" apt build-dep bad-amd64-armel-foo -s -a amd64
+testsuccessequal "$(installsfoosamey 'i386' 'i386')" apt build-dep bad-amd64-armel-foo -s -a i386
+testsuccessequal "$(installsfoosamey 'i386' 'armel')" apt build-dep bad-amd64-armel-foo -s -a armel
+
+testsuccessequal "$(installsfoosamey 'armel' 'amd64')" apt build-dep bad-amd64-i386-foo -s
+testsuccessequal "$(installsfoosamey 'armel' 'amd64')" apt build-dep bad-amd64-i386-foo -s -a amd64
+testsuccessequal "$(installsfoosamey 'armel' 'i386')" apt build-dep bad-amd64-i386-foo -s -a i386
+testsuccessequal "$(installsfoosamey 'armel' 'armel')" apt build-dep bad-amd64-i386-foo -s -a armel
+
+testsuccessequal "$(installsfoosamey 'mipsel' 'amd64')" apt build-dep bad-amd64-i386-armel-foo -s
+testsuccessequal "$(installsfoosamey 'mipsel' 'amd64')" apt build-dep bad-amd64-i386-armel-foo -s -a amd64
+testsuccessequal "$(installsfoosamey 'mipsel' 'i386')" apt build-dep bad-amd64-i386-armel-foo -s -a i386
+testsuccessequal "$(installsfoosamey 'mipsel' 'armel')" apt build-dep bad-amd64-i386-armel-foo -s -a armel
+
+
+msgmsg 'BarbarianArchitectures' 'config'
+echo 'APT::BarbarianArchitectures { "mipsel"; "armel"; };' > rootdir/etc/apt/apt.conf.d/99barbarianarchs
+testsuccess aptcache gencaches
+
+testsuccessequal "$(installsfoosamey 'amd64' 'i386')" apt build-dep cool-foo -s -a i386
+testsuccessequal "$(installsfoosamey 'i386' 'i386')" apt build-dep bad-amd64-foo -s -a i386
+testsuccessequal "$(installsfoosamey 'amd64' 'i386')" apt build-dep bad-armel-foo -s -a i386
+testsuccessequal "$(installsfoosamey 'i386' 'i386')" apt build-dep bad-amd64-armel-foo -s -a i386
+testfailureequal 'Reading package lists...
+Reading package lists...
+Building dependency tree...
+Some packages could not be installed. This may mean that you have
+requested an impossible situation or if you are using the unstable
+distribution that some required packages have not yet been created
+or been moved out of Incoming.
+The following information may help to resolve the situation:
+
+The following packages have unmet dependencies:
+ builddeps:bad-amd64-i386-foo:i386 : Depends: foo:i386
+E: Unable to correct problems, you have held broken packages.' apt build-dep bad-amd64-i386-foo -s -a i386
+testfailureequal 'Reading package lists...
+Reading package lists...
+Building dependency tree...
+Some packages could not be installed. This may mean that you have
+requested an impossible situation or if you are using the unstable
+distribution that some required packages have not yet been created
+or been moved out of Incoming.
+The following information may help to resolve the situation:
+
+The following packages have unmet dependencies:
+ builddeps:bad-amd64-i386-armel-foo:i386 : Depends: foo:i386
+E: Unable to correct problems, you have held broken packages.' apt build-dep bad-amd64-i386-armel-foo -s -a i386
+
+testsuccessequal "$(installsfoosamey 'amd64' 'armel')" apt build-dep cool-foo -s -a armel
+testsuccessequal "$(installsfoosamey 'i386' 'armel')" apt build-dep bad-amd64-foo -s -a armel
+testsuccessequal "$(installsfoosamey 'amd64' 'armel')" apt build-dep bad-armel-foo -s -a armel
+testsuccessequal "$(installsfoosamey 'i386' 'armel')" apt build-dep bad-amd64-armel-foo -s -a armel
+testsuccessequal "$(installsfoosamey 'armel' 'armel')" apt build-dep bad-amd64-i386-foo -s -a armel
+FAILURE='Reading package lists...
+Building dependency tree...
+Some packages could not be installed. This may mean that you have
+requested an impossible situation or if you are using the unstable
+distribution that some required packages have not yet been created
+or been moved out of Incoming.
+The following information may help to resolve the situation:
+
+The following packages have unmet dependencies:
+ builddeps:bad-amd64-i386-armel-foo:armel : Depends: foo:armel
+E: Unable to correct problems, you have held broken packages.'
+testfailureequal "Reading package lists...
+$FAILURE" apt build-dep bad-amd64-i386-armel-foo -s -a armel
+
+msgmsg 'BarbarianArchitectures' 'cmdline options'
+rm rootdir/etc/apt/apt.conf.d/99barbarianarchs
+testsuccess aptcache gencaches
+
+testsuccessequal "$(installsfoosamey 'mipsel' 'armel')" apt build-dep bad-amd64-i386-armel-foo -s -a armel
+testsuccess aptcache gencaches -o APT::BarbarianArchitectures::=armel
+testsuccessequal "$(installsfoosamey 'mipsel' 'armel')" apt build-dep bad-amd64-i386-armel-foo -s -a armel -o APT::BarbarianArchitectures::=armel
+testfailureequal "$FAILURE" apt build-dep bad-amd64-i386-armel-foo -s -a armel -o APT::BarbarianArchitectures::=mipsel
+testfailureequal "$FAILURE" apt build-dep bad-amd64-i386-armel-foo -s -a armel -o APT::BarbarianArchitectures::=mipsel -o APT::BarbarianArchitectures::=armel
+testfailureequal "Reading package lists...
+$FAILURE" apt build-dep bad-amd64-i386-armel-foo -s -a armel -o APT::BarbarianArchitectures=mipsel,armel
diff --git a/test/integration/test-apt-get-build-dep-file b/test/integration/test-apt-get-build-dep-file
index c4b6947bf..88bf10b0f 100755
--- a/test/integration/test-apt-get-build-dep-file
+++ b/test/integration/test-apt-get-build-dep-file
@@ -158,7 +158,19 @@ testsuccess aptget build-dep --simulate '..'
cd ../..
testfailureequal 'E: Must specify at least one package to check builddeps for' aptget build-dep
-testfailureequal 'E: No architecture information available for armel. See apt.conf(5) APT::Architectures for setup' aptget build-dep --simulate ./foo-1.0 -a armel
+testfailureequal "Note, using directory './foo-1.0' to get the build dependencies
+Reading package lists...
+Building dependency tree...
+Some packages could not be installed. This may mean that you have
+requested an impossible situation or if you are using the unstable
+distribution that some required packages have not yet been created
+or been moved out of Incoming.
+The following information may help to resolve the situation:
+
+The following packages have unmet dependencies:
+ builddeps:./foo-1.0:armel : Depends: debhelper:armel (>= 7) but it is not installable
+W: No architecture information available for armel. See apt.conf(5) APT::Architectures for setup
+E: Unable to correct problems, you have held broken packages." aptget build-dep --simulate ./foo-1.0 -a armel
testfailureequal 'Reading package lists...
E: Unable to find a source package for foo' aptget build-dep --simulate foo
diff --git a/test/integration/test-bug-632221-cross-dependency-satisfaction b/test/integration/test-bug-632221-cross-dependency-satisfaction
index d52652cad..0cf8d353f 100755
--- a/test/integration/test-bug-632221-cross-dependency-satisfaction
+++ b/test/integration/test-bug-632221-cross-dependency-satisfaction
@@ -232,14 +232,15 @@ configarchitecture 'amd64' 'armel'
insertinstalledpackage 'cool' 'amd64' '0.5'
insertinstalledpackage 'foreigner' 'armel' '0.5'
-testsuccessequal 'Reading package lists...
+APT_ON_AMD64='Reading package lists...
Building dependency tree...
The following NEW packages will be installed:
amdboot doxygen libc6 libc6-dev libfwibble-dev libfwibble1 linux-stuff
The following packages will be upgraded:
- foreigner:armel
-1 upgraded, 7 newly installed, 0 to remove and 1 not upgraded.
+ cool foreigner:armel
+2 upgraded, 7 newly installed, 0 to remove and 0 not upgraded.
Inst amdboot (1.0 unstable [amd64])
+Inst cool [0.5] (1.0 unstable [amd64])
Inst doxygen (1.0 unstable [amd64])
Inst foreigner:armel [0.5] (1.0 unstable [armel])
Inst libc6 (1.0 unstable [amd64])
@@ -248,13 +249,17 @@ Inst libfwibble1 (1.0 unstable [amd64])
Inst libfwibble-dev (1.0 unstable [amd64])
Inst linux-stuff (1.0 unstable [amd64])
Conf amdboot (1.0 unstable [amd64])
+Conf cool (1.0 unstable [amd64])
Conf doxygen (1.0 unstable [amd64])
Conf foreigner:armel (1.0 unstable [armel])
Conf libc6 (1.0 unstable [amd64])
Conf libc6-dev (1.0 unstable [amd64])
Conf libfwibble1 (1.0 unstable [amd64])
Conf libfwibble-dev (1.0 unstable [amd64])
-Conf linux-stuff (1.0 unstable [amd64])' aptget build-dep apt -s
+Conf linux-stuff (1.0 unstable [amd64])'
+testsuccessequal "$APT_ON_AMD64" aptget build-dep apt -s
+testsuccessequal "Reading package lists...
+$APT_ON_AMD64" aptget build-dep apt -s -a amd64
testsuccessequal 'Reading package lists...
Reading package lists...
@@ -288,19 +293,16 @@ Conf libfwibble-dev:armel (1.0 unstable [armel])' aptget build-dep apt -s -a arm
configarchitecture 'armel' 'amd64'
-# cool 0.5 is not M-A: allowed, so amd64 is not acceptable
-testsuccessequal 'Reading package lists...
+APT_ON_ARMEL='Reading package lists...
Building dependency tree...
-The following packages will be REMOVED:
- cool:amd64
The following NEW packages will be installed:
- amdboot:amd64 arm-stuff cool doxygen libc6 libc6-dev libfwibble-dev
- libfwibble1
-0 upgraded, 8 newly installed, 1 to remove and 1 not upgraded.
-Remv cool:amd64 [0.5]
+ amdboot:amd64 arm-stuff doxygen libc6 libc6-dev libfwibble-dev libfwibble1
+The following packages will be upgraded:
+ cool:amd64
+1 upgraded, 7 newly installed, 0 to remove and 1 not upgraded.
Inst amdboot:amd64 (1.0 unstable [amd64])
Inst arm-stuff (1.0 unstable [armel])
-Inst cool (1.0 unstable [armel])
+Inst cool:amd64 [0.5] (1.0 unstable [amd64])
Inst doxygen (1.0 unstable [armel])
Inst libc6 (1.0 unstable [armel])
Inst libc6-dev (1.0 unstable [armel])
@@ -308,12 +310,15 @@ Inst libfwibble1 (1.0 unstable [armel])
Inst libfwibble-dev (1.0 unstable [armel])
Conf amdboot:amd64 (1.0 unstable [amd64])
Conf arm-stuff (1.0 unstable [armel])
-Conf cool (1.0 unstable [armel])
+Conf cool:amd64 (1.0 unstable [amd64])
Conf doxygen (1.0 unstable [armel])
Conf libc6 (1.0 unstable [armel])
Conf libc6-dev (1.0 unstable [armel])
Conf libfwibble1 (1.0 unstable [armel])
-Conf libfwibble-dev (1.0 unstable [armel])' aptget build-dep apt -s
+Conf libfwibble-dev (1.0 unstable [armel])'
+testsuccessequal "$APT_ON_ARMEL" aptget build-dep apt -s
+testsuccessequal "Reading package lists...
+$APT_ON_ARMEL" aptget build-dep apt -s -a armel
testsuccessequal 'Reading package lists...
Reading package lists...
diff --git a/test/integration/test-bug-992993-marked-cycles b/test/integration/test-bug-992993-marked-cycles
new file mode 100755
index 000000000..a569040cf
--- /dev/null
+++ b/test/integration/test-bug-992993-marked-cycles
@@ -0,0 +1,30 @@
+#!/bin/sh
+set -e
+
+TESTDIR="$(readlink -f "$(dirname "$0")")"
+. "$TESTDIR/framework"
+setupenvironment
+configarchitecture 'amd64'
+
+insertinstalledpackage 'librust-nom-4-dev' 'all' '4.2.3-3' 'Provides: librust-nom-dev (= 4.2.3-3)'
+insertinstalledpackage 'librust-nom-dev' 'all' '5.0.1-4' 'Depends: librust-nom+default-dev (= 5.0.1-4)'
+insertinstalledpackage 'librust-nom+default-dev ' 'all' '5.0.1-4' 'Depends: librust-nom-dev (= 5.0.1-4)'
+insertinstalledpackage 'librust-nom-4+std-dev' 'all' '4.2.3-3' 'Provides: librust-nom+default-dev (= 4.2.3-3)'
+
+insertinstalledpackage 'foo' 'all' '1' 'Depends: librust-nom-4-dev, librust-nom-dev, librust-nom-4+std-dev'
+
+for AUTO in '' 'librust-nom-4-dev' 'librust*' 'foo' '.*'; do
+ msgmsg 'Running test with these packages marked auto:' "$AUTO"
+ testsuccess aptmark manual '.*'
+ if [ -n "$AUTO" ]; then
+ testsuccess aptmark auto "$AUTO"
+ fi
+
+ testsuccess aptget check
+ testsuccess aptget autoremove -s
+
+ testsuccess aptget upgrade
+ testsuccess aptget full-upgrade
+
+ testsuccess apt show foo
+done
diff --git a/test/integration/test-multiarch-allowed b/test/integration/test-multiarch-allowed
index a091635f0..69d0bfa10 100755
--- a/test/integration/test-multiarch-allowed
+++ b/test/integration/test-multiarch-allowed
@@ -19,8 +19,8 @@ insertpackage 'unstable' 'coolfoo' 'amd64' '1' 'Multi-Arch:allowed
Provides: coolbar'
insertpackage 'unstable' 'coolfoover' 'amd64' '1' 'Multi-Arch:allowed
Provides: coolbar (= 2)'
-insertpackage 'unstable' 'needscoolfoo' 'amd64' '1' 'Depends: coolfoo, coolbar'
-insertpackage 'unstable' 'needscoolfooany' 'amd64' '1' 'Depends: coolfoo:any, coolbar:any'
+insertpackage 'unstable' 'needscoolfoo' 'amd64,i386' '1' 'Depends: coolfoo, coolbar'
+insertpackage 'unstable' 'needscoolfooany' 'amd64,i386' '1' 'Depends: coolfoo:any, coolbar:any'
insertpackage 'unstable' 'needscoolfoover0' 'amd64' '1' 'Depends: coolfoo:any (>= 1), coolbar:any'
insertpackage 'unstable' 'needscoolfoover1' 'amd64' '1' 'Depends: coolfoo:any (>= 1), coolbar:any (>= 1)'
insertpackage 'unstable' 'needscoolfoover2' 'amd64' '1' 'Depends: coolfoo:any (>= 2), coolbar:any (>= 1)'
@@ -166,6 +166,28 @@ Inst hatesfoonative (1 unstable [amd64])
Conf foo:i386 (1 unstable [i386])
Conf hatesfoonative (1 unstable [amd64])' aptget install foo:i386 hatesfoonative -s
+testfailureequal "$BADPREFIX
+The following packages have unmet dependencies:
+ needscoolfoo:i386 : Depends: coolfoo:i386 but it is not installable
+ Depends: coolbar:i386 but it is not installable
+E: Unable to correct problems, you have held broken packages." aptget install needscoolfoo:i386 -s
+solveneedscoolfooanyin() {
+ local NEEDSCOOL='needscoolfooany'
+ if [ "$1" != 'amd64' ]; then NEEDSCOOL="${NEEDSCOOL}:$1"; fi
+ testsuccessequal "Reading package lists...
+Building dependency tree...
+The following additional packages will be installed:
+ coolfoo
+The following NEW packages will be installed:
+ coolfoo $NEEDSCOOL
+0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
+Inst coolfoo (1 unstable [amd64])
+Inst $NEEDSCOOL (1 unstable [$1])
+Conf coolfoo (1 unstable [amd64])
+Conf $NEEDSCOOL (1 unstable [$1])" aptget install $NEEDSCOOL -s
+}
+solveneedscoolfooanyin 'i386'
+
solveableinsinglearch3() {
testsuccessequal "Reading package lists...
Building dependency tree...
@@ -191,17 +213,7 @@ Inst needscoolfoo (1 unstable [amd64])
Conf coolfoo (1 unstable [amd64])
Conf coolfoover (1 unstable [amd64])
Conf needscoolfoo (1 unstable [amd64])" aptget install needscoolfoo coolfoover -s
- testsuccessequal "Reading package lists...
-Building dependency tree...
-The following additional packages will be installed:
- coolfoo
-The following NEW packages will be installed:
- coolfoo needscoolfooany
-0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
-Inst coolfoo (1 unstable [amd64])
-Inst needscoolfooany (1 unstable [amd64])
-Conf coolfoo (1 unstable [amd64])
-Conf needscoolfooany (1 unstable [amd64])" aptget install needscoolfooany -s
+ solveneedscoolfooanyin 'amd64'
testsuccessequal 'Reading package lists...
Building dependency tree...
The following additional packages will be installed:
@@ -252,12 +264,15 @@ testfailureequal "$NEEDSFOO2NATIVE" aptget install needsfoover2 -s
solveableinsinglearch2
solveableinsinglearch3
+testempty dpkg -C
msgmsg 'multi-arch with barbarian archs'
configarchitecture 'amd64' 'i386'
insertinstalledpackage 'foo' 'armel' '1' 'Multi-Arch: allowed'
insertinstalledpackage 'coolfoo' 'armel' '1' 'Multi-Arch:allowed
Provides: coolbar'
-insertinstalledpackage 'bar-needer' 'armel' '1.0' 'Depends: coolbar:any'
+insertinstalledpackage 'bar-needer' 'armel' '1.0' 'Depends: coolbar'
+insertinstalledpackage 'bar-any-needer' 'armel' '1.0' 'Depends: coolbar:any'
+insertinstalledpackage 'bar-armel-needer' 'armel' '1.0' 'Depends: coolbar:armel'
testsuccess aptget check
testsuccessequal 'Reading package lists...
@@ -293,11 +308,13 @@ Building dependency tree...
The following additional packages will be installed:
coolfoo
The following packages will be REMOVED:
- coolfoo:armel
+ bar-armel-needer:armel bar-needer:armel coolfoo:armel
The following NEW packages will be installed:
coolfoo needscoolfoover0
-0 upgraded, 2 newly installed, 1 to remove and 0 not upgraded.
-Remv coolfoo:armel [1] [bar-needer:armel ]
+0 upgraded, 2 newly installed, 3 to remove and 0 not upgraded.
+Remv bar-armel-needer:armel [1.0]
+Remv bar-needer:armel [1.0]
+Remv coolfoo:armel [1] [bar-any-needer:armel ]
Inst coolfoo (1 unstable [amd64])
Inst needscoolfoover0 (1 unstable [amd64])
Conf coolfoo (1 unstable [amd64])
diff --git a/test/integration/test-multiarch-barbarian b/test/integration/test-multiarch-barbarian
new file mode 100755
index 000000000..293f22735
--- /dev/null
+++ b/test/integration/test-multiarch-barbarian
@@ -0,0 +1,243 @@
+#!/bin/sh
+set -e
+
+TESTDIR="$(readlink -f "$(dirname "$0")")"
+. "$TESTDIR/framework"
+
+setupenvironment
+configarchitecture 'amd64' 'i386'
+
+buildsimplenativepackage 'foreign-foo' 'amd64,i386' '1' 'stable' 'Multi-Arch: foreign
+Provides: foreign-bar'
+buildsimplenativepackage 'allowed-foo' 'amd64,i386' '1' 'stable' 'Multi-Arch: allowed
+Provides: allowed-bar'
+buildsimplenativepackage 'needs-foreign-foo' 'amd64,i386' '1' 'stable' 'Depends: foreign-foo'
+buildsimplenativepackage 'needs-foreign-bar' 'amd64,i386' '1' 'stable' 'Depends: foreign-bar'
+buildsimplenativepackage 'needs-allowed-foo' 'amd64,i386' '1' 'stable' 'Depends: allowed-foo'
+buildsimplenativepackage 'needs-allowed-bar' 'amd64,i386' '1' 'stable' 'Depends: allowed-bar'
+buildsimplenativepackage 'needs-allowed-foo-any' 'amd64,i386' '1' 'stable' 'Depends: allowed-foo:any'
+buildsimplenativepackage 'needs-allowed-bar-any' 'amd64,i386' '1' 'stable' 'Depends: allowed-bar:any'
+
+setupaptarchive
+
+simulateinstall() {
+ testsuccessequal "Reading package lists...
+Building dependency tree...
+The following additional packages will be installed:
+ $1-foo
+The following NEW packages will be installed:
+ $1-foo needs-$1-$2
+0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
+Inst $1-foo (1 stable [amd64])
+Inst needs-$1-$2 (1 stable [amd64])
+Conf $1-foo (1 stable [amd64])
+Conf needs-$1-$2 (1 stable [amd64])" apt install needs-$1-$2 -s
+}
+simulateinstall 'foreign' 'foo'
+simulateinstall 'foreign' 'bar'
+simulateinstall 'allowed' 'foo'
+simulateinstall 'allowed' 'bar'
+simulateinstall 'allowed' 'foo-any'
+simulateinstall 'allowed' 'bar-any'
+
+# install a barbaric architecture which wont do
+insertinstalledpackage 'foreign-foo' 'armel' '1' 'Multi-Arch: foreign
+Provides: foreign-bar'
+insertinstalledpackage 'allowed-foo' 'armel' '1' 'Multi-Arch: allowed
+Provides: allowed-bar'
+testdpkginstalled foreign-foo:armel allowed-foo:armel
+
+runandsimulateaptinstall() {
+ local MSG="$1"
+ shift
+ testsuccessequal "$MSG" apt install -s "$@"
+ testsuccess apt install -y "$@"
+}
+
+runandsimulateaptinstall 'Reading package lists...
+Building dependency tree...
+The following additional packages will be installed:
+ allowed-foo foreign-foo
+The following packages will be REMOVED:
+ allowed-foo:armel foreign-foo:armel
+The following NEW packages will be installed:
+ allowed-foo foreign-foo needs-allowed-bar-any needs-allowed-foo-any
+ needs-foreign-bar needs-foreign-foo
+0 upgraded, 6 newly installed, 2 to remove and 0 not upgraded.
+Remv allowed-foo:armel [1]
+Remv foreign-foo:armel [1]
+Inst allowed-foo (1 stable [amd64])
+Inst foreign-foo (1 stable [amd64])
+Inst needs-allowed-bar-any (1 stable [amd64])
+Inst needs-allowed-foo-any (1 stable [amd64])
+Inst needs-foreign-bar (1 stable [amd64])
+Inst needs-foreign-foo (1 stable [amd64])
+Conf allowed-foo (1 stable [amd64])
+Conf foreign-foo (1 stable [amd64])
+Conf needs-allowed-bar-any (1 stable [amd64])
+Conf needs-allowed-foo-any (1 stable [amd64])
+Conf needs-foreign-bar (1 stable [amd64])
+Conf needs-foreign-foo (1 stable [amd64])' needs-foreign-foo needs-foreign-bar needs-allowed-foo-any needs-allowed-bar-any
+runandsimulateaptinstall 'Reading package lists...
+Building dependency tree...
+Reading state information...
+The following NEW packages will be installed:
+ needs-allowed-bar needs-allowed-foo
+0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
+Inst needs-allowed-bar (1 stable [amd64])
+Inst needs-allowed-foo (1 stable [amd64])
+Conf needs-allowed-bar (1 stable [amd64])
+Conf needs-allowed-foo (1 stable [amd64])' needs-allowed-foo needs-allowed-bar
+testdpkginstalled foreign-foo:amd64 allowed-foo:amd64 needs-foreign-foo needs-foreign-bar needs-allowed-foo-any needs-allowed-bar-any
+testempty dpkg -C
+
+# check if dependencies between barbarians work
+testsuccess aptget check
+configarchitecture 'i386'
+testsuccess aptget check
+configarchitecture 'amd64' 'i386'
+
+testsuccess apt purge -y needs-foreign-foo needs-foreign-bar needs-allowed-foo-any needs-allowed-bar-any
+testdpkgnotinstalled foreign-foo:armel allowed-foo:armel needs-foreign-foo needs-foreign-bar needs-allowed-foo-any needs-allowed-bar-any
+testdpkginstalled foreign-foo:amd64 allowed-foo:amd64 needs-allowed-foo needs-allowed-bar
+
+runandsimulateaptinstall 'Reading package lists...
+Building dependency tree...
+Reading state information...
+The following additional packages will be installed:
+ allowed-foo:i386 foreign-foo:i386
+The following packages will be REMOVED:
+ allowed-foo foreign-foo needs-allowed-bar needs-allowed-foo
+The following NEW packages will be installed:
+ allowed-foo:i386 foreign-foo:i386 needs-allowed-bar-any
+ needs-allowed-foo-any needs-foreign-bar needs-foreign-foo
+0 upgraded, 6 newly installed, 4 to remove and 0 not upgraded.
+Remv needs-allowed-foo [1]
+Remv needs-allowed-bar [1]
+Remv allowed-foo [1]
+Remv foreign-foo [1]
+Inst allowed-foo:i386 (1 stable [i386])
+Inst foreign-foo:i386 (1 stable [i386])
+Inst needs-allowed-bar-any (1 stable [amd64])
+Inst needs-allowed-foo-any (1 stable [amd64])
+Inst needs-foreign-bar (1 stable [amd64])
+Inst needs-foreign-foo (1 stable [amd64])
+Conf allowed-foo:i386 (1 stable [i386])
+Conf foreign-foo:i386 (1 stable [i386])
+Conf needs-allowed-bar-any (1 stable [amd64])
+Conf needs-allowed-foo-any (1 stable [amd64])
+Conf needs-foreign-bar (1 stable [amd64])
+Conf needs-foreign-foo (1 stable [amd64])' needs-foreign-foo needs-foreign-bar needs-allowed-foo-any needs-allowed-bar-any foreign-foo:amd64- allowed-foo:amd64-
+
+runandsimulateaptinstall 'Reading package lists...
+Building dependency tree...
+Reading state information...
+The following packages will be REMOVED:
+ needs-allowed-bar-any needs-allowed-foo-any needs-foreign-bar
+ needs-foreign-foo
+The following NEW packages will be installed:
+ needs-allowed-bar-any:i386 needs-allowed-foo-any:i386 needs-foreign-bar:i386
+ needs-foreign-foo:i386
+0 upgraded, 4 newly installed, 4 to remove and 0 not upgraded.
+Remv needs-allowed-bar-any [1]
+Remv needs-allowed-foo-any [1]
+Remv needs-foreign-bar [1]
+Remv needs-foreign-foo [1]
+Inst needs-allowed-bar-any:i386 (1 stable [i386])
+Inst needs-allowed-foo-any:i386 (1 stable [i386])
+Inst needs-foreign-bar:i386 (1 stable [i386])
+Inst needs-foreign-foo:i386 (1 stable [i386])
+Conf needs-allowed-bar-any:i386 (1 stable [i386])
+Conf needs-allowed-foo-any:i386 (1 stable [i386])
+Conf needs-foreign-bar:i386 (1 stable [i386])
+Conf needs-foreign-foo:i386 (1 stable [i386])' needs-foreign-foo:i386 needs-foreign-bar:i386 needs-allowed-foo-any:i386 needs-allowed-bar-any:i386
+
+runandsimulateaptinstall 'Reading package lists...
+Building dependency tree...
+Reading state information...
+The following packages will be REMOVED:
+ allowed-foo:i386 foreign-foo:i386
+The following NEW packages will be installed:
+ allowed-foo foreign-foo
+0 upgraded, 2 newly installed, 2 to remove and 0 not upgraded.
+Remv allowed-foo:i386 [1] [needs-allowed-bar-any:i386 needs-allowed-foo-any:i386 ]
+Inst allowed-foo (1 stable [amd64])
+Remv foreign-foo:i386 [1] [needs-foreign-bar:i386 needs-foreign-foo:i386 ]
+Inst foreign-foo (1 stable [amd64])
+Conf allowed-foo (1 stable [amd64])
+Conf foreign-foo (1 stable [amd64])' foreign-foo:amd64 allowed-foo:amd64
+testdpkginstalled foreign-foo:amd64 needs-foreign-foo:i386 needs-foreign-bar:i386
+
+testsuccessequal 'Reading package lists...
+Building dependency tree...
+Reading state information...
+The following additional packages will be installed:
+ allowed-foo:i386
+The following packages will be REMOVED:
+ allowed-foo
+The following NEW packages will be installed:
+ allowed-foo:i386 needs-allowed-bar:i386 needs-allowed-foo:i386
+0 upgraded, 3 newly installed, 1 to remove and 0 not upgraded.
+Remv allowed-foo [1] [needs-allowed-bar-any:i386 needs-allowed-foo-any:i386 ]
+Inst allowed-foo:i386 (1 stable [i386])
+Inst needs-allowed-bar:i386 (1 stable [i386])
+Inst needs-allowed-foo:i386 (1 stable [i386])
+Conf allowed-foo:i386 (1 stable [i386])
+Conf needs-allowed-bar:i386 (1 stable [i386])
+Conf needs-allowed-foo:i386 (1 stable [i386])' apt install needs-allowed-foo:i386 needs-allowed-bar:i386 -s
+
+testsuccess aptget check
+# make amd64 packages barbaric: the needs are i386 native, the providers amd64 barbaric!
+configarchitecture 'i386'
+testfailureequal "Reading package lists...
+Building dependency tree...
+Reading state information...
+You might want to run 'apt --fix-broken install' to correct these.
+The following packages have unmet dependencies:
+ needs-allowed-bar-any : Depends: allowed-bar:any
+ needs-allowed-foo-any : Depends: allowed-foo:any
+ needs-foreign-bar : Depends: foreign-bar
+ needs-foreign-foo : Depends: foreign-foo but it is not installed
+E: Unmet dependencies. Try 'apt --fix-broken install' with no packages (or specify a solution)." aptget check
+
+# make i386 packages barbaric, so the providers are now native
+configarchitecture 'amd64'
+testsuccess aptget check
+
+testsuccess apt install -y needs-allowed-foo needs-allowed-bar
+testsuccess dpkg --remove --force-depends foreign-foo:amd64 allowed-foo:amd64
+testdpkginstalled needs-foreign-foo:i386 needs-foreign-bar:i386 needs-allowed-foo needs-allowed-bar needs-allowed-foo-any:i386 needs-allowed-bar-any:i386
+testfailure aptget check
+
+testsuccessequal 'Reading package lists...
+Building dependency tree...
+Reading state information...
+Correcting dependencies... Done
+The following additional packages will be installed:
+ allowed-foo foreign-foo
+The following NEW packages will be installed:
+ allowed-foo foreign-foo
+0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
+Inst allowed-foo (1 stable [amd64]) [needs-foreign-bar:i386 needs-foreign-foo:i386 ]
+Inst foreign-foo (1 stable [amd64])
+Conf allowed-foo (1 stable [amd64])
+Conf foreign-foo (1 stable [amd64])' apt install --fix-broken -s
+# note that dpkg would not accept this as its a barbaric arch,
+# but it is the easiest to try if the dependencies as such work in apt
+testsuccessequal "Reading package lists...
+Building dependency tree...
+Reading state information...
+Correcting dependencies... Done
+Note, selecting 'foreign-foo:i386' instead of './incoming/foreign-foo_1_i386.deb'
+Note, selecting 'allowed-foo:i386' instead of './incoming/allowed-foo_1_i386.deb'
+The following packages will be REMOVED:
+ needs-allowed-bar needs-allowed-foo
+The following NEW packages will be installed:
+ allowed-foo:i386 foreign-foo:i386
+0 upgraded, 2 newly installed, 2 to remove and 0 not upgraded.
+Remv needs-allowed-bar [1] [needs-foreign-bar:i386 needs-foreign-foo:i386 needs-allowed-bar-any:i386 needs-allowed-foo-any:i386 needs-allowed-foo:amd64 ]
+Remv needs-allowed-foo [1] [needs-foreign-bar:i386 needs-foreign-foo:i386 needs-allowed-bar-any:i386 needs-allowed-foo-any:i386 ]
+Inst allowed-foo:i386 (1 local-deb [i386]) [needs-foreign-bar:i386 needs-foreign-foo:i386 ]
+Inst foreign-foo:i386 (1 local-deb [i386])
+Conf allowed-foo:i386 (1 local-deb [i386])
+Conf foreign-foo:i386 (1 local-deb [i386])" apt install --fix-broken -s ./incoming/foreign-foo_1_i386.deb ./incoming/allowed-foo_1_i386.deb
diff --git a/test/integration/test-prevent-markinstall-multiarch-same-versionscrew b/test/integration/test-prevent-markinstall-multiarch-same-versionscrew
index a45c0d55d..63fdb88d9 100755
--- a/test/integration/test-prevent-markinstall-multiarch-same-versionscrew
+++ b/test/integration/test-prevent-markinstall-multiarch-same-versionscrew
@@ -96,6 +96,7 @@ Conf fine-installed:i386 (3 experimental [i386])
Conf out-of-sync-gone-foreign (2 unstable [amd64])
Conf out-of-sync-gone-native:i386 (2 unstable [i386])' aptget dist-upgrade -s #-o Debug::pkgDepCache::Marker=1
+testempty dpkg -C
rm rootdir/var/lib/dpkg/status
insertinstalledpackage 'libsame2' 'i386' '1' 'Multi-Arch: same'
insertinstalledpackage 'libsame3' 'i386' '1' 'Multi-Arch: same'
@@ -128,3 +129,5 @@ Inst depender3 (3 unstable [all])
Conf libsame3:i386 (3 unstable [i386])
Conf libsame3 (3 unstable [amd64])
Conf depender3 (3 unstable [all])' aptget install depender3 -s
+
+testempty dpkg -C
diff --git a/test/interactive-helper/CMakeLists.txt b/test/interactive-helper/CMakeLists.txt
index 565474afd..fff47300b 100644
--- a/test/interactive-helper/CMakeLists.txt
+++ b/test/interactive-helper/CMakeLists.txt
@@ -11,7 +11,8 @@ target_link_libraries(aptdropprivs apt-pkg)
add_executable(test_fileutl test_fileutl.cc)
target_link_libraries(test_fileutl apt-pkg)
add_executable(createdeb-cve-2020-27350 createdeb-cve-2020-27350.cc)
-
+add_executable(longest-dependency-chain longest-dependency-chain.cc)
+target_link_libraries(longest-dependency-chain apt-pkg apt-private)
add_library(noprofile SHARED libnoprofile.c)
target_link_libraries(noprofile ${CMAKE_DL_LIBS})
diff --git a/test/interactive-helper/longest-dependency-chain.cc b/test/interactive-helper/longest-dependency-chain.cc
new file mode 100644
index 000000000..3da722a5b
--- /dev/null
+++ b/test/interactive-helper/longest-dependency-chain.cc
@@ -0,0 +1,72 @@
+#include <config.h>
+
+#include <apt-pkg/cachefile.h>
+#include <apt-pkg/pkgsystem.h>
+#include <apt-private/private-cmndline.h>
+
+#include <iostream>
+
+static bool ShowHelp(CommandLine &) /*{{{*/
+{
+ std::cout <<
+ "Usage: longest-dependecy-chain [options]\n"
+ "\n"
+ "Tries to find the longest dependency chain available in the data\n"
+ "assuming an empty status file, no conflicts, all or-group members\n"
+ "are followed and discovery order matters. In other words:\n"
+ "The found length might very well be too short and not realistic.\n"
+ "It is also not implemented very intelligently, so it runs forever.\n";
+ return true;
+}
+ /*}}}*/
+static std::vector<aptDispatchWithHelp> GetCommands() /*{{{*/
+{
+ return {
+ {nullptr, nullptr, nullptr}
+ };
+}
+ /*}}}*/
+static size_t findLongestInstallChain(pkgDepCache &Cache, pkgCache::PkgIterator const &Pkg, std::vector<bool> &installed)/*{{{*/
+{
+ if (installed[Pkg->ID])
+ return 0;
+ installed[Pkg->ID] = true;
+
+ auto const Ver = Cache.GetCandidateVersion(Pkg);
+ if (Ver.end())
+ return 0;
+
+ size_t maxdepth = 0;
+ for (auto D = Ver.DependsList(); not D.end(); ++D)
+ if (D->Type == pkgCache::Dep::Depends ||
+ D->Type == pkgCache::Dep::PreDepends ||
+ D->Type == pkgCache::Dep::Recommends ||
+ D->Type == pkgCache::Dep::Suggests)
+ maxdepth = std::max(maxdepth, findLongestInstallChain(Cache, D.TargetPkg(), installed));
+ return maxdepth + 1;
+}
+ /*}}}*/
+int main(int argc,const char *argv[]) /*{{{*/
+{
+ CommandLine CmdL;
+ auto const Cmds = ParseCommandLine(CmdL, APT_CMD::APT_SORTPKG, &_config, &_system, argc, argv, &ShowHelp, &GetCommands);
+ _config->Set("dir::state::status", "/dev/null");
+
+ pkgCacheFile CacheFile;
+ CacheFile.InhibitActionGroups(true);
+ pkgDepCache * const Cache = CacheFile.GetDepCache();
+ if (unlikely(Cache == nullptr))
+ return DispatchCommandLine(CmdL, Cmds);
+
+ size_t maxdepth = 0;
+ for (auto P = Cache->PkgBegin(); not P.end(); ++P)
+ {
+ std::vector<bool> installed(Cache->Head().PackageCount, false);
+ auto const depth = findLongestInstallChain(*Cache, P, installed);
+ std::cout << depth << ' ' << P.FullName() << '\n';
+ maxdepth = std::max(maxdepth, depth);
+ }
+
+ return 0;
+}
+ /*}}}*/
diff --git a/test/libapt/getarchitectures_test.cc b/test/libapt/getarchitectures_test.cc
index 57e9a5f2f..4f767226f 100644
--- a/test/libapt/getarchitectures_test.cc
+++ b/test/libapt/getarchitectures_test.cc
@@ -75,3 +75,31 @@ TEST(ArchitecturesTest,Duplicates)
_config->Clear();
}
+TEST(ArchitecturesTest,VeryForeign)
+{
+ _config->Clear();
+ _config->Set("APT::Architectures::", "i386");
+ _config->Set("APT::Architectures::", "amd64");
+ _config->Set("APT::Architectures::", "armel");
+
+ auto vec = APT::Configuration::getArchitectures(false);
+ ASSERT_EQ(3u, vec.size());
+ EXPECT_EQ("i386", vec[0]);
+ EXPECT_EQ("amd64", vec[1]);
+ EXPECT_EQ("armel", vec[2]);
+
+ _config->Set("APT::BarbarianArchitectures::", "mipsel");
+ vec = APT::Configuration::getArchitectures(false);
+ ASSERT_EQ(3u, vec.size());
+ EXPECT_EQ("i386", vec[0]);
+ EXPECT_EQ("amd64", vec[1]);
+ EXPECT_EQ("armel", vec[2]);
+
+ _config->Set("APT::BarbarianArchitectures::", "armel");
+ vec = APT::Configuration::getArchitectures(false);
+ ASSERT_EQ(2u, vec.size());
+ EXPECT_EQ("i386", vec[0]);
+ EXPECT_EQ("amd64", vec[1]);
+
+ _config->Clear();
+}