16 Sep
2008
16 Sep
'08
10:46
Hello community, here is the log from the commit of package smart checked in at Tue Sep 16 12:46:41 CEST 2008. -------- --- smart/smart.changes 2008-08-18 18:54:38.000000000 +0200 +++ /mounts/work_src_done/STABLE/smart/smart.changes 2008-09-10 14:25:56.867210000 +0200 @@ -1,0 +2,10 @@ +Wed Sep 10 14:22:37 CEST 2008 - cthiel@suse.de + +- update to version 1.1 + * The curl-based fetcher backend was handling 404 errors improperly. + * Handling of signed up apt-deb channels has been improved so that a + behavior similar to that of APT may be obtained. +- removed smart-order-test-packages.patch and smart--cast-test-sizes.patch, + both included upstream + +------------------------------------------------------------------- Old: ---- smart-1.0.tar.bz2 smart-cast-test-sizes.patch smart-order-test-packages.patch New: ---- smart-1.1.tar.bz2 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ smart.spec ++++++ --- /var/tmp/diff_new_pack.Z28404/_old 2008-09-16 12:46:24.000000000 +0200 +++ /var/tmp/diff_new_pack.Z28404/_new 2008-09-16 12:46:24.000000000 +0200 @@ -1,5 +1,5 @@ # -# spec file for package smart (Version 1.0) +# spec file for package smart (Version 1.1) # # Copyright (c) 2008 SUSE LINUX Products GmbH, Nuernberg, Germany. # @@ -27,7 +27,7 @@ BuildRequires: python-elementtree %endif Summary: Smart Package Manager -Version: 1.0 +Version: 1.1 Release: 1 Source: %{name}-%{version}.tar.bz2 Source1: distro.py @@ -43,8 +43,6 @@ Patch8: %{name}-interactive-newer.patch Patch9: %{name}-no-strict-aliasing.patch Patch10: %{name}-0.52-termios-0width.patch -Patch11: %{name}-order-test-packages.patch -Patch12: %{name}-cast-test-sizes.patch Url: http://smartpm.org Group: System/Packages License: GPL v2 or later @@ -111,8 +109,6 @@ %patch8 %patch9 %patch10 -%patch11 -%patch12 %if %{suse_version} < 1010 echo ' sysconf.set("no-rpm-readHeaderFromFD", 3)' >> "%{SOURCE1}" %endif @@ -229,6 +225,13 @@ /opt/kde3/share/icons/hicolor/48x48/apps/ksmarttray.png %changelog +* Wed Sep 10 2008 cthiel@suse.de +- update to version 1.1 + * The curl-based fetcher backend was handling 404 errors improperly. + * Handling of signed up apt-deb channels has been improved so that a + behavior similar to that of APT may be obtained. +- removed smart-order-test-packages.patch and smart--cast-test-sizes.patch, + both included upstream * Mon Aug 18 2008 cthiel@suse.de - enable testsuite * Fri Aug 15 2008 cthiel@suse.de ++++++ smart-1.0.tar.bz2 -> smart-1.1.tar.bz2 ++++++ diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/smart-1.0/smart/backends/deb/base.py new/smart-1.1/smart/backends/deb/base.py --- old/smart-1.0/smart/backends/deb/base.py 2008-08-15 01:58:53.000000000 +0200 +++ new/smart-1.1/smart/backends/deb/base.py 2008-09-08 22:28:03.000000000 +0200 @@ -33,6 +33,9 @@ "DebOrRequires", "DebOrPreRequires", "DEBARCH"] def getArchitecture(): + arch = sysconf.get("deb-arch") + if arch is not None: + return arch arch = os.uname()[-1] result = {"pentium": "i386", "sparc64": "sparc", @@ -53,7 +56,7 @@ else: return arch -DEBARCH = sysconf.get("deb-arch", getArchitecture()) +DEBARCH = getArchitecture() class DebPackage(Package): diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/smart-1.0/smart/ccache.c new/smart-1.1/smart/ccache.c --- old/smart-1.0/smart/ccache.c 2008-08-15 01:58:53.000000000 +0200 +++ new/smart-1.1/smart/ccache.c 2008-09-08 22:28:03.000000000 +0200 @@ -1399,6 +1399,8 @@ self->_packages = PyList_New(0); Py_INCREF(Py_False); self->_installed = Py_False; + Py_INCREF(Py_None); + self->_cache = Py_None; return 0; } diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/smart-1.0/smart/channel.py new/smart-1.1/smart/channel.py --- old/smart-1.0/smart/channel.py 2008-08-15 01:58:53.000000000 +0200 +++ new/smart-1.1/smart/channel.py 2008-09-08 22:28:03.000000000 +0200 @@ -98,7 +98,8 @@ def removeLoaders(self): for loader in self._loaders: cache = loader.getCache() - cache.removeLoader(loader) + if cache is not None: + cache.removeLoader(loader) del self._loaders[:] self._digest = object() diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/smart-1.0/smart/channels/apt_deb_info.py new/smart-1.1/smart/channels/apt_deb_info.py --- old/smart-1.0/smart/channels/apt_deb_info.py 2008-08-15 01:58:53.000000000 +0200 +++ new/smart-1.1/smart/channels/apt_deb_info.py 2008-09-08 22:28:03.000000000 +0200 @@ -36,4 +36,7 @@ ("components", _("Components"), str, "", _("Space separated list of components.")), ("fingerprint", _("Fingerprint"), str, "", - _("GPG fingerprint of key signing the channel."))] + _("GPG fingerprint of key signing the channel.")), + ("keyring", _("Keyring"), str, "", + _("If provided, channel must necessarily be signed by a key " + "in the GPG keyring at the given path."))] diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/smart-1.0/smart/channels/apt_deb.py new/smart-1.1/smart/channels/apt_deb.py --- old/smart-1.0/smart/channels/apt_deb.py 2008-08-15 01:58:53.000000000 +0200 +++ new/smart-1.1/smart/channels/apt_deb.py 2008-09-08 22:28:03.000000000 +0200 @@ -19,20 +19,26 @@ # along with Smart Package Manager; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # +import posixpath +import commands + from smart.backends.deb.loader import DebTagFileLoader from smart.util.filetools import getFileDigest -from smart.backends.deb.base import DEBARCH +from smart.backends.deb.base import getArchitecture from smart.channel import PackageChannel from smart.const import SUCCEEDED, NEVER from smart import * -import posixpath -import commands -import md5 -import os + class APTDEBChannel(PackageChannel): - def __init__(self, baseurl, distro, comps, fingerprint, *args): + # It's important for the default to be here so that old pickled + # instances which don't have these attributes still work fine. + _fingerprint = None + _keyring = None + _arch = None + + def __init__(self, baseurl, distro, comps, fingerprint, keyring, *args): super(APTDEBChannel, self).__init__(*args) distro = distro.lstrip('/') @@ -40,12 +46,13 @@ self._distro = distro self._comps = comps if fingerprint: - self._fingerprint = "".join([x for x in fingerprint - if not x.isspace()]) - else: - self._fingerprint = None + self._fingerprint = "".join(fingerprint.split()) + if keyring: + self._keyring = keyring def _getURL(self, filename="", component=None, subpath=False): + if self._arch is None: + self._arch = getArchitecture() if subpath: distrourl = "" elif not self._comps: @@ -54,7 +61,7 @@ distrourl = posixpath.join(self._baseurl, "dists", self._distro) if component: return posixpath.join(distrourl, component, - "binary-"+DEBARCH, filename) + "binary-"+self._arch, filename) else: return posixpath.join(distrourl, filename) @@ -63,173 +70,167 @@ def getFetchSteps(self): if self._comps: - # Release files are not being used - #return len(self._comps)*2+2 + # Packages*components + Release + Release.gpg return len(self._comps)+2 + # Component Release files are not being used, otherwise it'd be: + # (Packages+Release)*components + Release + Release.gpg + #return len(self._comps)*2+2 else: - return 1 + # Packages + Release + Release.gpg + return 3 + + def _checkRelease(self, release_item, release_gpg_item): + is_secure_channel = bool(self._fingerprint or self._keyring) + need_release = bool(is_secure_channel or self._comps) + release_failed = release_item.getFailedReason() + + if need_release and release_failed: + raise Error, _("Download of Release failed for channel '%s': %s") \ + % (self, release_failed) + + if is_secure_channel: + release_gpg_failed = release_gpg_item.getFailedReason() + if release_gpg_failed: + raise Error, \ + _("Download of Release.gpg failed for secure " + "channel '%s': %s") % (self, release_gpg_failed) + + arguments = ["gpg", "--batch", "--no-secmem-warning", + "--status-fd", "1"] + + if self._keyring: + arguments.extend(["--no-default-keyring", + "--keyring", self._keyring]) + + arguments.extend(["--verify", + release_gpg_item.getTargetPath(), + release_item.getTargetPath()]) + + command = " ".join(arguments) + status, output = commands.getstatusoutput(command) + + badsig = False + goodsig = False + validsig = None + for line in output.splitlines(): + if line.startswith("[GNUPG:]"): + tokens = line[8:].split() + first = tokens[0] + if first == "VALIDSIG": + validsig = tokens[1] + elif first == "GOODSIG": + goodsig = True + elif first == "BADSIG": + badsig = True + if badsig: + raise Error, _("Channel '%s' has bad signature") % self + if (not goodsig or + (self._fingerprint and validsig != self._fingerprint)): + raise Error, _("Channel '%s' signed with unknown key") % self + + def _parseRelease(self, release_item): + md5sum = {} + insidemd5sum = False + for line in open(release_item.getTargetPath()): + if not insidemd5sum: + if line.startswith("MD5Sum:"): + insidemd5sum = True + elif not line.startswith(" "): + insidemd5sum = False + else: + try: + md5, size, path = line.split() + except ValueError: + pass + else: + md5sum[path] = (md5, int(size)) + return md5sum + + def _enqueuePackages(self, fetcher, md5sum=None, component=None): + info = {} + url = self._getURL("Packages", component) + subpath = self._getURL("Packages", component, subpath=True) + if md5sum is not None: + if subpath+".bz2" in md5sum: + compressed_subpath = subpath+".bz2" + url += ".bz2" + elif subpath+".gz" in md5sum: + compressed_subpath = subpath+".gz" + url += ".gz" + elif subpath in md5sum: + compressed_subpath = None + else: + return None + if compressed_subpath: + info["uncomp"] = True + info["md5"], info["size"] = md5sum[compressed_subpath] + if subpath in md5sum: + info["uncomp_md5"], info["uncomp_size"] = md5sum[subpath] + else: + info["md5"], info["size"] = md5sum[subpath] + else: + # Default to Packages.gz when we can't find out. + info["uncomp"] = True + url += ".gz" + return fetcher.enqueue(url, **info) def fetch(self, fetcher, progress): fetcher.reset() - if self._comps: - - # Fetch release file - item = fetcher.enqueue(self._getURL("Release")) - gpgitem = fetcher.enqueue(self._getURL("Release.gpg")) - fetcher.run(progress=progress) - failed = item.getFailedReason() - if failed: - progress.add(self.getFetchSteps()-2) - progress.show() - if fetcher.getCaching() is NEVER: - lines = [_("Failed acquiring information for '%s':") % self, - u"%s: %s" % (item.getURL(), failed)] - raise Error, "\n".join(lines) + # Fetch release file + release_item = fetcher.enqueue(self._getURL("Release")) + release_gpg_item = fetcher.enqueue(self._getURL("Release.gpg")) + fetcher.run(progress=progress) + + try: + self._checkRelease(release_item, release_gpg_item) + except Error, e: + progress.add(self.getFetchSteps()-2) + progress.show() + if fetcher.getCaching() is NEVER: + raise + else: return False - digest = getFileDigest(item.getTargetPath()) + if not release_item.getFailedReason(): + digest = getFileDigest(release_item.getTargetPath()) if digest == self._digest: progress.add(self.getFetchSteps()-2) progress.show() return True self.removeLoaders() + md5sum = self._parseRelease(release_item) + else: + digest = None + md5sum = None - # Parse release file - md5sum = {} - insidemd5sum = False - for line in open(item.getTargetPath()): - if not insidemd5sum: - if line.startswith("MD5Sum:"): - insidemd5sum = True - elif not line.startswith(" "): - insidemd5sum = False - else: - try: - md5, size, path = line.split() - except ValueError: - pass - else: - md5sum[path] = (md5, int(size)) + fetcher.reset() - if self._fingerprint: - try: - failed = gpgitem.getFailedReason() - if failed: - raise Error, _("Channel '%s' has fingerprint but download " - "of Release.gpg failed: %s")%(self, failed) - - status, output = commands.getstatusoutput( - "gpg --batch --no-secmem-warning --status-fd 1 " - "--verify %s %s" % (gpgitem.getTargetPath(), - item.getTargetPath())) - - badsig = False - goodsig = False - validsig = None - for line in output.splitlines(): - if line.startswith("[GNUPG:]"): - tokens = line[8:].split() - first = tokens[0] - if first == "VALIDSIG": - validsig = tokens[1] - elif first == "GOODSIG": - goodsig = True - elif first == "BADSIG": - badsig = True - if badsig: - raise Error, _("Channel '%s' has bad signature") % self - if not goodsig or validsig != self._fingerprint: - raise Error, _("Channel '%s' signed with unknown key") \ - % self - except Error, e: - progress.add(self.getFetchSteps()-2) - progress.show() - if fetcher.getCaching() is NEVER: - raise - else: - return False - - # Fetch component package lists and release files - fetcher.reset() - pkgitems = [] - #relitems = [] - for comp in self._comps: - packages = self._getURL("Packages", comp, subpath=True) - url = self._getURL("Packages", comp) - if packages+".bz2" in md5sum: - upackages = packages - packages += ".bz2" - url += ".bz2" - elif packages+".gz" in md5sum: - upackages = packages - packages += ".gz" - url += ".gz" - elif packages not in md5sum: + if not self._comps: + packages_items = [self._enqueuePackages(fetcher, md5sum)] + else: + packages_items = [] + for component in self._comps: + item = self._enqueuePackages(fetcher, md5sum, component) + if item: + packages_items.append(item) + else: iface.warning(_("Component '%s' is not in Release file " "for channel '%s'") % (comp, self)) - continue - else: - upackages = None - info = {"component": comp, "uncomp": True} - info["md5"], info["size"] = md5sum[packages] - if upackages and upackages in md5sum: - info["uncomp_md5"], info["uncomp_size"] = md5sum[upackages] - pkgitems.append(fetcher.enqueue(url, **info)) - - #release = self._getURL("Release", comp, subpath=True) - #if release in md5sum: - # url = self._getURL("Release", comp) - # info = {"component": comp} - # info["md5"], info["size"] = md5sum[release] - # relitems.append(fetcher.enqueue(url, **info)) - #else: - # progress.add(1) - # progress.show() - # relitems.append(None) - - fetcher.run(progress=progress) - - else: # if not self._comps: - - item = fetcher.enqueue(self._getURL("Packages.gz"), uncomp=True) - fetcher.run(progress=progress) - failed = item.getFailedReason() - if failed: - if fetcher.getCaching() is NEVER: - lines = [_("Failed acquiring information for '%s':") % - self, u"%s: %s" % (item.getURL(), failed)] - raise Error, "\n".join(lines) - return False - digest = getFileDigest(item.getTargetPath()) - if digest == self._digest: - return True - self.removeLoaders() - - pkgitems = [item] + fetcher.run(progress=progress) errorlines = [] - for i in range(len(pkgitems)): - pkgitem = pkgitems[i] - #relitem = relitems[i] - if pkgitem.getStatus() == SUCCEEDED: - # Release files for components are not being used. - #if relitem and relitem.getStatus() == SUCCEEDED: - # try: - # for line in open(relitem.getTargetPath()): - # if line.startswith("..."): - # pass - # except (IOError, ValueError): - # pass - localpath = pkgitem.getTargetPath() + for item in packages_items: + if item.getStatus() == SUCCEEDED: + localpath = item.getTargetPath() loader = DebTagFileLoader(localpath, self._baseurl) loader.setChannel(self) self._loaders.append(loader) else: - errorlines.append(u"%s: %s" % (pkgitem.getURL(), - pkgitem.getFailedReason())) + errorlines.append(u"%s: %s" % (item.getURL(), + item.getFailedReason())) if errorlines: if fetcher.getCaching() is NEVER: @@ -238,15 +239,18 @@ raise Error, "\n".join(errorlines) return False - self._digest = digest + if digest: + self._digest = digest return True + def create(alias, data): return APTDEBChannel(data["baseurl"], data["distribution"], data["components"].split(), data["fingerprint"], + data["keyring"], data["type"], alias, data["name"], diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/smart-1.0/smart/const.py new/smart-1.1/smart/const.py --- old/smart-1.0/smart/const.py 2008-08-15 01:58:53.000000000 +0200 +++ new/smart-1.1/smart/const.py 2008-09-08 22:28:03.000000000 +0200 @@ -21,7 +21,7 @@ # import sys -VERSION = "1.0" +VERSION = "1.1" RECURSIONLIMIT = sys.getrecursionlimit() diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/smart-1.0/smart/fetcher.py new/smart-1.1/smart/fetcher.py --- old/smart-1.0/smart/fetcher.py 2008-08-15 01:58:53.000000000 +0200 +++ new/smart-1.1/smart/fetcher.py 2008-09-08 22:28:03.000000000 +0200 @@ -1512,8 +1512,11 @@ multi.remove_handle(handle) self._lock.release() - if handle.getinfo(pycurl.SIZE_DOWNLOAD) == 0: - # Not modified + http_code = handle.getinfo(pycurl.HTTP_CODE) + + if (http_code == 404 or + handle.getinfo(pycurl.SIZE_DOWNLOAD) == 0): + # Not modified or not found os.unlink(localpath+".part") else: if os.path.isfile(localpath): @@ -1527,15 +1530,18 @@ userhost = (url.user, url.host, url.port) self._inactive[handle] = userhost - valid, reason = fetcher.validate(item, localpath, - withreason=True) - if valid: - fetchedsize = handle.getinfo(pycurl.SIZE_DOWNLOAD) - item.setSucceeded(localpath, fetchedsize) - elif handle.partsize: - self._queue.append(item) + if http_code == 404: + item.setFailed(_("File not found")) else: - item.setFailed(reason) + valid, reason = fetcher.validate(item, localpath, + withreason=True) + if valid: + fetchedsize = handle.getinfo(pycurl.SIZE_DOWNLOAD) + item.setSucceeded(localpath, fetchedsize) + elif handle.partsize: + self._queue.append(item) + else: + item.setFailed(reason) for handle, errno, errmsg in failed: diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/smart-1.0/smart/plugins/aptchannelsync.py new/smart-1.1/smart/plugins/aptchannelsync.py --- old/smart-1.0/smart/plugins/aptchannelsync.py 2008-08-15 01:58:53.000000000 +0200 +++ new/smart-1.1/smart/plugins/aptchannelsync.py 2008-09-08 22:28:03.000000000 +0200 @@ -38,6 +38,10 @@ def _loadSourcesList(filename): + keyring_path = sysconf.get("sync-apt-keyring", "/etc/apt/trusted.gpg") + if not os.path.isfile(keyring_path): + keyring_path = None + file = open(filename) # The computed aliases we have seen in the given file. @@ -65,7 +69,7 @@ continue # We don't deal with these yet. # Build a unique alias. - m = md5.new("%s%s%s%s" % (type, uri, distro,comps)) + m = md5.new("%s|%s|%s|%s" % (type, uri, distro, comps)) alias = "aptsync-%s" % m.hexdigest() seen.add(alias) @@ -80,15 +84,22 @@ "name": "%s - %s" % (distro, comps), "baseurl": posixpath.join(uri, distro), "components": comps} - + # See if creating a channel works. try: createChannel(alias, data) except Error, e: iface.error(_("While using %s: %s") % (file.name, e)) else: - # Store it persistently. - sysconf.set(("channels", alias), data) + # Store it persistently, without destroying existing setttings. + channel = sysconf.get(("channels", alias)) + if channel is not None: + channel.update(data) + else: + channel = data + if keyring_path: + channel["keyring"] = keyring_path + sysconf.set(("channels", alias), channel) file.close() diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/smart-1.0/test.py new/smart-1.1/test.py --- old/smart-1.0/test.py 2008-08-15 01:58:53.000000000 +0200 +++ new/smart-1.1/test.py 2008-09-08 22:28:03.000000000 +0200 @@ -87,8 +87,6 @@ datadir = tempfile.mkdtemp() - __builtins__.__dict__.update(tests.__dict__) - try: const.DISTROFILE = "/non-existent/file" interface.getScreenWidth = lambda: 80 diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/smart-1.0/tests/aptdeb.py new/smart-1.1/tests/aptdeb.py --- old/smart-1.0/tests/aptdeb.py 1970-01-01 01:00:00.000000000 +0100 +++ new/smart-1.1/tests/aptdeb.py 2008-09-08 22:28:03.000000000 +0200 @@ -0,0 +1,343 @@ +from StringIO import StringIO +import shutil +import sys +import os + +from smart.channel import createChannel +from smart.progress import Progress +from smart.fetcher import Fetcher +from smart.const import NEVER +from smart.cache import Cache +from smart import Error, sysconf + +from tests.mocker import MockerTestCase +from tests import TESTDATADIR + + +FINGERPRINT = "2AAC 7928 0FBF 0299 5EB5 60E2 2253 B29A 6664 3A0C" + + +class AptDebChannelTest(MockerTestCase): + + def setUp(self): + self.progress = Progress() + self.fetcher = Fetcher() + self.cache = Cache() + + self.download_dir = self.makeDir() + self.fetcher.setLocalPathPrefix(self.download_dir + "/") + + # Disable caching so that things blow up when not found. + self.fetcher.setCaching(NEVER) + + sysconf.set("deb-arch", "i386") + + def tearDown(self): + sysconf.remove("deb-arch") + + def check_channel(self, channel): + self.assertEquals(channel.fetch(self.fetcher, self.progress), True) + + loaders = channel.getLoaders() + + self.assertEquals(len(loaders), 1) + + self.cache.addLoader(loaders[0]) + + saved = sys.stdout + sys.stdout = StringIO() + try: + self.cache.load() + finally: + sys.stdout = saved + + packages = sorted(self.cache.getPackages()) + + self.assertEquals(len(packages), 2) + self.assertEquals(packages[0].name, "name1") + self.assertEquals(packages[1].name, "name2") + + def test_fetch_with_component(self): + channel = createChannel("alias", + {"type": "apt-deb", + "baseurl": "file://%s/aptdeb" % TESTDATADIR, + "distribution": "./", + "components": "component"}) + self.check_channel(channel) + + def test_fetch_without_component(self): + channel = createChannel("alias", + {"type": "apt-deb", + "baseurl": "file://%s/aptdeb" % TESTDATADIR, + "distribution": "component-less"}) + self.check_channel(channel) + + def test_fetch_without_component_and_release_file(self): + channel = createChannel("alias", + {"type": "apt-deb", + "baseurl": "file://%s/deb" % TESTDATADIR, + "distribution": "./"}) + self.check_channel(channel) + + def test_fetch_without_component_and_release_file_with_keyring(self): + channel = createChannel("alias", + {"type": "apt-deb", + "baseurl": "file://%s/deb" % TESTDATADIR, + "distribution": "./", + "keyring": "/dev/null"}) + try: + self.check_channel(channel) + except Error, error: + self.assertEquals(str(error), + "Download of Release failed for channel 'alias': " + "File not found for validation") + else: + self.fail("Fetch worked with a bad signature! :-(") + + def test_fetch_with_unknown_signature(self): + channel = createChannel("alias", + {"type": "apt-deb", + "baseurl": "file://%s/aptdeb" % TESTDATADIR, + "distribution": "./", + "fingerprint": "NON-EXISTENT-FINGERPRINT", + "keyring": "%s/aptdeb/trusted.gpg" % + TESTDATADIR, + "components": "component"}) + try: + self.check_channel(channel) + except Error, error: + self.assertEquals(str(error), + "Channel 'alias' signed with unknown key") + else: + self.fail("Fetch worked with a bad signature! :-(") + + def test_fetch_without_component_and_with_unknown_signature(self): + channel = createChannel("alias", + {"type": "apt-deb", + "baseurl": "file://%s/aptdeb" % TESTDATADIR, + "distribution": "component-less", + "fingerprint": "NON-EXISTENT-FINGERPRINT", + "keyring": "%s/aptdeb/trusted.gpg" % + TESTDATADIR}) + try: + self.check_channel(channel) + except Error, error: + self.assertEquals(str(error), + "Channel 'alias' signed with unknown key") + else: + self.fail("Fetch worked with a bad signature! :-(") + + def test_fetch_with_unknown_signature_without_fingerprint(self): + channel = createChannel("alias", + {"type": "apt-deb", + "baseurl": "file://%s/aptdeb" % TESTDATADIR, + "distribution": "./", + "keyring": "%s/aptdeb/nonexistent.gpg" % + TESTDATADIR, + "components": "component"}) + try: + self.check_channel(channel) + except Error, error: + self.assertEquals(str(error), + "Channel 'alias' signed with unknown key") + else: + self.fail("Fetch worked with a bad signature! :-(") + + def test_fetch_with_unknown_signature_without_fingerprint_and_compon(self): + channel = createChannel("alias", + {"type": "apt-deb", + "baseurl": "file://%s/aptdeb" % TESTDATADIR, + "distribution": "component-less", + "keyring": "%s/aptdeb/nonexistent.gpg" % + TESTDATADIR}) + try: + self.check_channel(channel) + except Error, error: + self.assertEquals(str(error), + "Channel 'alias' signed with unknown key") + else: + self.fail("Fetch worked with a bad signature! :-(") + + def test_fetch_with_missing_keyring(self): + channel = createChannel("alias", + {"type": "apt-deb", + "baseurl": "file://%s/aptdeb" % TESTDATADIR, + "distribution": "./", + "fingerprint": "NON-EXISTENT-FINGERPRINT", + "keyring": "/dev/null", + "components": "component"}) + try: + self.check_channel(channel) + except Error, error: + self.assertEquals(str(error), + "Channel 'alias' signed with unknown key") + else: + self.fail("Fetch worked with a bad signature! :-(") + + def test_fetch_with_missing_keyring_without_component(self): + channel = createChannel("alias", + {"type": "apt-deb", + "baseurl": "file://%s/aptdeb" % TESTDATADIR, + "distribution": "component-less", + "fingerprint": "NON-EXISTENT-FINGERPRINT", + "keyring": "/dev/null"}) + try: + self.check_channel(channel) + except Error, error: + self.assertEquals(str(error), + "Channel 'alias' signed with unknown key") + else: + self.fail("Fetch worked with a bad signature! :-(") + + def test_fetch_with_good_signature(self): + channel = createChannel("alias", + {"type": "apt-deb", + "baseurl": "file://%s/aptdeb" % TESTDATADIR, + "distribution": "./", + "fingerprint": FINGERPRINT, + "keyring": "%s/aptdeb/trusted.gpg" % + TESTDATADIR, + "components": "component"}) + self.check_channel(channel) + + def test_fetch_with_good_signature_without_component(self): + channel = createChannel("alias", + {"type": "apt-deb", + "baseurl": "file://%s/aptdeb" % TESTDATADIR, + "distribution": "component-less", + "fingerprint": FINGERPRINT, + "keyring": "%s/aptdeb/trusted.gpg" % + TESTDATADIR}) + self.check_channel(channel) + + def test_fetch_with_good_signature_without_fingerprint(self): + channel = createChannel("alias", + {"type": "apt-deb", + "baseurl": "file://%s/aptdeb" % TESTDATADIR, + "distribution": "./", + "keyring": "%s/aptdeb/trusted.gpg" % + TESTDATADIR, + "components": "component"}) + self.check_channel(channel) + + def test_fetch_with_good_signature_without_fingerprint_and_component(self): + channel = createChannel("alias", + {"type": "apt-deb", + "baseurl": "file://%s/aptdeb" % TESTDATADIR, + "distribution": "component-less", + "keyring": "%s/aptdeb/trusted.gpg" % + TESTDATADIR}) + self.check_channel(channel) + + def test_fetch_without_component_with_corrupted_packages_file_size(self): + repo_dir = self.makeDir() + shutil.copytree(TESTDATADIR + "/aptdeb", repo_dir + "/aptdeb") + path = os.path.join(repo_dir, "aptdeb/component-less/Packages.gz") + file = open(path, "a") + file.write(" ") + file.close() + channel = createChannel("alias", + {"type": "apt-deb", + "baseurl": "file://%s/aptdeb" % repo_dir, + "distribution": "component-less"}) + try: + self.check_channel(channel) + except Error, error: + error_message = "Unexpected size (expected 571, got 572)" + self.assertTrue(str(error).endswith(error_message), str(error)) + else: + self.fail("Fetch worked with a bad signature! :-(") + + def test_fetch_without_component_with_corrupted_packages_file_md5(self): + repo_dir = self.makeDir() + shutil.copytree(TESTDATADIR + "/aptdeb", repo_dir + "/aptdeb") + path = os.path.join(repo_dir, "aptdeb/component-less/Packages.gz") + file = open(path, "r+") + file.seek(0) + file.write(" ") + file.close() + channel = createChannel("alias", + {"type": "apt-deb", + "baseurl": "file://%s/aptdeb" % repo_dir, + "distribution": "component-less"}) + try: + self.check_channel(channel) + except Error, error: + error_message = ("Invalid MD5 " + "(expected 384ccb05e3f6da02312b6e383b211777," + " got 6a2857275a35bf2b79e480e653431f83)") + self.assertTrue(str(error).endswith(error_message), str(error)) + else: + self.fail("Fetch worked with a bad signature! :-(") + + def test_fetch_without_component_with_corrupted_packages_file_md5(self): + repo_dir = self.makeDir() + shutil.copytree(TESTDATADIR + "/aptdeb", repo_dir + "/aptdeb") + path = os.path.join(repo_dir, "aptdeb/component-less/Packages.gz") + file = open(path, "r+") + file.seek(0) + file.write(" ") + file.close() + channel = createChannel("alias", + {"type": "apt-deb", + "baseurl": "file://%s/aptdeb" % repo_dir, + "distribution": "component-less"}) + try: + self.check_channel(channel) + except Error, error: + error_message = ("Invalid MD5 " + "(expected 384ccb05e3f6da02312b6e383b211777," + " got 6a2857275a35bf2b79e480e653431f83)") + self.assertTrue(str(error).endswith(error_message), str(error)) + else: + self.fail("Fetch worked with a bad signature! :-(") + + def test_fetch_with_corrupted_packages_file_size(self): + repo_dir = self.makeDir() + shutil.copytree(TESTDATADIR + "/aptdeb", repo_dir + "/aptdeb") + path = os.path.join(repo_dir, + "aptdeb/dists/component/binary-i386/Packages.gz") + file = open(path, "r+") + file.seek(0) + file.write(" ") + file.close() + channel = createChannel("alias", + {"type": "apt-deb", + "baseurl": "file://%s/aptdeb" % repo_dir, + "distribution": "./", + "components": "component", + }) + try: + self.check_channel(channel) + except Error, error: + error_message = ("Invalid MD5 " + "(expected 384ccb05e3f6da02312b6e383b211777," + " got 6a2857275a35bf2b79e480e653431f83)") + self.assertTrue(str(error).endswith(error_message), str(error)) + else: + self.fail("Fetch worked with a bad signature! :-(") + + def test_fetch_with_corrupted_packages_file_md5(self): + repo_dir = self.makeDir() + shutil.copytree(TESTDATADIR + "/aptdeb", repo_dir + "/aptdeb") + path = os.path.join(repo_dir, + "aptdeb/dists/component/binary-i386/Packages.gz") + file = open(path, "r+") + file.seek(0) + file.write(" ") + file.close() + channel = createChannel("alias", + {"type": "apt-deb", + "baseurl": "file://%s/aptdeb" % repo_dir, + "distribution": "./", + "components": "component", + }) + try: + self.check_channel(channel) + except Error, error: + error_message = ("Invalid MD5 " + "(expected 384ccb05e3f6da02312b6e383b211777," + " got 6a2857275a35bf2b79e480e653431f83)") + self.assertTrue(str(error).endswith(error_message), str(error)) + else: + self.fail("Fetch worked with a bad signature! :-(") diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/smart-1.0/tests/aptdeb.txt new/smart-1.1/tests/aptdeb.txt --- old/smart-1.0/tests/aptdeb.txt 2008-08-15 01:58:53.000000000 +0200 +++ new/smart-1.1/tests/aptdeb.txt 2008-09-08 22:28:03.000000000 +0200 @@ -1,6 +1,7 @@ Create the channel. + >>> from tests import * >>> from smart.channel import createChannel >>> channel = createChannel("alias", ... {"type": "apt-deb", @@ -43,10 +44,11 @@ This should give us one package with the data we already know. - >>> cache.getPackages() + >>> packages = sorted(cache.getPackages()) + >>> packages [name1_version1-release1, name2_version2-release2] - >>> pkg = cache.getPackages()[0] + >>> pkg = packages[0] >>> type(pkg)diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/smart-1.0/tests/aptrpm.txt new/smart-1.1/tests/aptrpm.txt --- old/smart-1.0/tests/aptrpm.txt 2008-08-15 01:58:53.000000000 +0200 +++ new/smart-1.1/tests/aptrpm.txt 2008-09-08 22:28:03.000000000 +0200 @@ -1,4 +1,6 @@ + >>> from tests import * + Create the channel. >>> from smart.channel import createChannel @@ -43,10 +45,11 @@ This should give us one package with the data we already know. - >>> cache.getPackages() + >>> packages = sorted(cache.getPackages()) + >>> packages [name1-version1-release1@noarch, name2-version2-release2@noarch] - >>> pkg = cache.getPackages()[0] + >>> pkg = packages[0] >>> type(pkg) diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/smart-1.0/tests/backend.txt new/smart-1.1/tests/backend.txt --- old/smart-1.0/tests/backend.txt 2008-08-15 01:58:53.000000000 +0200 +++ new/smart-1.1/tests/backend.txt 2008-09-08 22:28:03.000000000 +0200 @@ -4,6 +4,7 @@ We want everything from the cache. + >>> from tests import * >>> from smart.cache import * >>> class TestPackage(Package): pass diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/smart-1.0/tests/channel.py new/smart-1.1/tests/channel.py --- old/smart-1.0/tests/channel.py 2008-08-15 01:58:53.000000000 +0200 +++ new/smart-1.1/tests/channel.py 2008-09-08 22:28:03.000000000 +0200 @@ -1,6 +1,7 @@ import unittest -from smart.channel import parseChannelsDescription +from smart.channel import parseChannelsDescription, PackageChannel +from smart.cache import Loader class ParseChannelsDescriptionTest(unittest.TestCase): @@ -13,3 +14,12 @@ """) self.assertEquals(data, {'alias': {'type': 'deb-sys', 'name': 'first = second'}}) + + def test_removeLoaders_without_cache(self): + class TestChannel(PackageChannel): + def fetch(self, fetcher, progress): + self._loaders.append(Loader()) + channel = TestChannel("type", "alias") + channel.fetch(None, None) + channel.removeLoaders() + self.assertEquals(channel.getLoaders(), []) Files old/smart-1.0/tests/data/aptdeb/component-less/name1_version1-release1_all.deb and new/smart-1.1/tests/data/aptdeb/component-less/name1_version1-release1_all.deb differ Files old/smart-1.0/tests/data/aptdeb/component-less/name2_version2-release2_all.deb and new/smart-1.1/tests/data/aptdeb/component-less/name2_version2-release2_all.deb differ Files old/smart-1.0/tests/data/aptdeb/component-less/Packages.gz and new/smart-1.1/tests/data/aptdeb/component-less/Packages.gz differ diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/smart-1.0/tests/data/aptdeb/component-less/Release new/smart-1.1/tests/data/aptdeb/component-less/Release --- old/smart-1.0/tests/data/aptdeb/component-less/Release 1970-01-01 01:00:00.000000000 +0100 +++ new/smart-1.1/tests/data/aptdeb/component-less/Release 2008-09-08 22:28:03.000000000 +0200 @@ -0,0 +1,11 @@ +Origin: Smart +Codename: smart +Date: Wed, 03 Sep 2008 22:31:29 UTC +Label: Test Packages +Architectures: all +MD5Sum: + 384ccb05e3f6da02312b6e383b211777 571 Packages.gz +SHA1: + 1b795920940dbe025615e63c1e7326e4df606161 571 Packages.gz +SHA256: + beaa1d25b3102980dfa118841c9c569d7988f52f3c29aff044fc187a68a8891f 571 Packages.gz diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/smart-1.0/tests/data/aptdeb/component-less/Release.gpg new/smart-1.1/tests/data/aptdeb/component-less/Release.gpg --- old/smart-1.0/tests/data/aptdeb/component-less/Release.gpg 1970-01-01 01:00:00.000000000 +0100 +++ new/smart-1.1/tests/data/aptdeb/component-less/Release.gpg 2008-09-08 22:28:03.000000000 +0200 @@ -0,0 +1,7 @@ +-----BEGIN PGP SIGNATURE----- +Version: GnuPG v1.4.6 (GNU/Linux) + +iD8DBQBIwVHBIlOymmZkOgwRAmmbAKC7mPGvGDw7hitOBgtjJniyQrcx8gCgwg5F +1lZl26uLM1mQDGOX+Glo2IE= +=5cVJ +-----END PGP SIGNATURE----- Files old/smart-1.0/tests/data/aptdeb/dists/component/binary-i386/name1_version1-release1_all.deb and new/smart-1.1/tests/data/aptdeb/dists/component/binary-i386/name1_version1-release1_all.deb differ Files old/smart-1.0/tests/data/aptdeb/dists/component/binary-i386/name2_version2-release2_all.deb and new/smart-1.1/tests/data/aptdeb/dists/component/binary-i386/name2_version2-release2_all.deb differ Files old/smart-1.0/tests/data/aptdeb/dists/component/binary-i386/Packages.gz and new/smart-1.1/tests/data/aptdeb/dists/component/binary-i386/Packages.gz differ diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/smart-1.0/tests/data/aptdeb/dists/Release new/smart-1.1/tests/data/aptdeb/dists/Release --- old/smart-1.0/tests/data/aptdeb/dists/Release 1970-01-01 01:00:00.000000000 +0100 +++ new/smart-1.1/tests/data/aptdeb/dists/Release 2008-09-08 22:28:03.000000000 +0200 @@ -0,0 +1,12 @@ +Origin: Smart +Codename: smart +Date: Wed, 03 Sep 2008 22:31:29 UTC +Label: Test Packages +Architectures: all +Components: component +MD5Sum: + 384ccb05e3f6da02312b6e383b211777 571 component/binary-i386/Packages.gz +SHA1: + 1b795920940dbe025615e63c1e7326e4df606161 571 component/binary-all/Packages.gz +SHA256: + beaa1d25b3102980dfa118841c9c569d7988f52f3c29aff044fc187a68a8891f 571 component/binary-i386/Packages.gz diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/smart-1.0/tests/data/aptdeb/dists/Release.gpg new/smart-1.1/tests/data/aptdeb/dists/Release.gpg --- old/smart-1.0/tests/data/aptdeb/dists/Release.gpg 1970-01-01 01:00:00.000000000 +0100 +++ new/smart-1.1/tests/data/aptdeb/dists/Release.gpg 2008-09-08 22:28:03.000000000 +0200 @@ -0,0 +1,7 @@ +-----BEGIN PGP SIGNATURE----- +Version: GnuPG v1.4.6 (GNU/Linux) + +iD8DBQBIwD/oIlOymmZkOgwRAn7EAKCYogemoLIkN9BysZXejsK83WjA7QCgvXCQ +XexQLrr2xsAv2/L/aZQ+1zw= +=A5rE +-----END PGP SIGNATURE----- Files old/smart-1.0/tests/data/aptdeb/trusted.gpg and new/smart-1.1/tests/data/aptdeb/trusted.gpg differ File old/smart-1.0/tests/data/deb is a directory while file new/smart-1.1/tests/data/deb is a regular file diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/smart-1.0/tests/debdir.txt new/smart-1.1/tests/debdir.txt --- old/smart-1.0/tests/debdir.txt 2008-08-15 01:58:53.000000000 +0200 +++ new/smart-1.1/tests/debdir.txt 2008-09-08 22:28:03.000000000 +0200 @@ -1,6 +1,7 @@ Create the channel. + >>> from tests import * >>> from smart.channel import createChannel >>> channel = createChannel("alias", ... {"type": "deb-dir", @@ -42,10 +43,11 @@ This should give us one package with the data we already know. - >>> cache.getPackages() + >>> packages = sorted(cache.getPackages()) + >>> packages [name1_version1-release1, name2_version2-release2] - >>> pkg = cache.getPackages()[0] + >>> pkg = packages[0] >>> type(pkg) @@ -98,8 +100,8 @@ >>> url = info.getURLs()[0] >>> info.getSHA(url) - >>> info.getSize(url) - 1038L + >>> int(info.getSize(url)) + 1038 vim:ft=doctest diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/smart-1.0/tests/debpm.py new/smart-1.1/tests/debpm.py --- old/smart-1.0/tests/debpm.py 2008-08-15 01:58:53.000000000 +0200 +++ new/smart-1.1/tests/debpm.py 2008-09-08 22:28:03.000000000 +0200 @@ -10,7 +10,7 @@ from smart.fetcher import Fetcher from smart.cache import Cache from smart.const import INSTALL, REMOVE -from smart import iface +from smart import iface, sysconf from tests import TESTDATADIR, ctrl diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/smart-1.0/tests/fetcher.py new/smart-1.1/tests/fetcher.py --- old/smart-1.0/tests/fetcher.py 2008-08-15 01:58:53.000000000 +0200 +++ new/smart-1.1/tests/fetcher.py 2008-09-08 22:28:03.000000000 +0200 @@ -2,17 +2,25 @@ import threading import unittest import time +import os from smart.progress import Progress from smart.fetcher import Fetcher from smart.const import VERSION +from tests.mocker import MockerTestCase + PORT = 43543 -URL = "http://127.0.0.1:%d" % PORT +URL = "http://127.0.0.1:%d/filename.pkg" % PORT + +class FetcherTest(MockerTestCase): -class FetcherTest(unittest.TestCase): + def setUp(self): + self.local_path = self.makeDir() + self.fetcher = Fetcher() + self.fetcher.setLocalPathPrefix(self.local_path + "/") def start_server(self, handler): def server(): @@ -23,7 +31,7 @@ httpd.handle_request() self.server_thread = threading.Thread(target=server) self.server_thread.start() - time.sleep(0.2) + time.sleep(0.5) def wait_for_server(self): self.server_thread.join() @@ -33,9 +41,8 @@ def handler(request): headers[:] = request.headers.headers self.start_server(handler) - fetcher = Fetcher() - fetcher.enqueue(URL) - fetcher.run(progress=Progress()) + self.fetcher.enqueue(URL) + self.fetcher.run(progress=Progress()) self.assertTrue(("User-Agent: smart/%s\r\n" % VERSION) in headers) def test_remove_pragma_no_cache_from_curl(self): @@ -46,12 +53,23 @@ old_http_proxy = os.environ.get("http_proxy") os.environ["http_proxy"] = URL try: - fetcher = Fetcher() - fetcher.enqueue(URL) - fetcher.run(progress=Progress()) + self.fetcher.enqueue(URL) + self.fetcher.run(progress=Progress()) finally: if old_http_proxy: os.environ["http_proxy"] = old_http_proxy else: del os.environ["http_proxy"] self.assertTrue("Pragma: no-cache\r\n" not in headers) + + def test_404_handling(self): + headers = [] + def handler(request): + request.send_error(404, "An expected error") + request.send_header("Content-Length", "6") + request.wfile.write("Hello!") + self.start_server(handler) + self.fetcher.enqueue(URL) + self.fetcher.run(progress=Progress()) + item = self.fetcher.getItem(URL) + self.assertEquals(item.getFailedReason(), u"File not found") diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/smart-1.0/tests/metadata.txt new/smart-1.1/tests/metadata.txt --- old/smart-1.0/tests/metadata.txt 2008-08-15 01:58:53.000000000 +0200 +++ new/smart-1.1/tests/metadata.txt 2008-09-08 22:28:03.000000000 +0200 @@ -1,6 +1,7 @@ Create the channel. + >>> from tests import * >>> from smart.channel import createChannel >>> channel = createChannel("alias", ... {"type": "rpm-md", diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/smart-1.0/tests/nothing.txt new/smart-1.1/tests/nothing.txt --- old/smart-1.0/tests/nothing.txt 2008-08-15 01:58:53.000000000 +0200 +++ new/smart-1.1/tests/nothing.txt 2008-09-08 22:28:03.000000000 +0200 @@ -2,6 +2,7 @@ This test will execute the 'nothing' command. That command should just build the cache, and return. + >>> from tests import * >>> process = smart_process("nothing") >>> process.wait() 0 diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/smart-1.0/tests/plugins/test_aptchannelsync.py new/smart-1.1/tests/plugins/test_aptchannelsync.py --- old/smart-1.0/tests/plugins/test_aptchannelsync.py 2008-08-15 01:58:53.000000000 +0200 +++ new/smart-1.1/tests/plugins/test_aptchannelsync.py 2008-09-08 22:28:03.000000000 +0200 @@ -36,23 +36,26 @@ def setUp(self): self.apt_dir = self.makeDir() self.sources_dir = os.path.join(self.apt_dir, "sources.list.d") + self.keyring_file = os.path.join(self.apt_dir, "trusted.gpg") os.mkdir(self.sources_dir) + sysconf.set("sync-apt-keyring", self.keyring_file) def tearDown(self): sysconf.remove("channels") + sysconf.remove("sync-apt-keyring") def test_sychronize_sources_list(self): filename = self.makeFile(SOURCES_LIST_1, dirname=self.apt_dir, basename="sources.list") syncAptChannels(filename, self.sources_dir) self.assertEquals(sysconf.get("channels"), { - "aptsync-7448307d0748a16950338f05e5027cf1": + "aptsync-1cd42dbb12232a2e2582ad0145fd0516": {"distribution": "distro/name1", "type": "apt-deb", "name": "distro/name1 - comp1 comp2", "components": "comp1 comp2", "baseurl": "http://some/url/"}, - "aptsync-b15198b11bcb8f717051cb4fc5867522": + "aptsync-ca9430daa6beaccf4d4c9aad9e365c26": {"type": "apt-rpm", "name": "distro/name2 - comp1 comp2", "components": "comp1 comp2", @@ -65,18 +68,18 @@ self.makeFile(SOURCES_LIST_2, dirname=self.sources_dir, suffix=".list") syncAptChannels(filename, self.sources_dir) self.assertEquals(sysconf.get("channels"), { - "aptsync-7448307d0748a16950338f05e5027cf1": + "aptsync-1cd42dbb12232a2e2582ad0145fd0516": {"type": "apt-deb", "name": "distro/name1 - comp1 comp2", "distribution": "distro/name1", "components": "comp1 comp2", "baseurl": "http://some/url/"}, - "aptsync-b15198b11bcb8f717051cb4fc5867522": + "aptsync-ca9430daa6beaccf4d4c9aad9e365c26": {"type": "apt-rpm", "name": "distro/name2 - comp1 comp2", "components": "comp1 comp2", "baseurl": "http://some/url/distro/name2"}, - "aptsync-daf183fd6a41da026012b24e2d2904b7": + "aptsync-a3ea5e5aa96019e33241318e7f87a3d1": {"type": "apt-deb", "name": "distro/name3 - comp1 comp2", "distribution": "distro/name3", @@ -84,7 +87,6 @@ "baseurl": "http://some/url/"}, }) - def test_cleanup_removed_entries(self): filename = self.makeFile(SOURCES_LIST_1, dirname=self.apt_dir, basename="sources.list") @@ -94,13 +96,13 @@ basename="sources.list") syncAptChannels(filename, self.sources_dir) self.assertEquals(sysconf.get("channels"), { - "aptsync-7448307d0748a16950338f05e5027cf1": + "aptsync-1cd42dbb12232a2e2582ad0145fd0516": {"type": "apt-deb", "name": "distro/name1 - comp1 comp2", "distribution": "distro/name1", "components": "comp1 comp2", "baseurl": "http://some/url/"}, - "aptsync-daf183fd6a41da026012b24e2d2904b7": + "aptsync-a3ea5e5aa96019e33241318e7f87a3d1": {"type": "apt-deb", "name": "distro/name3 - comp1 comp2", "distribution": "distro/name3", @@ -113,3 +115,71 @@ basename="sources.list") syncAptChannels(filename, self.sources_dir) self.assertEquals(sysconf.get("channels"), None) + + def test_preserves_unrelated_changes(self): + filename = self.makeFile(SOURCES_LIST_1, dirname=self.apt_dir, + basename="sources.list") + syncAptChannels(filename, self.sources_dir) + channel_key = "aptsync-1cd42dbb12232a2e2582ad0145fd0516" + sysconf.set(("channels", channel_key, "disabled"), True) + syncAptChannels(filename, self.sources_dir) + self.assertEquals(sysconf.get(("channels", channel_key)), + {"distribution": "distro/name1", + "type": "apt-deb", + "name": "distro/name1 - comp1 comp2", + "components": "comp1 comp2", + "baseurl": "http://some/url/", + "disabled": True}) + + def test_keyring_is_set_when_present(self): + open(self.keyring_file, "w").close() + filename = self.makeFile(SOURCES_LIST_2, dirname=self.apt_dir, + basename="sources.list") + syncAptChannels(filename, self.sources_dir) + self.assertEquals(sysconf.get("channels"), + {"aptsync-a3ea5e5aa96019e33241318e7f87a3d1": + {"type": "apt-deb", + "name": "distro/name3 - comp1 comp2", + "distribution": "distro/name3", + "components": "comp1 comp2", + "baseurl": "http://some/url/", + "keyring": self.keyring_file} + }) + + def test_keyring_isnt_reset_after_being_removed(self): + open(self.keyring_file, "w").close() + filename = self.makeFile(SOURCES_LIST_2, dirname=self.apt_dir, + basename="sources.list") + syncAptChannels(filename, self.sources_dir) + sysconf.remove(("channels", + "aptsync-a3ea5e5aa96019e33241318e7f87a3d1", + "keyring")) + syncAptChannels(filename, self.sources_dir) + self.assertEquals(sysconf.get("channels"), + {"aptsync-a3ea5e5aa96019e33241318e7f87a3d1": + {"type": "apt-deb", + "name": "distro/name3 - comp1 comp2", + "distribution": "distro/name3", + "components": "comp1 comp2", + "baseurl": "http://some/url/"}, + }) + + def test_keyring_isnt_changed_if_modified(self): + open(self.keyring_file, "w").close() + filename = self.makeFile(SOURCES_LIST_2, dirname=self.apt_dir, + basename="sources.list") + syncAptChannels(filename, self.sources_dir) + sysconf.set(("channels", + "aptsync-a3ea5e5aa96019e33241318e7f87a3d1", + "keyring"), + "/a/different/keyring.gpg") + syncAptChannels(filename, self.sources_dir) + self.assertEquals(sysconf.get("channels"), + {"aptsync-a3ea5e5aa96019e33241318e7f87a3d1": + {"type": "apt-deb", + "name": "distro/name3 - comp1 comp2", + "distribution": "distro/name3", + "components": "comp1 comp2", + "baseurl": "http://some/url/", + "keyring": "/a/different/keyring.gpg"}, + }) diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/smart-1.0/tests/rpmdir.txt new/smart-1.1/tests/rpmdir.txt --- old/smart-1.0/tests/rpmdir.txt 2008-08-15 01:58:53.000000000 +0200 +++ new/smart-1.1/tests/rpmdir.txt 2008-09-08 22:28:03.000000000 +0200 @@ -1,6 +1,7 @@ Create the channel. + >>> from tests import * >>> from smart.channel import createChannel >>> channel = createChannel("alias", ... {"type": "rpm-dir", @@ -42,10 +43,11 @@ This should give us one package with the data we already know. - >>> cache.getPackages() + >>> packages = sorted(cache.getPackages()) + >>> packages [name1-version1-release1@noarch, name2-version2-release2@noarch] - >>> pkg = cache.getPackages()[0] + >>> pkg = packages[0] >>> type(pkg) @@ -96,8 +98,8 @@ >>> url = info.getURLs()[0] >>> info.getSHA(url) - >>> info.getSize(url) - 2160L + >>> int(info.getSize(url)) + 2160 vim:ft=doctest diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/smart-1.0/tests/urpmi.txt new/smart-1.1/tests/urpmi.txt --- old/smart-1.0/tests/urpmi.txt 2008-08-15 01:58:53.000000000 +0200 +++ new/smart-1.1/tests/urpmi.txt 2008-09-08 22:28:03.000000000 +0200 @@ -1,6 +1,7 @@ Create the channel. + >>> from tests import * >>> from smart.channel import createChannel >>> channel = createChannel("alias", ... {"type": "urpmi", @@ -46,10 +47,11 @@ This should give us one package with the data we already know. - >>> cache.getPackages() + >>> packages = sorted(cache.getPackages()) + >>> packages [name1-version1-release1@noarch, name2-version2-release2@noarch] - >>> pkg = cache.getPackages()[0] + >>> pkg = packages[0] >>> type(pkg) diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/smart-1.0/tests/yast2comp.txt new/smart-1.1/tests/yast2comp.txt --- old/smart-1.0/tests/yast2comp.txt 2008-08-15 01:58:53.000000000 +0200 +++ new/smart-1.1/tests/yast2comp.txt 2008-09-08 22:28:03.000000000 +0200 @@ -1,6 +1,7 @@ Create the channel. + >>> from tests import * >>> from smart.channel import createChannel >>> channel = createChannel("alias", ... {"type": "yast2", diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/smart-1.0/tests/yast2.txt new/smart-1.1/tests/yast2.txt --- old/smart-1.0/tests/yast2.txt 2008-08-15 01:58:53.000000000 +0200 +++ new/smart-1.1/tests/yast2.txt 2008-09-08 22:28:03.000000000 +0200 @@ -1,6 +1,7 @@ Create the channel. + >>> from tests import * >>> from smart.channel import createChannel >>> channel = createChannel("alias", ... {"type": "yast2", @@ -42,10 +43,11 @@ This should give us one package with the data we already know. - >>> cache.getPackages() + >>> packages = sorted(cache.getPackages()) + >>> packages [name1-version1-release1@noarch, name2-version2-release2@noarch] - >>> pkg = cache.getPackages()[0] + >>> pkg = packages[0] >>> type(pkg) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Remember to have fun... --------------------------------------------------------------------- To unsubscribe, e-mail: opensuse-commit+unsubscribe@opensuse.org For additional commands, e-mail: opensuse-commit+help@opensuse.org