Browse Source

Fix bug where the problemresolve can put a pkg into a heisenstate

The problemresolver will set the candidate version for pkg P back
to the current version if it encounters an impossible to satisfy
critical dependency on P. However it did not set the State of
the package back as well which lead to a situation where P is
neither in Keep,Install,Upgrade,Delete state.

Note that this can not be tested via the traditional sh based
framework. I added a python-apt based test for this.

LP: #1550741

[jak@debian.org: Make the test not fail if apt_pkg cannot be
 imported]
tags/debian/1.2.7
Michael Vogt Julian Andres Klode 5 years ago
parent
commit
0390edd545
5 changed files with 56 additions and 2 deletions
  1. +1
    -1
      .travis.yml
  2. +5
    -0
      apt-pkg/depcache.cc
  3. +1
    -1
      debian/tests/control
  4. +1
    -0
      test/integration/framework
  5. +48
    -0
      test/integration/test-bug-lp1550741-heisestate

+ 1
- 1
.travis.yml View File

@@ -8,7 +8,7 @@ before_install:
- sudo apt-get update -qq
install:
- sudo ./prepare-release travis-ci
- sudo apt-get -qq -y -t wily install gettext liblz4-dev
- sudo apt-get -qq -y -t wily install gettext liblz4-dev python3-apt
- make
script:
- make test


+ 5
- 0
apt-pkg/depcache.cc View File

@@ -1421,7 +1421,12 @@ bool pkgDepCache::IsInstallOkDependenciesSatisfiableByCandidates(PkgIterator con
// the dependency is critical, but can't be installed, so discard the candidate
// as the problemresolver will trip over it otherwise trying to install it (#735967)
if (Pkg->CurrentVer != 0 && (PkgState[Pkg->ID].iFlags & Protected) != Protected)
{
SetCandidateVersion(Pkg.CurrentVer());
StateCache &State = PkgState[Pkg->ID];
State.Mode = ModeKeep;
State.Update(Pkg, *this);
}
return false;
}
}


+ 1
- 1
debian/tests/control View File

@@ -1,4 +1,4 @@
Tests: run-tests
Restrictions: allow-stderr
Depends: @, @builddeps@, fakeroot, wget, stunnel4, lsof, db-util, gnupg, gnupg2,
libfile-fcntllock-perl
libfile-fcntllock-perl, python3-apt

+ 1
- 0
test/integration/framework View File

@@ -175,6 +175,7 @@ runapt() {
esac
MALLOC_PERTURB_=21 MALLOC_CHECK_=2 APT_CONFIG="$(getaptconfig)" LD_LIBRARY_PATH="${LIBRARYPATH}:${LD_LIBRARY_PATH}" "$CMD" "$@"
}
runpython3() { runapt command python3 "$@"; }
aptconfig() { runapt apt-config "$@"; }
aptcache() { runapt apt-cache "$@"; }
aptcdrom() { runapt apt-cdrom "$@"; }


+ 48
- 0
test/integration/test-bug-lp1550741-heisestate View File

@@ -0,0 +1,48 @@
#!/bin/sh
set -e

TESTDIR="$(readlink -f "$(dirname "$0")")"
. "$TESTDIR/framework"

setupenvironment
configarchitecture 'amd64'

insertpackage 'unstable' 'module-init-tools' 'amd64' '1.0' 'Depends: libkmod2 (= 21-1)'
insertpackage 'unstable' 'libkmod2' 'amd64' '0.22-1'
insertinstalledpackage 'module-init-tools' 'amd64' '0.1'

setupaptarchive

# this test only works if the python-apt is build against the same
# ABI version as the apt we are testing here
PYAPT_LIB_VER=$(runpython3 -c 'import apt_pkg;print(apt_pkg.LIB_VERSION)' 2>/dev/null || true)
if [ ! -f $LIBRARYPATH/libapt-pkg.so.$PYAPT_LIB_VER ]; then
msgskip "python-apt build with the wrong library version: $PYAPT_LIB_VER"
exit 0
fi

# we can not test this using our normal sh tests
cat > test.py <<EOF
#!/usr/bin/python3
import sys
import apt
def in_valid_state(pkg):
return (pkg.marked_keep or
pkg.marked_install or
pkg.marked_upgrade or
pkg.marked_delete or
pkg.marked_downgrade or
pkg.marked_reinstall)
# main
cache=apt.Cache()
pkgname="module-init-tools"
if not in_valid_state(cache[pkgname]):
print("the test is broken, %s should be in a valid state" % pkgname)
sys.exit(99)
cache.upgrade(True)
if not in_valid_state(cache[pkgname]):
print("package %s is in a heisen-state" % pkgname)
sys.exit(2)

EOF
testsuccess runpython3 test.py

Loading…
Cancel
Save