diff options
Diffstat (limited to 'test')
40 files changed, 784 insertions, 384 deletions
diff --git a/test/pacman/README b/test/pacman/README index 0bd02138..a3c36fc9 100644 --- a/test/pacman/README +++ b/test/pacman/README @@ -22,7 +22,7 @@ The following directory structure is used: - var/cache/pkg: sync packages cache - var/log/pactest.log: log file - var/pub: location for pseudo sync repositories - - tmp: hold all local package archives (to be used with pacman -A or -U) + - tmp: hold all local package archives (to be used with pacman -U) Note: the logfile is used to capture all pacman outputs. @@ -34,7 +34,7 @@ Test case example: "usr/man/man1/dummy.1"] self.addpkg(p) - self.args = "-A dummy-1.0-1.pkg.tar.gz" + self.args = "-U dummy-1.0-1.pkg.tar.gz" self.addrule("PACMAN_RETCODE=0") self.addrule("PKG_EXIST=dummy") @@ -42,7 +42,7 @@ Test case example: self.addrule("FILE_EXIST=%s" % f) Basically, the above test case will try to install a package (dummy-1.0-3), -including two files, from a local archive, by calling "pacman -A" +including two files, from a local archive, by calling "pacman -U" Upon completion, it checks that: - pacman returned no error code, - a "dummy" entry exists in the "local" database diff --git a/test/pacman/pactest.py b/test/pacman/pactest.py index 69e655a0..62034dc7 100755 --- a/test/pacman/pactest.py +++ b/test/pacman/pactest.py @@ -17,8 +17,12 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. -import os, sys, glob +import glob from optparse import OptionParser +import os +import shutil +import sys +import tempfile import pmenv import util @@ -26,10 +30,10 @@ import util __author__ = "Aurelien FORET" __version__ = "0.4" -def resolveBinPath(option, opt_str, value, parser): +def resolve_binary_path(option, opt_str, value, parser): setattr(parser.values, option.dest, os.path.abspath(value)) -def globTests(option, opt_str, value, parser): +def glob_tests(option, opt_str, value, parser): idx = 0 globlist = [] @@ -42,8 +46,7 @@ def globTests(option, opt_str, value, parser): parser.rargs = parser.rargs[idx:] setattr(parser.values, option.dest, globlist) -def createOptParser(): - testcases = [] +def create_parser(): usage = "usage: %prog [options] [[--test <path/to/testfile.py>] ...]" description = "Runs automated tests on the pacman binary. Tests are " \ "described using an easy python syntax, and several can be " \ @@ -57,12 +60,15 @@ def createOptParser(): dest = "debug", default = 0, help = "set debug level for pacman") parser.add_option("-p", "--pacman", action = "callback", - callback = resolveBinPath, type = "string", + callback = resolve_binary_path, type = "string", dest = "bin", default = "pacman", help = "specify location of the pacman binary") parser.add_option("-t", "--test", action = "callback", - callback = globTests, dest = "testcases", + callback = glob_tests, dest = "testcases", help = "specify test case(s)") + parser.add_option("--keep-root", action = "store_true", + dest = "keeproot", default = False, + help = "don't remove the generated pacman root filesystem") parser.add_option("--nolog", action = "store_true", dest = "nolog", default = False, help = "do not log pacman messages") @@ -80,8 +86,9 @@ def createOptParser(): if __name__ == "__main__": # instantiate env and parser objects - env = pmenv.pmenv() - opt_parser = createOptParser() + root_path = tempfile.mkdtemp() + env = pmenv.pmenv(root=root_path) + opt_parser = create_parser() (opts, args) = opt_parser.parse_args() # add parsed options to env object @@ -95,16 +102,22 @@ if __name__ == "__main__": if opts.testcases is None or len(opts.testcases) == 0: print "no tests defined, nothing to do" + os.rmdir(root_path) sys.exit(2) - else: - for i in opts.testcases: - env.addtest(i) - # run tests and print overall results - env.run() - env.results() + for i in opts.testcases: + env.addtest(i) + + # run tests and print overall results + env.run() + env.results() + + if not opts.keeproot: + shutil.rmtree(root_path) + else: + print "pacman testing root saved: %s" % root_path - if env.failed > 0: - sys.exit(1) + if env.failed > 0: + sys.exit(1) # vim: set ts=4 sw=4 et: diff --git a/test/pacman/pmdb.py b/test/pacman/pmdb.py index b31498a7..5195ec64 100755..100644 --- a/test/pacman/pmdb.py +++ b/test/pacman/pmdb.py @@ -17,41 +17,14 @@ import os +import shutil +from StringIO import StringIO import tarfile import pmpkg import util -def _mkfilelist(files): - """Generate a list of files from the list supplied as an argument. - - Each path is decomposed to generate the list of all directories leading - to the file. - - Example with 'usr/local/bin/dummy': - The resulting list will be - usr/ - usr/local/ - usr/local/bin/ - usr/local/bin/dummy - """ - file_set = set() - for f in files: - name = util.getfilename(f) - file_set.add(name) - while "/" in name: - [name, tmp] = name.rsplit("/", 1) - file_set.add(name + "/") - return sorted(file_set) - -def _mkbackuplist(backup): - """ - """ - return ["%s\t%s" % (util.getfilename(i), util.mkmd5sum(i)) for i in backup] - def _getsection(fd): - """ - """ i = [] while 1: line = fd.readline().strip("\n") @@ -60,16 +33,16 @@ def _getsection(fd): i.append(line) return i -def _mksection(title, data): - """ - """ - s = "" - if isinstance(data, list): - s = "\n".join(data) +def make_section(data, title, values): + if not values: + return + data.append("%%%s%%" % title) + if isinstance(values, (list, tuple)): + data.extend(str(item) for item in values) else: - s = data - return "%%%s%%\n" \ - "%s\n" % (title, s) + # just a single value + data.append(str(values)) + data.append('\n') class pmdb(object): @@ -78,45 +51,56 @@ class pmdb(object): def __init__(self, treename, root): self.treename = treename + self.root = root self.pkgs = [] self.option = {} if self.treename == "local": self.dbdir = os.path.join(root, util.PM_DBPATH, treename) + self.dbfile = None + self.is_local = True + self.read_dircache = None + self.read_pkgcache = {} else: - self.dbdir = os.path.join(root, util.PM_SYNCDBPATH, treename) + self.dbdir = None self.dbfile = os.path.join(root, util.PM_SYNCDBPATH, treename + ".db") + self.is_local = False def __str__(self): return "%s" % self.treename + def getverify(self): + for value in ("Always", "Never", "Optional"): + if value in self.treename: + return value + return "Never" + def getpkg(self, name): - """ - """ for pkg in self.pkgs: if name == pkg.name: return pkg def db_read(self, name): - """ - """ - path = self.dbdir - if not os.path.isdir(path): + if not self.dbdir or not os.path.isdir(self.dbdir): return None - dbentry = "" - for roots, dirs, files in os.walk(path): - for i in dirs: - [pkgname, pkgver, pkgrel] = i.rsplit("-", 2) - if pkgname == name: - dbentry = i - break - if not dbentry: + dbentry = None + if self.read_dircache is None: + self.read_dircache = os.listdir(self.dbdir) + for entry in self.read_dircache: + [pkgname, pkgver, pkgrel] = entry.rsplit("-", 2) + if pkgname == name: + dbentry = entry + break + if dbentry is None: return None - path = os.path.join(path, dbentry) - [pkgname, pkgver, pkgrel] = dbentry.rsplit("-", 2) + if pkgname in self.read_pkgcache: + return self.read_pkgcache[pkgname] + pkg = pmpkg.pmpkg(pkgname, pkgver + "-" + pkgrel) + self.read_pkgcache[pkgname] = pkg + path = os.path.join(self.dbdir, dbentry) # desc filename = os.path.join(path, "desc") if not os.path.isfile(filename): @@ -145,11 +129,21 @@ class pmdb(object): elif line == "%PACKAGER%": pkg.packager = fd.readline().strip("\n") elif line == "%REASON%": - pkg.reason = int(fd.readline().strip("\n")) + try: + pkg.reason = int(fd.readline().strip("\n")) + except ValueError: + pkg.reason = -1 + raise elif line == "%SIZE%" or line == "%CSIZE%": - pkg.size = int(fd.readline().strip("\n")) + try: + pkg.size = int(fd.readline().strip("\n")) + except ValueError: + pkg.size = -1 + raise elif line == "%MD5SUM%": pkg.md5sum = fd.readline().strip("\n") + elif line == "%PGPSIG%": + pkg.pgpsig = fd.readline().strip("\n") elif line == "%REPLACES%": pkg.replaces = _getsection(fd) elif line == "%DEPENDS%": @@ -191,100 +185,75 @@ class pmdb(object): # db_write is used to add both 'local' and 'sync' db entries # def db_write(self, pkg): - """ - """ - path = os.path.join(self.dbdir, pkg.fullname()) - util.mkdir(path) - - # desc - # for local db entries: name, version, desc, groups, url, license, - # arch, builddate, installdate, packager, - # size, reason, depends, conflicts, provides - # for sync entries: name, version, desc, groups, csize, md5sum, - # replaces, force, depends, conflicts, provides - data = [_mksection("NAME", pkg.name)] - data.append(_mksection("VERSION", pkg.version)) - if pkg.desc: - data.append(_mksection("DESC", pkg.desc)) - if pkg.groups: - data.append(_mksection("GROUPS", pkg.groups)) - if pkg.license: - data.append(_mksection("LICENSE", pkg.license)) - if pkg.arch: - data.append(_mksection("ARCH", pkg.arch)) - if pkg.builddate: - data.append(_mksection("BUILDDATE", pkg.builddate)) - if pkg.packager: - data.append(_mksection("PACKAGER", pkg.packager)) - if pkg.depends: - data.append(_mksection("DEPENDS", pkg.depends)) - if pkg.optdepends: - data.append(_mksection("OPTDEPENDS", pkg.optdepends)) - if pkg.conflicts: - data.append(_mksection("CONFLICTS", pkg.conflicts)) - if pkg.provides: - data.append(_mksection("PROVIDES", pkg.provides)) - if self.treename == "local": - if pkg.url: - data.append(_mksection("URL", pkg.url)) - if pkg.installdate: - data.append(_mksection("INSTALLDATE", pkg.installdate)) - if pkg.size: - data.append(_mksection("SIZE", pkg.size)) - if pkg.reason: - data.append(_mksection("REASON", pkg.reason)) + entry = {} + # desc/depends type entries + data = [] + make_section(data, "NAME", pkg.name) + make_section(data, "VERSION", pkg.version) + make_section(data, "DESC", pkg.desc) + make_section(data, "GROUPS", pkg.groups) + make_section(data, "LICENSE", pkg.license) + make_section(data, "ARCH", pkg.arch) + make_section(data, "BUILDDATE", pkg.builddate) + make_section(data, "PACKAGER", pkg.packager) + make_section(data, "DEPENDS", pkg.depends) + make_section(data, "OPTDEPENDS", pkg.optdepends) + make_section(data, "CONFLICTS", pkg.conflicts) + make_section(data, "PROVIDES", pkg.provides) + make_section(data, "URL", pkg.url) + if self.is_local: + make_section(data, "INSTALLDATE", pkg.installdate) + make_section(data, "SIZE", pkg.size) + make_section(data, "REASON", pkg.reason) else: - data.append(_mksection("FILENAME", pkg.filename())) - if pkg.replaces: - data.append(_mksection("REPLACES", pkg.replaces)) - if pkg.csize: - data.append(_mksection("CSIZE", pkg.csize)) - if pkg.md5sum: - data.append(_mksection("MD5SUM", pkg.md5sum)) - if data: - data.append("") - filename = os.path.join(path, "desc") - util.mkfile(filename, "\n".join(data)) + make_section(data, "FILENAME", pkg.filename()) + make_section(data, "REPLACES", pkg.replaces) + make_section(data, "CSIZE", pkg.csize) + make_section(data, "ISIZE", pkg.isize) + make_section(data, "MD5SUM", pkg.md5sum) + make_section(data, "PGPSIG", pkg.pgpsig) - # files - # for local entries, fields are: files, backup - # for sync ones: none - if self.treename == "local": + entry["desc"] = "\n".join(data) + + # files and install + if self.is_local: data = [] - if pkg.files: - data.append(_mksection("FILES", _mkfilelist(pkg.files))) - if pkg.backup: - data.append(_mksection("BACKUP", _mkbackuplist(pkg.backup))) - if data: - data.append("") - filename = os.path.join(path, "files") - util.mkfile(filename, "\n".join(data)) + make_section(data, "FILES", pkg.full_filelist()) + make_section(data, "BACKUP", pkg.local_backup_entries()) + entry["files"] = "\n".join(data) - # install - if self.treename == "local": - empty = 1 - for value in pkg.install.values(): - if value: - empty = 0 - if not empty: - filename = os.path.join(path, "install") - util.mkinstallfile(filename, pkg.install) + if any(pkg.install.values()): + entry["install"] = pkg.installfile() - def gensync(self): - """ - """ + return entry - if not self.dbfile: - return - curdir = os.getcwd() - os.chdir(self.dbdir) + def generate(self): + pkg_entries = [(pkg, self.db_write(pkg)) for pkg in self.pkgs] - # Generate database archive - tar = tarfile.open(self.dbfile, "w:gz") - for i in os.listdir("."): - tar.add(i) - tar.close() + if self.dbdir: + for pkg, entry in pkg_entries: + path = os.path.join(self.dbdir, pkg.fullname()) + util.mkdir(path) + for name, data in entry.iteritems(): + util.mkfile(path, name, data) - os.chdir(curdir) + if self.dbfile: + tar = tarfile.open(self.dbfile, "w:gz") + for pkg, entry in pkg_entries: + # TODO: the addition of the directory is currently a + # requirement for successful reading of a DB by libalpm + info = tarfile.TarInfo(pkg.fullname()) + info.type = tarfile.DIRTYPE + tar.addfile(info) + for name, data in entry.iteritems(): + filename = os.path.join(pkg.fullname(), name) + info = tarfile.TarInfo(filename) + info.size = len(data) + tar.addfile(info, StringIO(data)) + tar.close() + # TODO: this is a bit unnecessary considering only one test uses it + serverpath = os.path.join(self.root, util.SYNCREPO, self.treename) + util.mkdir(serverpath) + shutil.copy(self.dbfile, serverpath) # vim: set ts=4 sw=4 et: diff --git a/test/pacman/pmenv.py b/test/pacman/pmenv.py index 40444829..e9950fe8 100755..100644 --- a/test/pacman/pmenv.py +++ b/test/pacman/pmenv.py @@ -17,7 +17,6 @@ import os -import os.path import pmtest @@ -102,35 +101,39 @@ class pmenv(object): tfailed.append(test) def _printtest(t): - success = test.result["success"] - fail = test.result["fail"] - rules = len(test.rules) + success = t.result["success"] + fail = t.result["fail"] + rules = len(t.rules) if fail == 0: result = "[PASS]" else: result = "[FAIL]" print result, print "%s Rules: OK = %2u FAIL = %2u SKIP = %2u" \ - % (test.testname.ljust(34), success, fail, \ + % (t.testname.ljust(34), success, fail, \ rules - (success + fail)) if fail != 0: # print test description if test failed - print " ", test.description + print " ", t.description print "=========="*8 print "Results" print "----------"*8 print " Passed:" - for test in tpassed: _printtest(test) + for test in tpassed: + _printtest(test) print "----------"*8 print " Expected Failures:" - for test in texpectedfail: _printtest(test) + for test in texpectedfail: + _printtest(test) print "----------"*8 print " Unexpected Passes:" - for test in tunexpectedpass: _printtest(test) + for test in tunexpectedpass: + _printtest(test) print "----------"*8 print " Failed:" - for test in tfailed: _printtest(test) + for test in tfailed: + _printtest(test) print "----------"*8 total = len(self.testcases) @@ -142,7 +145,4 @@ class pmenv(object): print "Fail = %3u (%6.2f%%)" % (self.failed, float(self.failed) * 100 / total) print "" -if __name__ == "__main__": - pass - # vim: set ts=4 sw=4 et: diff --git a/test/pacman/pmfile.py b/test/pacman/pmfile.py index bd03a24e..638b451e 100755..100644 --- a/test/pacman/pmfile.py +++ b/test/pacman/pmfile.py @@ -17,38 +17,44 @@ import os +import stat import util -class pmfile(object): +class PacmanFile(object): """File object """ def __init__(self, root, name): - self.name = name self.root = root + self.name = name self.filename = os.path.join(self.root, self.name) self.checksum = util.getmd5sum(self.filename) - self.mtime = util.getmtime(self.filename) + self.mtime = self.getmtime() def __str__(self): return "%s (%s / %lu)" % (self.name, self.checksum, self.mtime) + def getmtime(self): + if not os.path.exists(self.filename): + return None, None + statbuf = os.lstat(self.filename) + return (statbuf[stat.ST_MTIME], statbuf[stat.ST_CTIME]) + def ismodified(self): - """ - """ checksum = util.getmd5sum(self.filename) - mtime = util.getmtime(self.filename) + mtime = self.getmtime() util.vprint("\tismodified(%s)" % self.name) util.vprint("\t\told: %s / %s" % (self.checksum, self.mtime)) util.vprint("\t\tnew: %s / %s" % (checksum, mtime)) if self.checksum != checksum \ - or (self.mtime[1], self.mtime[2]) != (mtime[1], mtime[2]): - return 1 + or self.mtime[0] != mtime[0] \ + or self.mtime[1] != mtime[1]: + return True - return 0 + return False # vim: set ts=4 sw=4 et: diff --git a/test/pacman/pmpkg.py b/test/pacman/pmpkg.py index be177f35..7aa77f6a 100755..100644 --- a/test/pacman/pmpkg.py +++ b/test/pacman/pmpkg.py @@ -20,6 +20,7 @@ import os import tempfile import stat import shutil +from StringIO import StringIO import tarfile import util @@ -27,7 +28,7 @@ import util class pmpkg(object): """Package object. - Object holding data from an ArchLinux package. + Object holding data from an Arch Linux package. """ def __init__(self, name, version = "1.0-1"): @@ -45,8 +46,10 @@ class pmpkg(object): self.packager = "" self.size = 0 self.csize = 0 + self.isize = 0 self.reason = 0 self.md5sum = "" # sync only + self.pgpsig = "" # sync only self.replaces = [] self.depends = [] self.optdepends = [] @@ -62,8 +65,9 @@ class pmpkg(object): "pre_remove": "", "post_remove": "", "pre_upgrade": "", - "post_upgrade": "" + "post_upgrade": "", } + self.path = None def __str__(self): s = ["%s" % self.fullname()] @@ -87,22 +91,24 @@ class pmpkg(object): """ return "%s%s" % (self.fullname(), util.PM_EXT_PKG) + @staticmethod + def parse_filename(name): + filename = name + if filename[-1] == "*": + filename = filename.rstrip("*") + if filename.find(" -> ") != -1: + filename, extra = filename.split(" -> ") + elif filename.find("|") != -1: + filename, extra = filename.split("|") + return filename + def makepkg(self, path): - """Creates an ArchLinux package archive. + """Creates an Arch Linux package archive. A package archive is generated in the location 'path', based on the data from the object. """ - self.path = os.path.join(path, self.filename()) - - curdir = os.getcwd() - tmpdir = tempfile.mkdtemp() - os.chdir(tmpdir) - - # Generate package file system - for f in self.files: - util.mkfile(f, f) - self.size += os.lstat(util.getfilename(f))[stat.ST_SIZE] + archive_files = [] # .PKGINFO data = ["pkgname = %s" % self.name] @@ -130,22 +136,82 @@ class pmpkg(object): data.append("provides = %s" % i) for i in self.backup: data.append("backup = %s" % i) - util.mkfile(".PKGINFO", "\n".join(data)) + archive_files.append((".PKGINFO", "\n".join(data))) # .INSTALL - if len(self.install.values()) > 0: - util.mkinstallfile(".INSTALL", self.install) + if any(self.install.values()): + archive_files.append((".INSTALL", self.installfile())) - # safely create the dir + self.path = os.path.join(path, self.filename()) util.mkdir(os.path.dirname(self.path)) - # Generate package archive + # Generate package metadata tar = tarfile.open(self.path, "w:gz") - for i in os.listdir("."): - tar.add(i) + for name, data in archive_files: + info = tarfile.TarInfo(name) + info.size = len(data) + tar.addfile(info, StringIO(data)) + + # Generate package file system + for name in self.files: + fileinfo = util.getfileinfo(name) + info = tarfile.TarInfo(fileinfo["filename"]) + if fileinfo["hasperms"]: + info.mode = fileinfo["perms"] + if fileinfo["isdir"]: + info.type = tarfile.DIRTYPE + tar.addfile(info) + elif fileinfo["islink"]: + info.type = tarfile.SYMTYPE + info.linkname = fileinfo["link"] + tar.addfile(info) + else: + # TODO wow what a hack, adding a newline to match mkfile? + filedata = name + "\n" + info.size = len(filedata) + tar.addfile(info, StringIO(filedata)) + tar.close() - os.chdir(curdir) - shutil.rmtree(tmpdir) + def install_package(self, root): + """Install the package in the given root.""" + for f in self.files: + util.mkfile(root, f, f) + path = os.path.join(root, f) + if os.path.isfile(path): + os.utime(path, (355, 355)) + + def full_filelist(self): + """Generate a list of package files. + + Each path is decomposed to generate the list of all directories leading + to the file. + + Example with 'usr/local/bin/dummy': + The resulting list will be: + usr/ + usr/local/ + usr/local/bin/ + usr/local/bin/dummy + """ + file_set = set() + for name in self.files: + name = self.parse_filename(name) + file_set.add(name) + while "/" in name: + name, tmp = name.rsplit("/", 1) + file_set.add(name + "/") + return sorted(file_set) + + def local_backup_entries(self): + return ["%s\t%s" % (self.parse_filename(i), util.mkmd5sum(i)) for i in self.backup] + + def installfile(self): + data = [] + for key, value in self.install.iteritems(): + if value: + data.append("%s() {\n%s\n}\n" % (key, value)) + + return "\n".join(data) # vim: set ts=4 sw=4 et: diff --git a/test/pacman/pmrule.py b/test/pacman/pmrule.py index 0f6ae602..d64f5194 100755..100644 --- a/test/pacman/pmrule.py +++ b/test/pacman/pmrule.py @@ -42,7 +42,7 @@ class pmrule(object): [testname, args] = self.rule.split("=") if testname[0] == "!": self.false = 1 - testname = testname.lstrip("!") + testname = testname[1:] [kind, case] = testname.split("_") if "|" in args: [key, value] = args.split("|", 1) @@ -146,6 +146,14 @@ class pmrule(object): else: print "FILE rule '%s' not found" % case success = -1 + elif kind == "DIR": + filename = os.path.join(test.root, key) + if case == "EXIST": + if not os.path.isdir(filename): + success = 0 + else: + print "DIR rule '%s' not found" % case + success = -1 elif kind == "LINK": filename = os.path.join(test.root, key) if case == "EXIST": diff --git a/test/pacman/pmtest.py b/test/pacman/pmtest.py index 82dfda6d..0572d6f0 100755..100644 --- a/test/pacman/pmtest.py +++ b/test/pacman/pmtest.py @@ -17,9 +17,10 @@ import os -import os.path +import shlex import shutil import stat +import subprocess import time import pmrule @@ -44,15 +45,11 @@ class pmtest(object): "root = %s" % (self.name, self.testname, self.root) def addpkg2db(self, treename, pkg): - """ - """ if not treename in self.db: self.db[treename] = pmdb.pmdb(treename, self.root) self.db[treename].pkgs.append(pkg) def addpkg(self, pkg): - """ - """ self.localpkgs.append(pkg) def findpkg(self, name, version, allow_local=False): @@ -60,7 +57,7 @@ class pmtest(object): either sync databases or the local package collection. The local database is allowed to match if allow_local is True.""" for db in self.db.itervalues(): - if db.treename == "local" and not allow_local: + if db.is_local and not allow_local: continue pkg = db.getpkg(name) if pkg and pkg.version == version: @@ -72,15 +69,10 @@ class pmtest(object): return None def addrule(self, rulename): - """ - """ rule = pmrule.pmrule(rulename) self.rules.append(rule) def load(self): - """ - """ - # Reset test parameters self.result = { "success": 0, @@ -111,9 +103,6 @@ class pmtest(object): raise IOError("file %s does not exist!" % self.name) def generate(self): - """ - """ - print "==> Generating test environment" # Cleanup leftover files from a previous test session @@ -123,7 +112,7 @@ class pmtest(object): # Create directory structure vprint(" Creating directory structure:") - dbdir = os.path.join(self.root, util.PM_DBPATH) + dbdir = os.path.join(self.root, util.PM_SYNCDBPATH) cachedir = os.path.join(self.root, util.PM_CACHEDIR) syncdir = os.path.join(self.root, util.SYNCREPO) tmpdir = os.path.join(self.root, util.TMPDIR) @@ -159,40 +148,21 @@ class pmtest(object): pkg.md5sum = util.getmd5sum(pkg.path) pkg.csize = os.stat(pkg.path)[stat.ST_SIZE] - # Populating databases - vprint(" Populating databases") - for key, value in self.db.iteritems(): - for pkg in value.pkgs: - vprint("\t%s/%s" % (key, pkg.fullname())) - if key == "local": - pkg.installdate = time.ctime() - value.db_write(pkg) - # Creating sync database archives - vprint(" Creating sync database archives") + vprint(" Creating databases") for key, value in self.db.iteritems(): - if key == "local": - continue vprint("\t" + value.treename) - value.gensync() - serverpath = os.path.join(syncdir, value.treename) - util.mkdir(serverpath) - shutil.copy(value.dbfile, serverpath) + value.generate() # Filesystem vprint(" Populating file system") for pkg in self.db["local"].pkgs: vprint("\tinstalling %s" % pkg.fullname()) - for f in pkg.files: - vprint("\t%s" % f) - path = os.path.join(self.root, f) - util.mkfile(path, f) - if os.path.isfile(path): - os.utime(path, (355, 355)) + pkg.install_package(self.root) for f in self.filesystem: vprint("\t%s" % f) + util.mkfile(self.root, f, f) path = os.path.join(self.root, f) - util.mkfile(path, f) if os.path.isfile(path): os.utime(path, (355, 355)) @@ -201,14 +171,11 @@ class pmtest(object): for roots, dirs, files in os.walk(self.root): for i in files: filename = os.path.join(roots, i) - f = pmfile.pmfile(self.root, filename.replace(self.root + "/", "")) + f = pmfile.PacmanFile(self.root, filename.replace(self.root + "/", "")) self.files.append(f) vprint("\t%s" % f.name) def run(self, pacman): - """ - """ - if os.path.isfile(util.PM_LOCK): print "\tERROR: another pacman session is on-going -- skipping" return @@ -216,7 +183,7 @@ class pmtest(object): print "==> Running test" vprint("\tpacman %s" % self.args) - cmd = [""] + cmd = [] if os.geteuid() != 0: fakeroot = util.which("fakeroot") if not fakeroot: @@ -229,41 +196,39 @@ class pmtest(object): cmd.append("fakechroot") if pacman["gdb"]: - cmd.append("libtool execute gdb --args") + cmd.extend(["libtool", "execute", "gdb", "--args"]) if pacman["valgrind"]: - cmd.append("valgrind -q --tool=memcheck --leak-check=full --show-reachable=yes --suppressions=%s/valgrind.supp" % os.getcwd()) - cmd.append("\"%s\" --config=\"%s\" --root=\"%s\" --dbpath=\"%s\" --cachedir=\"%s\"" \ - % (pacman["bin"], - os.path.join(self.root, util.PACCONF), - self.root, - os.path.join(self.root, util.PM_DBPATH), - os.path.join(self.root, util.PM_CACHEDIR))) + cmd.extend(["libtool", "execute", "valgrind", "-q", + "--tool=memcheck", "--leak-check=full", + "--show-reachable=yes", "--suppressions=%s/valgrind.supp" % os.getcwd()]) + cmd.extend([pacman["bin"], + "--config", os.path.join(self.root, util.PACCONF), + "--root", self.root, + "--dbpath", os.path.join(self.root, util.PM_DBPATH), + "--cachedir", os.path.join(self.root, util.PM_CACHEDIR)]) if not pacman["manual-confirm"]: cmd.append("--noconfirm") if pacman["debug"]: cmd.append("--debug=%s" % pacman["debug"]) - cmd.append("%s" % self.args) - if not pacman["gdb"] and not pacman["valgrind"] and not pacman["nolog"]: - cmd.append(">\"%s\" 2>&1" % os.path.join(self.root, util.LOGFILE)) + cmd.extend(shlex.split(self.args)) + if not (pacman["gdb"] or pacman["valgrind"] or pacman["nolog"]): + output = open(os.path.join(self.root, util.LOGFILE), 'w') + else: + output = None vprint("\trunning: %s" % " ".join(cmd)) # Change to the tmp dir before running pacman, so that local package # archives are made available more easily. - curdir = os.getcwd() - tmpdir = os.path.join(self.root, util.TMPDIR) - os.chdir(tmpdir) - time_start = time.time() - self.retcode = os.system(" ".join(cmd)) + self.retcode = subprocess.call(cmd, stdout=output, stderr=output, + cwd=os.path.join(self.root, util.TMPDIR)) time_end = time.time() - vprint("\ttime elapsed: %ds" % (time_end - time_start)) + vprint("\ttime elapsed: %.2fs" % (time_end - time_start)) + + if output: + output.close() - if self.retcode == None: - self.retcode = 0 - else: - self.retcode /= 256 vprint("\tretcode = %s" % self.retcode) - os.chdir(curdir) # Check if the lock is still there if os.path.isfile(util.PM_LOCK): @@ -274,9 +239,6 @@ class pmtest(object): print "\tERROR: pacman dumped a core file" def check(self): - """ - """ - print "==> Checking rules" for i in self.rules: diff --git a/test/pacman/tests/epoch005.py b/test/pacman/tests/epoch005.py new file mode 100644 index 00000000..4af8edfd --- /dev/null +++ b/test/pacman/tests/epoch005.py @@ -0,0 +1,25 @@ +self.description = "Sysupgrade with sync packages having absurd epochs" + +versions = ( + "1234327518932650063289125782697890:1.0-1", + "1234327518932650063289125782697891:0.9-1", + "1234327518932650063289125782697891:1.0-1", + "1234327518932650063289125782697891:1.1-1", + "1234327518932650063289125782697892:1.0-1", +) + +pkgvers = [(n, versions[n]) for n in range(len(versions))] +for k, v in pkgvers: + sp = pmpkg("pkg_%d" % k, v) + self.addpkg2db("sync", sp) + +for k, v in pkgvers: + lp = pmpkg("pkg_%d" % k, versions[2]) + self.addpkg2db("local", lp) + +self.args = "-Su" + +self.addrule("PACMAN_RETCODE=0") +for k, v in pkgvers: + right_ver = versions[max(k, 2)] + self.addrule("PKG_VERSION=pkg_%d|%s" % (k, right_ver)) diff --git a/test/pacman/tests/fileconflict001.py b/test/pacman/tests/fileconflict001.py index 8c13911c..dec61512 100644 --- a/test/pacman/tests/fileconflict001.py +++ b/test/pacman/tests/fileconflict001.py @@ -2,6 +2,7 @@ self.description = "Fileconflict with symlinks" lp = pmpkg("dummy") lp.files = ["dir/realdir/", + "dir/realdir/realfile", "dir/symdir -> realdir"] self.addpkg2db("local", lp) @@ -18,5 +19,7 @@ self.args = "-U %s" % " ".join([p.filename() for p in p1, p2]) self.addrule("PACMAN_RETCODE=1") self.addrule("!PKG_EXIST=pkg1") self.addrule("!PKG_EXIST=pkg2") +self.addrule("FILE_EXIST=dir/realdir/realfile") +self.addrule("!FILE_EXIST=dir/realdir/file") self.expectfailure = True diff --git a/test/pacman/tests/fileconflict002.py b/test/pacman/tests/fileconflict002.py index f70873ba..e107cd2e 100644 --- a/test/pacman/tests/fileconflict002.py +++ b/test/pacman/tests/fileconflict002.py @@ -1,12 +1,16 @@ self.description = "Fileconflict with symlinks (2)" p1 = pmpkg("pkg1") -p1.files = ["dir/realdir/file", +p1.files = ["dir/", + "dir/realdir/", + "dir/realdir/file", "dir/symdir -> realdir"] self.addpkg(p1) p2 = pmpkg("pkg2") -p2.files = ["dir/symdir/file"] +p2.files = ["dir/", + "dir/symdir/", + "dir/symdir/file"] self.addpkg(p2) self.args = "-U %s" % " ".join([p.filename() for p in p1, p2]) @@ -14,5 +18,6 @@ self.args = "-U %s" % " ".join([p.filename() for p in p1, p2]) self.addrule("PACMAN_RETCODE=1") self.addrule("!PKG_EXIST=pkg1") self.addrule("!PKG_EXIST=pkg2") +self.addrule("!FILE_EXIST=dir/realdir/file") self.expectfailure = True diff --git a/test/pacman/tests/fileconflict003.py b/test/pacman/tests/fileconflict003.py index 89696fcb..749e5a99 100644 --- a/test/pacman/tests/fileconflict003.py +++ b/test/pacman/tests/fileconflict003.py @@ -1,4 +1,4 @@ -self.description = "FS#8156" +self.description = "FS#8156- conflict between directory and incoming symlink" p1 = pmpkg("pkg1") p1.files = ["test/", diff --git a/test/pacman/tests/ignore007.py b/test/pacman/tests/ignore007.py index 90ff4ef6..7670e770 100644 --- a/test/pacman/tests/ignore007.py +++ b/test/pacman/tests/ignore007.py @@ -18,4 +18,4 @@ self.args = "--ask=1 -S grp" self.addrule("PACMAN_RETCODE=0") self.addrule("!PKG_EXIST=%s" % pkg1.name) self.addrule("PKG_EXIST=%s" % pkg2.name) -self.addrule("PACMAN_OUTPUT=is in IgnorePkg") +self.addrule("PKG_EXIST=%s" % pkg3.name) diff --git a/test/pacman/tests/remove070.py b/test/pacman/tests/remove070.py index e0587e17..898e2f50 100644 --- a/test/pacman/tests/remove070.py +++ b/test/pacman/tests/remove070.py @@ -1,21 +1,29 @@ -self.description = "Remove a package with an empty directory needed by another package" +self.description = "Remove a package with various directory overlaps" + +self.filesystem = ["lib/alsoonfs/randomfile"] p1 = pmpkg("pkg1") -p1.files = ["bin/pkg1", "opt/"] +p1.files = ["bin/pkg1", + "opt/", + "lib/onlyinp1/", + "lib/alsoonfs/"] p2 = pmpkg("pkg2") -p2.files = ["bin/pkg2", "opt/"] +p2.files = ["bin/pkg2", + "opt/", + "lib/onlyinp2/"] for p in p1, p2: - self.addpkg2db("local", p) + self.addpkg2db("local", p) self.args = "-R %s" % p1.name self.addrule("PACMAN_RETCODE=0") self.addrule("!PKG_EXIST=pkg1") self.addrule("PKG_EXIST=pkg2") -self.addrule("!FILE_EXIST=bin/pkg1") -self.addrule("FILE_EXIST=bin/pkg2") -self.addrule("FILE_EXIST=opt/") -self.expectfailure = True +self.addrule("DIR_EXIST=bin/") +self.addrule("DIR_EXIST=opt/") +self.addrule("!DIR_EXIST=lib/onlyinp1/") +self.addrule("DIR_EXIST=lib/onlyinp2/") +self.addrule("DIR_EXIST=lib/alsoonfs/") diff --git a/test/pacman/tests/remove071.py b/test/pacman/tests/remove071.py new file mode 100644 index 00000000..eff70a43 --- /dev/null +++ b/test/pacman/tests/remove071.py @@ -0,0 +1,33 @@ +# coding=utf8 +self.description = "Remove packages with evil filenames" + +self.filesystem = ["usr/bin/endwithspace", + "spaces/name"] + +p1 = pmpkg("spaces") +p1.files = ["usr/bin/endwithspace ", + " spaces/name"] +self.addpkg2db("local", p1) + +p2 = pmpkg("unicodechars") +# somewhat derived from FS#9906 +p2.files = ["usr/share/Märchen", + "usr/share/ƏƐƕƺ", + "usr/share/предупреждение", + "usr/share/סֶאבױ", + "usr/share/←↯↻⇈", + "usr/share/アヅヨヾ", + "usr/share/错误"] +self.addpkg2db("local", p2) + +self.args = "-R %s %s" % (p1.name, p2.name) + +self.addrule("PACMAN_RETCODE=0") +self.addrule("!PKG_EXIST=%s" % p1.name) +self.addrule("!PKG_EXIST=%s" % p2.name) + +for f in p1.files: + self.addrule("!FILE_EXIST=%s" % f) + self.addrule("FILE_EXIST=%s" % f.strip()) +for f in p2.files: + self.addrule("!FILE_EXIST=%s" % f) diff --git a/test/pacman/tests/replace101.py b/test/pacman/tests/replace101.py new file mode 100644 index 00000000..00d2b6b3 --- /dev/null +++ b/test/pacman/tests/replace101.py @@ -0,0 +1,18 @@ +self.description = "Sysupgrade with a versioned replacement, original disappears" + +sp1 = pmpkg("python2-yaml", "5-1") +sp1.replaces = ["python-yaml<5"] +sp1.conflicts = ["python-yaml<5"] +sp1.files = ["lib/python2/file"] +self.addpkg2db("sync", sp1) + +lp1 = pmpkg("python-yaml", "4-1") +lp1.files = ["lib/python2/file"] +self.addpkg2db("local", lp1) + +self.args = "-Su" + +self.addrule("PACMAN_RETCODE=0") +self.addrule("!PKG_EXIST=python-yaml") +self.addrule("PKG_VERSION=python2-yaml|5-1") +self.addrule("FILE_EXIST=lib/python2/file") diff --git a/test/pacman/tests/replace102.py b/test/pacman/tests/replace102.py new file mode 100644 index 00000000..ca05d4e6 --- /dev/null +++ b/test/pacman/tests/replace102.py @@ -0,0 +1,25 @@ +self.description = "Sysupgrade with a versioned replacement, original stays" + +sp1 = pmpkg("python2-yaml", "5-1") +sp1.replaces = ["python-yaml<5"] +sp1.conflicts = ["python-yaml<5"] +sp1.files = ["lib/python2/file"] +self.addpkg2db("sync", sp1) + +# the python3 version +sp2 = pmpkg("python-yaml", "5-1") +sp2.files = ["lib/python3/file"] +self.addpkg2db("sync", sp2) + +lp1 = pmpkg("python-yaml", "4-1") +lp1.files = ["lib/python2/file"] +self.addpkg2db("local", lp1) + +self.args = "-Su" + +self.addrule("PACMAN_RETCODE=0") +self.addrule("!PKG_EXIST=python-yaml") +self.addrule("PKG_VERSION=python2-yaml|5-1") +self.addrule("FILE_EXIST=lib/python2/file") + +self.expectfailure = True diff --git a/test/pacman/tests/replace110.py b/test/pacman/tests/replace110.py new file mode 100644 index 00000000..c6e2e5f0 --- /dev/null +++ b/test/pacman/tests/replace110.py @@ -0,0 +1,27 @@ +self.description = "Replace a package with a file in 'backup' (local modified)" +# FS#24543 + +lp = pmpkg("dummy") +lp.files = ["etc/dummy.conf*", "bin/dummy"] +lp.backup = ["etc/dummy.conf"] +self.addpkg2db("local", lp) + +sp = pmpkg("replacement") +sp.replaces = ["dummy"] +sp.files = ["etc/dummy.conf", "bin/dummy*"] +sp.backup = ["etc/dummy.conf"] +self.addpkg2db("sync", sp) + +self.args = "-Su" + +self.addrule("!PKG_EXIST=dummy") +self.addrule("PKG_EXIST=replacement") + +self.addrule("FILE_EXIST=etc/dummy.conf") +self.addrule("!FILE_MODIFIED=etc/dummy.conf") +self.addrule("!FILE_PACNEW=etc/dummy.conf") +self.addrule("!FILE_PACSAVE=etc/dummy.conf") + +self.addrule("FILE_EXIST=bin/dummy") + +self.expectfailure = True diff --git a/test/pacman/tests/sign001.py b/test/pacman/tests/sign001.py new file mode 100644 index 00000000..14add09c --- /dev/null +++ b/test/pacman/tests/sign001.py @@ -0,0 +1,9 @@ +self.description = "Add a bogus signature to a package DB" + +sp = pmpkg("pkg1") +sp.pgpsig = "asdfasdfsdfasdfsdafasdfsdfasd" +self.addpkg2db("sync+Optional", sp) + +self.args = "-Ss" + +self.addrule("PACMAN_RETCODE=0") diff --git a/test/pacman/tests/sign002.py b/test/pacman/tests/sign002.py new file mode 100644 index 00000000..b55f331e --- /dev/null +++ b/test/pacman/tests/sign002.py @@ -0,0 +1,10 @@ +self.description = "Verify a signature in a sync DB (failure)" + +sp = pmpkg("pkg1") +sp.pgpsig = "iEYEABECAAYFAkhMOggACgkQXC5GoPU6du2WVQCffVxF8GKXJIY4juJBIw/ljLrQxygAnj2QlvsUd7MdFekLX18+Ov/xzgZ1" +self.addpkg2db("sync+Always", sp) + +self.args = "-S %s" % sp.name + +self.addrule("PACMAN_RETCODE=1") +self.addrule("!PKG_EXIST=pkg1") diff --git a/test/pacman/tests/smoke002.py b/test/pacman/tests/smoke002.py index 44f2d0ec..8ff5cab7 100644 --- a/test/pacman/tests/smoke002.py +++ b/test/pacman/tests/smoke002.py @@ -10,10 +10,8 @@ self.addpkg(p2) self.args = "-U %s %s" % (p1.filename(), p2.filename()) -# Note that the current cutoff on line length is 512K, so the first package -# will succeed while the second one will fail to record the description. -self.addrule("PACMAN_RETCODE=0") -self.addrule("PKG_EXIST=pkg1") -self.addrule("PKG_DESC=pkg1|%s" % p1.desc) -self.addrule("PKG_EXIST=pkg1") -self.addrule("!PKG_DESC=pkg1|%s" % p2.desc) +# We error out when fed a package with an invalid description; the second one +# fits the bill in this case as the desc is > 512K +self.addrule("PACMAN_RETCODE=1") +self.addrule("!PKG_EXIST=pkg1") +self.addrule("!PKG_EXIST=pkg1") diff --git a/test/pacman/tests/smoke004.py b/test/pacman/tests/smoke004.py new file mode 100644 index 00000000..1f9b883d --- /dev/null +++ b/test/pacman/tests/smoke004.py @@ -0,0 +1,11 @@ +self.description = "Read a package DB with several PGP signatures" + +for i in range(1000): + sp = pmpkg("pkg%03d" % i) + sp.desc = "test description for package %d" % i + sp.pgpsig = "asdfasdfsdfasdfsdafasdfsdfasd" + self.addpkg2db("sync", sp) + +self.args = "-Ss" + +self.addrule("PACMAN_RETCODE=0") diff --git a/test/pacman/tests/sync600.py b/test/pacman/tests/sync600.py new file mode 100644 index 00000000..e0be668c --- /dev/null +++ b/test/pacman/tests/sync600.py @@ -0,0 +1,51 @@ +# coding=utf8 +self.description = "Sync packages with evil filenames" + +self.filesystem = ["usr/bin/endwithspace", + "usr/bin/newendwithspace", + "usr/bin/disappear", + "spaces/name", + "spaces/name2"] + +p1 = pmpkg("spaces") +p1.files = ["usr/bin/endwithspace ", + "usr/bin/disappear ", + " spaces/name", + " spaces/gone"] +self.addpkg2db("local", p1) + +sp1 = pmpkg("spaces", "1.1-1") +sp1.files = ["usr/bin/endwithspace ", + "usr/bin/newendwithspace ", + " spaces/name", + " spaces/name2"] +self.addpkg2db("sync", sp1) + +names = ["Märchen", "ƏƐƕƺ", "предупреждение", "סֶאבױ", + "←↯↻⇈", "アヅヨヾ", "错误"] + +p2 = pmpkg("unicodechars") +# somewhat derived from FS#9906 +p2.files = ["usr/share/%s" % name for name in names] +self.addpkg2db("local", p2) + +sp2 = pmpkg("unicodechars", "2.0-1") +sp2.files = ["usr/man/%s" % name for name in names] +self.addpkg2db("sync", sp2) + +self.args = "-S %s %s" % (sp1.name, sp2.name) + +self.addrule("PACMAN_RETCODE=0") +self.addrule("PKG_VERSION=%s|%s" % (sp1.name, sp1.version)) +self.addrule("PKG_VERSION=%s|%s" % (sp2.name, sp2.version)) + +for f in self.filesystem: + self.addrule("FILE_EXIST=%s" % f) +self.addrule("FILE_EXIST=usr/bin/endwithspace ") +self.addrule("FILE_EXIST= spaces/name") +self.addrule("FILE_EXIST= spaces/name2") +self.addrule("!FILE_EXIST=usr/bin/disappear ") +for f in p2.files: + self.addrule("!FILE_EXIST=%s" % f) +for f in sp2.files: + self.addrule("FILE_EXIST=%s" % f) diff --git a/test/pacman/tests/upgrade020.py b/test/pacman/tests/upgrade020.py index 6a7994bb..8b2e4025 100644 --- a/test/pacman/tests/upgrade020.py +++ b/test/pacman/tests/upgrade020.py @@ -12,6 +12,7 @@ self.addpkg(p) self.args = "-U %s" % p.filename() +self.addrule("PACMAN_RETCODE=0") self.addrule("PKG_VERSION=dummy|1.0-2") self.addrule("FILE_MODIFIED=etc/dummy.conf") self.addrule("!FILE_PACNEW=etc/dummy.conf") diff --git a/test/pacman/tests/upgrade021.py b/test/pacman/tests/upgrade021.py index b45ea18a..9c623c04 100644 --- a/test/pacman/tests/upgrade021.py +++ b/test/pacman/tests/upgrade021.py @@ -12,6 +12,7 @@ self.addpkg(p) self.args = "-U %s" % p.filename() +self.addrule("PACMAN_RETCODE=0") self.addrule("PKG_VERSION=dummy|1.0-2") self.addrule("!FILE_MODIFIED=etc/dummy.conf") self.addrule("!FILE_PACNEW=etc/dummy.conf") diff --git a/test/pacman/tests/upgrade022.py b/test/pacman/tests/upgrade022.py index dcf7ae01..581a66ad 100644 --- a/test/pacman/tests/upgrade022.py +++ b/test/pacman/tests/upgrade022.py @@ -12,6 +12,7 @@ self.addpkg(p) self.args = "-U %s" % p.filename() +self.addrule("PACMAN_RETCODE=0") self.addrule("PKG_VERSION=dummy|1.0-2") self.addrule("!FILE_MODIFIED=etc/dummy.conf") self.addrule("FILE_PACNEW=etc/dummy.conf") diff --git a/test/pacman/tests/upgrade023.py b/test/pacman/tests/upgrade023.py index d1d2e314..08afbb8f 100644 --- a/test/pacman/tests/upgrade023.py +++ b/test/pacman/tests/upgrade023.py @@ -11,6 +11,7 @@ self.addpkg(p) self.args = "-U %s" % p.filename() +self.addrule("PACMAN_RETCODE=0") self.addrule("PKG_VERSION=dummy|1.1-1") self.addrule("!FILE_MODIFIED=etc/dummy.conf") # Do we want this pacnew or not? diff --git a/test/pacman/tests/upgrade024.py b/test/pacman/tests/upgrade024.py index ec2f7623..0bacb76d 100644 --- a/test/pacman/tests/upgrade024.py +++ b/test/pacman/tests/upgrade024.py @@ -10,6 +10,7 @@ self.addpkg(p) self.args = "-U %s" % p.filename() +self.addrule("PACMAN_RETCODE=0") self.addrule("PKG_VERSION=dummy|1.0-2") self.addrule("FILE_PACSAVE=etc/dummy.conf") self.addrule("!FILE_EXIST=etc/dummy.conf") diff --git a/test/pacman/tests/upgrade025.py b/test/pacman/tests/upgrade025.py index 2c9c06f3..0ef0d0d8 100644 --- a/test/pacman/tests/upgrade025.py +++ b/test/pacman/tests/upgrade025.py @@ -11,6 +11,7 @@ self.addpkg(p) self.args = "-U %s" % p.filename() +self.addrule("PACMAN_RETCODE=0") self.addrule("PKG_VERSION=dummy|1.0-2") self.addrule("FILE_PACSAVE=etc/dummy.conf") self.addrule("!FILE_PACNEW=etc/dummy.conf") diff --git a/test/pacman/tests/upgrade026.py b/test/pacman/tests/upgrade026.py index 8e3ef239..7e91cbc9 100644 --- a/test/pacman/tests/upgrade026.py +++ b/test/pacman/tests/upgrade026.py @@ -11,6 +11,7 @@ self.addpkg(p) self.args = "-U %s" % p.filename() +self.addrule("PACMAN_RETCODE=0") self.addrule("PKG_VERSION=dummy|1.0-2") self.addrule("FILE_PACSAVE=etc/dummy.conf") self.addrule("!FILE_PACNEW=etc/dummy.conf") diff --git a/test/pacman/tests/upgrade027.py b/test/pacman/tests/upgrade027.py new file mode 100644 index 00000000..99087f34 --- /dev/null +++ b/test/pacman/tests/upgrade027.py @@ -0,0 +1,22 @@ +self.description = "Upgrade a package, with a file entering the pkg in 'backup' (changed)" + +self.filesystem = ["etc/dummy.conf"] + +lp = pmpkg("dummy") +lp.files = ["usr/bin/dummy"] +self.addpkg2db("local", lp) + +p = pmpkg("dummy", "1.0-2") +p.files = ["usr/bin/dummy", + "etc/dummy.conf*"] +p.backup = ["etc/dummy.conf"] +self.addpkg(p) + +self.args = "-U %s" % p.filename() + +self.addrule("PACMAN_RETCODE=0") +self.addrule("PKG_VERSION=dummy|1.0-2") +self.addrule("FILE_PACNEW=etc/dummy.conf") +self.addrule("!FILE_PACSAVE=etc/dummy.conf") +self.addrule("!FILE_PACORIG=etc/dummy.conf") +self.addrule("FILE_EXIST=etc/dummy.conf") diff --git a/test/pacman/tests/upgrade028.py b/test/pacman/tests/upgrade028.py new file mode 100644 index 00000000..18a10f57 --- /dev/null +++ b/test/pacman/tests/upgrade028.py @@ -0,0 +1,22 @@ +self.description = "Upgrade a package, with a file entering the pkg in 'backup' (unchanged)" + +self.filesystem = ["etc/dummy.conf"] + +lp = pmpkg("dummy") +lp.files = ["usr/bin/dummy"] +self.addpkg2db("local", lp) + +p = pmpkg("dummy", "1.0-2") +p.files = ["usr/bin/dummy", + "etc/dummy.conf"] +p.backup = ["etc/dummy.conf"] +self.addpkg(p) + +self.args = "-U %s" % p.filename() + +self.addrule("PACMAN_RETCODE=0") +self.addrule("PKG_VERSION=dummy|1.0-2") +self.addrule("!FILE_PACNEW=etc/dummy.conf") +self.addrule("!FILE_PACSAVE=etc/dummy.conf") +self.addrule("!FILE_PACORIG=etc/dummy.conf") +self.addrule("FILE_EXIST=etc/dummy.conf") diff --git a/test/pacman/tests/upgrade029.py b/test/pacman/tests/upgrade029.py new file mode 100644 index 00000000..c308f426 --- /dev/null +++ b/test/pacman/tests/upgrade029.py @@ -0,0 +1,24 @@ +self.description = "Upgrade a package, with an owned file entering the pkg in 'backup'" + +lp = pmpkg("dummy") +lp.files = ["usr/bin/dummy"] +self.addpkg2db("local", lp) + +lp2 = pmpkg("dummy2") +lp2.files = ["etc/dummy.conf"] +self.addpkg2db("local", lp2) + +p = pmpkg("dummy", "1.0-2") +p.files = ["usr/bin/dummy", + "etc/dummy.conf*"] +p.backup = ["etc/dummy.conf"] +self.addpkg(p) + +self.args = "-U %s" % p.filename() + +self.addrule("PACMAN_RETCODE=1") +self.addrule("PKG_VERSION=dummy|1.0-1") +self.addrule("!FILE_PACNEW=etc/dummy.conf") +self.addrule("!FILE_PACSAVE=etc/dummy.conf") +self.addrule("!FILE_PACORIG=etc/dummy.conf") +self.addrule("FILE_EXIST=etc/dummy.conf") diff --git a/test/pacman/tests/upgrade042.py b/test/pacman/tests/upgrade042.py index d6140d45..44754991 100644 --- a/test/pacman/tests/upgrade042.py +++ b/test/pacman/tests/upgrade042.py @@ -21,6 +21,7 @@ self.args = "-U %s" % " ".join([p.filename() for p in p1, p2]) self.filesystem = ["etc/profile"] +self.addrule("PACMAN_RETCODE=0") self.addrule("PKG_VERSION=bash|1.0-2") self.addrule("PKG_VERSION=filesystem|1.0-2") self.addrule("!FILE_PACSAVE=etc/profile") diff --git a/test/pacman/tests/upgrade043.py b/test/pacman/tests/upgrade043.py index e76dc463..f531cb82 100644 --- a/test/pacman/tests/upgrade043.py +++ b/test/pacman/tests/upgrade043.py @@ -21,6 +21,7 @@ self.args = "-U %s" % " ".join([p.filename() for p in p1, p2]) self.filesystem = ["etc/profile"] +self.addrule("PACMAN_RETCODE=0") self.addrule("PKG_VERSION=bash|1.0-2") self.addrule("PKG_VERSION=filesystem|1.0-2") self.addrule("!FILE_PACSAVE=etc/profile") diff --git a/test/pacman/tests/upgrade045.py b/test/pacman/tests/upgrade045.py index b2f81274..5d0ef2ff 100644 --- a/test/pacman/tests/upgrade045.py +++ b/test/pacman/tests/upgrade045.py @@ -12,5 +12,6 @@ self.addpkg(p1) self.args = "-U %s" % p1.filename() +self.addrule("PACMAN_RETCODE=0") self.addrule("PKG_VERSION=foo|1.0-2") self.addrule("FILE_EXIST=etc/foo.cfg") diff --git a/test/pacman/util.py b/test/pacman/util.py index 47fde310..60dea9e8 100755..100644 --- a/test/pacman/util.py +++ b/test/pacman/util.py @@ -19,7 +19,6 @@ import os import re import hashlib -import stat # ALPM @@ -48,78 +47,65 @@ def vprint(msg): # Methods to generate files # -def getfilename(name): - """ - """ - filename = name - extra = "" +def getfileinfo(filename): + data = { + 'changed': False, + 'isdir': False, + 'islink': False, + 'link': None, + 'hasperms': False, + 'perms': None, + } if filename[-1] == "*": + data["changed"] = True filename = filename.rstrip("*") if filename.find(" -> ") != -1: - filename, extra = filename.split(" -> ") - elif filename.find("|") != -1: - filename, extra = filename.split("|") - return filename - -def mkfile(name, data = ""): - """ - """ - isdir = 0 - islink = 0 - setperms = 0 - filename = name - link = "" - perms = "" - - if filename[-1] == "*": - filename = filename.rstrip("*") - if filename.find(" -> ") != -1: - islink = 1 filename, link = filename.split(" -> ") + data["islink"] = True + data["link"] = link elif filename.find("|") != -1: - setperms = 1 filename, perms = filename.split("|") + data["hasperms"] = True + data["perms"] = int(perms, 8) if filename[-1] == "/": - isdir = 1 + data["isdir"] = True - if isdir: - path = filename - else: - path = os.path.dirname(filename) - if path and not os.path.isdir(path): - os.makedirs(path, 0755) + data["filename"] = filename + return data + +def mkfile(base, name, data=""): + info = getfileinfo(name) + filename = info["filename"] - if isdir: + path = os.path.join(base, filename) + if info["isdir"]: + if not os.path.isdir(path): + os.makedirs(path, 0755) return - if islink: - curdir = os.getcwd() - if path: - os.chdir(path) - os.symlink(link, os.path.basename(filename)) - os.chdir(curdir) + + dir_path = os.path.dirname(path) + if dir_path and not os.path.isdir(dir_path): + os.makedirs(dir_path, 0755) + + if info["islink"]: + os.symlink(info["link"], path) else: - fd = file(filename, "w") - if data: - fd.write(data) - if data[-1] != "\n": - fd.write("\n") - fd.close() - if setperms: - os.chmod(filename, int(perms, 8)) - -def mkinstallfile(filename, install): - """ - """ - data = [] - for key, value in install.iteritems(): - if value: - data.append("%s() {\n%s\n}" % (key, value)) - - mkfile(filename, "\n".join(data)) + writedata(path, data) + + if info["perms"]: + os.chmod(path, info["perms"]) + +def writedata(filename, data): + if isinstance(data, list): + data = "\n".join(data) + fd = file(filename, "w") + if data: + fd.write(data) + if data[-1] != "\n": + fd.write("\n") + fd.close() def mkcfgfile(filename, root, option, db): - """ - """ # Options data = ["[options]"] for key, value in option.iteritems(): @@ -132,13 +118,14 @@ def mkcfgfile(filename, root, option, db): if key != "local": value = db[key] data.append("[%s]\n" \ + "SigLevel = %s\n" \ "Server = file://%s" \ - % (value.treename, + % (value.treename, value.getverify(), \ os.path.join(root, SYNCREPO, value.treename))) for optkey, optval in value.option.iteritems(): data.extend(["%s = %s" % (optkey, j) for j in optval]) - mkfile(os.path.join(root, filename), "\n".join(data)) + mkfile(root, filename, "\n".join(data)) # @@ -146,8 +133,6 @@ def mkcfgfile(filename, root, option, db): # def getmd5sum(filename): - """ - """ if not os.path.isfile(filename): return "" fd = open(filename, "rb") @@ -161,26 +146,12 @@ def getmd5sum(filename): return checksum.hexdigest() def mkmd5sum(data): - """ - """ checksum = hashlib.md5() checksum.update("%s\n" % data) return checksum.hexdigest() # -# Mtime helpers -# - -def getmtime(filename): - """ - """ - if not os.path.exists(filename): - return None, None, None - st = os.lstat(filename) - return st[stat.ST_ATIME], st[stat.ST_MTIME], st[stat.ST_CTIME] - -# # Miscellaneous # diff --git a/test/util/Makefile.am b/test/util/Makefile.am index 6e59d8e9..5839f37e 100644 --- a/test/util/Makefile.am +++ b/test/util/Makefile.am @@ -1,4 +1,5 @@ check_SCRIPTS = \ + pacsorttest.sh \ vercmptest.sh noinst_SCRIPTS = $(check_SCRIPTS) diff --git a/test/util/pacsorttest.sh b/test/util/pacsorttest.sh new file mode 100755 index 00000000..ff82a53f --- /dev/null +++ b/test/util/pacsorttest.sh @@ -0,0 +1,103 @@ +#!/bin/bash +# +# pacsorttest - a test suite for pacsort +# +# Copyright (c) 2011 by Dan McGee <dan@archlinux.org> +# +# 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, see <http://www.gnu.org/licenses/>. + +# default binary if one was not specified as $1 +bin='pacsort' +# holds counts of tests +total=0 +failure=0 + +# args: +# runtest input expected test_description optional_opts +runtest() { + # run the test + diff -u <(printf "$1" | $bin $4) <(printf "$2") + if [[ $? -ne 0 ]]; then + echo "FAILURE: $3" + ((failure++)) + fi + ((total++)) +} + +# use first arg as our binary if specified +[[ -n "$1" ]] && bin="$1" + +if ! type -p "$bin"; then + echo "pacsort binary ($bin) could not be located" + exit 1 +fi + +echo "Beginning pacsort tests" + +# BEGIN TESTS + +in="1\n2\n3\n4\n" +runtest $in $in "already ordered" + +in="4\n2\n3\n1\n" +ex="1\n2\n3\n4\n" +runtest $in $ex "easy reordering" + +in="1\n2\n3\n4" +ex="1\n2\n3\n4\n" +runtest $in $ex "add trailing newline" + +in="1\n2\n4\n3" +ex="1\n2\n3\n4\n" +runtest $in $ex "add trailing newline" + +in="1.0-1\n1.0\n1.0-2\n1.0\n" +runtest $in $in "stable sort" + +# generate some long input/expected for the next few tests +declare normal reverse names_normal names_reverse +for ((i=1; i<600; i++)); do + normal="${normal}${i}\n" + reverse="${reverse}$((600 - ${i}))\n" + fields="${fields}colA bogus$((600 - ${i})) ${i}\n" + fields_reverse="${fields_reverse}colA bogus${i} $((600 - ${i}))\n" + separator="${separator}colA|bogus$((600 - ${i}))|${i}\n" + separator_reverse="${separator_reverse}colA|bogus${i}|$((600 - ${i}))\n" +done + +runtest $normal $normal "really long input" +runtest $reverse $normal "really long input" +runtest $reverse $reverse "really long input, reversed" "-r" +runtest $normal $reverse "really long input, reversed" "-r" + +runtest "$fields" "$fields" "really long input, sort key" "-k3" +runtest "$fields_reverse" "$fields" "really long input, sort key" "-k3" +runtest "$fields_reverse" "$fields_reverse" "really long input, sort key, reversed" "-k 3 -r" +runtest "$fields" "$fields_reverse" "really long input, sort key, reversed" "-k 3 -r" + +runtest "$separator" "$separator" "really long input, sort key, separator" "-k3 -t|" +runtest "$separator_reverse" "$separator" "really long input, sort key, separator" "-k3 -t|" +runtest "$separator_reverse" "$separator_reverse" "really long input, sort key, separator, reversed" "-k 3 -t| -r" +runtest "$separator" "$separator_reverse" "really long input, sort key, separator, reversed" "-k 3 -t| -r" + +#END TESTS + +echo +if [[ $failure -eq 0 ]]; then + echo "All $total tests successful" + exit 0 +fi + +echo "$failure of $total tests failed" +exit 1 diff --git a/test/util/vercmptest.sh b/test/util/vercmptest.sh index 6b3869c5..54ede04b 100755 --- a/test/util/vercmptest.sh +++ b/test/util/vercmptest.sh @@ -36,7 +36,7 @@ pass() { fail() { echo "test: ver1: $1 ver2: $2 ret: $3 expected: $4" echo " ==> FAILURE" - failure=$(expr $failure + 1) + ((failure++)) } # args: @@ -45,24 +45,24 @@ runtest() { # run the test ret=$($bin $1 $2) func='pass' - [ $ret -eq $3 ] || func='fail' + [[ -n $ret && $ret -eq $3 ]] || func='fail' $func $1 $2 $ret $3 - total=$(expr $total + 1) + ((total++)) # and run its mirror case just to be sure reverse=0 - [ $3 -eq 1 ] && reverse=-1 - [ $3 -eq -1 ] && reverse=1 + [[ $3 -eq 1 ]] && reverse=-1 + [[ $3 -eq -1 ]] && reverse=1 ret=$($bin $2 $1) func='pass' - [ $ret -eq $reverse ] || func='fail' + [[ -n $ret && $ret -eq $reverse ]] || func='fail' $func $2 $1 $ret $reverse - total=$(expr $total + 1) + ((total++)) } # use first arg as our binary if specified -[ -n "$1" ] && bin="$1" +[[ -n "$1" ]] && bin="$1" -if [ ! $(type -p "$bin") ]; then +if ! type -p "$bin"; then echo "vercmp binary ($bin) could not be located" exit 1 fi @@ -140,7 +140,7 @@ runtest 1:1.1 1.1 1 #END TESTS echo -if [ $failure -eq 0 ]; then +if [[ $failure -eq 0 ]]; then echo "All $total tests successful" exit 0 fi |