diff options
author | Daniel Burrows <dburrows@debian.org> | 2008-06-04 21:34:21 -0700 |
---|---|---|
committer | Daniel Burrows <dburrows@debian.org> | 2008-06-04 21:34:21 -0700 |
commit | 45f522281d76b07c5ac6c3dfe64fc08c1f94400a (patch) | |
tree | a7c3eb9efa5c601cd12801fba99b3659fb50dba9 | |
parent | f993d36ecea2b0de580557b9f65a0fbaddff9ab4 (diff) | |
download | aptitude-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.cc | 139 |
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; |