summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Andres Klode <jak@debian.org>2021-10-18 13:36:00 +0000
committerJulian Andres Klode <jak@debian.org>2021-10-18 13:36:00 +0000
commitedf4b2169405e7ca6e21f408229e5fc4bbd4f4ed (patch)
tree864a13dbda22e3b4de7b69600521fb7e7d8b39a2
parent883a12310a4130370965eab0a710a2c8fae6cc09 (diff)
parent70c669e2566d119559d2986635bb6c1d0d368073 (diff)
Merge branch 'feature/barbarianarchs' into 'main'
Streamline access to barbarian architecture functionality See merge request apt-team/apt!184
-rw-r--r--apt-pkg/aptconfiguration.cc22
-rw-r--r--apt-pkg/deb/deblistparser.cc17
-rw-r--r--apt-pkg/deb/debmetaindex.cc20
-rw-r--r--apt-pkg/edsp.cc43
-rw-r--r--apt-pkg/pkgcache.cc5
-rw-r--r--apt-pkg/pkgcache.h2
-rw-r--r--apt-pkg/pkgcachegen.cc10
-rw-r--r--apt-private/private-source.cc25
-rw-r--r--doc/examples/configure-index1
-rw-r--r--test/integration/framework77
-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-multiarch-allowed51
-rwxr-xr-xtest/integration/test-multiarch-barbarian243
-rwxr-xr-xtest/integration/test-prevent-markinstall-multiarch-same-versionscrew3
-rw-r--r--test/libapt/getarchitectures_test.cc28
17 files changed, 604 insertions, 132 deletions
diff --git a/apt-pkg/aptconfiguration.cc b/apt-pkg/aptconfiguration.cc
index 671c3d553..00a97a0e7 100644
--- a/apt-pkg/aptconfiguration.cc
+++ b/apt-pkg/aptconfiguration.cc
@@ -315,13 +315,11 @@ bool Configuration::checkLanguage(std::string Lang, bool const All) {
/*}}}*/
// getArchitectures - Return Vector of preferred Architectures /*{{{*/
std::vector<std::string> const Configuration::getArchitectures(bool const &Cached) {
- using std::string;
-
- std::vector<string> static archs;
+ std::vector<std::string> static archs;
if (likely(Cached == true) && archs.empty() == false)
return archs;
- string const arch = _config->Find("APT::Architecture");
+ std::string const arch = _config->Find("APT::Architecture");
archs = _config->FindVector("APT::Architectures");
if (archs.empty() == true && _system != nullptr)
@@ -331,15 +329,13 @@ std::vector<std::string> const Configuration::getArchitectures(bool const &Cache
std::find(archs.begin(), archs.end(), arch) == archs.end())
archs.insert(archs.begin(), arch);
- // erase duplicates and empty strings
- for (std::vector<string>::reverse_iterator a = archs.rbegin();
- a != archs.rend(); ++a) {
- if (a->empty() == true || std::find(a + 1, archs.rend(), *a) != archs.rend())
- archs.erase(a.base()-1);
- if (a == archs.rend())
- break;
- }
-
+ // erase duplicates, empty strings and very foreign architectures
+ auto newend = std::remove_if(archs.begin(), archs.end(), [](auto const &a) { return a.empty(); });
+ for (auto a = archs.begin(); a != newend; ++a)
+ newend = std::remove(std::next(a), newend, *a);
+ for (auto const &f : _config->FindVector("APT::BarbarianArchitectures"))
+ newend = std::remove(archs.begin(), newend, f);
+ archs.erase(newend, archs.end());
return archs;
}
/*}}}*/
diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc
index 966246ca7..2f0ebaa7b 100644
--- a/apt-pkg/deb/deblistparser.cc
+++ b/apt-pkg/deb/deblistparser.cc
@@ -823,6 +823,7 @@ bool debListParser::ParseDepends(pkgCache::VerIterator &Ver,
return true;
string const pkgArch = Ver.Arch();
+ bool const barbarianArch = not APT::Configuration::checkArchitecture(pkgArch);
while (1)
{
@@ -843,7 +844,14 @@ bool debListParser::ParseDepends(pkgCache::VerIterator &Ver,
}
else if (Package.substr(found) == ":any")
{
- if (NewDepends(Ver,Package,"any",Version,Op,Type) == false)
+ if (barbarianArch)
+ {
+ if (not NewDepends(Ver, Package, "any", Version, Op | pkgCache::Dep::Or, Type))
+ return false;
+ if (not NewDepends(Ver, Package.substr(0, found), pkgArch, Version, Op, Type))
+ return false;
+ }
+ else if (not NewDepends(Ver, Package, "any", Version, Op, Type))
return false;
}
else
@@ -888,6 +896,7 @@ bool debListParser::ParseProvides(pkgCache::VerIterator &Ver)
}
string const Arch = Ver.Arch();
+ bool const barbarianArch = not APT::Configuration::checkArchitecture(Arch);
const char *Start;
const char *Stop;
if (Section.Find(pkgTagSection::Key::Provides,Start,Stop) == true)
@@ -914,7 +923,7 @@ bool debListParser::ParseProvides(pkgCache::VerIterator &Ver)
if (NewProvides(Ver, Package, "any", Version, pkgCache::Flag::ArchSpecific) == false)
return false;
} else if ((Ver->MultiArch & pkgCache::Version::Foreign) == pkgCache::Version::Foreign) {
- if (APT::Configuration::checkArchitecture(Arch))
+ if (not barbarianArch)
{
if (NewProvidesAllArch(Ver, Package, Version, 0) == false)
return false;
@@ -922,7 +931,7 @@ bool debListParser::ParseProvides(pkgCache::VerIterator &Ver)
else if (NewProvides(Ver, Package, Arch, Version, 0) == false)
return false;
} else {
- if ((Ver->MultiArch & pkgCache::Version::Allowed) == pkgCache::Version::Allowed)
+ if ((Ver->MultiArch & pkgCache::Version::Allowed) == pkgCache::Version::Allowed && not barbarianArch)
{
if (NewProvides(Ver, Package.to_string().append(":any"), "any", Version, pkgCache::Flag::MultiArchImplicit) == false)
return false;
@@ -945,7 +954,7 @@ bool debListParser::ParseProvides(pkgCache::VerIterator &Ver)
} while (Start != Stop);
}
- if (APT::Configuration::checkArchitecture(Arch))
+ if (not barbarianArch)
{
if ((Ver->MultiArch & pkgCache::Version::Allowed) == pkgCache::Version::Allowed)
{
diff --git a/apt-pkg/deb/debmetaindex.cc b/apt-pkg/deb/debmetaindex.cc
index f24a5e79e..d78cea758 100644
--- a/apt-pkg/deb/debmetaindex.cc
+++ b/apt-pkg/deb/debmetaindex.cc
@@ -18,6 +18,7 @@
#include <algorithm>
#include <map>
+#include <optional>
#include <sstream>
#include <string>
#include <utility>
@@ -966,13 +967,13 @@ pkgCache::RlsFileIterator debReleaseIndex::FindInCache(pkgCache &Cache, bool con
class APT_HIDDEN debSLTypeDebian : public pkgSourceList::Type /*{{{*/
{
- static std::vector<std::string> getDefaultSetOf(std::string const &Name,
- std::map<std::string, std::string> const &Options, std::vector<std::string> const &defaultValues)
+ static std::optional<std::vector<std::string>> getDefaultSetOf(std::string const &Name,
+ std::map<std::string, std::string> const &Options)
{
auto const val = Options.find(Name);
if (val != Options.end())
return VectorizeString(val->second, ',');
- return defaultValues;
+ return {};
}
static std::vector<std::string> applyPlusMinusOptions(std::string const &Name,
std::map<std::string, std::string> const &Options, std::vector<std::string> &&Values)
@@ -997,12 +998,21 @@ class APT_HIDDEN debSLTypeDebian : public pkgSourceList::Type /*{{{*/
static std::vector<std::string> parsePlusMinusOptions(std::string const &Name,
std::map<std::string, std::string> const &Options, std::vector<std::string> const &defaultValues)
{
- return applyPlusMinusOptions(Name, Options, getDefaultSetOf(Name, Options, defaultValues));
+ return applyPlusMinusOptions(Name, Options, getDefaultSetOf(Name, Options).value_or(defaultValues));
}
static std::vector<std::string> parsePlusMinusArchOptions(std::string const &Name,
std::map<std::string, std::string> const &Options)
{
- auto Values = getDefaultSetOf(Name, Options, APT::Configuration::getArchitectures());
+ std::vector<std::string> Values;
+ if (auto opt = getDefaultSetOf(Name, Options); opt.has_value())
+ Values = opt.value();
+ else
+ {
+ Values = APT::Configuration::getArchitectures();
+ auto veryforeign = _config->FindVector("APT::BarbarianArchitectures");
+ Values.reserve(Values.size() + veryforeign.size());
+ std::move(veryforeign.begin(), veryforeign.end(), std::back_inserter(Values));
+ }
// all is a very special architecture users shouldn't be concerned with explicitly
// but if the user does, do not override the choice
auto const val = Options.find(Name + "-");
diff --git a/apt-pkg/edsp.cc b/apt-pkg/edsp.cc
index 7e3993be4..b7c0d28d2 100644
--- a/apt-pkg/edsp.cc
+++ b/apt-pkg/edsp.cc
@@ -8,6 +8,7 @@
#include <config.h>
#include <apt-pkg/algorithms.h>
+#include <apt-pkg/aptconfiguration.h>
#include <apt-pkg/cacheset.h>
#include <apt-pkg/depcache.h>
#include <apt-pkg/edsp.h>
@@ -205,6 +206,25 @@ static bool WriteScenarioLimitedDependency(FileFd &output,
return WriteOkay(Okay, output, "\n");
}
/*}}}*/
+static bool checkKnownArchitecture(std::string const &arch) /*{{{*/
+{
+ if (APT::Configuration::checkArchitecture(arch))
+ return true;
+ static auto const veryforeign = _config->FindVector("APT::BarbarianArchitectures");
+ return std::find(veryforeign.begin(), veryforeign.end(), arch) != veryforeign.end();
+}
+ /*}}}*/
+static bool WriteGenericRequestHeaders(FileFd &output, APT::StringView const head)/*{{{*/
+{
+ bool Okay = WriteOkay(output, head, "Architecture: ", _config->Find("APT::Architecture"), "\n",
+ "Architectures:");
+ for (auto const &a : APT::Configuration::getArchitectures())
+ WriteOkay(Okay, output, " ", a);
+ for (auto const &a : _config->FindVector("APT::BarbarianArchitectures"))
+ WriteOkay(Okay, output, " ", a);
+ return WriteOkay(Okay, output, "\n");
+}
+ /*}}}*/
static bool SkipUnavailableVersions(pkgDepCache &Cache, pkgCache::PkgIterator const &Pkg, pkgCache::VerIterator const &Ver)/*{{{*/
{
/* versions which aren't current and aren't available in
@@ -266,11 +286,9 @@ bool EDSP::WriteScenario(pkgDepCache &Cache, FileFd &output, OpProgress *Progres
Progress->SubProgress(Cache.Head().VersionCount, _("Send scenario to solver"));
decltype(Cache.Head().VersionCount) p = 0;
bool Okay = output.Failed() == false;
- std::vector<std::string> archs = APT::Configuration::getArchitectures();
for (pkgCache::PkgIterator Pkg = Cache.PkgBegin(); Pkg.end() == false && likely(Okay); ++Pkg)
{
- std::string const arch = Pkg.Arch();
- if (Pkg->CurrentVer == 0 && std::find(archs.begin(), archs.end(), arch) == archs.end())
+ if (Pkg->CurrentVer == 0 && not checkKnownArchitecture(Pkg.Arch()))
continue;
for (pkgCache::VerIterator Ver = Pkg.VersionList(); Ver.end() == false && likely(Okay); ++Ver, ++p)
{
@@ -341,15 +359,8 @@ bool EDSP::WriteRequest(pkgDepCache &Cache, FileFd &output,
continue;
req->append(" ").append(Pkg.FullName());
}
- bool Okay = WriteOkay(output, "Request: EDSP 0.5\n");
-
- std::vector<string> archs = APT::Configuration::getArchitectures();
- WriteOkay(Okay, output, "Architecture: ", _config->Find("APT::Architecture").c_str(), "\n",
- "Architectures:");
- for (std::vector<string>::const_iterator a = archs.begin(); a != archs.end(); ++a)
- WriteOkay(Okay, output, " ", *a);
- WriteOkay(Okay, output, "\n");
+ bool Okay = WriteGenericRequestHeaders(output, "Request: EDSP 0.5\n");
if (del.empty() == false)
WriteOkay(Okay, output, "Remove:", del, "\n");
if (inst.empty() == false)
@@ -863,15 +874,8 @@ bool EIPP::WriteRequest(pkgDepCache &Cache, FileFd &output, /*{{{*/
continue;
req->append(" ").append(Pkg.FullName());
}
- bool Okay = WriteOkay(output, "Request: EIPP 0.1\n");
-
- std::vector<string> archs = APT::Configuration::getArchitectures();
- WriteOkay(Okay, output, "Architecture: ", _config->Find("APT::Architecture").c_str(), "\n",
- "Architectures:");
- for (std::vector<string>::const_iterator a = archs.begin(); a != archs.end(); ++a)
- WriteOkay(Okay, output, " ", *a);
- WriteOkay(Okay, output, "\n");
+ bool Okay = WriteGenericRequestHeaders(output, "Request: EIPP 0.1\n");
if (del.empty() == false)
WriteOkay(Okay, output, "Remove:", del, "\n");
if (inst.empty() == false)
@@ -934,7 +938,6 @@ bool EIPP::WriteScenario(pkgDepCache &Cache, FileFd &output, OpProgress * const
Progress->SubProgress(Cache.Head().PackageCount, _("Send scenario to planner"));
decltype(Cache.Head().PackageCount) p = 0;
bool Okay = output.Failed() == false;
- std::vector<std::string> archs = APT::Configuration::getArchitectures();
std::vector<bool> pkgset(Cache.Head().PackageCount, false);
auto const MarkVersion = [&](pkgCache::PkgIterator const &Pkg, pkgCache::VerIterator const &Ver) {
pkgset[Pkg->ID] = true;
diff --git a/apt-pkg/pkgcache.cc b/apt-pkg/pkgcache.cc
index cbde7c42f..68efcaddc 100644
--- a/apt-pkg/pkgcache.cc
+++ b/apt-pkg/pkgcache.cc
@@ -127,10 +127,7 @@ bool pkgCache::Header::CheckSizes(Header &Against) const
/* */
pkgCache::pkgCache(MMap *Map, bool DoMap) : Map(*Map), VS(nullptr), d(NULL)
{
- // call getArchitectures() with cached=false to ensure that the
- // architectures cache is re-evaluated. this is needed in cases
- // when the APT::Architecture field changes between two cache creations
- MultiArchEnabled = APT::Configuration::getArchitectures(false).size() > 1;
+ MultiArchEnabled = true;
if (DoMap == true)
ReMap();
}
diff --git a/apt-pkg/pkgcache.h b/apt-pkg/pkgcache.h
index 55baa3cef..0e8046ddc 100644
--- a/apt-pkg/pkgcache.h
+++ b/apt-pkg/pkgcache.h
@@ -268,7 +268,7 @@ class APT_PUBLIC pkgCache /*{{{*/
inline RlsFileIterator RlsFileBegin();
inline RlsFileIterator RlsFileEnd();
- inline bool MultiArchCache() const { return MultiArchEnabled; }
+ APT_DEPRECATED_MSG("Always true") inline bool MultiArchCache() const { return MultiArchEnabled; }
inline char const * NativeArch();
// Make me a function
diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc
index b4fd0641e..807f3bf6c 100644
--- a/apt-pkg/pkgcachegen.cc
+++ b/apt-pkg/pkgcachegen.cc
@@ -626,16 +626,16 @@ bool pkgCacheGenerator::NewPackage(pkgCache::PkgIterator &Pkg, StringView Name,
pkgCache::PkgIterator const M = Grp.FindPreferredPkg(false); // native or any foreign pkg will do
if (M.end() == false) {
pkgCache::PrvIterator Prv;
+ pkgCache::VerIterator Ver;
Dynamic<pkgCache::PrvIterator> DynPrv(Prv);
+ Dynamic<pkgCache::VerIterator> DynVer(Ver);
for (Prv = M.ProvidesList(); Prv.end() == false; ++Prv)
{
if ((Prv->Flags & pkgCache::Flag::ArchSpecific) != 0)
continue;
- pkgCache::VerIterator Ver = Prv.OwnerVer();
- Dynamic<pkgCache::VerIterator> DynVer(Ver);
- if ((Ver->MultiArch & pkgCache::Version::Allowed) == pkgCache::Version::Allowed ||
- ((Ver->MultiArch & pkgCache::Version::Foreign) == pkgCache::Version::Foreign &&
- (Prv->Flags & pkgCache::Flag::MultiArchImplicit) == 0))
+ Ver = Prv.OwnerVer();
+ if ((Ver->MultiArch & pkgCache::Version::Foreign) == pkgCache::Version::Foreign &&
+ (Prv->Flags & pkgCache::Flag::MultiArchImplicit) == 0)
{
if (APT::Configuration::checkArchitecture(Ver.ParentPkg().Arch()) == false)
continue;
diff --git a/apt-private/private-source.cc b/apt-private/private-source.cc
index def24bd27..db96cb17f 100644
--- a/apt-private/private-source.cc
+++ b/apt-private/private-source.cc
@@ -568,7 +568,7 @@ bool DoSource(CommandLine &CmdL)
/* This function will look at the build depends list of the given source
package and install the necessary packages to make it true, or fail. */
static std::vector<pkgSrcRecords::Parser::BuildDepRec> GetBuildDeps(pkgSrcRecords::Parser * const Last,
- char const * const Src, bool const StripMultiArch, std::string const &hostArch)
+ char const * const Src, std::string const &hostArch)
{
std::vector<pkgSrcRecords::Parser::BuildDepRec> BuildDeps;
// FIXME: Can't specify architecture to use for [wildcard] matching, so switch default arch temporary
@@ -576,7 +576,7 @@ static std::vector<pkgSrcRecords::Parser::BuildDepRec> GetBuildDeps(pkgSrcRecord
{
std::string nativeArch = _config->Find("APT::Architecture");
_config->Set("APT::Architecture", hostArch);
- bool Success = Last->BuildDepends(BuildDeps, _config->FindB("APT::Get::Arch-Only", false), StripMultiArch);
+ bool Success = Last->BuildDepends(BuildDeps, _config->FindB("APT::Get::Arch-Only", false), false);
_config->Set("APT::Architecture", nativeArch);
if (Success == false)
{
@@ -584,7 +584,7 @@ static std::vector<pkgSrcRecords::Parser::BuildDepRec> GetBuildDeps(pkgSrcRecord
return {};
}
}
- else if (Last->BuildDepends(BuildDeps, _config->FindB("APT::Get::Arch-Only", false), StripMultiArch) == false)
+ else if (Last->BuildDepends(BuildDeps, _config->FindB("APT::Get::Arch-Only", false), false) == false)
{
_error->Error(_("Unable to get build-dependency information for %s"), Src);
return {};
@@ -637,17 +637,16 @@ static void WriteBuildDependencyPackage(std::ostringstream &buildDepsPkgFile,
}
bool DoBuildDep(CommandLine &CmdL)
{
- bool StripMultiArch;
std::string hostArch = _config->Find("APT::Get::Host-Architecture");
- if (hostArch.empty() == false)
+ if (not hostArch.empty())
{
- std::vector<std::string> archs = APT::Configuration::getArchitectures();
- if (std::find(archs.begin(), archs.end(), hostArch) == archs.end())
- return _error->Error(_("No architecture information available for %s. See apt.conf(5) APT::Architectures for setup"), hostArch.c_str());
- StripMultiArch = false;
+ if (not APT::Configuration::checkArchitecture(hostArch))
+ {
+ auto const veryforeign = _config->FindVector("APT::BarbarianArchitectures");
+ if (std::find(veryforeign.begin(), veryforeign.end(), hostArch) == veryforeign.end())
+ _error->Warning(_("No architecture information available for %s. See apt.conf(5) APT::Architectures for setup"), hostArch.c_str());
+ }
}
- else
- StripMultiArch = true;
auto const nativeArch = _config->Find("APT::Architecture");
std::string const pseudoArch = hostArch.empty() ? nativeArch : hostArch;
@@ -777,7 +776,7 @@ bool DoBuildDep(CommandLine &CmdL)
auto pseudo = std::string("builddeps:") + pkg.name;
WriteBuildDependencyPackage(buildDepsPkgFile, pseudo, pseudoArch,
- GetBuildDeps(Last.get(), pkg.name.c_str(), StripMultiArch, hostArch));
+ GetBuildDeps(Last.get(), pkg.name.c_str(), hostArch));
pkg.name = std::move(pseudo);
pseudoPkgs.push_back(std::move(pkg));
}
@@ -802,7 +801,7 @@ bool DoBuildDep(CommandLine &CmdL)
std::string const pseudo = std::string("builddeps:") + Src;
WriteBuildDependencyPackage(buildDepsPkgFile, pseudo, pseudoArch,
- GetBuildDeps(Last, Src.c_str(), StripMultiArch, hostArch));
+ GetBuildDeps(Last, Src.c_str(), hostArch));
std::string reltag = *I;
size_t found = reltag.find_last_of("/");
if (found == std::string::npos)
diff --git a/doc/examples/configure-index b/doc/examples/configure-index
index 4eca100f5..f3f7f5ebc 100644
--- a/doc/examples/configure-index
+++ b/doc/examples/configure-index
@@ -49,6 +49,7 @@ APT
{
Architecture "<STRING>"; // debian architecture like amd64, i386, powerpc, armhf, mips, …
Architectures "<LIST>"; // a list of (foreign) debian architectures, defaults to: dpkg --print-foreign-architectures
+ BarbarianArchitectures "<LIST>"; // a list of architectures considered too foreign to satisfy M-A:foreign
Build-Essential "<LIST>"; // list of package names
Build-Profiles "<STRING_OR_LIST>";
diff --git a/test/integration/framework b/test/integration/framework
index 1f942d162..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
@@ -315,6 +317,16 @@ _removetmpworkingdirectory() {
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
@@ -347,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"}"
@@ -372,17 +406,15 @@ setupenvironment() {
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
@@ -499,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
@@ -529,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() {
@@ -1059,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
}
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-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/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();
+}