summaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/pacman/README6
-rwxr-xr-xtest/pacman/pactest.py47
-rw-r--r--[-rwxr-xr-x]test/pacman/pmdb.py257
-rw-r--r--[-rwxr-xr-x]test/pacman/pmenv.py26
-rw-r--r--[-rwxr-xr-x]test/pacman/pmfile.py24
-rw-r--r--[-rwxr-xr-x]test/pacman/pmpkg.py110
-rw-r--r--[-rwxr-xr-x]test/pacman/pmrule.py10
-rw-r--r--[-rwxr-xr-x]test/pacman/pmtest.py98
-rw-r--r--test/pacman/tests/epoch005.py25
-rw-r--r--test/pacman/tests/fileconflict001.py3
-rw-r--r--test/pacman/tests/fileconflict002.py9
-rw-r--r--test/pacman/tests/fileconflict003.py2
-rw-r--r--test/pacman/tests/ignore007.py2
-rw-r--r--test/pacman/tests/remove070.py24
-rw-r--r--test/pacman/tests/remove071.py33
-rw-r--r--test/pacman/tests/replace101.py18
-rw-r--r--test/pacman/tests/replace102.py25
-rw-r--r--test/pacman/tests/replace110.py27
-rw-r--r--test/pacman/tests/sign001.py9
-rw-r--r--test/pacman/tests/sign002.py10
-rw-r--r--test/pacman/tests/smoke002.py12
-rw-r--r--test/pacman/tests/smoke004.py11
-rw-r--r--test/pacman/tests/sync600.py51
-rw-r--r--test/pacman/tests/upgrade020.py1
-rw-r--r--test/pacman/tests/upgrade021.py1
-rw-r--r--test/pacman/tests/upgrade022.py1
-rw-r--r--test/pacman/tests/upgrade023.py1
-rw-r--r--test/pacman/tests/upgrade024.py1
-rw-r--r--test/pacman/tests/upgrade025.py1
-rw-r--r--test/pacman/tests/upgrade026.py1
-rw-r--r--test/pacman/tests/upgrade027.py22
-rw-r--r--test/pacman/tests/upgrade028.py22
-rw-r--r--test/pacman/tests/upgrade029.py24
-rw-r--r--test/pacman/tests/upgrade042.py1
-rw-r--r--test/pacman/tests/upgrade043.py1
-rw-r--r--test/pacman/tests/upgrade045.py1
-rw-r--r--[-rwxr-xr-x]test/pacman/util.py127
-rw-r--r--test/util/Makefile.am1
-rwxr-xr-xtest/util/pacsorttest.sh103
-rwxr-xr-xtest/util/vercmptest.sh20
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