diff options
-rw-r--r-- | apt-pkg/aptconfiguration.cc | 2 | ||||
-rw-r--r-- | apt-pkg/deb/deblistparser.cc | 9 | ||||
-rw-r--r-- | cmdline/apt-get.cc | 302 | ||||
-rwxr-xr-x | cmdline/apt-key | 2 | ||||
-rw-r--r-- | debian/changelog | 13 | ||||
-rw-r--r-- | doc/apt-get.8.xml | 27 | ||||
-rw-r--r-- | doc/examples/configure-index | 1 | ||||
-rw-r--r-- | test/integration/framework | 22 | ||||
-rwxr-xr-x | test/integration/test-bug-632221-cross-dependency-satisfaction | 183 | ||||
-rw-r--r-- | test/libapt/assert.h | 42 | ||||
-rw-r--r-- | test/libapt/getarchitectures_test.cc | 6 | ||||
-rw-r--r-- | test/libapt/getlanguages_test.cc | 4 |
12 files changed, 496 insertions, 117 deletions
diff --git a/apt-pkg/aptconfiguration.cc b/apt-pkg/aptconfiguration.cc index e8c8e73d0..9ccbeecf1 100644 --- a/apt-pkg/aptconfiguration.cc +++ b/apt-pkg/aptconfiguration.cc @@ -352,7 +352,7 @@ std::vector<std::string> const Configuration::getArchitectures(bool const &Cache if (archs.empty() == true || std::find(archs.begin(), archs.end(), arch) == archs.end()) - archs.push_back(arch); + archs.insert(archs.begin(), arch); // erase duplicates and empty strings for (std::vector<string>::reverse_iterator a = archs.rbegin(); diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index 9ae1065a4..651fa2a81 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -461,7 +461,7 @@ const char *debListParser::ConvertRelation(const char *I,unsigned int &Op) * * The complete architecture, consisting of <kernel>-<cpu>. */ -static string CompleteArch(std::string& arch) { +static string CompleteArch(std::string const &arch) { if (arch == "armel") return "linux-arm"; if (arch == "armhf") return "linux-arm"; if (arch == "lpia") return "linux-i386"; @@ -500,9 +500,13 @@ const char *debListParser::ParseDepends(const char *Start,const char *Stop, Package.assign(Start,I - Start); // We don't want to confuse library users which can't handle MultiArch + string const arch = _config->Find("APT::Architecture"); if (StripMultiArch == true) { size_t const found = Package.rfind(':'); - if (found != string::npos) + if (found != string::npos && + (strcmp(Package.c_str() + found, ":any") == 0 || + strcmp(Package.c_str() + found, ":native") == 0 || + strcmp(Package.c_str() + found + 1, arch.c_str()) == 0)) Package = Package.substr(0,found); } @@ -543,7 +547,6 @@ const char *debListParser::ParseDepends(const char *Start,const char *Stop, if (ParseArchFlags == true) { - string arch = _config->Find("APT::Architecture"); string completeArch = CompleteArch(arch); // Parse an architecture diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index 1e7fee96b..9de341df0 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -1388,6 +1388,14 @@ bool TryToInstallBuildDep(pkgCache::PkgIterator Pkg,pkgCacheFile &Cache, return AllowFail; } + if (_config->FindB("Debug::BuildDeps",false) == true) + { + if (Remove == true) + cout << " Trying to remove " << Pkg << endl; + else + cout << " Trying to install " << Pkg << endl; + } + if (Remove == true) { TryToRemove RemoveAction(Cache, &Fix); @@ -2612,12 +2620,17 @@ bool DoSource(CommandLine &CmdL) // Try to compile it with dpkg-buildpackage if (_config->FindB("APT::Get::Compile",false) == true) { + string buildopts = _config->Find("APT::Get::Host-Architecture"); + if (buildopts.empty() == false) + buildopts = "-a " + buildopts + " "; + buildopts.append(_config->Find("DPkg::Build-Options","-b -uc")); + // Call dpkg-buildpackage char S[500]; snprintf(S,sizeof(S),"cd %s && %s %s", Dir.c_str(), _config->Find("Dir::Bin::dpkg-buildpackage","dpkg-buildpackage").c_str(), - _config->Find("DPkg::Build-Options","-b -uc").c_str()); + buildopts.c_str()); if (system(S) != 0) { @@ -2679,8 +2692,19 @@ bool DoBuildDep(CommandLine &CmdL) if (Fetcher.Setup(&Stat) == false) return false; + bool StripMultiArch; + string hostArch = _config->Find("APT::Get::Host-Architecture"); + if (hostArch.empty() == false) + { + 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; + } + else + StripMultiArch = true; + unsigned J = 0; - bool const StripMultiArch = APT::Configuration::getArchitectures().size() <= 1; for (const char **I = CmdL.FileList + 1; *I != 0; I++, J++) { string Src; @@ -2714,7 +2738,7 @@ bool DoBuildDep(CommandLine &CmdL) ioprintf(c1out,_("%s has no build depends.\n"),Src.c_str()); continue; } - + // Install the requested packages vector <pkgSrcRecords::Parser::BuildDepRec>::iterator D; pkgProblemResolver Fix(Cache); @@ -2725,6 +2749,16 @@ bool DoBuildDep(CommandLine &CmdL) if (skipAlternatives == true) { + /* + * if there are alternatives, we've already picked one, so skip + * the rest + * + * TODO: this means that if there's a build-dep on A|B and B is + * installed, we'll still try to install A; more importantly, + * if A is currently broken, we cannot go back and try B. To fix + * this would require we do a Resolve cycle for each package we + * add to the install list. Ugh + */ if (!hasAlternatives) skipAlternatives = false; // end of or group continue; @@ -2733,27 +2767,117 @@ bool DoBuildDep(CommandLine &CmdL) if ((*D).Type == pkgSrcRecords::Parser::BuildConflict || (*D).Type == pkgSrcRecords::Parser::BuildConflictIndep) { - pkgCache::PkgIterator Pkg = Cache->FindPkg((*D).Package); + pkgCache::GrpIterator Grp = Cache->FindGrp((*D).Package); // Build-conflicts on unknown packages are silently ignored - if (Pkg.end() == true) + if (Grp.end() == true) continue; - pkgCache::VerIterator IV = (*Cache)[Pkg].InstVerIter(*Cache); - - /* - * Remove if we have an installed version that satisfies the - * version criteria - */ - if (IV.end() == false && - Cache->VS().CheckDep(IV.VerStr(),(*D).Op,(*D).Version.c_str()) == true) - TryToInstallBuildDep(Pkg,Cache,Fix,true,false); + for (pkgCache::PkgIterator Pkg = Grp.PackageList(); Pkg.end() == false; Pkg = Grp.NextPkg(Pkg)) + { + pkgCache::VerIterator IV = (*Cache)[Pkg].InstVerIter(*Cache); + /* + * Remove if we have an installed version that satisfies the + * version criteria + */ + if (IV.end() == false && + Cache->VS().CheckDep(IV.VerStr(),(*D).Op,(*D).Version.c_str()) == true) + TryToInstallBuildDep(Pkg,Cache,Fix,true,false); + } } else // BuildDep || BuildDepIndep { - pkgCache::PkgIterator Pkg = Cache->FindPkg((*D).Package); if (_config->FindB("Debug::BuildDeps",false) == true) cout << "Looking for " << (*D).Package << "...\n"; + pkgCache::PkgIterator Pkg; + + // Cross-Building? + if (StripMultiArch == false) + { + size_t const colon = D->Package.find(":"); + if (colon != string::npos && + (strcmp(D->Package.c_str() + colon, ":any") == 0 || strcmp(D->Package.c_str() + colon, ":native") == 0)) + Pkg = Cache->FindPkg(D->Package.substr(0,colon)); + else + Pkg = Cache->FindPkg(D->Package); + + // We need to decide if host or build arch, so find a version we can look at + pkgCache::VerIterator Ver; + + // a bad version either is invalid or doesn't satify dependency + #define BADVER(Ver) Ver.end() == true || \ + (Ver.end() == false && D->Version.empty() == false && \ + Cache->VS().CheckDep(Ver.VerStr(),D->Op,D->Version.c_str()) == false) + + if (Pkg.end() == false) + { + Ver = (*Cache)[Pkg].InstVerIter(*Cache); + if (BADVER(Ver)) + Ver = (*Cache)[Pkg].CandidateVerIter(*Cache); + } + if (BADVER(Ver)) + { + pkgCache::PkgIterator HostPkg = Cache->FindPkg(D->Package, hostArch); + if (HostPkg.end() == false) + { + Ver = (*Cache)[HostPkg].InstVerIter(*Cache); + if (BADVER(Ver)) + Ver = (*Cache)[HostPkg].CandidateVerIter(*Cache); + } + } + if ((BADVER(Ver)) == false) + { + string forbidden; + if (Ver->MultiArch == pkgCache::Version::None || Ver->MultiArch == pkgCache::Version::All); + else if (Ver->MultiArch == pkgCache::Version::Same) + { + if (colon != string::npos) + Pkg = Ver.ParentPkg().Group().FindPkg(hostArch); + else if (strcmp(D->Package.c_str() + colon, ":any") == 0) + forbidden = "Multi-Arch: same"; + // :native gets the buildArch + } + else if (Ver->MultiArch == pkgCache::Version::Foreign || Ver->MultiArch == pkgCache::Version::AllForeign) + { + if (colon != string::npos) + forbidden = "Multi-Arch: foreign"; + } + else if (Ver->MultiArch == pkgCache::Version::Allowed || Ver->MultiArch == pkgCache::Version::AllAllowed) + { + if (colon == string::npos) + Pkg = Ver.ParentPkg().Group().FindPkg(hostArch); + else if (strcmp(D->Package.c_str() + colon, ":any") == 0) + { + // prefer any installed over preferred non-installed architectures + pkgCache::GrpIterator Grp = Ver.ParentPkg().Group(); + // we don't check for version here as we are better of with upgrading than remove and install + for (Pkg = Grp.PackageList(); Pkg.end() == false; Pkg = Grp.NextPkg(Pkg)) + if (Pkg.CurrentVer().end() == false) + break; + if (Pkg.end() == true) + Pkg = Grp.FindPreferredPkg(true); + } + // native gets buildArch + } + if (forbidden.empty() == false) + { + if (_config->FindB("Debug::BuildDeps",false) == true) + cout << " :any is not allowed from M-A: same package " << (*D).Package << endl; + if (hasAlternatives) + continue; + return _error->Error(_("%s dependency for %s can't be satisfied " + "because %s is not allowed on '%s' packages"), + Last->BuildDepType(D->Type), Src.c_str(), + D->Package.c_str(), "Multi-Arch: same"); + } + } + else if (_config->FindB("Debug::BuildDeps",false) == true) + cout << " No multiarch info as we have no satisfying installed nor candidate for " << D->Package << " on build or host arch" << endl; + #undef BADVER + } + else + Pkg = Cache->FindPkg(D->Package); + if (Pkg.end() == true) { if (_config->FindB("Debug::BuildDeps",false) == true) @@ -2768,99 +2892,74 @@ bool DoBuildDep(CommandLine &CmdL) (*D).Package.c_str()); } - /* - * if there are alternatives, we've already picked one, so skip - * the rest - * - * TODO: this means that if there's a build-dep on A|B and B is - * installed, we'll still try to install A; more importantly, - * if A is currently broken, we cannot go back and try B. To fix - * this would require we do a Resolve cycle for each package we - * add to the install list. Ugh - */ - - /* - * If this is a virtual package, we need to check the list of - * packages that provide it and see if any of those are - * installed - */ - pkgCache::PrvIterator Prv = Pkg.ProvidesList(); - for (; Prv.end() != true; Prv++) - { - if (_config->FindB("Debug::BuildDeps",false) == true) - cout << " Checking provider " << Prv.OwnerPkg().FullName() << endl; - - if ((*Cache)[Prv.OwnerPkg()].InstVerIter(*Cache).end() == false) - break; - } - - // Get installed version and version we are going to install pkgCache::VerIterator IV = (*Cache)[Pkg].InstVerIter(*Cache); + if (IV.end() == false) + { + if (_config->FindB("Debug::BuildDeps",false) == true) + cout << " Is installed\n"; - if ((*D).Version[0] != '\0') { - // Versioned dependency - - pkgCache::VerIterator CV = (*Cache)[Pkg].CandidateVerIter(*Cache); - - for (; CV.end() != true; CV++) - { - if (Cache->VS().CheckDep(CV.VerStr(),(*D).Op,(*D).Version.c_str()) == true) - break; - } - if (CV.end() == true) - { - if (hasAlternatives) - { - continue; - } - else - { - return _error->Error(_("%s dependency for %s cannot be satisfied " - "because no available versions of package %s " - "can satisfy version requirements"), - Last->BuildDepType((*D).Type),Src.c_str(), - (*D).Package.c_str()); - } - } - } - else - { - // Only consider virtual packages if there is no versioned dependency - if (Prv.end() == false) - { - if (_config->FindB("Debug::BuildDeps",false) == true) - cout << " Is provided by installed package " << Prv.OwnerPkg().FullName() << endl; - skipAlternatives = hasAlternatives; - continue; - } - } + if (D->Version.empty() == true || + Cache->VS().CheckDep(IV.VerStr(),(*D).Op,(*D).Version.c_str()) == true) + { + skipAlternatives = hasAlternatives; + continue; + } - if (IV.end() == false) - { - if (_config->FindB("Debug::BuildDeps",false) == true) - cout << " Is installed\n"; + if (_config->FindB("Debug::BuildDeps",false) == true) + cout << " ...but the installed version doesn't meet the version requirement\n"; - if (Cache->VS().CheckDep(IV.VerStr(),(*D).Op,(*D).Version.c_str()) == true) - { - skipAlternatives = hasAlternatives; - continue; - } + if (((*D).Op & pkgCache::Dep::LessEq) == pkgCache::Dep::LessEq) + return _error->Error(_("Failed to satisfy %s dependency for %s: Installed package %s is too new"), + Last->BuildDepType((*D).Type), Src.c_str(), Pkg.FullName(true).c_str()); + } - if (_config->FindB("Debug::BuildDeps",false) == true) - cout << " ...but the installed version doesn't meet the version requirement\n"; - - if (((*D).Op & pkgCache::Dep::LessEq) == pkgCache::Dep::LessEq) - { - return _error->Error(_("Failed to satisfy %s dependency for %s: Installed package %s is too new"), - Last->BuildDepType((*D).Type), - Src.c_str(), - Pkg.FullName(true).c_str()); - } - } + // Only consider virtual packages if there is no versioned dependency + if ((*D).Version.empty() == true) + { + /* + * If this is a virtual package, we need to check the list of + * packages that provide it and see if any of those are + * installed + */ + pkgCache::PrvIterator Prv = Pkg.ProvidesList(); + for (; Prv.end() != true; Prv++) + { + if (_config->FindB("Debug::BuildDeps",false) == true) + cout << " Checking provider " << Prv.OwnerPkg().FullName() << endl; + if ((*Cache)[Prv.OwnerPkg()].InstVerIter(*Cache).end() == false) + break; + } - if (_config->FindB("Debug::BuildDeps",false) == true) - cout << " Trying to install " << (*D).Package << endl; + if (Prv.end() == false) + { + if (_config->FindB("Debug::BuildDeps",false) == true) + cout << " Is provided by installed package " << Prv.OwnerPkg().FullName() << endl; + skipAlternatives = hasAlternatives; + continue; + } + } + else // versioned dependency + { + pkgCache::VerIterator CV = (*Cache)[Pkg].CandidateVerIter(*Cache); + if (CV.end() == true || + Cache->VS().CheckDep(CV.VerStr(),(*D).Op,(*D).Version.c_str()) == false) + { + if (hasAlternatives) + continue; + else if (CV.end() == false) + return _error->Error(_("%s dependency for %s cannot be satisfied " + "because candidate version of package %s " + "can't satisfy version requirements"), + Last->BuildDepType(D->Type), Src.c_str(), + D->Package.c_str()); + else + return _error->Error(_("%s dependency for %s cannot be satisfied " + "because package %s has no candidate version"), + Last->BuildDepType(D->Type), Src.c_str(), + D->Package.c_str()); + } + } if (TryToInstallBuildDep(Pkg,Cache,Fix,false,false) == true) { @@ -3246,6 +3345,7 @@ int main(int argc,const char *argv[]) /*{{{*/ {'m',"ignore-missing","APT::Get::Fix-Missing",0}, {'t',"target-release","APT::Default-Release",CommandLine::HasArg}, {'t',"default-release","APT::Default-Release",CommandLine::HasArg}, + {'a',"host-architecture","APT::Get::Host-Architecture",CommandLine::HasArg}, {0,"download","APT::Get::Download",0}, {0,"fix-missing","APT::Get::Fix-Missing",0}, {0,"ignore-hold","APT::Ignore-Hold",0}, diff --git a/cmdline/apt-key b/cmdline/apt-key index 8a995dadd..e632be706 100755 --- a/cmdline/apt-key +++ b/cmdline/apt-key @@ -7,7 +7,7 @@ unset GREP_OPTIONS # implodes if there isn't one available SECRETKEYRING="$(mktemp)" trap "rm -f '${SECRETKEYRING}'" 0 HUP INT QUIT ILL ABRT FPE SEGV PIPE TERM -GPG_CMD="gpg --ignore-time-conflict --no-options --no-default-keyring --secret-keyring '${SECRETKEYRING}'" +GPG_CMD="gpg --ignore-time-conflict --no-options --no-default-keyring --secret-keyring ${SECRETKEYRING}" if [ "$(id -u)" -eq 0 ]; then # we could use a tmpfile here too, but creation of this tends to be time-consuming diff --git a/debian/changelog b/debian/changelog index 1ceeebfc5..18b59ec4e 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,4 +1,4 @@ -apt (0.8.15.3) UNRELEASED; urgency=low +apt (0.8.15.3) unstable; urgency=low [ Michael Vogt ] * apt-pkg/acquire-item.cc: @@ -20,6 +20,8 @@ apt (0.8.15.3) UNRELEASED; urgency=low * cmdline/apt-get.cc: - restore all important dependencies for garbage packages (LP: #806274) - do not require unused partial dirs in 'source' (Closes: #633510) + - buildconflicts effect all architectures + - implement MultiarchCross for build-dep and source (Closes: #632221) * apt-pkg/init.cc: - use CndSet in pkgInitConfig (Closes: #629617) * apt-pkg/depcache.cc: @@ -32,8 +34,15 @@ apt (0.8.15.3) UNRELEASED; urgency=low - apply madison typofix from John Feuerstein, thanks! (Closes: #633455) * apt-pkg/policy.cc: - emit an error on unknown APT::Default-Release value (Closes: #407511) + * apt-pkg/aptconfiguration.cc: + - ensure that native architecture is if not specified otherwise the + first architecture in the Architectures vector + * apt-pkg/deb/deblistparser.cc: + - Strip only :any and :native if MultiArch should be stripped as it is + save to ignore them in non-MultiArch contexts but if the dependency + is a specific architecture (and not the native) do not strip - -- David Kalnischkies <kalnischkies@gmail.com> Sat, 16 Jul 2011 16:43:37 +0200 + -- Michael Vogt <mvo@debian.org> Mon, 25 Jul 2011 15:04:43 +0200 apt (0.8.15.2) unstable; urgency=high diff --git a/doc/apt-get.8.xml b/doc/apt-get.8.xml index 11b53e5e7..9d901b492 100644 --- a/doc/apt-get.8.xml +++ b/doc/apt-get.8.xml @@ -54,6 +54,13 @@ <replaceable>target_release</replaceable> </arg> </arg> + <arg> + <option>-a=</option> + <arg choice='plain'> + <replaceable>default_architecture</replaceable> + </arg> + </arg> + <group choice="req"> <arg choice='plain'>update</arg> @@ -254,8 +261,10 @@ <para>If the <option>--compile</option> option is specified then the package will be compiled to a binary .deb using - <command>dpkg-buildpackage</command>, if <option>--download-only</option> - is specified then the source package will not be unpacked.</para> + <command>dpkg-buildpackage</command> for the architecture as + defined by the <command>--host-architecture</command> option. + If <option>--download-only</option> is specified then the source package + will not be unpacked.</para> <para>A specific source version can be retrieved by postfixing the source name with an equals and then the version to fetch, similar to the mechanism @@ -270,7 +279,9 @@ <varlistentry><term>build-dep</term> <listitem><para><literal>build-dep</literal> causes apt-get to install/remove packages in an - attempt to satisfy the build dependencies for a source package.</para></listitem> + attempt to satisfy the build dependencies for a source package. By default the dependencies are + satisfied to build the package nativly. If desired a host-architecture can be specified + with the <option>--host-architecture</option> option instead.</para></listitem> </varlistentry> <varlistentry><term>check</term> @@ -433,6 +444,16 @@ Configuration Item: <literal>APT::Get::Show-Versions</literal>.</para></listitem> </varlistentry> + <varlistentry><term><option>-a</option></term> + <term><option>--host-architecture</option></term> + <listitem><para>This option controls the architecture packages are built for + by <command>apt-get source --compile</command> and how cross-builddependencies + are satisfied. By default is not set which means that the host architecture + is the same as the build architecture (which is defined by <literal>APT::Architecture</literal>) + Configuration Item: <literal>APT::Get::Host-Architecture</literal> + </para></listitem> + </varlistentry> + <varlistentry><term><option>-b</option></term><term><option>--compile</option></term> <term><option>--build</option></term> <listitem><para>Compile source packages after downloading them. diff --git a/doc/examples/configure-index b/doc/examples/configure-index index 27232d40b..49e803f91 100644 --- a/doc/examples/configure-index +++ b/doc/examples/configure-index @@ -32,6 +32,7 @@ APT // Options for apt-get Get { + Host-Architecture "armel"; Arch-Only "false"; AllowUnauthenticated "false"; AutomaticRemove "false"; diff --git a/test/integration/framework b/test/integration/framework index 702e352a3..fa451cf4f 100644 --- a/test/integration/framework +++ b/test/integration/framework @@ -151,6 +151,7 @@ setupenvironment() { configarchitecture() { local CONFFILE=rootdir/etc/apt/apt.conf.d/01multiarch.conf + rm -f $CONFFILE echo "APT::Architecture \"$1\";" > $CONFFILE shift while [ -n "$1" ]; do @@ -429,6 +430,27 @@ Filename: pool/main/${NAME}/${NAME}_${VERSION}_${arch}.deb" >> $FILE done } +insertsource() { + local RELEASE="$1" + local NAME="$2" + local ARCH="$3" + local VERSION="$4" + local DEPENDENCIES="$5" + local ARCHS="" + local SPATH="aptarchive/dists/${RELEASE}/main/source" + mkdir -p $SPATH + local FILE="${SPATH}/Sources" + echo "Package: $NAME +Binary: $NAME +Version: $VERSION +Maintainer: Joe Sixpack <joe@example.org> +Architecture: $ARCH" >> $FILE + test -z "$DEPENDENCIES" || echo "$DEPENDENCIES" >> $FILE + echo "Files: + d41d8cd98f00b204e9800998ecf8427e 0 ${NAME}_${VERSION}.dsc + d41d8cd98f00b204e9800998ecf8427e 0 ${NAME}_${VERSION}.tar.gz" >> $FILE +} + insertinstalledpackage() { local NAME="$1" local ARCH="$2" diff --git a/test/integration/test-bug-632221-cross-dependency-satisfaction b/test/integration/test-bug-632221-cross-dependency-satisfaction new file mode 100755 index 000000000..58de44843 --- /dev/null +++ b/test/integration/test-bug-632221-cross-dependency-satisfaction @@ -0,0 +1,183 @@ +#!/bin/sh +set -e + +TESTDIR=$(readlink -f $(dirname $0)) +. $TESTDIR/framework +setupenvironment +configarchitecture 'amd64' 'armel' + +insertinstalledpackage 'build-essential' 'all' '11.5' + +insertpackage 'unstable' 'doxygen' 'amd64,armel' '1.0' +insertpackage 'unstable' 'libc6' 'amd64,armel' '1.0' 'Multi-Arch: same' +insertpackage 'unstable' 'libc6-dev' 'amd64,armel' '1.0' 'Depends: libc6 +Multi-Arch: same' +insertpackage 'unstable' 'cool' 'amd64,armel' '1.0' 'Multi-Arch: allowed' +insertpackage 'unstable' 'amdboot' 'amd64' '1.0' +insertpackage 'unstable' 'foreigner' 'amd64,armel' '1.0' 'Multi-Arch: foreign' + +insertsource 'unstable' 'apt' 'any' '0.8.15' 'Build-Depends: doxygen, libc6-dev, libc6-dev:native, cool:any, amdboot:amd64, foreigner' + +setupaptarchive + +testequal 'Reading package lists... +Building dependency tree... +The following NEW packages will be installed: + amdboot cool doxygen foreigner libc6 libc6-dev +0 upgraded, 6 newly installed, 0 to remove and 0 not upgraded. +Inst amdboot (1.0 unstable [amd64]) +Inst cool (1.0 unstable [amd64]) +Inst doxygen (1.0 unstable [amd64]) +Inst foreigner (1.0 unstable [amd64]) +Inst libc6 (1.0 unstable [amd64]) +Inst libc6-dev (1.0 unstable [amd64]) +Conf amdboot (1.0 unstable [amd64]) +Conf cool (1.0 unstable [amd64]) +Conf doxygen (1.0 unstable [amd64]) +Conf foreigner (1.0 unstable [amd64]) +Conf libc6 (1.0 unstable [amd64]) +Conf libc6-dev (1.0 unstable [amd64])' aptget build-dep apt -s + +testequal 'Reading package lists... +Building dependency tree... +The following NEW packages will be installed: + amdboot cool doxygen foreigner libc6 libc6:armel libc6-dev libc6-dev:armel +0 upgraded, 8 newly installed, 0 to remove and 0 not upgraded. +Inst amdboot (1.0 unstable [amd64]) +Inst cool (1.0 unstable [amd64]) +Inst doxygen (1.0 unstable [amd64]) +Inst foreigner (1.0 unstable [amd64]) +Inst libc6:armel (1.0 unstable [armel]) +Inst libc6 (1.0 unstable [amd64]) +Inst libc6-dev:armel (1.0 unstable [armel]) +Inst libc6-dev (1.0 unstable [amd64]) +Conf amdboot (1.0 unstable [amd64]) +Conf cool (1.0 unstable [amd64]) +Conf doxygen (1.0 unstable [amd64]) +Conf foreigner (1.0 unstable [amd64]) +Conf libc6 (1.0 unstable [amd64]) +Conf libc6:armel (1.0 unstable [armel]) +Conf libc6-dev (1.0 unstable [amd64]) +Conf libc6-dev:armel (1.0 unstable [armel])' aptget build-dep apt -s -a armel + +configarchitecture 'armel' 'amd64' + +testequal 'Reading package lists... +Building dependency tree... +The following NEW packages will be installed: + amdboot:amd64 cool doxygen foreigner libc6 libc6-dev +0 upgraded, 6 newly installed, 0 to remove and 0 not upgraded. +Inst amdboot:amd64 (1.0 unstable [amd64]) +Inst cool (1.0 unstable [armel]) +Inst doxygen (1.0 unstable [armel]) +Inst foreigner (1.0 unstable [armel]) +Inst libc6 (1.0 unstable [armel]) +Inst libc6-dev (1.0 unstable [armel]) +Conf amdboot:amd64 (1.0 unstable [amd64]) +Conf cool (1.0 unstable [armel]) +Conf doxygen (1.0 unstable [armel]) +Conf foreigner (1.0 unstable [armel]) +Conf libc6 (1.0 unstable [armel]) +Conf libc6-dev (1.0 unstable [armel])' aptget build-dep apt -s + +testequal 'Reading package lists... +Building dependency tree... +The following NEW packages will be installed: + amdboot:amd64 cool doxygen foreigner libc6:amd64 libc6 libc6-dev:amd64 + libc6-dev +0 upgraded, 8 newly installed, 0 to remove and 0 not upgraded. +Inst amdboot:amd64 (1.0 unstable [amd64]) +Inst cool (1.0 unstable [armel]) +Inst doxygen (1.0 unstable [armel]) +Inst foreigner (1.0 unstable [armel]) +Inst libc6 (1.0 unstable [armel]) +Inst libc6:amd64 (1.0 unstable [amd64]) +Inst libc6-dev (1.0 unstable [armel]) +Inst libc6-dev:amd64 (1.0 unstable [amd64]) +Conf amdboot:amd64 (1.0 unstable [amd64]) +Conf cool (1.0 unstable [armel]) +Conf doxygen (1.0 unstable [armel]) +Conf foreigner (1.0 unstable [armel]) +Conf libc6:amd64 (1.0 unstable [amd64]) +Conf libc6 (1.0 unstable [armel]) +Conf libc6-dev:amd64 (1.0 unstable [amd64]) +Conf libc6-dev (1.0 unstable [armel])' aptget build-dep apt -s -a amd64 + +configarchitecture 'amd64' 'armel' + +insertinstalledpackage 'cool' 'amd64' '0.5' +insertinstalledpackage 'foreigner' 'armel' '0.5' + +testequal 'Reading package lists... +Building dependency tree... +The following NEW packages will be installed: + amdboot doxygen libc6 libc6-dev +0 upgraded, 4 newly installed, 0 to remove and 2 not upgraded. +Inst amdboot (1.0 unstable [amd64]) +Inst doxygen (1.0 unstable [amd64]) +Inst libc6 (1.0 unstable [amd64]) +Inst libc6-dev (1.0 unstable [amd64]) +Conf amdboot (1.0 unstable [amd64]) +Conf doxygen (1.0 unstable [amd64]) +Conf libc6 (1.0 unstable [amd64]) +Conf libc6-dev (1.0 unstable [amd64])' aptget build-dep apt -s + +testequal 'Reading package lists... +Building dependency tree... +The following NEW packages will be installed: + amdboot doxygen libc6 libc6:armel libc6-dev libc6-dev:armel +0 upgraded, 6 newly installed, 0 to remove and 2 not upgraded. +Inst amdboot (1.0 unstable [amd64]) +Inst doxygen (1.0 unstable [amd64]) +Inst libc6:armel (1.0 unstable [armel]) +Inst libc6 (1.0 unstable [amd64]) +Inst libc6-dev:armel (1.0 unstable [armel]) +Inst libc6-dev (1.0 unstable [amd64]) +Conf amdboot (1.0 unstable [amd64]) +Conf doxygen (1.0 unstable [amd64]) +Conf libc6 (1.0 unstable [amd64]) +Conf libc6:armel (1.0 unstable [armel]) +Conf libc6-dev (1.0 unstable [amd64]) +Conf libc6-dev:armel (1.0 unstable [armel])' aptget build-dep apt -s -a armel + +configarchitecture 'armel' 'amd64' + +# cool 0.5 is not M-A: allowed, so amd64 is not acceptable +testequal 'Reading package lists... +Building dependency tree... +The following packages will be REMOVED: + cool:amd64 +The following NEW packages will be installed: + amdboot:amd64 cool doxygen libc6 libc6-dev +0 upgraded, 5 newly installed, 1 to remove and 1 not upgraded. +Remv cool:amd64 [0.5] +Inst amdboot:amd64 (1.0 unstable [amd64]) +Inst cool (1.0 unstable [armel]) +Inst doxygen (1.0 unstable [armel]) +Inst libc6 (1.0 unstable [armel]) +Inst libc6-dev (1.0 unstable [armel]) +Conf amdboot:amd64 (1.0 unstable [amd64]) +Conf cool (1.0 unstable [armel]) +Conf doxygen (1.0 unstable [armel]) +Conf libc6 (1.0 unstable [armel]) +Conf libc6-dev (1.0 unstable [armel])' aptget build-dep apt -s + +testequal 'Reading package lists... +Building dependency tree... +The following NEW packages will be installed: + amdboot:amd64 doxygen libc6:amd64 libc6 libc6-dev:amd64 libc6-dev +0 upgraded, 6 newly installed, 0 to remove and 2 not upgraded. +Inst amdboot:amd64 (1.0 unstable [amd64]) +Inst doxygen (1.0 unstable [armel]) +Inst libc6 (1.0 unstable [armel]) +Inst libc6:amd64 (1.0 unstable [amd64]) +Inst libc6-dev (1.0 unstable [armel]) +Inst libc6-dev:amd64 (1.0 unstable [amd64]) +Conf amdboot:amd64 (1.0 unstable [amd64]) +Conf doxygen (1.0 unstable [armel]) +Conf libc6:amd64 (1.0 unstable [amd64]) +Conf libc6 (1.0 unstable [armel]) +Conf libc6-dev:amd64 (1.0 unstable [amd64]) +Conf libc6-dev (1.0 unstable [armel])' aptget build-dep apt -s -a amd64 + + diff --git a/test/libapt/assert.h b/test/libapt/assert.h index 5da76ae0a..92b662dfa 100644 --- a/test/libapt/assert.h +++ b/test/libapt/assert.h @@ -1,9 +1,9 @@ #include <iostream> -#define equals(x,y) assertEquals(x, y, __LINE__) +#define equals(x,y) assertEquals(y, x, __LINE__) template < typename X, typename Y > -void OutputAssert(X expect, char const* compare, Y get, unsigned long const &line) { +void OutputAssertEqual(X expect, char const* compare, Y get, unsigned long const &line) { std::cerr << "Test FAILED: »" << expect << "« " << compare << " »" << get << "« at line " << line << std::endl; } @@ -11,11 +11,45 @@ template < typename X, typename Y > void assertEquals(X expect, Y get, unsigned long const &line) { if (expect == get) return; - OutputAssert(expect, "==", get, line); + OutputAssertEqual(expect, "==", get, line); } void assertEquals(unsigned int const &expect, int const &get, unsigned long const &line) { if (get < 0) - OutputAssert(expect, "==", get, line); + OutputAssertEqual(expect, "==", get, line); assertEquals<unsigned int const&, unsigned int const&>(expect, get, line); } + +void assertEquals(int const &expect, unsigned int const &get, unsigned long const &line) { + if (expect < 0) + OutputAssertEqual(expect, "==", get, line); + assertEquals<unsigned int const&, unsigned int const&>(expect, get, line); +} + + +#define equalsOr2(x,y,z) assertEqualsOr2(y, z, x, __LINE__) + +template < typename X, typename Y > +void OutputAssertEqualOr2(X expect1, X expect2, char const* compare, Y get, unsigned long const &line) { + std::cerr << "Test FAILED: »" << expect1 << "« or »" << expect2 << "« " << compare << " »" << get << "« at line " << line << std::endl; +} + +template < typename X, typename Y > +void assertEqualsOr2(X expect1, X expect2, Y get, unsigned long const &line) { + if (expect1 == get || expect2 == get) + return; + OutputAssertEqualOr2(expect1, expect2, "==", get, line); +} + +void assertEqualsOr2(unsigned int const &expect1, unsigned int const &expect2, int const &get, unsigned long const &line) { + if (get < 0) + OutputAssertEqualOr2(expect1, expect2, "==", get, line); + assertEqualsOr2<unsigned int const&, unsigned int const&>(expect1, expect2, get, line); +} + +void assertEqualsOr2(int const &expect1, int const &expect2, unsigned int const &get, unsigned long const &line) { + if (expect1 < 0 && expect2 < 0) + OutputAssertEqualOr2(expect1, expect2, "==", get, line); + assertEqualsOr2<unsigned int const&, unsigned int const&>(expect1, expect2, get, line); +} + diff --git a/test/libapt/getarchitectures_test.cc b/test/libapt/getarchitectures_test.cc index 1500caeed..e3ca7bbc2 100644 --- a/test/libapt/getarchitectures_test.cc +++ b/test/libapt/getarchitectures_test.cc @@ -39,6 +39,12 @@ int main(int argc,char *argv[]) _config->Set("APT::Architecture", "armel"); vec = APT::Configuration::getArchitectures(false); equals(vec.size(), 2); + equals(vec[0], "armel"); + equals(vec[1], "i386"); + + _config->Set("APT::Architectures::2", "armel"); + vec = APT::Configuration::getArchitectures(false); + equals(vec.size(), 2); equals(vec[0], "i386"); equals(vec[1], "armel"); diff --git a/test/libapt/getlanguages_test.cc b/test/libapt/getlanguages_test.cc index 707142aef..3d63e0e74 100644 --- a/test/libapt/getlanguages_test.cc +++ b/test/libapt/getlanguages_test.cc @@ -138,8 +138,8 @@ int main(int argc,char *argv[]) equals(vec[1], "de"); equals(vec[2], "en"); equals(vec[3], "none"); - equals(vec[4], "pt"); - equals(vec[5], "tr"); + equalsOr2(vec[4], "pt", "tr"); + equalsOr2(vec[5], "tr", "pt"); _config->Set("Dir::State::lists", "/non-existing-dir"); _config->Set("Acquire::Languages::1", "none"); |