summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Burrows <dburrows@debian.org>2008-06-04 21:34:21 -0700
committerDaniel Burrows <dburrows@debian.org>2008-06-04 21:34:21 -0700
commit45f522281d76b07c5ac6c3dfe64fc08c1f94400a (patch)
treea7c3eb9efa5c601cd12801fba99b3659fb50dba9
parentf993d36ecea2b0de580557b9f65a0fbaddff9ab4 (diff)
downloadaptitude-45f522281d76b07c5ac6c3dfe64fc08c1f94400a.tar.gz
In the internal resolver self-test, check that the set of packages and versions known to the resolver is consistent with reality.
-rw-r--r--src/cmdline/cmdline_check_resolver.cc139
1 files changed, 138 insertions, 1 deletions
diff --git a/src/cmdline/cmdline_check_resolver.cc b/src/cmdline/cmdline_check_resolver.cc
index 6a059ef2..04463602 100644
--- a/src/cmdline/cmdline_check_resolver.cc
+++ b/src/cmdline/cmdline_check_resolver.cc
@@ -1,6 +1,6 @@
// cmdline_check_resolver.cc
//
-// Copyright (C) 2005, 2007 Daniel Burrows
+// Copyright (C) 2005, 2007-2008 Daniel Burrows
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@@ -26,8 +26,134 @@
#include <apt-pkg/error.h>
+#include <algorithm>
+#include <iterator>
+
using namespace std;
+namespace
+{
+ // Check that each real (non-virtual) package and real version are
+ // represented in the universe.
+ void check_packages_and_versions(const aptitude_universe &u)
+ {
+ std::set<pkgCache::PkgIterator> real_packages;
+
+ // Insert each non-virtual package into real_packages.
+ for(pkgCache::PkgIterator pkg = (*apt_cache_file)->PkgBegin();
+ !pkg.end(); ++pkg)
+ {
+ if(!pkg.VersionList().end())
+ real_packages.insert(pkg);
+ }
+
+ std::set<pkgCache::PkgIterator> seen_packages;
+
+ for(aptitude_universe::package_iterator pi = u.packages_begin();
+ !pi.end(); ++pi)
+ {
+ const aptitude_universe::package p = *pi;
+ const pkgCache::PkgIterator apt_pkg = p.get_pkg();
+ bool seen_uninst = false;
+
+ seen_packages.insert(apt_pkg);
+
+ std::set<pkgCache::VerIterator> real_versions;
+ for(pkgCache::VerIterator ver = apt_pkg.VersionList();
+ !ver.end(); ++ver)
+ {
+ // Skip versions that exist only on the current system and
+ // that have been removed; the resolver does.
+ if( ! (!ver.Downloadable() &&
+ (ver != apt_pkg.CurrentVer() ||
+ apt_pkg->CurrentState == pkgCache::State::ConfigFiles) ))
+ real_versions.insert(ver);
+ }
+
+ std::set<pkgCache::VerIterator> seen_versions;
+ for(aptitude_universe::package::version_iterator vi = p.versions_begin();
+ !vi.end(); ++vi)
+ {
+ if(vi.get_ver().end())
+ seen_uninst = true;
+ else
+ seen_versions.insert(vi.get_ver());
+ }
+
+ if(!seen_uninst)
+ std::cout << "Didn't see the UNINST version of the package " << apt_pkg.Name() << "." << std::endl;
+
+ std::vector<pkgCache::VerIterator> remaining_versions;
+ std::set_difference(real_versions.begin(), real_versions.end(),
+ seen_versions.begin(), seen_versions.end(),
+ std::back_inserter(remaining_versions));
+
+ for(std::vector<pkgCache::VerIterator>::const_iterator it =
+ remaining_versions.begin(); it != remaining_versions.end();
+ ++it)
+ {
+ std::cout << "The package version " << it->ParentPkg().Name()
+ << " " << it->VerStr() << " is missing from the resolver."
+ << std::endl;
+ }
+
+ if((*apt_cache_file)[apt_pkg].Keep() &&
+ apt_pkg->CurrentState == pkgCache::State::ConfigFiles)
+ {
+ if(!p.current_version().get_ver().end())
+ {
+ std::cout << "The package " << apt_pkg.Name()
+ << " only has config files installed, but version "
+ << p.current_version().get_ver().VerStr()
+ << " is installed according to the resolver."
+ << std::endl;
+ }
+ }
+ else
+ {
+ pkgCache::VerIterator cache_instver = (*apt_cache_file)[apt_pkg].InstVerIter(*apt_cache_file);
+ pkgCache::VerIterator resolver_instver = p.current_version().get_ver();
+
+ if(cache_instver != resolver_instver)
+ {
+ if(cache_instver.end())
+ std::cout << "The package " << apt_pkg.Name()
+ << " should not be installed, but version "
+ << resolver_instver.VerStr()
+ << " is installed according to the resolver."
+ << std::endl;
+ else if(resolver_instver.end())
+ std::cout << "The package " << apt_pkg.Name()
+ << " should be installed at version "
+ << cache_instver.VerStr()
+ << ", but it isn't installed according to the resolver."
+ << std::endl;
+ else
+ std::cout << "The package " << apt_pkg.Name()
+ << " should be installed at version "
+ << cache_instver.VerStr()
+ << ", but version "
+ << resolver_instver.VerStr()
+ << " is installed according to the resolver."
+ << std::endl;
+ }
+ }
+ }
+
+ std::vector<pkgCache::PkgIterator> remaining_packages;
+ std::set_difference(real_packages.begin(), real_packages.end(),
+ seen_packages.begin(), seen_packages.end(),
+ std::back_inserter(remaining_packages));
+
+ for(std::vector<pkgCache::PkgIterator>::const_iterator it =
+ remaining_packages.begin(); it != remaining_packages.end(); ++it)
+ {
+ std::cout << "The package " << it->Name()
+ << " is missing from the resolver model." << std::endl;
+ }
+ }
+}
+
int cmdline_check_resolver(int argc, char *argv[],
const char *status_fname)
{
@@ -45,6 +171,17 @@ int cmdline_check_resolver(int argc, char *argv[],
aptitude_universe u(*apt_cache_file);
+ std::cout << "Checking that packages and versions are properly projected."
+ << std::endl;
+
+ check_packages_and_versions(u);
+
+ // TODO: test that all dependencies are represented, somehow. This
+ // is complicated since dependency representation isn't one-to-one.
+
+ std::cout << "Checking internal consistency of the dependency model."
+ << std::endl;
+
sanity_check_universe(u);
std::cout << "Sanity check complete." << std::endl;