summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apt-pkg/cacheset.cc65
-rw-r--r--apt-pkg/cacheset.h10
-rw-r--r--apt-pkg/versionmatch.cc15
-rw-r--r--apt-private/private-cacheset.cc162
-rw-r--r--apt-private/private-cacheset.h2
-rwxr-xr-xtest/integration/test-apt-get-install-virtual-pkgs74
-rwxr-xr-xtest/integration/test-bug-758153-versioned-provides-support26
7 files changed, 287 insertions, 67 deletions
diff --git a/apt-pkg/cacheset.cc b/apt-pkg/cacheset.cc
index df750cb44..e52f76272 100644
--- a/apt-pkg/cacheset.cc
+++ b/apt-pkg/cacheset.cc
@@ -489,14 +489,12 @@ bool VersionContainerInterface::FromString(VersionContainerInterface * const vci
pkgVersionMatch Match(ver, (verIsRel == true ? pkgVersionMatch::Release :
pkgVersionMatch::Version));
V = Match.Find(P);
- if (V.end() == true) {
+ helper.setLastVersionMatcher(ver);
+ if (V.end()) {
if (verIsRel == true)
- _error->Error(_("Release '%s' for '%s' was not found"),
- ver.c_str(), P.FullName(true).c_str());
+ V = helper.canNotGetVersion(CacheSetHelper::RELEASE, Cache, P);
else
- _error->Error(_("Version '%s' for '%s' was not found"),
- ver.c_str(), P.FullName(true).c_str());
- continue;
+ V = helper.canNotGetVersion(CacheSetHelper::VERSIONNUMBER, Cache, P);
}
}
if (V.end() == true)
@@ -569,9 +567,25 @@ bool VersionContainerInterface::FromPackage(VersionContainerInterface * const vc
helper.canNotFindVersion(CacheSetHelper::NEWEST, vci, Cache, P);
break;
case CacheSetHelper::RELEASE:
+ {
+ pkgVersionMatch Match(helper.getLastVersionMatcher(), pkgVersionMatch::Release);
+ V = Match.Find(P);
+ if (not V.end())
+ found |= vci->insert(V);
+ else
+ helper.canNotFindVersion(CacheSetHelper::RELEASE, vci, Cache, P);
+ }
+ break;
case CacheSetHelper::VERSIONNUMBER:
- // both make no sense here, so always false
- return false;
+ {
+ pkgVersionMatch Match(helper.getLastVersionMatcher(), pkgVersionMatch::Version);
+ V = Match.Find(P);
+ if (not V.end())
+ found |= vci->insert(V);
+ else
+ helper.canNotFindVersion(CacheSetHelper::VERSIONNUMBER, vci, Cache, P);
+ }
+ break;
}
return found;
}
@@ -729,10 +743,8 @@ void CacheSetHelper::canNotFindVersion(enum VerSelector const select, VersionCon
case CANDIDATE: canNotFindCandidateVer(Cache, Pkg); break;
case INSTALLED: canNotFindInstalledVer(Cache, Pkg); break;
case CANDANDINST: canNotGetCandInstVer(Cache, Pkg); break;
- case RELEASE:
- case VERSIONNUMBER:
- // invalid in this branch
- break;
+ case RELEASE: canNotGetVerFromRelease(Cache, Pkg, getLastVersionMatcher()); break;
+ case VERSIONNUMBER: canNotGetVerFromVersionNumber(Cache, Pkg, getLastVersionMatcher()); break;
}
}
// canNotFindAllVer /*{{{*/
@@ -763,10 +775,10 @@ pkgCache::VerIterator CacheSetHelper::canNotGetVersion(enum VerSelector const se
case INSTALLED: return canNotFindInstalledVer(Cache, Pkg);
case CANDINST: return canNotGetCandInstVer(Cache, Pkg);
case INSTCAND: return canNotGetInstCandVer(Cache, Pkg);
+ case RELEASE: return canNotGetVerFromRelease(Cache, Pkg, getLastVersionMatcher());
+ case VERSIONNUMBER: return canNotGetVerFromVersionNumber(Cache, Pkg, getLastVersionMatcher());
case ALL:
case CANDANDINST:
- case RELEASE:
- case VERSIONNUMBER:
// invalid in this branch
return pkgCache::VerIterator(Cache, 0);
}
@@ -812,6 +824,20 @@ pkgCache::VerIterator CacheSetHelper::canNotGetCandInstVer(pkgCacheFile &Cache,
return pkgCache::VerIterator(Cache, 0);
}
/*}}}*/
+// canNotFindMatchingVer /*{{{*/
+pkgCache::VerIterator CacheSetHelper::canNotGetVerFromRelease(pkgCacheFile &Cache,
+ pkgCache::PkgIterator const &Pkg, std::string const &release) {
+ if (ShowError == true)
+ _error->Insert(ErrorType, _("Release '%s' for '%s' was not found"), release.c_str(), Pkg.FullName(true).c_str());
+ return pkgCache::VerIterator(Cache, 0);
+}
+pkgCache::VerIterator CacheSetHelper::canNotGetVerFromVersionNumber(pkgCacheFile &Cache,
+ pkgCache::PkgIterator const &Pkg, std::string const &verstr) {
+ if (ShowError == true)
+ _error->Insert(ErrorType, _("Version '%s' for '%s' was not found"), verstr.c_str(), Pkg.FullName(true).c_str());
+ return pkgCache::VerIterator(Cache, 0);
+}
+ /*}}}*/
/*}}}*/
// showPackageSelection - by selector and given pattern /*{{{*/
void CacheSetHelper::showPackageSelection(pkgCache::PkgIterator const &pkg, enum PkgSelector const select,
@@ -876,9 +902,16 @@ void CacheSetHelper::showSelectedVersion(pkgCache::PkgIterator const &/*Pkg*/,
}
/*}}}*/
+class CacheSetHelper::Private {
+public:
+ std::string version_or_release;
+};
+std::string CacheSetHelper::getLastVersionMatcher() const { return d->version_or_release; }
+void CacheSetHelper::setLastVersionMatcher(std::string const &matcher) { d->version_or_release = matcher; }
+
CacheSetHelper::CacheSetHelper(bool const ShowError, GlobalError::MsgType ErrorType) :
- ShowError(ShowError), ErrorType(ErrorType), d(NULL) {}
-CacheSetHelper::~CacheSetHelper() {}
+ ShowError(ShowError), ErrorType(ErrorType), d(new Private{}) {}
+CacheSetHelper::~CacheSetHelper() { delete d; }
PackageContainerInterface::PackageContainerInterface() : ConstructedBy(CacheSetHelper::UNKNOWN), d(NULL) {}
PackageContainerInterface::PackageContainerInterface(PackageContainerInterface const &by) : PackageContainerInterface() { *this = by; }
diff --git a/apt-pkg/cacheset.h b/apt-pkg/cacheset.h
index eb9e3e523..383d26b76 100644
--- a/apt-pkg/cacheset.h
+++ b/apt-pkg/cacheset.h
@@ -157,6 +157,8 @@ public: /*{{{*/
}
}
+ std::string getLastVersionMatcher() const;
+ void setLastVersionMatcher(std::string const &matcher);
/*}}}*/
protected:
bool ShowError;
@@ -167,6 +169,11 @@ protected:
pkgCache::VerIterator canNotGetCandInstVer(pkgCacheFile &Cache,
pkgCache::PkgIterator const &Pkg);
+ pkgCache::VerIterator canNotGetVerFromRelease(pkgCacheFile &Cache,
+ pkgCache::PkgIterator const &Pkg, std::string const &release);
+ pkgCache::VerIterator canNotGetVerFromVersionNumber(pkgCacheFile &Cache,
+ pkgCache::PkgIterator const &Pkg, std::string const &verstr);
+
bool PackageFromTask(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string pattern);
bool PackageFromRegEx(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string pattern);
bool PackageFromFnmatch(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string pattern);
@@ -191,7 +198,8 @@ private:
pkgCache::VerIterator canNotFindCandidateVer(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg);
pkgCache::VerIterator canNotFindInstalledVer(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg);
- void * const d;
+ class Private;
+ Private * const d;
}; /*}}}*/
// Iterator templates for our Containers /*{{{*/
template<typename Interface, typename Master, typename iterator_type, typename container_iterator, typename container_value> class Container_iterator_base :
diff --git a/apt-pkg/versionmatch.cc b/apt-pkg/versionmatch.cc
index 340f5a64c..82590edfe 100644
--- a/apt-pkg/versionmatch.cc
+++ b/apt-pkg/versionmatch.cc
@@ -159,15 +159,16 @@ bool pkgVersionMatch::MatchVer(const char *A,string B,bool Prefix)
/* */
pkgCache::VerIterator pkgVersionMatch::Find(pkgCache::PkgIterator Pkg)
{
- pkgCache::VerIterator Ver = Pkg.VersionList();
- for (; Ver.end() == false; ++Ver)
- {
+ for (auto Ver = Pkg.VersionList(); not Ver.end(); ++Ver)
if (VersionMatches(Ver))
return Ver;
- }
-
- // This will be Ended by now.
- return Ver;
+ // check if the package provides itself in a matching version
+ for (auto Prov = Pkg.ProvidesList(); not Prov.end(); ++Prov)
+ if (Prov->ProvideVersion != 0 && Prov.OwnerPkg() == Prov.ParentPkg())
+ if (MatchVer(Prov.ProvideVersion(), VerStr, VerPrefixMatch) ||
+ ExpressionMatches(VerStr, Prov.ProvideVersion()))
+ return Prov.OwnerVer();
+ return pkgCache::VerIterator{};
}
/*}}}*/
diff --git a/apt-private/private-cacheset.cc b/apt-private/private-cacheset.cc
index 2a5afac7b..2d85aaf4f 100644
--- a/apt-private/private-cacheset.cc
+++ b/apt-private/private-cacheset.cc
@@ -1,5 +1,6 @@
#include <config.h>
+#include <apt-pkg/cacheset.h>
#include <apt-pkg/aptconfiguration.h>
#include <apt-pkg/cachefile.h>
#include <apt-pkg/cachefilter.h>
@@ -102,8 +103,21 @@ pkgCache::VerIterator CacheSetHelperVirtuals::canNotGetVersion(
pkgCacheFile &Cache,
pkgCache::PkgIterator const &Pkg)
{
- if (select == NEWEST || select == CANDIDATE || select == ALL)
- virtualPkgs.insert(Pkg);
+ switch (select)
+ {
+ case VERSIONNUMBER:
+ case RELEASE:
+ case INSTALLED:
+ case CANDIDATE:
+ case NEWEST:
+ case ALL:
+ virtualPkgs.insert(Pkg);
+ break;
+ case CANDANDINST:
+ case CANDINST:
+ case INSTCAND:
+ break;
+ }
return CacheSetHelper::canNotGetVersion(select, Cache, Pkg);
}
void CacheSetHelperVirtuals::canNotFindVersion(
@@ -230,10 +244,11 @@ void CacheSetHelperAPTGet::showVersionSelection(pkgCache::PkgIterator const &Pkg
{
switch (select)
{
- case RELEASE:
case VERSIONNUMBER:
if (pattern == Ver.VerStr())
return;
+ /* fall through */
+ case RELEASE:
selectedByRelease.push_back(make_pair(Ver, pattern));
break;
default:
@@ -258,7 +273,9 @@ bool CacheSetHelperAPTGet::showVirtualPackageErrors(pkgCacheFile &Cache)
if (Cache[OPkg].CandidateVerIter(Cache) == I.OwnerVer())
{
- c1out << " " << OPkg.FullName(true) << " " << I.OwnerVer().VerStr();
+ c1out << " " << OPkg.FullName(true) << ' ' << I.OwnerVer().VerStr();
+ if (I->ProvideVersion != 0)
+ c1out << " (= " << I.ProvideVersion() << ")";
if (Cache[OPkg].Install() == true && Cache[OPkg].NewInstall() == false)
c1out << _(" [Installed]");
c1out << std::endl;
@@ -268,8 +285,12 @@ bool CacheSetHelperAPTGet::showVirtualPackageErrors(pkgCacheFile &Cache)
// if we found no candidate which provide this package, show non-candidates
if (provider == 0)
for (I = Pkg.ProvidesList(); I.end() == false; ++I)
- c1out << " " << I.OwnerPkg().FullName(true) << " " << I.OwnerVer().VerStr()
- << _(" [Not candidate version]") << std::endl;
+ {
+ c1out << " " << I.OwnerPkg().FullName(true) << " " << I.OwnerVer().VerStr();
+ if (I->ProvideVersion != 0)
+ c1out << " (= " << I.ProvideVersion() << ")";
+ c1out << _(" [Not candidate version]") << std::endl;
+ }
else
out << _("You should explicitly select one to install.") << std::endl;
} else {
@@ -305,6 +326,10 @@ pkgCache::VerIterator CacheSetHelperAPTGet::canNotGetVersion(enum VerSelector co
return canNotFindNewestVer(Cache, Pkg);
case CANDIDATE:
return canNotFindCandidateVer(Cache, Pkg);
+ case VERSIONNUMBER:
+ return canNotFindVersionNumber(Cache, Pkg, getLastVersionMatcher());
+ case RELEASE:
+ return canNotFindVersionRelease(Cache, Pkg, getLastVersionMatcher());
default:
return APT::CacheSetHelper::canNotGetVersion(select, Cache, Pkg);
}
@@ -324,6 +349,34 @@ void CacheSetHelperAPTGet::canNotFindVersion(enum VerSelector const select, APT:
}
}
+pkgCache::VerIterator CacheSetHelperAPTGet::canNotFindVersionNumber(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg, std::string const &verstr)
+{
+ APT::VersionSet const verset = tryVirtualPackage(Cache, Pkg, CacheSetHelper::VERSIONNUMBER);
+ if (not verset.empty())
+ return *(verset.begin());
+ else if (ShowError)
+ {
+ auto const V = canNotGetVerFromVersionNumber(Cache, Pkg, verstr);
+ if (not V.end())
+ return V;
+ virtualPkgs.insert(Pkg);
+ }
+ return pkgCache::VerIterator(Cache, 0);
+}
+pkgCache::VerIterator CacheSetHelperAPTGet::canNotFindVersionRelease(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg, std::string const &verstr)
+{
+ APT::VersionSet const verset = tryVirtualPackage(Cache, Pkg, CacheSetHelper::RELEASE);
+ if (not verset.empty())
+ return *(verset.begin());
+ else if (ShowError)
+ {
+ auto const V = canNotGetVerFromRelease(Cache, Pkg, verstr);
+ if (not V.end())
+ return V;
+ virtualPkgs.insert(Pkg);
+ }
+ return pkgCache::VerIterator(Cache, 0);
+}
pkgCache::VerIterator CacheSetHelperAPTGet::canNotFindCandidateVer(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg)
{
APT::VersionSet const verset = tryVirtualPackage(Cache, Pkg, CacheSetHelper::CANDIDATE);
@@ -368,49 +421,72 @@ pkgCache::VerIterator CacheSetHelperAPTGet::canNotFindNewestVer(pkgCacheFile &Ca
APT::VersionSet CacheSetHelperAPTGet::tryVirtualPackage(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg,
CacheSetHelper::VerSelector const select)
{
- /* This is a pure virtual package and there is a single available
- candidate providing it. */
- if (unlikely(Cache[Pkg].CandidateVer != 0) || Pkg->ProvidesList == 0)
- return APT::VersionSet();
-
- pkgCache::PkgIterator Prov;
- bool found_one = false;
- for (pkgCache::PrvIterator P = Pkg.ProvidesList(); P; ++P) {
- pkgCache::VerIterator const PVer = P.OwnerVer();
- pkgCache::PkgIterator const PPkg = PVer.ParentPkg();
+ /* If this is a virtual package see if we have a single matching provider
+ (ignoring multiple matches from the same package due to e.g. M-A) */
+ if (Pkg->ProvidesList == 0)
+ return APT::VersionSet{};
- /* Ignore versions that are not a candidate. */
- if (Cache[PPkg].CandidateVer != PVer)
- continue;
+ auto const oldShowError = showErrors(false);
+ APT::VersionVector verset;
+ auto const lastmatcher = getLastVersionMatcher();
+ for (auto P = Pkg.ProvidesList(); not P.end(); ++P)
+ {
+ auto V = P.OwnerVer();
+ switch (select)
+ {
+ case RELEASE:
+ for (auto File = V.FileList(); not File.end(); ++File)
+ if (lastmatcher == File.File().Archive() || lastmatcher == File.File().Codename())
+ {
+ verset.push_back(V);
+ break;
+ }
+ break;
+ case VERSIONNUMBER:
+ if (P->ProvideVersion != 0 && lastmatcher == P.ProvideVersion())
+ verset.push_back(V);
+ break;
+ default:
+ if (Cache[V.ParentPkg()].CandidateVerIter(Cache) == V)
+ verset.push_back(V);
+ break;
+ }
+ }
+ // do not change the candidate if we have more than one option for this package
+ if (select == VERSIONNUMBER || select == RELEASE)
+ for (auto const &V : verset)
+ if (std::count_if(verset.begin(), verset.end(), [Pkg = V.ParentPkg()](auto const &v) { return v.ParentPkg() == Pkg; }) == 1)
+ Cache->SetCandidateVersion(V);
+ showErrors(oldShowError);
- if (found_one == false) {
- Prov = PPkg;
- found_one = true;
- } else if (PPkg != Prov) {
- // same group, so it's a foreign package
- if (PPkg->Group == Prov->Group) {
- // do we already have the requested arch?
- if (strcmp(Pkg.Arch(), Prov.Arch()) == 0 ||
- strcmp(Prov.Arch(), "all") == 0 ||
- unlikely(strcmp(PPkg.Arch(), Prov.Arch()) == 0)) // packages have only on candidate, but just to be sure
- continue;
- // see which architecture we prefer more and switch to it
- std::vector<std::string> archs = APT::Configuration::getArchitectures();
- if (std::find(archs.begin(), archs.end(), PPkg.Arch()) < std::find(archs.begin(), archs.end(), Prov.Arch()))
- Prov = PPkg;
+ pkgCache::VerIterator Choosen;
+ for (auto const &Ver : verset)
+ {
+ if (Choosen.end())
+ Choosen = Ver;
+ else
+ {
+ auto const ChoosenPkg = Choosen.ParentPkg();
+ auto const AltPkg = Ver.ParentPkg();
+ // seeing two different packages makes it not simple anymore
+ if (ChoosenPkg->Group != AltPkg->Group)
+ return APT::VersionSet{};
+ // do we already have the requested arch?
+ if (strcmp(Pkg.Arch(), ChoosenPkg.Arch()) == 0 ||
+ strcmp(ChoosenPkg.Arch(), "all") == 0)
continue;
- }
- found_one = false; // we found at least two
- break;
+ // see which architecture we prefer more and switch to it
+ std::vector<std::string> archs = APT::Configuration::getArchitectures();
+ if (std::find(archs.begin(), archs.end(), AltPkg.Arch()) < std::find(archs.begin(), archs.end(), ChoosenPkg.Arch()))
+ Choosen = Ver;
}
}
+ if (Choosen.end())
+ return APT::VersionSet{};
- if (found_one == true) {
- ioprintf(out, _("Note, selecting '%s' instead of '%s'\n"),
- Prov.FullName(true).c_str(), Pkg.FullName(true).c_str());
- return APT::VersionSet::FromPackage(Cache, Prov, select, *this);
- }
- return APT::VersionSet();
+ ioprintf(out, _("Note, selecting '%s' instead of '%s'\n"),
+ Choosen.ParentPkg().FullName(true).c_str(), Pkg.FullName(true).c_str());
+ return { Choosen };
}
pkgCache::PkgIterator CacheSetHelperAPTGet::canNotFindPkgName(pkgCacheFile &Cache, std::string const &str)
{
diff --git a/apt-private/private-cacheset.h b/apt-private/private-cacheset.h
index f3f737b5c..e8dba5a7d 100644
--- a/apt-private/private-cacheset.h
+++ b/apt-private/private-cacheset.h
@@ -118,6 +118,8 @@ public:
void canNotFindVersion(enum VerSelector const select, APT::VersionContainerInterface * const vci, pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg) APT_OVERRIDE;
pkgCache::VerIterator canNotFindCandidateVer(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg);
pkgCache::VerIterator canNotFindNewestVer(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg);
+ pkgCache::VerIterator canNotFindVersionNumber(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg, std::string const &verstr);
+ pkgCache::VerIterator canNotFindVersionRelease(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg, std::string const &verstr);
virtual pkgCache::PkgIterator canNotFindPkgName(pkgCacheFile &Cache, std::string const &str) APT_OVERRIDE;
APT::VersionSet tryVirtualPackage(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg,
diff --git a/test/integration/test-apt-get-install-virtual-pkgs b/test/integration/test-apt-get-install-virtual-pkgs
index b2fd7499c..99e01ab2c 100755
--- a/test/integration/test-apt-get-install-virtual-pkgs
+++ b/test/integration/test-apt-get-install-virtual-pkgs
@@ -23,6 +23,11 @@ insertpackage 'unstable' 'foo4' 'i386' '2' 'Provides: foo-prv4:amd64'
insertpackage 'experimental' 'baz5' 'amd64' '1' 'Provides: foo-prv5:amd64'
insertpackage 'experimental' 'foo5' 'i386' '2' 'Provides: foo-prv5:amd64'
+insertpackage 'stable' 'debhelper' 'amd64,i386' '1' 'Provides: debhelper-compat (= 12)'
+insertpackage 'unstable,testing' 'debhelper' 'amd64,i386' '2' 'Provides: debhelper-compat (= 13)'
+insertpackage 'experimental' 'debhelper' 'amd64,i386' '3' 'Provides: debhelper-compat (= 13)'
+insertpackage 'experimental' 'debhelper-ng' 'amd64,i386' '4' 'Provides: debhelper-compat (= 13)'
+
setupaptarchive
testsuccessequal "Reading package lists...
@@ -62,3 +67,72 @@ Package foo-prv5 is a virtual package provided by:
baz5 1 [Not candidate version]
E: Package 'foo-prv5' has no installation candidate" aptget install foo-prv5 -s
+
+testsuccessequal 'Reading package lists...
+Building dependency tree...
+The following NEW packages will be installed:
+ debhelper
+0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
+Inst debhelper (2 testing, unstable [amd64])
+Conf debhelper (2 testing, unstable [amd64])' apt install debhelper -s
+testsuccessequal "Reading package lists...
+Building dependency tree...
+Note, selecting 'debhelper' instead of 'debhelper-compat'
+The following NEW packages will be installed:
+ debhelper
+0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
+Inst debhelper (2 testing, unstable [amd64])
+Conf debhelper (2 testing, unstable [amd64])" apt install debhelper-compat -s
+testsuccessequal "Reading package lists...
+Building dependency tree...
+Note, selecting 'debhelper' instead of 'debhelper-compat'
+Selected version '1' (stable [amd64]) for 'debhelper'
+The following NEW packages will be installed:
+ debhelper
+0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
+Inst debhelper (1 stable [amd64])
+Conf debhelper (1 stable [amd64])" apt install debhelper-compat=12 -s
+testsuccessequal "Reading package lists...
+Building dependency tree...
+Note, selecting 'debhelper' instead of 'debhelper-compat'
+Selected version '1' (stable [amd64]) for 'debhelper'
+The following NEW packages will be installed:
+ debhelper
+0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
+Inst debhelper (1 stable [amd64])
+Conf debhelper (1 stable [amd64])" apt install debhelper-compat/stable -s
+# by version selection we have selected the experimental debhelper-ng here
+# but dehelper stays at the candidate as it already provides 13
+testfailureequal "Reading package lists...
+Building dependency tree...
+Package debhelper-compat is a virtual package provided by:
+ debhelper 2 (= 13)
+ debhelper-ng 4 (= 13)
+You should explicitly select one to install.
+
+E: Version '13' for 'debhelper-compat' was not found" apt install debhelper-compat=13 -s
+testsuccessequal "Reading package lists...
+Building dependency tree...
+Note, selecting 'debhelper' instead of 'debhelper-compat'
+Selected version '2' (testing, unstable [amd64]) for 'debhelper'
+The following NEW packages will be installed:
+ debhelper
+0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
+Inst debhelper (2 testing, unstable [amd64])
+Conf debhelper (2 testing, unstable [amd64])" apt install debhelper-compat/unstable -s
+testfailureequal "Reading package lists...
+Building dependency tree...
+Package debhelper-compat is a virtual package provided by:
+ debhelper-ng 4 (= 13)
+ debhelper 3 (= 13)
+You should explicitly select one to install.
+
+E: Version '13' for 'debhelper-compat' was not found" apt install debhelper-compat=13 -st experimental
+testfailureequal "Reading package lists...
+Building dependency tree...
+Package debhelper-compat is a virtual package provided by:
+ debhelper-ng 4 (= 13)
+ debhelper 3 (= 13)
+You should explicitly select one to install.
+
+E: Release 'experimental' for 'debhelper-compat' was not found" apt install debhelper-compat/experimental -s
diff --git a/test/integration/test-bug-758153-versioned-provides-support b/test/integration/test-bug-758153-versioned-provides-support
index fb8ed39e8..7bf9d76bd 100755
--- a/test/integration/test-bug-758153-versioned-provides-support
+++ b/test/integration/test-bug-758153-versioned-provides-support
@@ -337,6 +337,32 @@ E: Unable to correct problems, you have held broken packages." aptget install ne
fi
testsuccessequal "$HEADER
+The following NEW packages will be installed:
+ selfprov
+0 upgraded, 1 newly installed, 0 to remove and 2 not upgraded.
+Inst selfprov (2 unstable [amd64])
+Conf selfprov (2 unstable [amd64])" apt install selfprov -s --solver $solver
+ if [ "$solver" = 'apt' ]; then
+ HEADER_POST_NL="
+$HEADER_POST"
+ else
+ HEADER_POST_NL=''
+ fi
+ testsuccessequal "$HEADER_PRE
+Selected version '2' (unstable [amd64]) for 'selfprov'$HEADER_POST_NL
+The following NEW packages will be installed:
+ selfprov
+0 upgraded, 1 newly installed, 0 to remove and 2 not upgraded.
+Inst selfprov (2 unstable [amd64])
+Conf selfprov (2 unstable [amd64])" apt install selfprov=1 -s --solver $solver
+ testsuccessequal "$HEADER
+The following NEW packages will be installed:
+ selfprov
+0 upgraded, 1 newly installed, 0 to remove and 2 not upgraded.
+Inst selfprov (2 unstable [amd64])
+Conf selfprov (2 unstable [amd64])" apt install selfprov=2 -s --solver $solver
+
+ testsuccessequal "$HEADER
The following additional packages will be installed:
selfprov
The following NEW packages will be installed: