From b0940220822459891fcc593f77171e7ee2a6cf12 Mon Sep 17 00:00:00 2001 From: Sebastian Heinlein Date: Mon, 16 Apr 2012 19:09:34 +0200 Subject: Fix: Initialize the depcache on apt.cache.Cache.open() (fixes LP: #659438) If there are packages in the reqreinst state cache operations won't fail anymore with the "cannot locate file for package x" error message. During the 0.8 API rewrite of apt_pkg.GetDepCache() this functionality was lost. --- apt/cache.py | 1 + 1 file changed, 1 insertion(+) diff --git a/apt/cache.py b/apt/cache.py index 86a788bb..aaa6595a 100644 --- a/apt/cache.py +++ b/apt/cache.py @@ -144,6 +144,7 @@ class Cache(object): self._cache = apt_pkg.Cache(progress) self._depcache = apt_pkg.DepCache(self._cache) + self._depcache.init(progress) self._records = apt_pkg.PackageRecords(self._cache) self._list = apt_pkg.SourceList() self._list.read_main_list() -- cgit v1.2.3 From ef6911924b5e1647dd2c57649478ebc7501f4682 Mon Sep 17 00:00:00 2001 From: Sebastian Heinlein Date: Mon, 16 Apr 2012 19:11:11 +0200 Subject: Fix apt_pkg.DepCache.init() documentation which still states that the method would be called automatically on construction --- python/depcache.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/python/depcache.cc b/python/depcache.cc index 73993c82..d19ec856 100644 --- a/python/depcache.cc +++ b/python/depcache.cc @@ -568,8 +568,7 @@ static PyMethodDef PkgDepCacheMethods[] = { {"init",PkgDepCacheInit,METH_VARARGS, "init(progress: apt.progress.base.OpProgress)\n\n" - "Initialize the depcache (done automatically when constructing\n" - "the object)."}, + "Initialize the depcache."}, {"get_candidate_ver",PkgDepCacheGetCandidateVer,METH_VARARGS, "get_candidate_ver(pkg: apt_pkg.Package) -> apt_pkg.Version\n\n" "Return the candidate version for the package, normally the version\n" -- cgit v1.2.3 From 72b1f8e86e203df1d8bfef41c71d228ee21e9d99 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Tue, 17 Apr 2012 14:10:22 +0200 Subject: * python/cache.cc: - ensure that pkgApplyStatus is called when the cache is opened (thanks to Sebastian Heinlein for finding this bug), LP: #659438 --- debian/changelog | 8 ++++++++ python/cache.cc | 4 +++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/debian/changelog b/debian/changelog index c1b12cc8..63f72fa5 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,11 @@ +python-apt (0.8.5) UNRELEASED; urgency=low + + * python/cache.cc: + - ensure that pkgApplyStatus is called when the cache is opened + (thanks to Sebastian Heinlein for finding this bug), LP: #659438 + + -- Michael Vogt Tue, 17 Apr 2012 14:09:24 +0200 + python-apt (0.8.4) unstable; urgency=low [ Michael Vogt ] diff --git a/python/cache.cc b/python/cache.cc index 191e2204..52ce32e3 100644 --- a/python/cache.cc +++ b/python/cache.cc @@ -197,12 +197,14 @@ static PyObject *PkgCacheOpen(PyObject *Self,PyObject *Args) return HandleErrors(); } + // ensure that the states are correct (LP: #659438) + pkgApplyStatus(*Cache); + //std::cout << "new cache is " << (pkgCache*)(*Cache) << std::endl; // update the cache pointer after the cache was rebuild ((CppPyObject *)Self)->Object = (pkgCache*)(*Cache); - Py_INCREF(Py_None); return HandleErrors(Py_None); } -- cgit v1.2.3 From 89e3cd4d1141fea8ecb5b8828cde622c9bf12649 Mon Sep 17 00:00:00 2001 From: Sebastian Heinlein Date: Tue, 17 Apr 2012 20:36:02 +0200 Subject: Add a regression test --- tests/test_lp659438.py | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 tests/test_lp659438.py diff --git a/tests/test_lp659438.py b/tests/test_lp659438.py new file mode 100644 index 00000000..25a6278f --- /dev/null +++ b/tests/test_lp659438.py @@ -0,0 +1,68 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +"""Regression test for LP: #981896, LP: #659438""" +# Copyright (C) 2012 Sebastian Heinlein +# +# Licensed under the GNU General Public License Version 2 +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# Licensed under the GNU General Public License Version 2 + +__author__ = "Sebastian Heinlein " + +import os +import shutil +import tempfile +import unittest + +import apt_pkg +import apt + + +class RegressionTestCase(unittest.TestCase): + + """Test suite for LP: #981896, LP: #659438 + 'Cannot locate a file for package X' + """ + + def setUp(self): + apt_pkg.init_config() + chroot_path = tempfile.mkdtemp() + self.addCleanup(lambda: shutil.rmtree(chroot_path)) + # Create a damaged status file + self.cache = apt.cache.Cache(rootdir=chroot_path) + with open(apt_pkg.config.find_file("Dir::State::status"), + "a") as status: + status.write("""Package: abrowser +Status: install reinstreq half-installed +Priority: optional +Section: admin +Version: 3.6.9+build1+nobinonly-0ubuntu1""") + sources_list_path = apt_pkg.config.find_file("Dir::Etc::sourcelist") + repo_path = os.path.abspath("./data/test-repo") + with open(sources_list_path, "w") as sources_list: + sources_list.write("deb copy:%s /\n" % repo_path) + # os.makedirs(os.path.join(chroot_path, "etc/apt/sources.list.d/")) + self.cache.update(sources_list=sources_list_path) + self.cache.open() + + def test_survive_reqreinst(self): + """Test that we survive a package in require reinstallation state""" + self.assertEqual(self.cache.required_download, 82324L) + +if __name__ == "__main__": + unittest.main() + +# vim: ts=4 et sts=4 -- cgit v1.2.3 From 16635641b3492e236f50d1a795fceeec2b620890 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Wed, 18 Apr 2012 10:13:10 +0200 Subject: tests/test_lp659438.py: ensure apt_pkg.config is reset for later tests via workaround --- tests/test_lp659438.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/test_lp659438.py b/tests/test_lp659438.py index 25a6278f..47123a03 100644 --- a/tests/test_lp659438.py +++ b/tests/test_lp659438.py @@ -58,6 +58,11 @@ Version: 3.6.9+build1+nobinonly-0ubuntu1""") self.cache.update(sources_list=sources_list_path) self.cache.open() + def tearDown(self): + # this resets the rootdir apt_pkg.config to ensure it does not + # "pollute" the later tests + cache = apt.cache.Cache(rootdir="/") + def test_survive_reqreinst(self): """Test that we survive a package in require reinstallation state""" self.assertEqual(self.cache.required_download, 82324L) -- cgit v1.2.3 From 8c17defbb7ef82f5791cf37973c9b26a367359ea Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Wed, 18 Apr 2012 10:20:32 +0200 Subject: tests/test_lp659438.py: fix test for py3.2 --- tests/test_lp659438.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/test_lp659438.py b/tests/test_lp659438.py index 47123a03..01edf3bd 100644 --- a/tests/test_lp659438.py +++ b/tests/test_lp659438.py @@ -65,7 +65,8 @@ Version: 3.6.9+build1+nobinonly-0ubuntu1""") def test_survive_reqreinst(self): """Test that we survive a package in require reinstallation state""" - self.assertEqual(self.cache.required_download, 82324L) + # this should be 82324L but python3.2 gets unhappy about the "L" + self.assertEqual(self.cache.required_download, 82324) if __name__ == "__main__": unittest.main() -- cgit v1.2.3