diff options
author | Julian Andres Klode <jak@debian.org> | 2021-10-18 13:36:00 +0000 |
---|---|---|
committer | Julian Andres Klode <jak@debian.org> | 2021-10-18 13:36:00 +0000 |
commit | edf4b2169405e7ca6e21f408229e5fc4bbd4f4ed (patch) | |
tree | 864a13dbda22e3b4de7b69600521fb7e7d8b39a2 | |
parent | 883a12310a4130370965eab0a710a2c8fae6cc09 (diff) | |
parent | 70c669e2566d119559d2986635bb6c1d0d368073 (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.cc | 22 | ||||
-rw-r--r-- | apt-pkg/deb/deblistparser.cc | 17 | ||||
-rw-r--r-- | apt-pkg/deb/debmetaindex.cc | 20 | ||||
-rw-r--r-- | apt-pkg/edsp.cc | 43 | ||||
-rw-r--r-- | apt-pkg/pkgcache.cc | 5 | ||||
-rw-r--r-- | apt-pkg/pkgcache.h | 2 | ||||
-rw-r--r-- | apt-pkg/pkgcachegen.cc | 10 | ||||
-rw-r--r-- | apt-private/private-source.cc | 25 | ||||
-rw-r--r-- | doc/examples/configure-index | 1 | ||||
-rw-r--r-- | test/integration/framework | 77 | ||||
-rwxr-xr-x | test/integration/test-apt-get-build-dep-barbarian | 140 | ||||
-rwxr-xr-x | test/integration/test-apt-get-build-dep-file | 14 | ||||
-rwxr-xr-x | test/integration/test-bug-632221-cross-dependency-satisfaction | 35 | ||||
-rwxr-xr-x | test/integration/test-multiarch-allowed | 51 | ||||
-rwxr-xr-x | test/integration/test-multiarch-barbarian | 243 | ||||
-rwxr-xr-x | test/integration/test-prevent-markinstall-multiarch-same-versionscrew | 3 | ||||
-rw-r--r-- | test/libapt/getarchitectures_test.cc | 28 |
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(); +} |