summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apt/auth.py3
-rw-r--r--apt/cache.py23
-rw-r--r--apt/package.py2
-rw-r--r--aptsources/distinfo.py3
-rw-r--r--aptsources/distro.py8
-rw-r--r--aptsources/sourceslist.py2
-rw-r--r--data/templates/Ubuntu.info.in129
-rw-r--r--debian/changelog72
-rw-r--r--debian/control1
-rw-r--r--debian/tests/control2
-rw-r--r--debian/tests/run-tests8
-rw-r--r--python/cache.cc8
-rw-r--r--python/generic.h4
-rw-r--r--tests/test_all.py13
-rw-r--r--tests/test_apt_cache.py69
-rw-r--r--tests/test_aptsources.py3
-rw-r--r--tests/test_auth.py67
-rw-r--r--tests/test_debfile.py4
-rw-r--r--tests/test_debfile_multiarch.py10
-rw-r--r--tests/test_lp659438.py6
-rw-r--r--tests/test_progress.py2
-rw-r--r--tests/test_tagfile.py4
22 files changed, 402 insertions, 41 deletions
diff --git a/apt/auth.py b/apt/auth.py
index eff13b1a..c1b8da2a 100644
--- a/apt/auth.py
+++ b/apt/auth.py
@@ -78,7 +78,8 @@ def _call_apt_key_script(*args, **kwargs):
stderr=subprocess.PIPE)
content = kwargs.get("stdin", None)
- if isinstance(content, unicode):
+ # py2 needs this encoded, py3.3 will crash if it is
+ if isinstance(content, unicode) and sys.version_info[:2] < (3, 3):
content = content.encode("utf-8")
output, stderr = proc.communicate(content)
diff --git a/apt/cache.py b/apt/cache.py
index 86a788bb..9842cb2a 100644
--- a/apt/cache.py
+++ b/apt/cache.py
@@ -42,6 +42,9 @@ class FetchFailedException(IOError):
class LockFailedException(IOError):
"""Exception that is thrown when locking fails."""
+class CacheClosedException(Exception):
+ """Exception that is thrown when the cache is used after close()."""
+
class Cache(object):
"""Dictionary-like package cache.
@@ -139,6 +142,8 @@ class Cache(object):
"""
if progress is None:
progress = apt.progress.base.OpProgress()
+ # close old cache on (re)open
+ self.close()
self.op_progress = progress
self._run_callbacks("cache_pre_open")
@@ -172,6 +177,20 @@ class Cache(object):
progress.done()
self._run_callbacks("cache_post_open")
+ def close(self):
+ """ Close the package cache """
+ # explicitely free the FDs that _records has open
+ del self._records
+ self._records = None
+
+ def __enter__(self):
+ """ Enter the with statement """
+ return self
+
+ def __exit__(self, exc_type, exc_value, traceback):
+ """ Exit the with statement """
+ self.close()
+
def __getitem__(self, key):
""" look like a dictionary (get key) """
try:
@@ -238,6 +257,8 @@ class Cache(object):
@property
def required_download(self):
"""Get the size of the packages that are required to download."""
+ if self._records is None:
+ raise CacheClosedException("Cache object used after close() called")
pm = apt_pkg.PackageManager(self._depcache)
fetcher = apt_pkg.Acquire()
pm.get_archives(fetcher, self._list, self._records)
@@ -288,6 +309,8 @@ class Cache(object):
def _fetch_archives(self, fetcher, pm):
""" fetch the needed archives """
+ if self._records is None:
+ raise CacheClosedException("Cache object used after close() called")
# get lock
lockfile = apt_pkg.config.find_dir("Dir::Cache::Archives") + "lock"
diff --git a/apt/package.py b/apt/package.py
index 51da95f8..dbaab320 100644
--- a/apt/package.py
+++ b/apt/package.py
@@ -137,6 +137,7 @@ class Origin(object):
component - The component (eg. main)
label - The Label, as set in the Release file
origin - The Origin, as set in the Release file
+ codename - The Codename, as set in the Release file
site - The hostname of the site.
trusted - Boolean value whether this is trustworthy.
"""
@@ -146,6 +147,7 @@ class Origin(object):
self.component = packagefile.component
self.label = packagefile.label
self.origin = packagefile.origin
+ self.codename = packagefile.codename
self.site = packagefile.site
self.not_automatic = packagefile.not_automatic
# check the trust
diff --git a/aptsources/distinfo.py b/aptsources/distinfo.py
index e0ee915d..d80721e5 100644
--- a/aptsources/distinfo.py
+++ b/aptsources/distinfo.py
@@ -172,7 +172,8 @@ class DistInfo(object):
stdout=PIPE).communicate()[0].strip()
except OSError as exc:
if exc.errno != errno.ENOENT:
- logging.warn('lsb_release failed, using defaults:' % exc)
+ logging.warning(
+ 'lsb_release failed, using defaults:' % exc)
dist = "Debian"
self.dist = dist
diff --git a/aptsources/distro.py b/aptsources/distro.py
index 15b93823..e9facbfb 100644
--- a/aptsources/distro.py
+++ b/aptsources/distro.py
@@ -164,7 +164,11 @@ class Distribution(object):
fname = "/usr/share/xml/iso-codes/iso_3166.xml"
if os.path.exists(fname):
et = ElementTree(file=fname)
- it = et.getiterator('iso_3166_entry')
+ # python2.6 compat, the next two lines can get removed
+ # once we do not use py2.6 anymore
+ if getattr(et, "iter", None) is None:
+ et.iter = et.getiterator
+ it = et.iter('iso_3166_entry')
for elm in it:
try:
descr = elm.attrib["common_name"]
@@ -466,7 +470,7 @@ def _lsb_release():
result.update(l.split(":\t") for l in out.split("\n") if ':\t' in l)
except OSError as exc:
if exc.errno != errno.ENOENT:
- logging.warn('lsb_release failed, using defaults:' % exc)
+ logging.warning('lsb_release failed, using defaults:' % exc)
return result
diff --git a/aptsources/sourceslist.py b/aptsources/sourceslist.py
index 40902d84..f5a86ecb 100644
--- a/aptsources/sourceslist.py
+++ b/aptsources/sourceslist.py
@@ -375,7 +375,7 @@ class SourcesList(object):
source = SourceEntry(line, file)
self.list.append(source)
except:
- logging.warn("could not open file '%s'\n" % file)
+ logging.warning("could not open file '%s'\n" % file)
def save(self):
""" save the current sources """
diff --git a/data/templates/Ubuntu.info.in b/data/templates/Ubuntu.info.in
index 2aba269e..567456b3 100644
--- a/data/templates/Ubuntu.info.in
+++ b/data/templates/Ubuntu.info.in
@@ -1,5 +1,124 @@
_ChangelogURI: http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog
+Suite: raring
+RepositoryType: deb
+BaseURI: http://ports.ubuntu.com/ubuntu-ports/
+MatchURI: ports.ubuntu.com/ubuntu-ports
+BaseURI-amd64: http://archive.ubuntu.com/ubuntu
+MatchURI-amd64: archive.ubuntu.com/ubuntu
+BaseURI-i386: http://archive.ubuntu.com/ubuntu
+MatchURI-i386: archive.ubuntu.com/ubuntu
+MirrorsFile-amd64: Ubuntu.mirrors
+MirrorsFile-i386: Ubuntu.mirrors
+_Description: Ubuntu 13.04 'Raring Ringtail'
+Component: main
+_CompDescription: Officially supported
+_CompDescriptionLong: Canonical-supported free and open-source software
+Component: universe
+_CompDescription: Community-maintained
+_CompDescriptionLong: Community-maintained free and open-source software
+Component: restricted
+_CompDescription: Non-free drivers
+_CompDescriptionLong: Proprietary drivers for devices
+Component: multiverse
+ParentComponent: universe
+_CompDescription: Restricted software
+_CompDescriptionLong: Software restricted by copyright or legal issues
+
+Suite: raring
+ParentSuite: raring
+RepositoryType: deb-src
+BaseURI: http://archive.ubuntu.com/ubuntu/
+MatchURI: archive.ubuntu.com/ubuntu|ports.ubuntu.com/ubuntu-ports
+_Description: Ubuntu 13.04 'Raring Ringtail'
+
+Suite: raring
+RepositoryType: deb
+MatchName: .*
+BaseURI: cdrom:\[Ubuntu.*13.04
+MatchURI: cdrom:\[Ubuntu.*13.04
+_Description: Cdrom with Ubuntu 13.04 'Raring Ringtail'
+Available: False
+Component: main
+_CompDescription: Officially supported
+Component: restricted
+_CompDescription: Restricted copyright
+
+Suite: raring
+Official: false
+RepositoryType: deb
+BaseURI: http://archive.canonical.com
+MatchURI: archive.canonical.com
+_Description: Canonical Partners
+Component: partner
+_CompDescription: Software packaged by Canonical for their partners
+_CompDescriptionLong: This software is not part of Ubuntu.
+
+Suite: raring
+Official: false
+RepositoryType: deb
+BaseURI: http://extras.ubuntu.com
+MatchURI: extras.ubuntu.com
+_Description: Independent
+Component: main
+_CompDescription: Provided by third-party software developers
+_CompDescriptionLong: Software offered by third party developers.
+
+Suite: raring-security
+ParentSuite: raring
+RepositoryType: deb
+BaseURI: http://ports.ubuntu.com/ubuntu-ports/
+MatchURI: ports.ubuntu.com/ubuntu-ports
+BaseURI-amd64: http://security.ubuntu.com/ubuntu/
+MatchURI-amd64: archive.ubuntu.com/ubuntu|security.ubuntu.com
+BaseURI-i386: http://security.ubuntu.com/ubuntu/
+MatchURI-i386: archive.ubuntu.com/ubuntu|security.ubuntu.com
+_Description: Important security updates
+
+Suite: raring-security
+ParentSuite: raring
+RepositoryType: deb-src
+BaseURI: http://archive.ubuntu.com/ubuntu/
+MatchURI: archive.ubuntu.com/ubuntu|ports.ubuntu.com/ubuntu-ports|security.ubuntu.com
+_Description: Important security updates
+
+Suite: raring-updates
+ParentSuite: raring
+RepositoryType: deb
+_Description: Recommended updates
+
+Suite: raring-updates
+ParentSuite: raring
+RepositoryType: deb-src
+BaseURI: http://archive.ubuntu.com/ubuntu/
+MatchURI: archive.ubuntu.com/ubuntu|ports.ubuntu.com/ubuntu-ports
+_Description: Recommended updates
+
+Suite: raring-proposed
+ParentSuite: raring
+RepositoryType: deb
+_Description: Pre-released updates
+
+Suite: raring-proposed
+ParentSuite: raring
+RepositoryType: deb-src
+BaseURI: http://archive.ubuntu.com/ubuntu/
+MatchURI: archive.ubuntu.com/ubuntu|ports.ubuntu.com/ubuntu-ports
+_Description: Pre-released updates
+
+Suite: raring-backports
+ParentSuite: raring
+RepositoryType: deb
+_Description: Unsupported updates
+
+Suite: raring-backports
+ParentSuite: raring
+RepositoryType: deb-src
+BaseURI: http://archive.ubuntu.com/ubuntu/
+MatchURI: archive.ubuntu.com/ubuntu|ports.ubuntu.com/ubuntu-ports
+_Description: Unsupported updates
+
+
Suite: quantal
RepositoryType: deb
BaseURI: http://ports.ubuntu.com/ubuntu-ports/
@@ -10,7 +129,7 @@ BaseURI-i386: http://archive.ubuntu.com/ubuntu
MatchURI-i386: archive.ubuntu.com/ubuntu
MirrorsFile-amd64: Ubuntu.mirrors
MirrorsFile-i386: Ubuntu.mirrors
-_Description: Ubuntu 12.04 'Precise Pangolin'
+_Description: Ubuntu 12.10 'Quantal Quetzal'
Component: main
_CompDescription: Officially supported
_CompDescriptionLong: Canonical-supported free and open-source software
@@ -30,14 +149,14 @@ ParentSuite: quantal
RepositoryType: deb-src
BaseURI: http://archive.ubuntu.com/ubuntu/
MatchURI: archive.ubuntu.com/ubuntu|ports.ubuntu.com/ubuntu-ports
-_Description: Ubuntu 12.04 'Precise Pangolin'
+_Description: Ubuntu 12.10 'Quantal Quetzal'
Suite: quantal
RepositoryType: deb
MatchName: .*
-BaseURI: cdrom:\[Ubuntu.*12.04
-MatchURI: cdrom:\[Ubuntu.*12.04
-_Description: Cdrom with Ubuntu 12.04 'Precise Pangolin'
+BaseURI: cdrom:\[Ubuntu.*12.10
+MatchURI: cdrom:\[Ubuntu.*12.10
+_Description: Cdrom with Ubuntu 12.10 'Quantal Quetzal'
Available: False
Component: main
_CompDescription: Officially supported
diff --git a/debian/changelog b/debian/changelog
index 2bea7d52..53197196 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,73 @@
+python-apt (0.8.9) unstable; urgency=low
+
+ * upload previous experimental upload to sid
+
+ -- Michael Vogt <mvo@debian.org> Wed, 08 May 2013 18:23:36 +0200
+
+python-apt (0.8.9~exp2) experimental; urgency=low
+
+ * apt/package.py:
+ - export codename in apt.package.Origin as well
+ (closes: #703401)
+
+ -- Michael Vogt <mvo@debian.org> Tue, 19 Mar 2013 16:57:40 +0100
+
+python-apt (0.8.9~exp1) experimental; urgency=low
+
+ [ Michael Vogt ]
+ * python/tag.cc:
+ - make TagSecString_FromStringAndSize, TagSecString_FromString
+ static, thanks to jcristau
+ * python/cache.cc:
+ - add "Codename" to PackageFile object
+ * add dep8 style autopkgtest support
+ * build fixes for python3.3
+ * data/templates/Ubuntu.info.in:
+ - add raring
+ * tests/test_all.py, aptsources/distro.py:
+ - python2.6 compat fixes
+
+ [ Jason Conti ]
+ * lp:~jconti/python-apt/closeable-cache:
+ - add apt.Cache.close() method
+
+ [ Martin Pitt ]
+ * tests/*.py: Do not prepend None to sys.path, Python 3.3 redeems that with
+ an unintelligible crash.
+ * tests/test_auth.py: In test_add_key_from_server_mitm(), show the exception
+ if it does not match the expectation, so that this becomes possible to
+ debug.
+ * aptsources/distro.py: Replace the deprecated getiterator() ElementTree
+ method with iter(), to avoid raising a PendingDeprecationWarning.
+ * tests/test_auth.py: Temporarily disable $http_proxy for the tests, as
+ gnupg does not get along with proxies (LP #789049)
+
+ [ Colin Watson ]
+ * tests/test_apt_cache.py, tests/test_lp659438.py, tests/test_progress.py:
+ - Clear out APT::Update::Post-Invoke and
+ APT::Update::Post-Invoke-Success in tests that call cache.update to
+ avoid pollution from the host system.
+ * tests/test_auth.py:
+ - Discard stderr from gpg.
+ - Try successive keyserver ports if 19191 is already in use.
+ * aptsources/distinfo.py, aptsources/distro.py, aptsources/sourceslist.py,
+ tests/test_apt_cache.py, tests/test_debfile_multiarch.py:
+ - Use logging.warning rather than the deprecated logging.warn.
+ * tests/test_debfile_multiarch.py:
+ - Don't log warnings when skipping tests; the resulting stderr output
+ causes autopkgtest to fail.
+ * tests/test_all.py:
+ - Write general test status output to stdout, not stderr.
+ * tests/test_aptsources.py:
+ - Clean up file object in test_enable_component.
+ * tests/test_lp659438.py:
+ - Add an Architecture: line to the test Packages file so that apt
+ doesn't get upset with it.
+ * data/templates/Ubuntu.info.in:
+ - Fix descriptions of quantal and raring.
+
+ -- Michael Vogt <mvo@debian.org> Wed, 13 Mar 2013 18:36:37 +0100
+
python-apt (0.8.8.3) UNRELEASED; urgency=low
* aptsources/distro.py:
@@ -33,7 +103,7 @@ python-apt (0.8.8) unstable; urgency=low
[ Program translation updates ]
* po/pl.po: Polish (Michał Kułach) (closes: #684308)
* po/da.po: Danish (Joe Hansen) (closes: #689827)
-
+
[ Michael Vogt ]
* merged lp:~sampo555/python-apt/fix_1042916 reuse existing but
disabled sources.list entries instead of duplicating them.
diff --git a/debian/control b/debian/control
index 1619aacb..dd951ed2 100644
--- a/debian/control
+++ b/debian/control
@@ -21,6 +21,7 @@ Build-Depends: apt (>= 0.9.6),
python-unittest2
Vcs-Bzr: http://bzr.debian.org/apt/python-apt/debian-sid
Vcs-Browser: http://bzr.debian.org/loggerhead/apt/python-apt/debian-sid/changes
+XS-Testsuite: autopkgtest
Package: python-apt
Architecture: any
diff --git a/debian/tests/control b/debian/tests/control
new file mode 100644
index 00000000..2ca0a401
--- /dev/null
+++ b/debian/tests/control
@@ -0,0 +1,2 @@
+Tests: run-tests
+Depends: @, apt-utils, python-debian, fakeroot, intltool
diff --git a/debian/tests/run-tests b/debian/tests/run-tests
new file mode 100644
index 00000000..bb980c6b
--- /dev/null
+++ b/debian/tests/run-tests
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+set -e
+
+# from debian/rules
+for python in $(utils/pyversions -r); do
+ $python tests/test_all.py -q
+done
diff --git a/python/cache.cc b/python/cache.cc
index 10561ca0..e527faba 100644
--- a/python/cache.cc
+++ b/python/cache.cc
@@ -1247,6 +1247,12 @@ static PyObject *PackageFile_GetArchitecture(PyObject *Self,void*)
return Safe_FromString(File.Architecture());
}
+static PyObject *PackageFile_GetCodename(PyObject *Self,void*)
+{
+ pkgCache::PkgFileIterator &File = GetCpp<pkgCache::PkgFileIterator>(Self);
+ return Safe_FromString(File.Codename());
+}
+
static PyObject *PackageFile_GetSite(PyObject *Self,void*)
{
pkgCache::PkgFileIterator &File = GetCpp<pkgCache::PkgFileIterator>(Self);
@@ -1305,6 +1311,8 @@ static PyGetSetDef PackageFileGetSet[] = {
"The archive of the package file (i.e. 'Suite' in the Release file)."},
{"component",PackageFile_GetComponent,0,
"The component of this package file (e.g. 'main')."},
+ {"codename",PackageFile_GetCodename,0,
+ "The codename of this package file (e.g. squeeze-updates)."},
{"filename",PackageFile_GetFileName,0,
"The path to the file."},
{"id",PackageFile_GetID,0,
diff --git a/python/generic.h b/python/generic.h
index f9680ca5..914456e2 100644
--- a/python/generic.h
+++ b/python/generic.h
@@ -80,10 +80,14 @@ typedef int Py_ssize_t;
static inline const char *PyUnicode_AsString(PyObject *op) {
// Convert to bytes object, using the default encoding.
+#if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 3
+ return PyUnicode_AsUTF8(op);
+#else
// Use Python-internal API, there is no other way to do this
// without a memory leak.
PyObject *bytes = _PyUnicode_AsDefaultEncodedString(op, 0);
return bytes ? PyBytes_AS_STRING(bytes) : 0;
+#endif
}
// Convert any type of string based object to a const char.
diff --git a/tests/test_all.py b/tests/test_all.py
index 80526d76..25774617 100644
--- a/tests/test_all.py
+++ b/tests/test_all.py
@@ -40,17 +40,22 @@ def get_library_dir():
plat_specifier)
return os.path.abspath(library_dir)
+class MyTestRunner(unittest.runner.TextTestRunner):
+ def __init__(self, *args, **kwargs):
+ kwargs["stream"] = sys.stdout
+ super(MyTestRunner, self).__init__(*args, **kwargs)
+
if __name__ == '__main__':
if not os.access("/etc/apt/sources.list", os.R_OK):
- sys.stderr.write("[tests] Skipping because sources.list is not readable\n")
+ sys.stdout.write("[tests] Skipping because sources.list is not readable\n")
sys.exit(0)
- sys.stderr.write("[tests] Running on %s\n" % sys.version.replace("\n", ""))
+ sys.stdout.write("[tests] Running on %s\n" % sys.version.replace("\n", ""))
dirname = os.path.dirname(__file__)
if dirname:
os.chdir(dirname)
library_dir = get_library_dir()
- sys.stderr.write("Using library_dir: '%s'" % library_dir)
+ sys.stdout.write("Using library_dir: '%s'" % library_dir)
if library_dir:
sys.path.insert(0, os.path.abspath(library_dir))
@@ -58,4 +63,4 @@ if __name__ == '__main__':
if path.endswith('.py') and os.path.isfile(path):
exec('from %s import *' % path[:-3])
- unittest.main()
+ unittest.main(testRunner=MyTestRunner)
diff --git a/tests/test_apt_cache.py b/tests/test_apt_cache.py
index 448aed75..21dfeb98 100644
--- a/tests/test_apt_cache.py
+++ b/tests/test_apt_cache.py
@@ -7,29 +7,49 @@
# are permitted in any medium without royalty provided the copyright
# notice and this notice are preserved.
"""Unit tests for verifying the correctness of check_dep, etc in apt_pkg."""
+
+import glob
+import logging
import os
+import shutil
+import sys
import tempfile
import unittest
+if sys.version_info[0] == 2 and sys.version_info[1] == 6:
+ from unittest2 import TestCase
+else:
+ from unittest import TestCase
+
+
from test_all import get_library_dir
-import sys
-sys.path.insert(0, get_library_dir())
+libdir = get_library_dir()
+if libdir:
+ sys.path.insert(0, libdir)
import apt
import apt_pkg
-import shutil
-import glob
-import logging
+
def if_sources_list_is_readable(f):
def wrapper(*args, **kwargs):
if os.access("/etc/apt/sources.list", os.R_OK):
f(*args, **kwargs)
else:
- logging.warn("skipping '%s' because sources.list is not readable" % f)
+ logging.warning("skipping '%s' because sources.list is not readable" % f)
return wrapper
-class TestAptCache(unittest.TestCase):
+
+def get_open_file_descriptors():
+ try:
+ fds = os.listdir("/proc/self/fd")
+ except OSError:
+ logging.warning("failed to list /proc/self/fd")
+ return set([])
+ return set(map(int, fds))
+
+
+class TestAptCache(TestCase):
""" test the apt cache """
def setUp(self):
@@ -39,6 +59,8 @@ class TestAptCache(unittest.TestCase):
self._cnf = {}
for item in apt_pkg.config.keys():
self._cnf[item] = apt_pkg.config.find(item)
+ apt_pkg.config.clear("APT::Update::Post-Invoke")
+ apt_pkg.config.clear("APT::Update::Post-Invoke-Success")
def tearDown(self):
for item in self._cnf:
@@ -68,14 +90,41 @@ class TestAptCache(unittest.TestCase):
self.assertEqual(r['Package'], pkg.shortname)
self.assertTrue('Version' in r)
self.assertTrue(len(r['Description']) > 0)
- self.assertTrue(str(r).startswith('Package: %s\n' % pkg.shortname))
+ self.assertTrue(
+ str(r).startswith('Package: %s\n' % pkg.shortname))
+
+ @if_sources_list_is_readable
+ def test_cache_close_leak_fd(self):
+ fds_before_open = get_open_file_descriptors()
+ cache = apt.Cache()
+ opened_fd = get_open_file_descriptors().difference(fds_before_open)
+ cache.close()
+ fds_after_close = get_open_file_descriptors()
+ unclosed_fd = opened_fd.intersection(fds_after_close)
+ self.assertEqual(fds_before_open, fds_after_close)
+ self.assertEqual(unclosed_fd, set())
+
+ def test_cache_open_twice_leaks_fds(self):
+ cache = apt.Cache()
+ fds_before_open = get_open_file_descriptors()
+ cache.open()
+ fds_after_open_twice = get_open_file_descriptors()
+ self.assertEqual(fds_before_open, fds_after_open_twice)
+
+ @if_sources_list_is_readable
+ def test_cache_close_download_fails(self):
+ cache = apt.Cache()
+ self.assertEqual(cache.required_download, 0)
+ cache.close()
+ with self.assertRaises(apt.cache.CacheClosedException):
+ cache.required_download
def test_get_provided_packages(self):
apt.apt_pkg.config.set("Apt::architecture", "i386")
cache = apt.Cache(rootdir="./data/test-provides/")
cache.open()
if len(cache) == 0:
- logging.warn("skipping test_get_provided_packages, cache empty?!?")
+ logging.warning("skipping test_get_provided_packages, cache empty?!?")
return
# a true virtual pkg
l = cache.get_providing_packages("mail-transport-agent")
@@ -88,7 +137,7 @@ class TestAptCache(unittest.TestCase):
# create highlevel cache and get the lowlevel one from it
highlevel_cache = apt.Cache(rootdir="./data/test-provides")
if len(highlevel_cache) == 0:
- logging.warn("skipping test_log_level_pkg_provides, cache empty?!?")
+ logging.warning("skipping test_log_level_pkg_provides, cache empty?!?")
return
# low level cache provides list of the pkg
cache = highlevel_cache._cache
diff --git a/tests/test_aptsources.py b/tests/test_aptsources.py
index 41cfabb3..75dd91c1 100644
--- a/tests/test_aptsources.py
+++ b/tests/test_aptsources.py
@@ -164,7 +164,8 @@ class TestAptSources(unittest.TestCase):
from subprocess import Popen, PIPE
target = "./data/aptsources/sources.list.enable_comps"
line = "deb http://archive.ubuntu.com/ubuntu lucid main\n"
- open(target, "w").write(line)
+ with open(target, "w") as target_file:
+ target_file.write(line)
apt_pkg.config.set("Dir::Etc::sourcelist", target)
sources = aptsources.sourceslist.SourcesList(True, self.templates)
distro = aptsources.distro.get_distro(id="Ubuntu")
diff --git a/tests/test_auth.py b/tests/test_auth.py
index 2b524d28..bc353427 100644
--- a/tests/test_auth.py
+++ b/tests/test_auth.py
@@ -1,5 +1,10 @@
#!/usr/bin/env python
+from __future__ import print_function
+
+import contextlib
+import errno
+import itertools
import os
import shutil
import sys
@@ -152,6 +157,21 @@ class TestAuthKeys(TestCase):
for item in cnf:
apt_pkg.config.set(item, cnf[item])
+ @contextlib.contextmanager
+ def _discard_stderr(self):
+ stderr_fd = sys.stderr.fileno()
+ stderr_save = os.dup(stderr_fd)
+ try:
+ devnull = os.open('/dev/null', os.O_WRONLY)
+ try:
+ os.dup2(devnull, stderr_fd)
+ yield
+ finally:
+ os.close(devnull)
+ finally:
+ os.dup2(stderr_save, stderr_fd)
+ os.close(stderr_save)
+
def testAddAndExportKey(self):
"""Add an example key."""
apt.auth.add_key(WHEEZY_KEY)
@@ -202,20 +222,22 @@ class TestAuthKeys(TestCase):
self._start_keyserver()
self.addCleanup(self._stop_keyserver)
with self.assertRaises(apt.auth.AptKeyError) as cm:
- apt.auth.add_key_from_keyserver(
- "0101010178F7FE5C3E65D8AF8B48AD6246925553",
- "hkp://localhost:19191")
+ with self._discard_stderr():
+ apt.auth.add_key_from_keyserver(
+ "0101010178F7FE5C3E65D8AF8B48AD6246925553",
+ "hkp://localhost:%d" % self.keyserver_port)
self.assertTrue(
- str(cm.exception).startswith("Fingerprints do not match"))
+ str(cm.exception).startswith("Fingerprints do not match"), cm.exception)
def testAddKeyFromServer(self):
"""Install a GnuPG key from a remote server."""
self._start_keyserver()
self.addCleanup(self._stop_keyserver)
- apt.auth.add_key_from_keyserver(
- "0xa1bD8E9D78F7FE5C3E65D8AF8B48AD6246925553",
- "hkp://localhost:19191")
+ with self._discard_stderr():
+ apt.auth.add_key_from_keyserver(
+ "0xa1bD8E9D78F7FE5C3E65D8AF8B48AD6246925553",
+ "hkp://localhost:%d" % self.keyserver_port)
ret = apt.auth.list_keys()
self.assertEqual(len(ret), 1)
@@ -228,6 +250,8 @@ class TestAuthKeys(TestCase):
def _start_keyserver(self):
"""Start a fake keyserver on http://localhost:19191
+ If port 19191 is unavailable, try successive ports until one is.
+ Store the port actually in use in self.keyserver_port.
Thanks pitti.
"""
dir = tempfile.mkdtemp()
@@ -236,15 +260,39 @@ class TestAuthKeys(TestCase):
with open(os.path.join(dir, "pks", "lookup"), "w") as key_file:
key_file.write(WHEEZY_KEY)
+ keyserver_pipe = os.pipe()
self.keyserver_pid = os.fork()
if self.keyserver_pid == 0:
+ os.close(keyserver_pipe[0])
# quiesce server log
os.dup2(os.open('/dev/null', os.O_WRONLY), sys.stderr.fileno())
os.chdir(dir)
- httpd = HTTPServer(('localhost', 19191), HTTPRequestHandler)
+ for port in itertools.count(19191):
+ try:
+ httpd = HTTPServer(('localhost', port), HTTPRequestHandler)
+ break
+ except IOError as e:
+ if e.errno != errno.EADDRINUSE:
+ raise
+ keyserver_write = os.fdopen(keyserver_pipe[1], 'w')
+ print(port, file=keyserver_write)
+ keyserver_write.close()
httpd.serve_forever()
os._exit(0)
+ os.close(keyserver_pipe[1])
+ keyserver_read = os.fdopen(keyserver_pipe[0])
+ self.keyserver_port = int(keyserver_read.readline())
+ keyserver_read.close()
+
+ # temporarily disable proxy, as gnupg does not get along with that
+ # (LP #789049)
+ self.orig_proxy = os.environ.get('http_proxy')
+ try:
+ del os.environ['http_proxy']
+ except KeyError:
+ pass
+
# wait a bit until server is ready
time.sleep(0.5)
@@ -255,6 +303,9 @@ class TestAuthKeys(TestCase):
os.kill(self.keyserver_pid, 15)
os.wait()
+ # restore proxy
+ if self.orig_proxy is not None:
+ os.environ['http_proxy'] = self.orig_proxy
if __name__ == "__main__":
unittest.main()
diff --git a/tests/test_debfile.py b/tests/test_debfile.py
index 04a6b65a..75c46966 100644
--- a/tests/test_debfile.py
+++ b/tests/test_debfile.py
@@ -13,7 +13,9 @@ import unittest
from test_all import get_library_dir
import sys
-sys.path.insert(0, get_library_dir())
+libdir = get_library_dir()
+if libdir:
+ sys.path.insert(0, libdir)
import apt_pkg
import apt.debfile
diff --git a/tests/test_debfile_multiarch.py b/tests/test_debfile_multiarch.py
index 7c02a32a..bbf62016 100644
--- a/tests/test_debfile_multiarch.py
+++ b/tests/test_debfile_multiarch.py
@@ -13,7 +13,9 @@ import unittest
from test_all import get_library_dir
import sys
-sys.path.insert(0, get_library_dir())
+libdir = get_library_dir()
+if libdir:
+ sys.path.insert(0, libdir)
import apt
import apt_pkg
import apt.debfile
@@ -23,7 +25,8 @@ class TestDebfileMultiarch(unittest.TestCase):
def test_multiarch_deb_check(self):
if apt_pkg.get_architectures() != ["amd64", "i386"]:
- logging.warn("skipping test because running on a non-multiarch system")
+ # TODO: use unittest.skip
+ #logging.warning("skipping test because running on a non-multiarch system")
return
deb = apt.debfile.DebPackage(
"./data/test_debs/multiarch-test1_i386.deb")
@@ -37,7 +40,8 @@ class TestDebfileMultiarch(unittest.TestCase):
# use "lib3ds-1-3" as a test to see if non-multiach lib conflicts work
canary = "lib3ds-1-3"
if not canary in cache:
- logging.warn("skipping test because %s is missing" % canary)
+ # TODO: use unittest.skip
+ #logging.warning("skipping test because %s is missing" % canary)
return
cache[canary].mark_install()
deb = apt.debfile.DebPackage(
diff --git a/tests/test_lp659438.py b/tests/test_lp659438.py
index d3bdd910..b9a837b4 100644
--- a/tests/test_lp659438.py
+++ b/tests/test_lp659438.py
@@ -39,6 +39,8 @@ class RegressionTestCase(unittest.TestCase):
def setUp(self):
apt_pkg.init_config()
+ apt_pkg.config.clear("APT::Update::Post-Invoke")
+ apt_pkg.config.clear("APT::Update::Post-Invoke-Success")
self.chroot_path = chroot_path = tempfile.mkdtemp()
# Create a damaged status file
self.cache = apt.cache.Cache(rootdir=chroot_path)
@@ -48,8 +50,8 @@ class RegressionTestCase(unittest.TestCase):
Status: install reinstreq half-installed
Priority: optional
Section: admin
-Architecture: all
-Version: 3.6.9+build1+nobinonly-0ubuntu1""")
+Version: 3.6.9+build1+nobinonly-0ubuntu1
+Architecture: all""")
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:
diff --git a/tests/test_progress.py b/tests/test_progress.py
index 3b6285d6..b7bba02f 100644
--- a/tests/test_progress.py
+++ b/tests/test_progress.py
@@ -37,6 +37,8 @@ class TestProgress(unittest.TestCase):
with open("fetch_sources.list","w") as fobj:
fobj.write(deb_line)
apt_pkg.config.set("Dir::Etc::sourcelist", "fetch_sources.list")
+ apt_pkg.config.clear("APT::Update::Post-Invoke")
+ apt_pkg.config.clear("APT::Update::Post-Invoke-Success")
def test_acquire_progress(self):
progress = TestAcquireProgress()
diff --git a/tests/test_tagfile.py b/tests/test_tagfile.py
index 33197e6a..f26f851b 100644
--- a/tests/test_tagfile.py
+++ b/tests/test_tagfile.py
@@ -21,7 +21,9 @@ import tempfile
import unittest
from test_all import get_library_dir
-sys.path.insert(0, get_library_dir())
+libdir = get_library_dir()
+if libdir:
+ sys.path.insert(0, libdir)
import apt_pkg