Send patches - preferably formatted by git format-patch - to patches at archlinux32 dot org.
summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/pacman/.gitignore1
-rw-r--r--test/pacman/ChangeLog29
-rw-r--r--test/pacman/Makefile.am22
-rw-r--r--test/pacman/README323
-rw-r--r--test/pacman/TODO8
-rwxr-xr-xtest/pacman/pactest.py110
-rwxr-xr-xtest/pacman/pmdb.py386
-rwxr-xr-xtest/pacman/pmenv.py156
-rwxr-xr-xtest/pacman/pmfile.py71
-rwxr-xr-xtest/pacman/pmpkg.py184
-rwxr-xr-xtest/pacman/pmrule.py159
-rwxr-xr-xtest/pacman/pmtest.py265
-rw-r--r--test/pacman/tests/.gitignore1
-rw-r--r--test/pacman/tests/Makefile.am27
-rw-r--r--test/pacman/tests/config001.py17
-rw-r--r--test/pacman/tests/config002.py12
-rw-r--r--test/pacman/tests/database001.py11
-rw-r--r--test/pacman/tests/database002.py11
-rw-r--r--test/pacman/tests/database010.py17
-rw-r--r--test/pacman/tests/database011.py17
-rw-r--r--test/pacman/tests/database012.py31
-rw-r--r--test/pacman/tests/depconflict100.py15
-rw-r--r--test/pacman/tests/depconflict110.py13
-rw-r--r--test/pacman/tests/depconflict111.py13
-rw-r--r--test/pacman/tests/depconflict120.py19
-rw-r--r--test/pacman/tests/deptest001.py16
-rw-r--r--test/pacman/tests/dummy001.py21
-rw-r--r--test/pacman/tests/fileconflict001.py22
-rw-r--r--test/pacman/tests/fileconflict002.py18
-rw-r--r--test/pacman/tests/fileconflict003.py18
-rw-r--r--test/pacman/tests/fileconflict004.py19
-rw-r--r--test/pacman/tests/fileconflict005.py22
-rw-r--r--test/pacman/tests/fileconflict006.py24
-rw-r--r--test/pacman/tests/fileconflict007.py17
-rw-r--r--test/pacman/tests/ignore001.py17
-rw-r--r--test/pacman/tests/ignore002.py35
-rw-r--r--test/pacman/tests/ignore003.py35
-rw-r--r--test/pacman/tests/ignore004.py46
-rw-r--r--test/pacman/tests/ignore005.py46
-rw-r--r--test/pacman/tests/ldconfig001.py12
-rw-r--r--test/pacman/tests/ldconfig002.py16
-rw-r--r--test/pacman/tests/ldconfig003.py14
-rw-r--r--test/pacman/tests/mode001.py12
-rw-r--r--test/pacman/tests/mode002.py12
-rw-r--r--test/pacman/tests/mode003.py20
-rw-r--r--test/pacman/tests/pacman001.py5
-rw-r--r--test/pacman/tests/pacman002.py5
-rw-r--r--test/pacman/tests/pacman003.py5
-rw-r--r--test/pacman/tests/pacman004.py5
-rw-r--r--test/pacman/tests/provision001.py10
-rw-r--r--test/pacman/tests/provision010.py15
-rw-r--r--test/pacman/tests/provision011.py15
-rw-r--r--test/pacman/tests/provision012.py15
-rw-r--r--test/pacman/tests/provision020.py15
-rw-r--r--test/pacman/tests/provision021.py15
-rw-r--r--test/pacman/tests/provision022.py15
-rw-r--r--test/pacman/tests/query001.py10
-rw-r--r--test/pacman/tests/query002.py21
-rw-r--r--test/pacman/tests/query003.py11
-rw-r--r--test/pacman/tests/query004.py10
-rw-r--r--test/pacman/tests/query005.py21
-rw-r--r--test/pacman/tests/reason001.py16
-rw-r--r--test/pacman/tests/remove001.py9
-rw-r--r--test/pacman/tests/remove010.py13
-rw-r--r--test/pacman/tests/remove011.py13
-rw-r--r--test/pacman/tests/remove020.py13
-rw-r--r--test/pacman/tests/remove021.py13
-rw-r--r--test/pacman/tests/remove030.py11
-rw-r--r--test/pacman/tests/remove040.py15
-rw-r--r--test/pacman/tests/remove041.py19
-rw-r--r--test/pacman/tests/remove042.py15
-rw-r--r--test/pacman/tests/remove043.py15
-rw-r--r--test/pacman/tests/remove044.py16
-rw-r--r--test/pacman/tests/remove045.py27
-rw-r--r--test/pacman/tests/remove047.py24
-rw-r--r--test/pacman/tests/remove049.py18
-rw-r--r--test/pacman/tests/remove050.py20
-rw-r--r--test/pacman/tests/remove051.py20
-rw-r--r--test/pacman/tests/remove052.py21
-rw-r--r--test/pacman/tests/remove060.py19
-rw-r--r--test/pacman/tests/scriptlet001.py20
-rw-r--r--test/pacman/tests/scriptlet002.py20
-rw-r--r--test/pacman/tests/smoke001.py23
-rw-r--r--test/pacman/tests/symlink001.py20
-rw-r--r--test/pacman/tests/sync001.py13
-rw-r--r--test/pacman/tests/sync002.py18
-rw-r--r--test/pacman/tests/sync003.py13
-rw-r--r--test/pacman/tests/sync009.py13
-rw-r--r--test/pacman/tests/sync010.py27
-rw-r--r--test/pacman/tests/sync011.py20
-rw-r--r--test/pacman/tests/sync012.py20
-rw-r--r--test/pacman/tests/sync020.py19
-rw-r--r--test/pacman/tests/sync021.py21
-rw-r--r--test/pacman/tests/sync030.py19
-rw-r--r--test/pacman/tests/sync031.py19
-rw-r--r--test/pacman/tests/sync040.py15
-rw-r--r--test/pacman/tests/sync041.py16
-rw-r--r--test/pacman/tests/sync042.py14
-rw-r--r--test/pacman/tests/sync043.py18
-rw-r--r--test/pacman/tests/sync044.py20
-rw-r--r--test/pacman/tests/sync045.py18
-rw-r--r--test/pacman/tests/sync050.py11
-rw-r--r--test/pacman/tests/sync100.py12
-rw-r--r--test/pacman/tests/sync1000.py17
-rw-r--r--test/pacman/tests/sync1003.py21
-rw-r--r--test/pacman/tests/sync1004.py18
-rw-r--r--test/pacman/tests/sync1008.py19
-rw-r--r--test/pacman/tests/sync101.py12
-rw-r--r--test/pacman/tests/sync102.py12
-rw-r--r--test/pacman/tests/sync103.py13
-rw-r--r--test/pacman/tests/sync104.py12
-rw-r--r--test/pacman/tests/sync110.py22
-rw-r--r--test/pacman/tests/sync1100.py23
-rw-r--r--test/pacman/tests/sync1101.py12
-rw-r--r--test/pacman/tests/sync1102.py12
-rw-r--r--test/pacman/tests/sync1103.py11
-rw-r--r--test/pacman/tests/sync120.py21
-rw-r--r--test/pacman/tests/sync130.py16
-rw-r--r--test/pacman/tests/sync131.py18
-rw-r--r--test/pacman/tests/sync132.py18
-rw-r--r--test/pacman/tests/sync133.py18
-rw-r--r--test/pacman/tests/sync134.py21
-rw-r--r--test/pacman/tests/sync135.py31
-rw-r--r--test/pacman/tests/sync136.py15
-rw-r--r--test/pacman/tests/sync137.py14
-rw-r--r--test/pacman/tests/sync138.py22
-rw-r--r--test/pacman/tests/sync150.py25
-rw-r--r--test/pacman/tests/sync200.py.in18
-rw-r--r--test/pacman/tests/sync300.py14
-rw-r--r--test/pacman/tests/sync301.py27
-rw-r--r--test/pacman/tests/sync400.py24
-rw-r--r--test/pacman/tests/sync401.py21
-rw-r--r--test/pacman/tests/sync402.py21
-rw-r--r--test/pacman/tests/sync403.py23
-rw-r--r--test/pacman/tests/sync404.py26
-rw-r--r--test/pacman/tests/sync405.py24
-rw-r--r--test/pacman/tests/sync406.py31
-rw-r--r--test/pacman/tests/sync500.py15
-rw-r--r--test/pacman/tests/sync501.py18
-rw-r--r--test/pacman/tests/sync890.py20
-rw-r--r--test/pacman/tests/sync891.py22
-rw-r--r--test/pacman/tests/sync892.py24
-rw-r--r--test/pacman/tests/sync893.py20
-rw-r--r--test/pacman/tests/sync895.py20
-rw-r--r--test/pacman/tests/sync896.py21
-rw-r--r--test/pacman/tests/sync897.py24
-rw-r--r--test/pacman/tests/sync898.py18
-rw-r--r--test/pacman/tests/sync899.py18
-rw-r--r--test/pacman/tests/sync900.py25
-rw-r--r--test/pacman/tests/sync901.py25
-rw-r--r--test/pacman/tests/sync990.py19
-rw-r--r--test/pacman/tests/sync992.py23
-rw-r--r--test/pacman/tests/sync993.py20
-rw-r--r--test/pacman/tests/sync999.py21
-rw-r--r--test/pacman/tests/trans001.py20
-rw-r--r--test/pacman/tests/type001.py17
-rw-r--r--test/pacman/tests/unresolvable001.py21
-rw-r--r--test/pacman/tests/upgrade001.py18
-rw-r--r--test/pacman/tests/upgrade002.py18
-rw-r--r--test/pacman/tests/upgrade003.py18
-rw-r--r--test/pacman/tests/upgrade004.py12
-rw-r--r--test/pacman/tests/upgrade005.py23
-rw-r--r--test/pacman/tests/upgrade010.py18
-rw-r--r--test/pacman/tests/upgrade011.py16
-rw-r--r--test/pacman/tests/upgrade012.py14
-rw-r--r--test/pacman/tests/upgrade013.py20
-rw-r--r--test/pacman/tests/upgrade014.py23
-rw-r--r--test/pacman/tests/upgrade015.py15
-rw-r--r--test/pacman/tests/upgrade016.py16
-rw-r--r--test/pacman/tests/upgrade020.py18
-rw-r--r--test/pacman/tests/upgrade021.py18
-rw-r--r--test/pacman/tests/upgrade022.py18
-rw-r--r--test/pacman/tests/upgrade023.py18
-rw-r--r--test/pacman/tests/upgrade024.py15
-rw-r--r--test/pacman/tests/upgrade025.py17
-rw-r--r--test/pacman/tests/upgrade026.py17
-rw-r--r--test/pacman/tests/upgrade030.py21
-rw-r--r--test/pacman/tests/upgrade031.py19
-rw-r--r--test/pacman/tests/upgrade032.py19
-rw-r--r--test/pacman/tests/upgrade040.py31
-rw-r--r--test/pacman/tests/upgrade041.py31
-rw-r--r--test/pacman/tests/upgrade042.py28
-rw-r--r--test/pacman/tests/upgrade043.py28
-rw-r--r--test/pacman/tests/upgrade045.py16
-rw-r--r--test/pacman/tests/upgrade046.py33
-rw-r--r--test/pacman/tests/upgrade050.py15
-rw-r--r--test/pacman/tests/upgrade051.py15
-rw-r--r--test/pacman/tests/upgrade052.py20
-rw-r--r--test/pacman/tests/upgrade053.py19
-rw-r--r--test/pacman/tests/upgrade054.py19
-rw-r--r--test/pacman/tests/upgrade055.py25
-rw-r--r--test/pacman/tests/upgrade056.py23
-rw-r--r--test/pacman/tests/upgrade057.py21
-rw-r--r--test/pacman/tests/upgrade058.py16
-rw-r--r--test/pacman/tests/upgrade059.py26
-rw-r--r--test/pacman/tests/upgrade060.py21
-rw-r--r--test/pacman/tests/upgrade061.py22
-rw-r--r--test/pacman/tests/upgrade070.py15
-rw-r--r--test/pacman/tests/upgrade071.py14
-rw-r--r--test/pacman/tests/upgrade072.py15
-rw-r--r--test/pacman/tests/upgrade073.py27
-rw-r--r--test/pacman/tests/upgrade074.py14
-rw-r--r--test/pacman/tests/upgrade075.py14
-rw-r--r--test/pacman/tests/upgrade076.py18
-rw-r--r--test/pacman/tests/upgrade080.py16
-rw-r--r--test/pacman/tests/upgrade081.py16
-rw-r--r--test/pacman/tests/upgrade082.py19
-rw-r--r--test/pacman/tests/upgrade083.py19
-rw-r--r--test/pacman/tests/upgrade084.py16
-rw-r--r--test/pacman/tests/upgrade090.py28
-rw-r--r--test/pacman/tests/xfercommand001.py20
-rwxr-xr-xtest/pacman/util.py276
-rwxr-xr-xtest/pacman/vercmptest.sh130
213 files changed, 5799 insertions, 0 deletions
diff --git a/test/pacman/.gitignore b/test/pacman/.gitignore
new file mode 100644
index 00000000..0d20b648
--- /dev/null
+++ b/test/pacman/.gitignore
@@ -0,0 +1 @@
+*.pyc
diff --git a/test/pacman/ChangeLog b/test/pacman/ChangeLog
new file mode 100644
index 00000000..fec0eb23
--- /dev/null
+++ b/test/pacman/ChangeLog
@@ -0,0 +1,29 @@
+
+Release 0.3 (pending)
+-------------
+- added detection for fakeroot enabled pacman binaries and leftover lock
+and core files.
+- fixed number format for statistics line
+- display elapsed times for each test cases
+- added COPYING file
+- added patch to disable fakeroot support for pacman 2.9.x
+- added "--gdb" command line options to ease debugging (as suggested by VMiklos)
+- added "--valgrind" option to run tests through valgrind memory checker
+- added more test cases
+- added gensync archives
+
+Release 0.2 (06/02/13)
+-----------
+- added support for directories, symlinks and altered files
+- removed hardcoded references to package names in testcase scripts
+- splited pactest.py in several modules
+- lots of code optimizations
+- created a home page to host the project
+- added README, TODO and ChangeLog files
+
+Release 0.1 (06/01/30)
+-----------
+Initial release.
+
+Annoucement on the ArchLinux pacman-dev mailing list:
+http://www.archlinux.org/pipermail/pacman-dev/2006-January/000186.html
diff --git a/test/pacman/Makefile.am b/test/pacman/Makefile.am
new file mode 100644
index 00000000..64f9a22e
--- /dev/null
+++ b/test/pacman/Makefile.am
@@ -0,0 +1,22 @@
+SUBDIRS = tests
+
+check_SCRIPTS = \
+ pactest.py \
+ pmdb.py \
+ pmenv.py \
+ pmfile.py \
+ pmpkg.py \
+ pmrule.py \
+ pmtest.py \
+ util.py \
+ vercmptest.sh
+
+noinst_SCRIPTS = $(check_SCRIPTS)
+
+EXTRA_DIST = \
+ README \
+ TODO \
+ ChangeLog \
+ $(check_SCRIPTS)
+
+# vim:set ts=2 sw=2 noet:
diff --git a/test/pacman/README b/test/pacman/README
new file mode 100644
index 00000000..8f97a17d
--- /dev/null
+++ b/test/pacman/README
@@ -0,0 +1,323 @@
+README
+======
+
+pactest is a test suite for the ArchLinux package manager: pacman.
+
+It has a rather high level view of operations performed by pacman: it
+automatically creates a test environment based on a test case file
+description, the run pacman, and finally check the results of test according
+to a set of rules defined in the test case.
+
+It is written in Python and makes available most of what can be found in
+pacman's code to create ArchLinux packages or read and write databases entries.
+
+Each test case is defined in a separate file that is sourced in order to set
+the environment.
+
+pactest creates the environment in the subdirectory "root" created in the
+current directory.
+The following directory structure is used:
+ - var/lib/pacman: databases path (local and sync ones)
+ - etc/pacman.conf for pacman configuration file
+ - 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)
+
+Note: the logfile is used to capture all pacman outputs.
+
+Test case example:
+ self.description = "Install a package"
+
+ p = pmpkg("dummy", "1.0-3")
+ p.files = ["bin/dummy",
+ "usr/man/man1/dummy.1"]
+ self.addpkg(p)
+
+ self.args = "-A dummy-1.0-1.pkg.tar.gz"
+
+ self.addrule("PACMAN_RETCODE=0")
+ self.addrule("PKG_EXIST=dummy")
+ for f in p.files:
+ 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"
+Upon completion, it checks that:
+ - pacman returned no error code,
+ - a "dummy" entry exists in the "local" database
+ - all files from the package exist in the filesystem.
+
+
+Installation
+============
+
+Simply extract the pactest tarball, jump into the newly created directory and
+run pactest.py. See the usage section below.
+
+Remark: pacman 3.x restrictions regarding fakeroot must be disabled.
+It can be done by configuring pacman with the --disable-fakeroot flag:
+ ./configure --disable-fakeroot
+
+For pacman 2.9.x releases, apply the patch found in the patches directory,
+then export CFLAGS as following before rebuilding pacman:
+ export CFLAGS=-DNOFAKEROOT
+
+
+Usage
+=====
+
+pactest will run the suite of tests defined by the "--test" parameter.
+
+Example:
+ ./pactest.py --test tests/*.py
+
+This example will run all tests from the "tests" directory.
+Note: several "--test" options can be passed to pactest.
+
+Use the "help" option to get the full list of parameters:
+ ./pactest.py --help
+
+
+Parameters
+==========
+
+The test environment is described by the following basic parameters:
+
+ description
+ -----------
+
+A short string describing the aim of the test case. It is displayed on the
+standard output during test execution.
+
+ args
+ ----
+
+A string of arguments that are passed to the pacman binary when the test is
+run.
+
+Example:
+ self.args = "-S dummy"
+
+ option
+ ------
+
+A dictionary that holds the data used in the pacman configuration file.
+The following options are known to be useful in pactest tests; this list
+is not necessarily complete:
+ - HoldPkg
+ - IgnorePkg
+ - IgnoreGroup
+ - SyncFirst
+ - NoExtract
+ - NoUpgrade
+ - XferCommand
+
+For documentation on these options, see the pacman.conf documentation.
+
+Examples:
+ self.option["NoUpgrade"] = ["etc/X11/xorg.conf",
+ "etc/pacman.conf"]
+ self.option["NoExtract"] = ["etc/lilo.conf"]
+
+ filesystem
+ ----------
+
+A list of strings describing a set of files supposed to exist in the filesystem
+when the test case is run.
+Upon test startup, pactest will automatically populate the test environment
+filesystem with this list of files.
+
+Example:
+ self.filesystem = ["bin/dummy",
+ "etc/X11/xorg.conf.pacsave"]
+
+Note that all paths are relative ones, and thus file names should not start
+with a "/".
+
+
+Packages
+========
+
+The test case file description shall define a number of packages that can be
+used to either populate a database, or to feed pacman with data needed during
+its execution.
+
+This can be achieved by creating pmpkg objects, with the following constructor:
+ pmpkg(name, version)
+
+Both "name" and "version" are strings. Also, note that if not provided, the
+version defaults to "1.0-1".
+
+Example:
+ pkg1 = pmpkg("dummy", "2.1-1")
+ pkg2 = pmpkg("foobar")
+
+All fields from a ArchLinux package can be set and modified directly with no
+methods to access them.
+Note: some fields are automatically set by pactest and should preferably not
+be modified by hand (i.e. "md5sum", "size", or "csize").
+
+Examples:
+ pkg.depends = ["pkg2", "pkg3>=2.0"]
+ pkg.files = ["bin/dummy", "etc/dummy.conf", "usr/man/man1/dummy.1"]
+
+
+Databases
+=========
+
+The test environment provides a way to create and fill databases (local or
+sync ones).
+
+The following methods shall be used:
+
+ * addpkg2db(database, package)
+
+Notes: "database" is a string, and "package" shall be a previously created
+pmpkg object.
+
+Examples:
+ self.addpkg2db("local", lpkg)
+ self.addpkg2db("sync1", spkg11)
+ self.addpkg2db("sync1", spkg12)
+ self.addpkg2db("sync2", spkg21)
+
+Note: there is no need to explicitly create a database. The "local" one
+already exists (even if empty), and sync databases are created on the fly when
+a new database new is given.
+
+ * addpkg(package)
+
+package is an existing pmpkg object.
+It creates a package archive based on the given object. The resulting archive
+is located in the temporary directory of the test environment, ready to be
+supplied to pacman for test purposes.
+
+
+Files
+=====
+
+All files created by pactest are filled with a content defaulting to the file
+name, with an additional line feed.
+For instance, the content of a file "bin/dummy" created in the test environment
+file system is: "bin/dummy\n".
+
+It is possible to create directories by appending a slash "/" to the name and
+to create symlinks by appending an arrow followed by a filename " -> target".
+
+Note: only relative symlinks are supported.
+
+Example:
+ pkg = pmpkg("dummy")
+ pkg.files = ["bin/dummy",
+ "usr/local/",
+ "lib/libfoo.so.O",
+ "lib/libfoo.so -> ./libfoo.so.0"]
+
+In this example, "usr/local/" is a directory, and "libfoo.so" will be a
+symlink pointing at "libfoo.so.0". It is usually a good idea to also define
+the target of the symlink!
+
+It can be interesting for some tests to create altered files. This can be
+done by appending one or more asterisks "*" to the file name.
+
+Example:
+ lpkg = pmpkg("dummy")
+ lpkg.files = ["bin/dummy"]
+ self.addpkg2db("local", lpkg)
+
+ newpkg = pmpkg("dummy", "1.0-2")
+ newpkg.files = ["bin/dummy*"]
+ self.addpkg(newpkg)
+
+ self.args = "-U dummy-1.0-2.pkg.tar.gz"
+
+In this case, package "lpkg" will install a file "bin/dummy" with "bin/dummy\n"
+as its content. Upon package upgrade, newpkg will provide a file named
+"bin/dummy" with "bin/dummy*\n" as its content.
+This is useful to simulate that a file has been modified between two different
+releases of a same package.
+
+The same also applies to files from the "filesystem" parameter of the test
+environment, and to the "backup" attribute of a package object.
+
+
+Rules
+=====
+
+Finally, to check test success or failure, one shall define a set of rules.
+
+ addrule(rule)
+ -------------
+
+A rule is a string composed by a key and an item, joined with a "=" symbol.
+
+Examples:
+ self.addrule("PACMAN_RETCODE=0")
+ self.addrule("PKG_EXIST=dummy")
+ self.addrule("FILE_MODIFIED=bin/dummy")
+ self.addrule("PKG_DEPENDS=xorg|fontconfig")
+
+Note: an item can be divided into two arguments, as shown in the latter
+example.
+
+All rules can be prepended with a bang "!" in order to tell pactest to expect
+the exact opposite result.
+
+Example:
+ self.addrule("!FILE_MODIFIED=bin/dummy")
+
+Finally, the following rules are supported:
+
+ . PACMAN rules
+
+Possible rules are:
+
+ PACMAN_RETCODE=value
+ PACMAN_OUTPUT=value
+
+For RETCODE, pactest will ensure the pacman return code is the value given.
+For OUTPUT, pactest will grep pacman outputs for the given value.
+
+Note: PACMAN_OUTPUT should not be used. Pacman outputs are likely to change
+from one release to another, so that it's reliability is quite low.
+
+ . PKG rules
+
+For each rule, pactest will read the entry "name" from the local database and
+challenge the requested data with it.
+
+Possible rules are:
+
+ PKG_EXIST=name
+ PKG_MODIFIED=name
+ PKG_VERSION=name|version
+ PKG_GROUPS=name|group
+ PKG_PROVIDES=name|providename
+ PKG_DEPENDS=name|depname
+ PKG_OPTDEPENDS=name|depname
+ PKG_REASON=name|intvalue
+ PKG_FILES=name|filename
+ PKG_BACKUP=name|backupname
+
+Example:
+ PKG_DEPENDS=ncurses|glibc
+
+pactest will test to ensure the local database entry "ncurses" has "glibc" in
+its DEPENDS field.
+
+ . FILE rules
+
+ FILE_EXIST=path/to/file
+ FILE_MODIFIED=path/to/file
+ FILE_MODE=path/to/file|octal
+ FILE_TYPE=path/to/file|type (possible types: dir, file, link)
+ FILE_PACNEW=path/to/file
+ FILE_PACSAVE=path/to/file
+ FILE_PACORIG=path/to/file
+
+Example:
+ FILE_EXIST=etc/test.conf
+
+pactest will ensure the file /etc/test.conf exists in the filesystem.
+
diff --git a/test/pacman/TODO b/test/pacman/TODO
new file mode 100644
index 00000000..c7d4555a
--- /dev/null
+++ b/test/pacman/TODO
@@ -0,0 +1,8 @@
+TODO
+====
+
+Features:
+- implement script support (makekpg, repo-add, etc)
+
+Tests:
+- add test cases for pacman -D and pacman -T
diff --git a/test/pacman/pactest.py b/test/pacman/pactest.py
new file mode 100755
index 00000000..f95ef3c1
--- /dev/null
+++ b/test/pacman/pactest.py
@@ -0,0 +1,110 @@
+#! /usr/bin/python
+#
+# pactest : run automated testing on the pacman binary
+#
+# Copyright (c) 2006 by Aurelien Foret <orelien@chez.com>
+#
+# 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/>.
+
+import os, sys, glob
+from optparse import OptionParser
+
+import pmenv
+import util
+
+__author__ = "Aurelien FORET"
+__version__ = "0.4"
+
+def resolveBinPath(option, opt_str, value, parser):
+ setattr(parser.values, option.dest, os.path.abspath(value))
+
+def globTests(option, opt_str, value, parser):
+ idx=0
+ globlist = []
+
+ # maintain the idx so we can modify rargs
+ while idx < len(parser.rargs) and \
+ not parser.rargs[idx].startswith('-'):
+ globlist += glob.glob(parser.rargs[idx])
+ idx += 1
+
+ parser.rargs = parser.rargs[idx:]
+ setattr(parser.values, option.dest, globlist)
+
+def createOptParser():
+ testcases = []
+ 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 " \
+ "ran at once."
+ parser = OptionParser(usage = usage, description = description)
+
+ parser.add_option("-v", "--verbose", action = "count",
+ dest = "verbose", default = 0,
+ help = "print verbose output")
+ parser.add_option("-d", "--debug", type = "int",
+ dest = "debug", default = 0,
+ help = "set debug level for pacman")
+ parser.add_option("-p", "--pacman", action = "callback",
+ callback = resolveBinPath, type = "string",
+ dest = "bin", default = "pacman",
+ help = "specify location of the pacman binary")
+ parser.add_option("-t", "--test", action = "callback",
+ callback = globTests, dest = "testcases",
+ help = "specify test case(s)")
+ parser.add_option("--nolog", action = "store_true",
+ dest = "nolog", default = False,
+ help = "do not log pacman messages")
+ parser.add_option("--gdb", action = "store_true",
+ dest = "gdb", default = False,
+ help = "use gdb while calling pacman")
+ parser.add_option("--valgrind", action = "store_true",
+ dest = "valgrind", default = False,
+ help = "use valgrind while calling pacman")
+ parser.add_option("--manual-confirm", action = "store_true",
+ dest = "manualconfirm", default = False,
+ help = "do not use --noconfirm for pacman calls")
+ return parser
+
+
+if __name__ == "__main__":
+ # instantiate env and parser objects
+ env = pmenv.pmenv()
+ parser = createOptParser()
+ (opts, args) = parser.parse_args()
+
+ # add parsed options to env object
+ util.verbose = opts.verbose
+ env.pacman["debug"] = opts.debug
+ env.pacman["bin"] = opts.bin
+ env.pacman["nolog"] = opts.nolog
+ env.pacman["gdb"] = opts.gdb
+ env.pacman["valgrind"] = opts.valgrind
+ env.pacman["manual-confirm"] = opts.manualconfirm
+
+ if opts.testcases is None or len(opts.testcases) == 0:
+ print "no tests defined, nothing to do"
+ sys.exit(2)
+ else:
+ for i in opts.testcases:
+ env.addtest(i)
+
+ # run tests and print overall results
+ env.run()
+ env.results()
+
+ 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
new file mode 100755
index 00000000..8cb1b832
--- /dev/null
+++ b/test/pacman/pmdb.py
@@ -0,0 +1,386 @@
+#! /usr/bin/python
+#
+# Copyright (c) 2006 by Aurelien Foret <orelien@chez.com>
+#
+# 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/>.
+
+
+import os
+import tempfile
+import shutil
+import tarfile
+
+import pmpkg
+from util import *
+
+
+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
+ """
+ i = []
+ for f in files:
+ dir = getfilename(f)
+ i.append(dir)
+ while "/" in dir:
+ [dir, tmp] = dir.rsplit("/", 1)
+ if not dir + "/" in files:
+ i.append(dir + "/")
+ i.sort()
+ return i
+
+def _mkbackuplist(backup):
+ """
+ """
+ return ["%s\t%s" % (getfilename(i), mkmd5sum(i)) for i in backup]
+
+def _getsection(fd):
+ """
+ """
+ i = []
+ while 1:
+ line = fd.readline().strip("\n")
+ if not line:
+ break
+ i.append(line)
+ return i
+
+def _mksection(title, data):
+ """
+ """
+ s = ""
+ if isinstance(data, list):
+ s = "\n".join(data)
+ else:
+ s = data
+ return "%%%s%%\n" \
+ "%s\n" % (title, s)
+
+
+class pmdb:
+ """Database object
+ """
+
+ def __init__(self, treename, dbdir):
+ self.treename = treename
+ self.dbdir = dbdir
+ self.pkgs = []
+ self.option = {}
+
+ def __str__(self):
+ return "%s" % self.treename
+
+ def getpkg(self, name):
+ """
+ """
+ for pkg in self.pkgs:
+ if name == pkg.name:
+ return pkg
+
+ def db_read(self, name):
+ """
+ """
+
+ path = os.path.join(self.dbdir, self.treename)
+ if not os.path.isdir(path):
+ 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:
+ return None
+ path = os.path.join(path, dbentry)
+
+ [pkgname, pkgver, pkgrel] = dbentry.rsplit("-", 2)
+ pkg = pmpkg.pmpkg(pkgname, pkgver + "-" + pkgrel)
+
+ # desc
+ filename = os.path.join(path, "desc")
+ if not os.path.isfile(filename):
+ print "invalid db entry found (desc missing) for pkg", pkgname
+ return None
+ fd = open(filename, "r")
+ while 1:
+ line = fd.readline()
+ if not line:
+ break
+ line = line.strip("\n")
+ if line == "%DESC%":
+ pkg.desc = fd.readline().strip("\n")
+ elif line == "%GROUPS%":
+ pkg.groups = _getsection(fd)
+ elif line == "%URL%":
+ pkg.url = fd.readline().strip("\n")
+ elif line == "%LICENSE%":
+ pkg.license = _getsection(fd)
+ elif line == "%ARCH%":
+ pkg.arch = fd.readline().strip("\n")
+ elif line == "%BUILDDATE%":
+ pkg.builddate = fd.readline().strip("\n")
+ elif line == "%INSTALLDATE%":
+ pkg.installdate = fd.readline().strip("\n")
+ elif line == "%PACKAGER%":
+ pkg.packager = fd.readline().strip("\n")
+ elif line == "%REASON%":
+ pkg.reason = int(fd.readline().strip("\n"))
+ elif line == "%SIZE%" or line == "%CSIZE%":
+ pkg.size = int(fd.readline().strip("\n"))
+ elif line == "%MD5SUM%":
+ pkg.md5sum = fd.readline().strip("\n")
+ elif line == "%REPLACES%":
+ pkg.replaces = _getsection(fd)
+ elif line == "%FORCE%":
+ fd.readline()
+ pkg.force = 1
+ fd.close()
+ pkg.checksum["desc"] = getmd5sum(filename)
+ pkg.mtime["desc"] = getmtime(filename)
+
+ # files
+ filename = os.path.join(path, "files")
+ if not os.path.isfile(filename):
+ print "invalid db entry found (files missing) for pkg", pkgname
+ return None
+ fd = open(filename, "r")
+ while 1:
+ line = fd.readline()
+ if not line:
+ break
+ line = line.strip("\n")
+ if line == "%FILES%":
+ while line:
+ line = fd.readline().strip("\n")
+ if line and line[-1] != "/":
+ pkg.files.append(line)
+ if line == "%BACKUP%":
+ pkg.backup = _getsection(fd)
+ fd.close()
+ pkg.checksum["files"] = getmd5sum(filename)
+ pkg.mtime["files"] = getmtime(filename)
+
+ # depends
+ filename = os.path.join(path, "depends")
+ if not os.path.isfile(filename):
+ print "invalid db entry found (depends missing) for pkg", pkgname
+ return None
+ fd = file(filename, "r")
+ while 1:
+ line = fd.readline()
+ if not line:
+ break
+ line = line.strip("\n")
+ if line == "%DEPENDS%":
+ pkg.depends = _getsection(fd)
+ elif line == "%OPTDEPENDS%":
+ pkg.optdepends = _getsection(fd)
+ elif line == "%CONFLICTS%":
+ pkg.conflicts = _getsection(fd)
+ elif line == "%PROVIDES%":
+ pkg.provides = _getsection(fd)
+ # TODO this was going to be changed, but isn't anymore
+ #elif line == "%REPLACES%":
+ # pkg.replaces = _getsection(fd)
+ #elif line == "%FORCE%":
+ # fd.readline()
+ # pkg.force = 1
+ fd.close()
+ pkg.checksum["depends"] = getmd5sum(filename)
+ pkg.mtime["depends"] = getmtime(filename)
+
+ # install
+ filename = os.path.join(path, "install")
+ if os.path.isfile(filename):
+ pkg.checksum["install"] = getmd5sum(filename)
+ pkg.mtime["install"] = getmtime(filename)
+
+ return pkg
+
+ #
+ # db_write is used to add both 'local' and 'sync' db entries
+ #
+ def db_write(self, pkg):
+ """
+ """
+
+ if self.treename == "local":
+ path = os.path.join(self.dbdir, self.treename, pkg.fullname())
+ else:
+ path = os.path.join(self.dbdir, "sync", self.treename, pkg.fullname())
+ mkdir(path)
+
+ # desc
+ # for local db entries: name, version, desc, groups, url, license,
+ # arch, builddate, installdate, packager,
+ # size, reason
+ # for sync entries: name, version, desc, groups, csize, md5sum,
+ # replaces, force
+ 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 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))
+ else:
+ data.append(_mksection("FILENAME", pkg.filename()))
+ if pkg.replaces:
+ data.append(_mksection("REPLACES", pkg.replaces))
+ if pkg.force:
+ data.append(_mksection("FORCE", ""))
+ 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")
+ mkfile(filename, "\n".join(data))
+ pkg.checksum["desc"] = getmd5sum(filename)
+ pkg.mtime["desc"] = getmtime(filename)
+
+ # files
+ # for local entries, fields are: files, backup
+ # for sync ones: none
+ if self.treename == "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")
+ mkfile(filename, "\n".join(data))
+ pkg.checksum["files"] = getmd5sum(filename)
+ pkg.mtime["files"] = getmtime(filename)
+
+ # depends
+ # for local db entries: depends, conflicts, provides
+ # for sync ones: depends, conflicts, provides
+ data = []
+ 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.replaces:
+ # data.append(_mksection("REPLACES", pkg.replaces))
+ # if pkg.force:
+ # data.append(_mksection("FORCE", ""))
+ if data:
+ data.append("")
+ filename = os.path.join(path, "depends")
+ mkfile(filename, "\n".join(data))
+ pkg.checksum["depends"] = getmd5sum(filename)
+ pkg.mtime["depends"] = getmtime(filename)
+
+ # 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")
+ mkinstallfile(filename, pkg.install)
+ pkg.checksum["install"] = getmd5sum(filename)
+ pkg.mtime["install"] = getmtime(filename)
+
+ def gensync(self, path):
+ """
+ """
+
+ curdir = os.getcwd()
+ tmpdir = tempfile.mkdtemp()
+ os.chdir(tmpdir)
+
+ for pkg in self.pkgs:
+ mkdescfile(pkg.fullname(), pkg)
+
+ # Generate database archive
+ mkdir(path)
+ archive = os.path.join(path, "%s%s" % (self.treename, PM_EXT_DB))
+ tar = tarfile.open(archive, "w:gz")
+ for root, dirs, files in os.walk('.'):
+ for d in dirs:
+ tar.add(os.path.join(root, d), recursive=False)
+ for f in files:
+ tar.add(os.path.join(root, f))
+ tar.close()
+
+ os.chdir(curdir)
+ shutil.rmtree(tmpdir)
+
+ def ispkgmodified(self, pkg):
+ """
+ """
+
+ modified = 0
+
+ oldpkg = self.getpkg(pkg.name)
+ if not oldpkg:
+ return 0
+
+ vprint("\toldpkg.checksum : %s" % oldpkg.checksum)
+ vprint("\toldpkg.mtime : %s" % oldpkg.mtime)
+
+ for key in pkg.mtime.keys():
+ if key == "install" \
+ and oldpkg.mtime[key] == (0, 0, 0) \
+ and pkg.mtime[key] == (0, 0, 0):
+ continue
+ if oldpkg.mtime[key][1:3] != pkg.mtime[key][1:3]:
+ modified += 1
+
+ return modified
+
+
+if __name__ == "__main__":
+ db = pmdb("local")
+ print db
+# vim: set ts=4 sw=4 et:
diff --git a/test/pacman/pmenv.py b/test/pacman/pmenv.py
new file mode 100755
index 00000000..cc433dd0
--- /dev/null
+++ b/test/pacman/pmenv.py
@@ -0,0 +1,156 @@
+#! /usr/bin/python
+#
+# Copyright (c) 2006 by Aurelien Foret <orelien@chez.com>
+#
+# 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/>.
+
+
+import os
+import os.path
+import time
+
+import pmtest
+
+
+class pmenv:
+ """Environment object
+ """
+
+ testcases = []
+ passed = 0
+ failed = 0
+ expectedfail = 0
+ unexpectedpass = 0
+
+ def __init__(self, root = "root"):
+ self.root = os.path.abspath(root)
+ self.pacman = {
+ "bin": "pacman",
+ "debug": 0,
+ "gdb": 0,
+ "valgrind": 0,
+ "nolog": 0
+ }
+
+ def __str__(self):
+ return "root = %s\n" \
+ "pacman = %s" \
+ % (self.root, self.pacman)
+
+ def addtest(self, testcase):
+ """
+ """
+ if not os.path.isfile(testcase):
+ raise IOError("test file %s not found" % testcase)
+ test = pmtest.pmtest(testcase, self.root)
+ self.testcases.append(test)
+
+ def run(self):
+ """
+ """
+
+ for t in self.testcases:
+ print "=========="*8
+ print "Running '%s'" % t.testname
+
+ t.load()
+ print t.description
+ print "----------"*8
+
+ t.generate()
+ # Hack for mtimes consistency
+ for i in t.rules:
+ if i.rule.find("FILE_MODIFIED") != -1:
+ [test, arg] = i.rule.split("=")
+ for f in t.files:
+ if f.name == arg:
+ f.resettimes()
+
+ t.run(self.pacman)
+
+ t.check()
+ print "==> Test result"
+ if t.result["fail"] == 0:
+ print "\tPASS"
+ else:
+ print "\tFAIL"
+ print
+
+ def results(self):
+ """
+ """
+ tpassed = []
+ tfailed = []
+ texpectedfail = []
+ tunexpectedpass = []
+ for test in self.testcases:
+ fail = test.result["fail"]
+ if fail == 0 and not test.expectfailure:
+ self.passed += 1
+ tpassed.append(test)
+ elif fail != 0 and test.expectfailure:
+ self.expectedfail += 1
+ texpectedfail.append(test)
+ elif fail == 0: # and not test.expectfail
+ self.unexpectedpass += 1
+ tunexpectedpass.append(test)
+ else:
+ self.failed += 1
+ tfailed.append(test)
+
+ def _printtest(t):
+ success = test.result["success"]
+ fail = test.result["fail"]
+ rules = len(test.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, \
+ rules - (success + fail))
+ if fail != 0:
+ # print test description if test failed
+ print " ", test.description
+
+ print "=========="*8
+ print "Results"
+ print "----------"*8
+ print " Passed:"
+ for test in tpassed: _printtest(test)
+ print "----------"*8
+ print " Expected Failures:"
+ for test in texpectedfail: _printtest(test)
+ print "----------"*8
+ print " Unexpected Passes:"
+ for test in tunexpectedpass: _printtest(test)
+ print "----------"*8
+ print " Failed:"
+ for test in tfailed: _printtest(test)
+ print "----------"*8
+
+ total = len(self.testcases)
+ print "Total = %3u" % total
+ if total:
+ print "Pass = %3u (%6.2f%%)" % (self.passed, float(self.passed) * 100 / total)
+ print "Expected Fail = %3u (%6.2f%%)" % (self.expectedfail, float(self.expectedfail) * 100 / total)
+ print "Unexpected Pass = %3u (%6.2f%%)" % (self.unexpectedpass, float(self.unexpectedpass) * 100 / total)
+ 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
new file mode 100755
index 00000000..ab4aa2c7
--- /dev/null
+++ b/test/pacman/pmfile.py
@@ -0,0 +1,71 @@
+#! /usr/bin/python
+#
+# Copyright (c) 2006 by Aurelien Foret <orelien@chez.com>
+#
+# 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/>.
+
+
+import os
+
+from util import *
+
+
+class pmfile:
+ """File object
+ """
+
+ def __init__(self, root, name):
+ self.name = name
+ self.root = root
+
+ filename = os.path.join(self.root, self.name)
+ self.checksum = getmd5sum(filename)
+ self.mtime = getmtime(filename)
+
+ def __str__(self):
+ return "%s (%s / %lu)" % (self.name, self.checksum, self.mtime)
+
+ def ismodified(self):
+ """
+ """
+
+ retval = 0
+
+ filename = os.path.join(self.root, self.name)
+ checksum = getmd5sum(filename)
+ mtime = getmtime(filename)
+
+ vprint("\tismodified(%s)" % self.name)
+ vprint("\t\told: %s / %s" % (self.checksum, self.mtime))
+ vprint("\t\tnew: %s / %s" % (checksum, mtime))
+
+ if self.checksum != checksum \
+ or (self.mtime[1], self.mtime[2]) != (mtime[1], mtime[2]):
+ retval = 1
+
+ return retval
+
+ def resettimes(self):
+ """
+ """
+
+ filename = os.path.join(self.root, self.name)
+ os.utime(filename, (355, 355))
+ self.mtime = getmtime(filename)
+ vprint("\tmtime reset (%s)" % self.name)
+
+if __name__ == "__main__":
+ f = pmfile("/tmp", "foobar")
+ print f
+# vim: set ts=4 sw=4 et:
diff --git a/test/pacman/pmpkg.py b/test/pacman/pmpkg.py
new file mode 100755
index 00000000..48d79a35
--- /dev/null
+++ b/test/pacman/pmpkg.py
@@ -0,0 +1,184 @@
+#! /usr/bin/python
+#
+# Copyright (c) 2006 by Aurelien Foret <orelien@chez.com>
+#
+# 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/>.
+
+
+import os
+import tempfile
+import stat
+import shutil
+import tarfile
+
+from util import *
+
+
+class pmpkg:
+ """Package object.
+
+ Object holding data from an ArchLinux package.
+ """
+
+ def __init__(self, name, version = "1.0-1"):
+ self.path = "" #the path of the generated package
+ # desc
+ self.name = name
+ self.version = version
+ self.desc = ""
+ self.groups = []
+ self.url = ""
+ self.license = []
+ self.arch = ""
+ self.builddate = ""
+ self.installdate = ""
+ self.packager = ""
+ self.size = 0
+ self.csize = 0
+ self.reason = 0
+ self.md5sum = "" # sync only
+ self.replaces = [] # sync only (will be moved to depends)
+ self.force = 0 # sync only (will be moved to depends)
+ # depends
+ self.depends = []
+ self.optdepends = []
+ self.conflicts = []
+ self.provides = []
+ # files
+ self.files = []
+ self.backup = []
+ # install
+ self.install = {
+ "pre_install": "",
+ "post_install": "",
+ "pre_remove": "",
+ "post_remove": "",
+ "pre_upgrade": "",
+ "post_upgrade": ""
+ }
+ self.checksum = {
+ "desc": "",
+ "depends": "",
+ "files": "",
+ "install": ""
+ }
+ self.mtime = {
+ "desc": (0, 0, 0),
+ "depends": (0, 0, 0),
+ "files": (0, 0, 0),
+ "install": (0, 0, 0)
+ }
+
+ def __str__(self):
+ s = ["%s" % self.fullname()]
+ s.append("description: %s" % self.desc)
+ s.append("url: %s" % self.url)
+ s.append("depends: %s" % " ".join(self.depends))
+ s.append("files: %s" % " ".join(self.files))
+ s.append("reason: %d" % self.reason)
+ return "\n".join(s)
+
+ def fullname(self):
+ """Long name of a package.
+
+ Returns a string formatted as follows: "pkgname-pkgver".
+ """
+ return "%s-%s" % (self.name, self.version)
+
+ def filename(self):
+ """File name of a package, including its extension.
+
+ Returns a string formatted as follows: "pkgname-pkgver.PKG_EXT_PKG".
+ """
+ return "%s%s" % (self.fullname(), PM_EXT_PKG)
+
+ def install_files(self, root):
+ """Install files in the filesystem located under "root".
+
+ Files are created with content generated automatically.
+ """
+ [mkfile(os.path.join(root, f), f) for f in self.files]
+
+ def makepkg(self, path):
+ """Creates an ArchLinux 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:
+ mkfile(f, f)
+ self.size += os.stat(getfilename(f))[stat.ST_SIZE]
+
+ # .PKGINFO
+ data = ["pkgname = %s" % self.name]
+ data.append("pkgver = %s" % self.version)
+ data.append("pkgdesc = %s" % self.desc)
+ data.append("url = %s" % self.url)
+ data.append("builddate = %s" % self.builddate)
+ data.append("packager = %s" % self.packager)
+ data.append("size = %s" % self.size)
+ if self.arch:
+ data.append("arch = %s" % self.arch)
+ for i in self.license:
+ data.append("license = %s" % i)
+ for i in self.replaces:
+ data.append("replaces = %s" % i)
+ for i in self.groups:
+ data.append("group = %s" % i)
+ for i in self.depends:
+ data.append("depend = %s" % i)
+ for i in self.optdepends:
+ data.append("optdepend = %s" % i)
+ for i in self.conflicts:
+ data.append("conflict = %s" % i)
+ for i in self.provides:
+ data.append("provides = %s" % i)
+ for i in self.backup:
+ data.append("backup = %s" % i)
+ mkfile(".PKGINFO", "\n".join(data))
+
+ # .INSTALL
+ if len(self.install.values()) > 0:
+ mkinstallfile(".INSTALL", self.install)
+
+ # safely create the dir
+ mkdir(os.path.dirname(self.path))
+
+ # Generate package archive
+ tar = tarfile.open(self.path, "w:gz")
+
+ # package files
+ for root, dirs, files in os.walk('.'):
+ for d in dirs:
+ tar.add(os.path.join(root, d), recursive=False)
+ for f in files:
+ tar.add(os.path.join(root, f))
+
+ tar.close()
+
+ os.chdir(curdir)
+ shutil.rmtree(tmpdir)
+
+
+if __name__ == "__main__":
+ pkg = pmpkg("dummy")
+ print pkg
+# vim: set ts=4 sw=4 et:
diff --git a/test/pacman/pmrule.py b/test/pacman/pmrule.py
new file mode 100755
index 00000000..e7c9c44f
--- /dev/null
+++ b/test/pacman/pmrule.py
@@ -0,0 +1,159 @@
+#! /usr/bin/python
+#
+# Copyright (c) 2006 by Aurelien Foret <orelien@chez.com>
+#
+# 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/>.
+
+import os
+from util import *
+from stat import *
+
+class pmrule:
+ """Rule object
+ """
+
+ def __init__(self, rule):
+ self.rule = rule
+ self.false = 0
+ self.result = 0
+
+ def __str__(self):
+ return "rule = %s" % self.rule
+
+ def check(self, root, retcode, localdb, files):
+ """
+ """
+
+ success = 1
+
+ [test, args] = self.rule.split("=")
+ if test[0] == "!":
+ self.false = 1
+ test = test.lstrip("!")
+ [kind, case] = test.split("_")
+ if "|" in args:
+ [key, value] = args.split("|", 1)
+ else:
+ [key, value] = [args, None]
+
+ if kind == "PACMAN":
+ if case == "RETCODE":
+ if retcode != int(key):
+ success = 0
+ elif case == "OUTPUT":
+ logfile = os.path.join(root, LOGFILE)
+ if not os.access(logfile, os.F_OK):
+ print "LOGFILE not found, cannot validate 'OUTPUT' rule"
+ success = 0
+ elif not grep(os.path.join(root, LOGFILE), key):
+ success = 0
+ else:
+ print "PACMAN rule '%s' not found" % case
+ success = -1
+ elif kind == "PKG":
+ newpkg = localdb.db_read(key)
+ if not newpkg:
+ success = 0
+ else:
+ vprint("\tnewpkg.checksum : %s" % newpkg.checksum)
+ vprint("\tnewpkg.mtime : %s" % newpkg.mtime)
+ if case == "EXIST":
+ success = 1
+ elif case == "MODIFIED":
+ if not localdb.ispkgmodified(newpkg):
+ success = 0
+ elif case == "VERSION":
+ if value != newpkg.version:
+ success = 0
+ elif case == "GROUPS":
+ if not value in newpkg.groups:
+ success = 0
+ elif case == "PROVIDES":
+ if not value in newpkg.provides:
+ success = 0
+ elif case == "DEPENDS":
+ if not value in newpkg.depends:
+ success = 0
+ elif case == "OPTDEPENDS":
+ if not value in newpkg.optdepends:
+ success = 0
+ elif case == "REASON":
+ if newpkg.reason != int(value):
+ success = 0
+ elif case == "FILES":
+ if not value in newpkg.files:
+ success = 0
+ elif case == "BACKUP":
+ found = 0
+ for f in newpkg.backup:
+ name, md5sum = f.split("\t")
+ if value == name:
+ found = 1
+ if not found:
+ success = 0
+ else:
+ print "PKG rule '%s' not found" % case
+ success = -1
+ elif kind == "FILE":
+ filename = os.path.join(root, key)
+ if case == "EXIST":
+ if not os.path.isfile(filename):
+ success = 0
+ elif case == "MODIFIED":
+ for f in files:
+ if f.name == key:
+ if not f.ismodified():
+ success = 0
+ elif case == "MODE":
+ if not os.path.isfile(filename):
+ success = 0
+ else:
+ mode = os.lstat(filename)[ST_MODE]
+ if int(value,8) != S_IMODE(mode):
+ success = 0
+ elif case == "TYPE":
+ if value == "dir":
+ if not os.path.isdir(filename):
+ success = 0
+ elif value == "file":
+ if not os.path.isfile(filename):
+ success = 0
+ elif value == "link":
+ if not os.path.islink(filename):
+ success = 0
+ elif case == "PACNEW":
+ if not os.path.isfile("%s%s" % (filename, PM_PACNEW)):
+ success = 0
+ elif case == "PACORIG":
+ if not os.path.isfile("%s%s" % (filename, PM_PACORIG)):
+ success = 0
+ elif case == "PACSAVE":
+ if not os.path.isfile("%s%s" % (filename, PM_PACSAVE)):
+ success = 0
+ else:
+ print "FILE rule '%s' not found" % case
+ success = -1
+ else:
+ print "Rule kind '%s' not found" % kind
+ success = -1
+
+ if self.false and success != -1:
+ success = not success
+ self.result = success
+ return success
+
+
+if __name__ != "__main__":
+ rule = pmrule("PKG_EXIST=dummy")
+# vim: set ts=4 sw=4 et:
diff --git a/test/pacman/pmtest.py b/test/pacman/pmtest.py
new file mode 100755
index 00000000..f2b96760
--- /dev/null
+++ b/test/pacman/pmtest.py
@@ -0,0 +1,265 @@
+#! /usr/bin/python
+#
+# Copyright (c) 2006 by Aurelien Foret <orelien@chez.com>
+#
+# 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/>.
+
+
+import os
+import os.path
+import shutil
+import time
+
+import pmrule
+import pmdb
+import pmfile
+from pmpkg import pmpkg
+from util import *
+
+
+class pmtest:
+ """Test object
+ """
+
+ def __init__(self, name, root):
+ self.name = name
+ self.testname = os.path.basename(name).replace('.py', '')
+ self.root = root
+ self.cachepkgs = True
+
+ def __str__(self):
+ return "name = %s\n" \
+ "testname = %s\n" \
+ "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, os.path.join(self.root, PM_DBPATH))
+ self.db[treename].pkgs.append(pkg)
+
+ def addpkg(self, pkg):
+ """
+ """
+ self.localpkgs.append(pkg)
+
+ def addrule(self, rulename):
+ """
+ """
+ rule = pmrule.pmrule(rulename)
+ self.rules.append(rule)
+
+ def load(self):
+ """
+ """
+
+ # Reset test parameters
+ self.result = {
+ "success": 0,
+ "fail": 0
+ }
+ self.args = ""
+ self.retcode = 0
+ self.db = {
+ "local": pmdb.pmdb("local", os.path.join(self.root, PM_DBPATH))
+ }
+ self.localpkgs = []
+ self.filesystem = []
+
+ self.description = ""
+ self.option = {}
+
+ # Test rules
+ self.rules = []
+ self.files = []
+ self.expectfailure = False
+
+ if os.path.isfile(self.name):
+ execfile(self.name)
+ else:
+ raise IOerror("file %s does not exist!" % self.name)
+
+ def generate(self):
+ """
+ """
+
+ print "==> Generating test environment"
+
+ # Cleanup leftover files from a previous test session
+ if os.path.isdir(self.root):
+ shutil.rmtree(self.root)
+ vprint("\t%s" % self.root)
+
+ # Create directory structure
+ vprint(" Creating directory structure:")
+ dbdir = os.path.join(self.root, PM_DBPATH)
+ cachedir = os.path.join(self.root, PM_CACHEDIR)
+ syncdir = os.path.join(self.root, SYNCREPO)
+ tmpdir = os.path.join(self.root, TMPDIR)
+ logdir = os.path.join(self.root, os.path.dirname(LOGFILE))
+ etcdir = os.path.join(self.root, os.path.dirname(PACCONF))
+ for dir in [dbdir, cachedir, syncdir, tmpdir, logdir, etcdir]:
+ if not os.path.isdir(dir):
+ vprint("\t%s" % dir[len(self.root)+1:])
+ os.makedirs(dir, 0755)
+
+ # Configuration file
+ vprint(" Creating configuration file")
+ vprint("\t%s" % PACCONF)
+ mkcfgfile(PACCONF, self.root, self.option, self.db)
+
+ # Creating packages
+ vprint(" Creating package archives")
+ for pkg in self.localpkgs:
+ vprint("\t%s" % os.path.join(TMPDIR, pkg.filename()))
+ pkg.makepkg(tmpdir)
+ for key, value in self.db.iteritems():
+ if key == "local": continue
+ for pkg in value.pkgs:
+ vprint("\t%s" % os.path.join(PM_CACHEDIR, pkg.filename()))
+ if self.cachepkgs:
+ pkg.makepkg(cachedir)
+ else:
+ pkg.makepkg(os.path.join(syncdir, value.treename))
+ pkg.md5sum = 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")
+ for key, value in self.db.iteritems():
+ if key == "local": continue
+ archive = value.treename + PM_EXT_DB
+ vprint("\t" + os.path.join(SYNCREPO, archive))
+ value.gensync(os.path.join(syncdir, value.treename))
+
+ # Filesystem
+ vprint(" Populating file system")
+ for pkg in self.db["local"].pkgs:
+ vprint("\tinstalling %s" % pkg.fullname())
+ pkg.install_files(self.root)
+ for f in self.filesystem:
+ vprint("\t%s" % f)
+ mkfile(os.path.join(self.root, f), f)
+
+ # Done.
+ vprint(" Taking a snapshot of the file system")
+ 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 + "/", ""))
+ self.files.append(f)
+ vprint("\t%s" % f.name)
+
+ def run(self, pacman):
+ """
+ """
+
+ if os.path.isfile(PM_LOCK):
+ print "\tERROR: another pacman session is on-going -- skipping"
+ return
+
+ print "==> Running test"
+ vprint("\tpacman %s" % self.args)
+
+ cmd = [""]
+ if os.geteuid() != 0:
+ fakeroot = which("fakeroot")
+ if not fakeroot:
+ print "WARNING: fakeroot not found!"
+ else:
+ cmd.append("fakeroot")
+
+ fakechroot = which("fakechroot")
+ if fakechroot:
+ cmd.append("fakechroot")
+
+ if pacman["gdb"]:
+ cmd.append("libtool execute gdb --args")
+ if pacman["valgrind"]:
+ cmd.append("valgrind -q --tool=memcheck --leak-check=full --show-reachable=yes")
+ cmd.append("\"%s\" --config=\"%s\" --root=\"%s\" --dbpath=\"%s\" --cachedir=\"%s\"" \
+ % (pacman["bin"],
+ os.path.join(self.root, PACCONF),
+ self.root,
+ os.path.join(self.root, PM_DBPATH),
+ os.path.join(self.root, 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, LOGFILE))
+ 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, TMPDIR)
+ os.chdir(tmpdir)
+
+ t0 = time.time()
+ self.retcode = os.system(" ".join(cmd))
+ t1 = time.time()
+ vprint("\ttime elapsed: %ds" % (t1-t0))
+
+ 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(PM_LOCK):
+ print "\tERROR: %s not removed" % PM_LOCK
+ os.unlink(PM_LOCK)
+ # Look for a core file
+ if os.path.isfile(os.path.join(self.root, TMPDIR, "core")):
+ print "\tERROR: pacman dumped a core file"
+
+ def check(self):
+ """
+ """
+
+ print "==> Checking rules"
+
+ for i in self.rules:
+ success = i.check(self.root, self.retcode, self.db["local"], self.files)
+ if success == 1:
+ msg = " OK "
+ self.result["success"] += 1
+ elif success == 0:
+ msg = "FAIL"
+ self.result["fail"] += 1
+ else:
+ msg = "SKIP"
+ print "\t[%s] %s" % (msg, i.rule)
+ i.result = success
+
+
+if __name__ == "__main__":
+ pass
+
+# vim: set ts=4 sw=4 et:
diff --git a/test/pacman/tests/.gitignore b/test/pacman/tests/.gitignore
new file mode 100644
index 00000000..665d9ce6
--- /dev/null
+++ b/test/pacman/tests/.gitignore
@@ -0,0 +1 @@
+sync200.py
diff --git a/test/pacman/tests/Makefile.am b/test/pacman/tests/Makefile.am
new file mode 100644
index 00000000..b793687b
--- /dev/null
+++ b/test/pacman/tests/Makefile.am
@@ -0,0 +1,27 @@
+CONFTESTS = $(patsubst %py.in,%py,$(wildcard *.py.in))
+
+check_SCRIPTS = \
+ $(wildcard *.py) \
+ $(CONFTESTS)
+
+noinst_SCRIPTS = $(check_SCRIPTS)
+
+EXTRA_DIST = $(check_SCRIPTS)
+
+CLEANFILES = $(CONFTESTS)
+
+#### Taken from the autoconf scripts Makefile.am ####
+edit = sed \
+ -e 's|@LIBS[@]|$(LIBS)|g' \
+ -e 's|@configure_input[@]|Generated from $@.in; do not edit by hand.|g'
+
+
+$(CONFTESTS): Makefile
+ @echo ' ' GEN $@;
+ @rm -f $@ $@.tmp
+ @test -f $(srcdir)/$@.in && $(edit) $(srcdir)/$@.in >$@.tmp || true
+ @test -f $@.tmp || false
+ @chmod a-w $@.tmp
+ @mv $@.tmp $@
+
+# vim:set ts=2 sw=2 noet:
diff --git a/test/pacman/tests/config001.py b/test/pacman/tests/config001.py
new file mode 100644
index 00000000..3411433f
--- /dev/null
+++ b/test/pacman/tests/config001.py
@@ -0,0 +1,17 @@
+self.description = "Quick check for Include being parsed in [options]"
+
+self.option['Include'] = ['/dev/null']
+
+p = pmpkg("foobar")
+p.files = ["bin/foobar"]
+p.desc = "test description"
+p.groups = ["foo"]
+p.url = "http://www.archlinux.org"
+p.license = "GPL2"
+p.arch = "i686"
+
+self.addpkg2db("local", p)
+
+self.args = "-Qi %s" % p.name
+
+self.addrule("PACMAN_RETCODE=0")
diff --git a/test/pacman/tests/config002.py b/test/pacman/tests/config002.py
new file mode 100644
index 00000000..8efe5a04
--- /dev/null
+++ b/test/pacman/tests/config002.py
@@ -0,0 +1,12 @@
+self.description = "Quick check for Include being parsed in [db]"
+
+sp = pmpkg("dummy")
+sp.files = ["bin/dummy",
+ "usr/man/man1/dummy.1"]
+self.addpkg2db("sync", sp)
+
+self.db['sync'].option['Include'] = ['/dev/null']
+
+self.args = "-Si %s" % sp.name
+
+self.addrule("PACMAN_RETCODE=0")
diff --git a/test/pacman/tests/database001.py b/test/pacman/tests/database001.py
new file mode 100644
index 00000000..de4c0404
--- /dev/null
+++ b/test/pacman/tests/database001.py
@@ -0,0 +1,11 @@
+self.description = "-D --asdeps"
+
+lp = pmpkg("pkg")
+lp.reason = 0
+self.addpkg2db("local", lp)
+
+self.args = "-D pkg --asdeps"
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_EXIST=pkg")
+self.addrule("PKG_REASON=pkg|1")
diff --git a/test/pacman/tests/database002.py b/test/pacman/tests/database002.py
new file mode 100644
index 00000000..05fa7f4b
--- /dev/null
+++ b/test/pacman/tests/database002.py
@@ -0,0 +1,11 @@
+self.description = "-D --asexplicit"
+
+lp = pmpkg("pkg")
+lp.reason = 1
+self.addpkg2db("local", lp)
+
+self.args = "-D pkg --asexplicit"
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_EXIST=pkg")
+self.addrule("PKG_REASON=pkg|0")
diff --git a/test/pacman/tests/database010.py b/test/pacman/tests/database010.py
new file mode 100644
index 00000000..662dc1b6
--- /dev/null
+++ b/test/pacman/tests/database010.py
@@ -0,0 +1,17 @@
+# TODO: these are labeled as database packages because they sure seem to me to
+# be database-type operations. In their current implementation however they are
+# calling -U and -R rather than -D. Obviously the tests will need to be updated
+# if this changes.
+self.description = "Remove a package with --dbonly, no files touched"
+
+p = pmpkg("dummy")
+p.files = ["bin/dummy",
+ "usr/man/man1/dummy.1"]
+self.addpkg2db("local", p)
+
+self.args = "-R --dbonly %s" % p.name
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("!PKG_EXIST=dummy")
+for f in p.files:
+ self.addrule("FILE_EXIST=%s" % f)
diff --git a/test/pacman/tests/database011.py b/test/pacman/tests/database011.py
new file mode 100644
index 00000000..7d475d91
--- /dev/null
+++ b/test/pacman/tests/database011.py
@@ -0,0 +1,17 @@
+# TODO: these are labeled as database packages because they sure seem to me to
+# be database-type operations. In their current implementation however they are
+# calling -U and -R rather than -D. Obviously the tests will need to be updated
+# if this changes.
+self.description = "Install a package with --dbonly, no files touched"
+
+p = pmpkg("dummy")
+p.files = ["bin/dummy",
+ "usr/man/man1/dummy.1"]
+self.addpkg(p)
+
+self.args = "-U --dbonly %s" % p.filename()
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_EXIST=dummy")
+for f in p.files:
+ self.addrule("!FILE_EXIST=%s" % f)
diff --git a/test/pacman/tests/database012.py b/test/pacman/tests/database012.py
new file mode 100644
index 00000000..a1f86980
--- /dev/null
+++ b/test/pacman/tests/database012.py
@@ -0,0 +1,31 @@
+# TODO: these are labeled as database packages because they sure seem to me to
+# be database-type operations. In their current implementation however they are
+# calling -U and -R rather than -D. Obviously the tests will need to be updated
+# if this changes.
+self.description = "Upgrade a package with --dbonly, no files touched"
+
+lp = pmpkg("dummy")
+lp.files = ["bin/dummy",
+ "usr/man/man1/dummy.1"]
+self.addpkg2db("local", lp)
+
+p = pmpkg("dummy", "2.0-1")
+p.files = ["bin/dummy",
+ "bin/dummy2",
+ "usr/man/man1/dummy.1"]
+self.addpkg(p)
+
+self.args = "-U --dbonly %s" % p.filename()
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_EXIST=dummy")
+self.addrule("PKG_VERSION=dummy|2.0-1")
+for f in lp.files:
+ self.addrule("!FILE_EXIST=%s" % f)
+# TODO: I honestly think the above should NOT delete the original files, it
+# should upgrade the DB entry without touching anything on the file system.
+# E.g. this test should be the same as:
+# pacman -R --dbonly dummy && pacman -U --dbonly dummy.pkg.tar.gz
+#for f in lp.files:
+# self.addrule("FILE_EXIST=%s" % f)
+self.addrule("!FILE_EXIST=bin/dummy2")
diff --git a/test/pacman/tests/depconflict100.py b/test/pacman/tests/depconflict100.py
new file mode 100644
index 00000000..948017d9
--- /dev/null
+++ b/test/pacman/tests/depconflict100.py
@@ -0,0 +1,15 @@
+self.description = "a package conflicts with itself"
+
+sp1 = pmpkg("pkg1")
+sp1.conflicts = ["pkg1"]
+self.addpkg2db("sync", sp1);
+
+sp2 = pmpkg("pkg2", "1.0-2")
+self.addpkg2db("sync", sp2)
+
+self.args = "-S %s" % " ".join([p.name for p in sp1, sp2])
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_EXIST=pkg1")
+self.addrule("PKG_EXIST=pkg2")
+self.addrule("PKG_VERSION=pkg2|1.0-2")
diff --git a/test/pacman/tests/depconflict110.py b/test/pacman/tests/depconflict110.py
new file mode 100644
index 00000000..82e17d0b
--- /dev/null
+++ b/test/pacman/tests/depconflict110.py
@@ -0,0 +1,13 @@
+self.description = "conflict with version (conflict)"
+
+p = pmpkg("pkg1")
+p.conflicts = ["pkg2<=1.0-2"]
+self.addpkg(p);
+
+lp = pmpkg("pkg2", "1.0-1")
+self.addpkg2db("local", lp)
+
+self.args = "-U %s --ask=4" % p.filename()
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_EXIST=pkg1")
+self.addrule("!PKG_EXIST=pkg2")
diff --git a/test/pacman/tests/depconflict111.py b/test/pacman/tests/depconflict111.py
new file mode 100644
index 00000000..0d11dd92
--- /dev/null
+++ b/test/pacman/tests/depconflict111.py
@@ -0,0 +1,13 @@
+self.description = "conflict with version (no conflict)"
+
+p = pmpkg("pkg1")
+p.conflicts = ["pkg2=1.0-2"]
+self.addpkg(p);
+
+lp = pmpkg("pkg2", "1.0-1")
+self.addpkg2db("local", lp)
+
+self.args = "-U %s" % p.filename()
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_EXIST=pkg1")
+self.addrule("PKG_EXIST=pkg2")
diff --git a/test/pacman/tests/depconflict120.py b/test/pacman/tests/depconflict120.py
new file mode 100644
index 00000000..a9f3f6b3
--- /dev/null
+++ b/test/pacman/tests/depconflict120.py
@@ -0,0 +1,19 @@
+self.description = "target vs db conflict will disappear after upgrade"
+
+sp1 = pmpkg("pkg1")
+sp1.conflicts = ["imaginary"]
+self.addpkg2db("sync", sp1);
+
+sp2 = pmpkg("pkg2", "1.0-2")
+self.addpkg2db("sync", sp2)
+
+lp = pmpkg("pkg2", "1.0-1")
+lp.provides = ["imaginary"]
+self.addpkg2db("local", lp)
+
+self.args = "-S %s" % " ".join([p.name for p in sp1, sp2])
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_EXIST=pkg1")
+self.addrule("PKG_EXIST=pkg2")
+self.addrule("PKG_VERSION=pkg2|1.0-2")
diff --git a/test/pacman/tests/deptest001.py b/test/pacman/tests/deptest001.py
new file mode 100644
index 00000000..18569bea
--- /dev/null
+++ b/test/pacman/tests/deptest001.py
@@ -0,0 +1,16 @@
+self.description = "test deptest (-T) functionality"
+
+lp1 = pmpkg("pkg1")
+self.addpkg2db("local", lp1)
+
+lp3 = pmpkg("pkg3", "2.0-1")
+lp3.provides = ("prov=3.0")
+self.addpkg2db("local", lp3)
+
+self.args = "-T pkg1 pkg2 pkg3\>2.1 prov\>\=3.0"
+
+self.addrule("PACMAN_RETCODE=127")
+self.addrule("!PACMAN_OUTPUT=pkg1")
+self.addrule("PACMAN_OUTPUT=pkg2")
+self.addrule("PACMAN_OUTPUT=pkg3")
+self.addrule("!PACMAN_OUTPUT=prov")
diff --git a/test/pacman/tests/dummy001.py b/test/pacman/tests/dummy001.py
new file mode 100644
index 00000000..85a5d99c
--- /dev/null
+++ b/test/pacman/tests/dummy001.py
@@ -0,0 +1,21 @@
+self.description = "Dummy test case (modify for own use)"
+
+p1 = pmpkg("dummy")
+p1.files = ["etc/dummy.conf*",
+ "lib/libdummy.so.0",
+ "lib/libdummy.so -> ./libdummy.so.0",
+ "usr/",
+ "bin/dummy"]
+p1.backup = ["etc/dummy.conf*"]
+p1.install['post_install'] = "echo toto";
+p1.url="ze url"
+self.addpkg(p1)
+
+#p2 = pmpkg("dummy", "1.0-2")
+#p2.files = ["etc/dummy.conf**"]
+#p2.backup = ["etc/dummy.conf"]
+#self.addpkg(p2)
+
+self.args = "-U %s" % p1.filename()
+
+self.addrule("PACMAN_RETCODE=0")
diff --git a/test/pacman/tests/fileconflict001.py b/test/pacman/tests/fileconflict001.py
new file mode 100644
index 00000000..8c13911c
--- /dev/null
+++ b/test/pacman/tests/fileconflict001.py
@@ -0,0 +1,22 @@
+self.description = "Fileconflict with symlinks"
+
+lp = pmpkg("dummy")
+lp.files = ["dir/realdir/",
+ "dir/symdir -> realdir"]
+self.addpkg2db("local", lp)
+
+p1 = pmpkg("pkg1")
+p1.files = ["dir/realdir/file"]
+self.addpkg(p1)
+
+p2 = pmpkg("pkg2")
+p2.files = ["dir/symdir/file"]
+self.addpkg(p2)
+
+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.expectfailure = True
diff --git a/test/pacman/tests/fileconflict002.py b/test/pacman/tests/fileconflict002.py
new file mode 100644
index 00000000..f70873ba
--- /dev/null
+++ b/test/pacman/tests/fileconflict002.py
@@ -0,0 +1,18 @@
+self.description = "Fileconflict with symlinks (2)"
+
+p1 = pmpkg("pkg1")
+p1.files = ["dir/realdir/file",
+ "dir/symdir -> realdir"]
+self.addpkg(p1)
+
+p2 = pmpkg("pkg2")
+p2.files = ["dir/symdir/file"]
+self.addpkg(p2)
+
+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.expectfailure = True
diff --git a/test/pacman/tests/fileconflict003.py b/test/pacman/tests/fileconflict003.py
new file mode 100644
index 00000000..89696fcb
--- /dev/null
+++ b/test/pacman/tests/fileconflict003.py
@@ -0,0 +1,18 @@
+self.description = "FS#8156"
+
+p1 = pmpkg("pkg1")
+p1.files = ["test/",
+ "test/file"]
+self.addpkg2db("local", p1)
+
+p2 = pmpkg("pkg2")
+p2.files = ["test2/",
+ "test2/file2",
+ "test -> test2"]
+self.addpkg2db("sync", p2)
+
+self.args = "-S pkg2"
+
+self.addrule("PACMAN_RETCODE=1")
+self.addrule("PKG_EXIST=pkg1")
+self.addrule("!PKG_EXIST=pkg2")
diff --git a/test/pacman/tests/fileconflict004.py b/test/pacman/tests/fileconflict004.py
new file mode 100644
index 00000000..a5347ccd
--- /dev/null
+++ b/test/pacman/tests/fileconflict004.py
@@ -0,0 +1,19 @@
+self.description = "dir->symlink change during package upgrade (no conflict)"
+
+p1 = pmpkg("pkg1", "1.0-1")
+p1.files = ["test/",
+ "test/file"]
+self.addpkg2db("local", p1)
+
+p2 = pmpkg("pkg1", "2.0-1")
+p2.files = ["test2/",
+ "test2/file2",
+ "test -> test2"]
+self.addpkg2db("sync", p2)
+
+self.args = "-S pkg1"
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_EXIST=pkg1")
+self.addrule("PKG_VERSION=pkg1|2.0-1")
+self.addrule("FILE_TYPE=test|link")
diff --git a/test/pacman/tests/fileconflict005.py b/test/pacman/tests/fileconflict005.py
new file mode 100644
index 00000000..5c554afe
--- /dev/null
+++ b/test/pacman/tests/fileconflict005.py
@@ -0,0 +1,22 @@
+self.description = "dir->symlink change during package upgrade (conflict)"
+
+p1 = pmpkg("pkg1", "1.0-1")
+p1.files = ["test/",
+ "test/file1"]
+self.addpkg2db("local", p1)
+
+p2 = pmpkg("pkg2")
+p2.files = ["test/file2"]
+self.addpkg2db("local", p2)
+
+p3 = pmpkg("pkg1", "2.0-1")
+p3.files = ["test2/",
+ "test2/file3",
+ "test -> test2"]
+self.addpkg2db("sync", p3)
+
+self.args = "-S pkg1"
+
+self.addrule("PACMAN_RETCODE=1")
+self.addrule("PKG_EXIST=pkg1")
+self.addrule("PKG_VERSION=pkg1|1.0-1")
diff --git a/test/pacman/tests/fileconflict006.py b/test/pacman/tests/fileconflict006.py
new file mode 100644
index 00000000..84afff2d
--- /dev/null
+++ b/test/pacman/tests/fileconflict006.py
@@ -0,0 +1,24 @@
+self.description = "dir->symlink change during package upgrade (conflict)"
+
+p1 = pmpkg("pkg1", "1.0-1")
+p1.files = ["test/",
+ "test/file1",
+ "test/dir/file1",
+ "test/dir/file2"]
+self.addpkg2db("local", p1)
+
+p2 = pmpkg("pkg2")
+p2.files = ["test/dir/file3"]
+self.addpkg2db("local", p2)
+
+p3 = pmpkg("pkg1", "2.0-1")
+p3.files = ["test2/",
+ "test2/file3",
+ "test -> test2"]
+self.addpkg2db("sync", p3)
+
+self.args = "-S pkg1"
+
+self.addrule("PACMAN_RETCODE=1")
+self.addrule("PKG_EXIST=pkg1")
+self.addrule("PKG_VERSION=pkg1|1.0-1")
diff --git a/test/pacman/tests/fileconflict007.py b/test/pacman/tests/fileconflict007.py
new file mode 100644
index 00000000..7e6d85ef
--- /dev/null
+++ b/test/pacman/tests/fileconflict007.py
@@ -0,0 +1,17 @@
+self.description = "Fileconflict with symlinks (klibc case)"
+
+lp = pmpkg("pkg")
+lp.files = ["dir/realdir/",
+ "dir/symdir -> realdir",
+ "dir/realdir/file"]
+self.addpkg2db("local", lp)
+
+p = pmpkg("pkg", "1.0-2")
+p.files = ["dir/symdir/file"]
+self.addpkg(p)
+
+self.args = "-U %s" % p.filename()
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_EXIST=pkg")
+self.addrule("PKG_VERSION=pkg|1.0-2")
diff --git a/test/pacman/tests/ignore001.py b/test/pacman/tests/ignore001.py
new file mode 100644
index 00000000..bb3fa59a
--- /dev/null
+++ b/test/pacman/tests/ignore001.py
@@ -0,0 +1,17 @@
+self.description = "Sync with irrelevant ignored packages"
+
+package1 = pmpkg("package1")
+self.addpkg2db("local", package1)
+
+package2 = pmpkg("package2")
+self.addpkg2db("local", package2)
+
+package2up = pmpkg("package2", "2.0-1")
+self.addpkg2db("sync", package2up)
+
+self.option["IgnorePkg"] = ["irrelavent"]
+self.args = "-Su"
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_VERSION=package1|1.0-1")
+self.addrule("PKG_VERSION=package2|2.0-1")
diff --git a/test/pacman/tests/ignore002.py b/test/pacman/tests/ignore002.py
new file mode 100644
index 00000000..9b09e8f7
--- /dev/null
+++ b/test/pacman/tests/ignore002.py
@@ -0,0 +1,35 @@
+self.description = "Sync with relevant ignored packages"
+
+package1 = pmpkg("package1")
+self.addpkg2db("local", package1)
+
+package2 = pmpkg("package2")
+self.addpkg2db("local", package2)
+
+package3 = pmpkg("package3")
+package3.depends = ["package2=1.0-1"]
+self.addpkg2db("local", package3)
+
+package4 = pmpkg("package4")
+package4.depends = ["package3=1.0-1"]
+self.addpkg2db("local", package4)
+
+package2up = pmpkg("package2", "2.0-1")
+self.addpkg2db("sync", package2up)
+
+package3up = pmpkg("package3", "2.0-1")
+package3up.depends = ["package2=2.0-1"]
+self.addpkg2db("sync", package3up)
+
+package4up = pmpkg("package4", "2.0-1")
+package4up.depends = ["package3=2.0-1"]
+self.addpkg2db("sync", package4up)
+
+self.option["IgnorePkg"] = ["package2"]
+self.args = "-Su"
+
+self.addrule("PACMAN_RETCODE=1")
+self.addrule("PKG_VERSION=package1|1.0-1")
+self.addrule("PKG_VERSION=package2|1.0-1")
+self.addrule("PKG_VERSION=package3|1.0-1")
+self.addrule("PKG_VERSION=package4|1.0-1")
diff --git a/test/pacman/tests/ignore003.py b/test/pacman/tests/ignore003.py
new file mode 100644
index 00000000..8768a6ef
--- /dev/null
+++ b/test/pacman/tests/ignore003.py
@@ -0,0 +1,35 @@
+self.description = "Sync with relevant ignored packages and dependency loop"
+
+package1 = pmpkg("package1")
+self.addpkg2db("local", package1)
+
+package2 = pmpkg("package2")
+self.addpkg2db("local", package2)
+
+package3 = pmpkg("package3")
+package3.depends = ["package2=1.0-1"]
+self.addpkg2db("local", package3)
+
+package4 = pmpkg("package4")
+package4.depends = ["package3=1.0-1"]
+self.addpkg2db("local", package4)
+
+package2up = pmpkg("package2", "2.0-1")
+self.addpkg2db("sync", package2up)
+
+package3up = pmpkg("package3", "2.0-1")
+package3up.depends = ["package2=2.0-1", "package4=2.0-1"]
+self.addpkg2db("sync", package3up)
+
+package4up = pmpkg("package4", "2.0-1")
+package4up.depends = ["package3=2.0-1"]
+self.addpkg2db("sync", package4up)
+
+self.option["IgnorePkg"] = ["package2"]
+self.args = "-Su"
+
+self.addrule("PACMAN_RETCODE=1")
+self.addrule("PKG_VERSION=package1|1.0-1")
+self.addrule("PKG_VERSION=package2|1.0-1")
+self.addrule("PKG_VERSION=package3|1.0-1")
+self.addrule("PKG_VERSION=package4|1.0-1")
diff --git a/test/pacman/tests/ignore004.py b/test/pacman/tests/ignore004.py
new file mode 100644
index 00000000..e6af48bd
--- /dev/null
+++ b/test/pacman/tests/ignore004.py
@@ -0,0 +1,46 @@
+self.description = "Sync with ignore causing top-level to be ignored"
+
+packageA1 = pmpkg("packageA1")
+packageA1.depends = ["packageA2=1.0-1", "packageA3=1.0-1"];
+self.addpkg2db("local", packageA1)
+
+packageA2 = pmpkg("packageA2")
+packageA2.depends = ["packageA4=1.0-1", "packageA5=1.0-1"];
+self.addpkg2db("local", packageA2)
+
+packageA3 = pmpkg("packageA3")
+self.addpkg2db("local", packageA3)
+
+packageA4 = pmpkg("packageA4")
+self.addpkg2db("local", packageA4)
+
+packageA5 = pmpkg("packageA5")
+self.addpkg2db("local", packageA5)
+
+packageA1up = pmpkg("packageA1", "2.0-1")
+packageA1up.depends = ["packageA2=2.0-1", "packageA3=2.0-1"];
+self.addpkg2db("sync", packageA1up)
+
+packageA2up = pmpkg("packageA2", "2.0-1")
+packageA2up.depends = ["packageA4=2.0-1", "packageA5=2.0-1"];
+self.addpkg2db("sync", packageA2up)
+
+packageA3up = pmpkg("packageA3", "2.0-1")
+self.addpkg2db("sync", packageA3up)
+
+packageA4up = pmpkg("packageA4", "2.0-1")
+self.addpkg2db("sync", packageA4up)
+
+packageA5up = pmpkg("packageA5", "2.0-1")
+self.addpkg2db("sync", packageA5up)
+
+
+self.option["IgnorePkg"] = ["packageA3"]
+self.args = "-S packageA1"
+
+self.addrule("PACMAN_RETCODE=1")
+self.addrule("PKG_VERSION=packageA1|1.0-1")
+self.addrule("PKG_VERSION=packageA2|1.0-1")
+self.addrule("PKG_VERSION=packageA3|1.0-1")
+self.addrule("PKG_VERSION=packageA4|1.0-1")
+self.addrule("PKG_VERSION=packageA5|1.0-1")
diff --git a/test/pacman/tests/ignore005.py b/test/pacman/tests/ignore005.py
new file mode 100644
index 00000000..274e44c3
--- /dev/null
+++ b/test/pacman/tests/ignore005.py
@@ -0,0 +1,46 @@
+self.description = "Sync with ignore causing top-level to be included"
+
+packageA1 = pmpkg("packageA1")
+packageA1.depends = ["packageA2>=1.0-1", "packageA3=1.0-1"];
+self.addpkg2db("local", packageA1)
+
+packageA2 = pmpkg("packageA2")
+packageA2.depends = ["packageA4=1.0-1", "packageA5=1.0-1"];
+self.addpkg2db("local", packageA2)
+
+packageA3 = pmpkg("packageA3")
+self.addpkg2db("local", packageA3)
+
+packageA4 = pmpkg("packageA4")
+self.addpkg2db("local", packageA4)
+
+packageA5 = pmpkg("packageA5")
+self.addpkg2db("local", packageA5)
+
+packageA1up = pmpkg("packageA1", "2.0-1")
+packageA1up.depends = ["packageA2>=2.0-1", "packageA3=2.0-1"];
+self.addpkg2db("sync", packageA1up)
+
+packageA2up = pmpkg("packageA2", "2.0-1")
+packageA2up.depends = ["packageA4=2.0-1", "packageA5=2.0-1"];
+self.addpkg2db("sync", packageA2up)
+
+packageA3up = pmpkg("packageA3", "2.0-1")
+self.addpkg2db("sync", packageA3up)
+
+packageA4up = pmpkg("packageA4", "2.0-1")
+self.addpkg2db("sync", packageA4up)
+
+packageA5up = pmpkg("packageA5", "2.0-1")
+self.addpkg2db("sync", packageA5up)
+
+
+self.option["IgnorePkg"] = ["packageA3"]
+self.args = "-S packageA1 packageA2 --ask=32"
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_VERSION=packageA1|1.0-1")
+self.addrule("PKG_VERSION=packageA2|2.0-1")
+self.addrule("PKG_VERSION=packageA3|1.0-1")
+self.addrule("PKG_VERSION=packageA4|2.0-1")
+self.addrule("PKG_VERSION=packageA5|2.0-1")
diff --git a/test/pacman/tests/ldconfig001.py b/test/pacman/tests/ldconfig001.py
new file mode 100644
index 00000000..9ac2ff35
--- /dev/null
+++ b/test/pacman/tests/ldconfig001.py
@@ -0,0 +1,12 @@
+# quick note here - chroot() is expected to fail. We're not checking the
+# validity of the scripts, only that they fire (or try to)
+self.description = "Make sure ldconfig runs on an add operation"
+
+p = pmpkg("dummy")
+self.addpkg(p)
+
+# --debug is necessary to check PACMAN_OUTPUT
+self.args = "--debug -U %s" % p.filename()
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PACMAN_OUTPUT=ldconfig")
diff --git a/test/pacman/tests/ldconfig002.py b/test/pacman/tests/ldconfig002.py
new file mode 100644
index 00000000..162f5831
--- /dev/null
+++ b/test/pacman/tests/ldconfig002.py
@@ -0,0 +1,16 @@
+# quick note here - chroot() is expected to fail. We're not checking the
+# validity of the scripts, only that they fire (or try to)
+self.description = "Make sure ldconfig runs on an upgrade operation"
+
+lp = pmpkg("dummy")
+self.addpkg2db("local", lp)
+
+p = pmpkg("dummy", "1.0-2")
+self.addpkg(p)
+
+# --debug is necessary to check PACMAN_OUTPUT
+self.args = "--debug -U %s" % p.filename()
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_VERSION=dummy|1.0-2")
+self.addrule("PACMAN_OUTPUT=ldconfig")
diff --git a/test/pacman/tests/ldconfig003.py b/test/pacman/tests/ldconfig003.py
new file mode 100644
index 00000000..1b48efad
--- /dev/null
+++ b/test/pacman/tests/ldconfig003.py
@@ -0,0 +1,14 @@
+# quick note here - chroot() is expected to fail. We're not checking the
+# validity of the scripts, only that they fire (or try to)
+self.description = "Make sure ldconfig runs on a sync operation"
+
+sp = pmpkg("dummy")
+self.addpkg2db("sync", sp)
+
+self.args = "-S %s" % sp.name
+
+# --debug is necessary to check PACMAN_OUTPUT
+self.args = "--debug -S %s" % sp.name
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PACMAN_OUTPUT=ldconfig")
diff --git a/test/pacman/tests/mode001.py b/test/pacman/tests/mode001.py
new file mode 100644
index 00000000..4ec11e10
--- /dev/null
+++ b/test/pacman/tests/mode001.py
@@ -0,0 +1,12 @@
+self.description = "Check the mode of default files in a package"
+
+p = pmpkg("pkg1")
+p.files = ["bin/foo",
+ "bin/bar"]
+self.addpkg(p)
+
+self.args = "-U %s" % p.filename()
+
+self.addrule("PACMAN_RETCODE=0")
+for f in p.files:
+ self.addrule("FILE_MODE=%s|644" % f)
diff --git a/test/pacman/tests/mode002.py b/test/pacman/tests/mode002.py
new file mode 100644
index 00000000..cc4a8fe8
--- /dev/null
+++ b/test/pacman/tests/mode002.py
@@ -0,0 +1,12 @@
+self.description = "Check execute mode on files in a package"
+
+p = pmpkg("pkg1")
+p.files = ["bin/foo|755",
+ "bin/bar|755"]
+self.addpkg(p)
+
+self.args = "-U %s" % p.filename()
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("FILE_MODE=bin/foo|755")
+self.addrule("FILE_MODE=bin/bar|755")
diff --git a/test/pacman/tests/mode003.py b/test/pacman/tests/mode003.py
new file mode 100644
index 00000000..1193a5cf
--- /dev/null
+++ b/test/pacman/tests/mode003.py
@@ -0,0 +1,20 @@
+self.description = "Backup file permissions test (same as orig)"
+
+lp = pmpkg("filesystem")
+lp.files = ["etc/profile|666"]
+lp.backup = ["etc/profile*"]
+self.addpkg2db("local", lp)
+
+p = pmpkg("filesystem", "1.0-2")
+p.files = ["etc/profile|666**"]
+p.backup = ["etc/profile"]
+self.addpkg(p)
+
+self.args = "-U %s" % p.filename()
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("!FILE_PACSAVE=etc/profile")
+self.addrule("FILE_PACNEW=etc/profile")
+self.addrule("FILE_EXIST=etc/profile")
+self.addrule("FILE_MODE=etc/profile|666")
+self.addrule("FILE_MODE=etc/profile.pacnew|666")
diff --git a/test/pacman/tests/pacman001.py b/test/pacman/tests/pacman001.py
new file mode 100644
index 00000000..d467e3f2
--- /dev/null
+++ b/test/pacman/tests/pacman001.py
@@ -0,0 +1,5 @@
+self.description = "Test command line option (--version)"
+
+self.args = "--version"
+
+self.addrule("PACMAN_RETCODE=2")
diff --git a/test/pacman/tests/pacman002.py b/test/pacman/tests/pacman002.py
new file mode 100644
index 00000000..c0217259
--- /dev/null
+++ b/test/pacman/tests/pacman002.py
@@ -0,0 +1,5 @@
+self.description = "Test command line option (--help)"
+
+self.args = "--help"
+
+self.addrule("PACMAN_RETCODE=2")
diff --git a/test/pacman/tests/pacman003.py b/test/pacman/tests/pacman003.py
new file mode 100644
index 00000000..b5275943
--- /dev/null
+++ b/test/pacman/tests/pacman003.py
@@ -0,0 +1,5 @@
+self.description = "Test command line option (-S --help)"
+
+self.args = "-S --help"
+
+self.addrule("PACMAN_RETCODE=2")
diff --git a/test/pacman/tests/pacman004.py b/test/pacman/tests/pacman004.py
new file mode 100644
index 00000000..d8d6b102
--- /dev/null
+++ b/test/pacman/tests/pacman004.py
@@ -0,0 +1,5 @@
+self.description = "Test command line option (-v)"
+
+self.args = "-v"
+
+self.addrule("PACMAN_RETCODE=1")
diff --git a/test/pacman/tests/provision001.py b/test/pacman/tests/provision001.py
new file mode 100644
index 00000000..37e3d935
--- /dev/null
+++ b/test/pacman/tests/provision001.py
@@ -0,0 +1,10 @@
+self.description = "-S provision"
+
+sp = pmpkg("pkg1")
+sp.provides = ["provision=1.0-1"]
+self.addpkg2db("sync", sp)
+
+self.args = "-S provision"
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_EXIST=pkg1")
diff --git a/test/pacman/tests/provision010.py b/test/pacman/tests/provision010.py
new file mode 100644
index 00000000..711a7319
--- /dev/null
+++ b/test/pacman/tests/provision010.py
@@ -0,0 +1,15 @@
+self.description = "provision>=1.0-2 dependency"
+
+p = pmpkg("pkg1", "1.0-2")
+p.depends = ["provision>=1.0-2"]
+self.addpkg(p)
+
+lp = pmpkg("pkg2", "1.0-2")
+lp.provides = ["provision"]
+self.addpkg2db("local", lp)
+
+self.args = "-U %s" % p.filename()
+
+self.addrule("PACMAN_RETCODE=1")
+self.addrule("!PKG_EXIST=pkg1")
+self.addrule("PKG_EXIST=pkg2")
diff --git a/test/pacman/tests/provision011.py b/test/pacman/tests/provision011.py
new file mode 100644
index 00000000..96aac300
--- /dev/null
+++ b/test/pacman/tests/provision011.py
@@ -0,0 +1,15 @@
+self.description = "provision>=1.0-2 dependency (2)"
+
+p = pmpkg("pkg1", "1.0-2")
+p.depends = ["provision>=1.0-2"]
+self.addpkg(p)
+
+lp = pmpkg("pkg2", "1.0-2")
+lp.provides = ["provision=1.0-2"]
+self.addpkg2db("local", lp)
+
+self.args = "-U %s" % p.filename()
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_EXIST=pkg1")
+self.addrule("PKG_EXIST=pkg2")
diff --git a/test/pacman/tests/provision012.py b/test/pacman/tests/provision012.py
new file mode 100644
index 00000000..f7ed2216
--- /dev/null
+++ b/test/pacman/tests/provision012.py
@@ -0,0 +1,15 @@
+self.description = "provision>=1.0-2 dependency (3)"
+
+p = pmpkg("pkg1", "1.0-2")
+p.depends = ["provision>=1.0-2"]
+self.addpkg(p)
+
+lp = pmpkg("pkg2", "1.0-2")
+lp.provides = ["provision=1.0-1"]
+self.addpkg2db("local", lp)
+
+self.args = "-U %s" % p.filename()
+
+self.addrule("PACMAN_RETCODE=1")
+self.addrule("!PKG_EXIST=pkg1")
+self.addrule("PKG_EXIST=pkg2")
diff --git a/test/pacman/tests/provision020.py b/test/pacman/tests/provision020.py
new file mode 100644
index 00000000..7cb0a01b
--- /dev/null
+++ b/test/pacman/tests/provision020.py
@@ -0,0 +1,15 @@
+self.description = "provision>=1.0-2 dependency"
+
+p = pmpkg("pkg1", "1.0-2")
+p.depends = ["provision>=1.0-2"]
+self.addpkg2db("sync", p)
+
+lp = pmpkg("pkg2", "1.0-2")
+lp.provides = ["provision"]
+self.addpkg2db("local", lp)
+
+self.args = "-S %s" % p.name
+
+self.addrule("PACMAN_RETCODE=1")
+self.addrule("!PKG_EXIST=pkg1")
+self.addrule("PKG_EXIST=pkg2")
diff --git a/test/pacman/tests/provision021.py b/test/pacman/tests/provision021.py
new file mode 100644
index 00000000..a98e1f33
--- /dev/null
+++ b/test/pacman/tests/provision021.py
@@ -0,0 +1,15 @@
+self.description = "provision>=1.0-2 dependency (2)"
+
+p = pmpkg("pkg1", "1.0-2")
+p.depends = ["provision>=1.0-2"]
+self.addpkg2db("sync", p)
+
+lp = pmpkg("pkg2", "1.0-2")
+lp.provides = ["provision=1.0-2"]
+self.addpkg2db("local", lp)
+
+self.args = "-S %s" % p.name
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_EXIST=pkg1")
+self.addrule("PKG_EXIST=pkg2")
diff --git a/test/pacman/tests/provision022.py b/test/pacman/tests/provision022.py
new file mode 100644
index 00000000..4883d428
--- /dev/null
+++ b/test/pacman/tests/provision022.py
@@ -0,0 +1,15 @@
+self.description = "provision>=1.0-2 dependency (3)"
+
+p = pmpkg("pkg1", "1.0-2")
+p.depends = ["provision>=1.0-2"]
+self.addpkg2db("sync", p)
+
+lp = pmpkg("pkg2", "1.0-2")
+lp.provides = ["provision=1.0-1"]
+self.addpkg2db("local", lp)
+
+self.args = "-S %s" % p.name
+
+self.addrule("PACMAN_RETCODE=1")
+self.addrule("!PKG_EXIST=pkg1")
+self.addrule("PKG_EXIST=pkg2")
diff --git a/test/pacman/tests/query001.py b/test/pacman/tests/query001.py
new file mode 100644
index 00000000..8faf0e15
--- /dev/null
+++ b/test/pacman/tests/query001.py
@@ -0,0 +1,10 @@
+self.description = "Query a package"
+
+p = pmpkg("foobar")
+p.files = ["bin/foobar"]
+self.addpkg2db("local", p)
+
+self.args = "-Q %s" % p.name
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PACMAN_OUTPUT=%s" % p.name)
diff --git a/test/pacman/tests/query002.py b/test/pacman/tests/query002.py
new file mode 100644
index 00000000..7d943644
--- /dev/null
+++ b/test/pacman/tests/query002.py
@@ -0,0 +1,21 @@
+self.description = "Query info on a package"
+
+p = pmpkg("foobar")
+p.files = ["bin/foobar"]
+p.desc = "test description"
+p.groups = ["foo"]
+p.url = "http://www.archlinux.org"
+p.license = "GPL2"
+p.arch = "i686"
+# test old style date
+p.builddate = "Mon Oct 1 01:40:21 2007 UTC"
+p.packager = "Arch Linux"
+
+self.addpkg2db("local", p)
+
+self.args = "-Qi %s" % p.name
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PACMAN_OUTPUT=%s" % p.name)
+self.addrule("PACMAN_OUTPUT=%s" % p.desc)
+self.addrule("PACMAN_OUTPUT=2007")
diff --git a/test/pacman/tests/query003.py b/test/pacman/tests/query003.py
new file mode 100644
index 00000000..41b8a45b
--- /dev/null
+++ b/test/pacman/tests/query003.py
@@ -0,0 +1,11 @@
+self.description = "Query search for a package"
+
+p = pmpkg("foobar")
+p.files = ["bin/foobar"]
+p.groups = ["group1", "group2"]
+self.addpkg2db("local", p)
+
+self.args = "-Qs %s" % p.name
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PACMAN_OUTPUT=%s" % p.name)
diff --git a/test/pacman/tests/query004.py b/test/pacman/tests/query004.py
new file mode 100644
index 00000000..8faf0e15
--- /dev/null
+++ b/test/pacman/tests/query004.py
@@ -0,0 +1,10 @@
+self.description = "Query a package"
+
+p = pmpkg("foobar")
+p.files = ["bin/foobar"]
+self.addpkg2db("local", p)
+
+self.args = "-Q %s" % p.name
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PACMAN_OUTPUT=%s" % p.name)
diff --git a/test/pacman/tests/query005.py b/test/pacman/tests/query005.py
new file mode 100644
index 00000000..0c0bc51e
--- /dev/null
+++ b/test/pacman/tests/query005.py
@@ -0,0 +1,21 @@
+self.description = "Query info on a package"
+
+p = pmpkg("foobar")
+p.files = ["bin/foobar"]
+p.desc = "test description"
+p.groups = ["foo"]
+p.url = "http://www.archlinux.org"
+p.license = "GPL2"
+p.arch = "i686"
+# test new style date
+p.builddate = "1196640127"
+p.packager = "Arch Linux"
+
+self.addpkg2db("local", p)
+
+self.args = "-Qi %s" % p.name
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PACMAN_OUTPUT=%s" % p.name)
+self.addrule("PACMAN_OUTPUT=%s" % p.desc)
+self.addrule("PACMAN_OUTPUT=2007")
diff --git a/test/pacman/tests/reason001.py b/test/pacman/tests/reason001.py
new file mode 100644
index 00000000..40433f5e
--- /dev/null
+++ b/test/pacman/tests/reason001.py
@@ -0,0 +1,16 @@
+self.description = "Copy reason (to-be-replaced -> replacement)"
+
+sp = pmpkg("libfoo-ng")
+sp.replaces = [ "libfoo" ]
+self.addpkg2db("sync", sp)
+
+lp = pmpkg("libfoo")
+lp.reason = 1
+self.addpkg2db("local", lp)
+
+self.args = "-Su"
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("!PKG_EXIST=libfoo")
+self.addrule("PKG_EXIST=libfoo-ng")
+self.addrule("PKG_REASON=libfoo-ng|1")
diff --git a/test/pacman/tests/remove001.py b/test/pacman/tests/remove001.py
new file mode 100644
index 00000000..02d00a42
--- /dev/null
+++ b/test/pacman/tests/remove001.py
@@ -0,0 +1,9 @@
+self.description = "Remove a package listed 5 times"
+
+p = pmpkg("foo")
+self.addpkg2db("local", p)
+
+self.args = "-R " + "foo "*5
+
+self.addrule("PACMAN_RETCODE=1")
+self.addrule("PKG_EXIST=foo")
diff --git a/test/pacman/tests/remove010.py b/test/pacman/tests/remove010.py
new file mode 100644
index 00000000..dbdc47e7
--- /dev/null
+++ b/test/pacman/tests/remove010.py
@@ -0,0 +1,13 @@
+self.description = "Remove a package with an unchanged file marked for backup"
+
+p1 = pmpkg("dummy")
+p1.files = ["etc/dummy.conf"]
+p1.backup = ["etc/dummy.conf"]
+self.addpkg2db("local", p1)
+
+self.args = "-R %s" % p1.name
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("!PKG_EXIST=dummy")
+self.addrule("!FILE_EXIST=etc/dummy.conf")
+self.addrule("!FILE_PACSAVE=etc/dummy.conf")
diff --git a/test/pacman/tests/remove011.py b/test/pacman/tests/remove011.py
new file mode 100644
index 00000000..3e559bf9
--- /dev/null
+++ b/test/pacman/tests/remove011.py
@@ -0,0 +1,13 @@
+self.description = "Remove a package with a modified file marked for backup"
+
+p1 = pmpkg("dummy")
+p1.files = ["etc/dummy.conf*"]
+p1.backup = ["etc/dummy.conf"]
+self.addpkg2db("local", p1)
+
+self.args = "-R %s" % p1.name
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("!PKG_EXIST=dummy")
+self.addrule("!FILE_EXIST=etc/dummy.conf")
+self.addrule("FILE_PACSAVE=etc/dummy.conf")
diff --git a/test/pacman/tests/remove020.py b/test/pacman/tests/remove020.py
new file mode 100644
index 00000000..bdfc2c26
--- /dev/null
+++ b/test/pacman/tests/remove020.py
@@ -0,0 +1,13 @@
+self.description = "Remove a package with a file marked for backup (--nosave)"
+
+p1 = pmpkg("dummy")
+p1.files = ["etc/dummy.conf"]
+p1.backup = ["etc/dummy.conf"]
+self.addpkg2db("local", p1)
+
+self.args = "-Rn %s" % p1.name
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("!PKG_EXIST=dummy")
+self.addrule("!FILE_EXIST=etc/dummy.conf")
+self.addrule("!FILE_PACSAVE=etc/dummy.conf")
diff --git a/test/pacman/tests/remove021.py b/test/pacman/tests/remove021.py
new file mode 100644
index 00000000..87217563
--- /dev/null
+++ b/test/pacman/tests/remove021.py
@@ -0,0 +1,13 @@
+self.description = "Remove a package with a modified file marked for backup (--nosave)"
+
+p1 = pmpkg("dummy")
+p1.files = ["etc/dummy.conf*"]
+p1.backup = ["etc/dummy.conf"]
+self.addpkg2db("local", p1)
+
+self.args = "-Rn %s" % p1.name
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("!PKG_EXIST=dummy")
+self.addrule("!FILE_EXIST=etc/dummy.conf")
+self.addrule("!FILE_PACSAVE=etc/dummy.conf")
diff --git a/test/pacman/tests/remove030.py b/test/pacman/tests/remove030.py
new file mode 100644
index 00000000..e975a4ba
--- /dev/null
+++ b/test/pacman/tests/remove030.py
@@ -0,0 +1,11 @@
+self.description = "Remove a package in HoldPkg"
+
+p1 = pmpkg("dummy")
+self.addpkg2db("local", p1)
+
+self.option["HoldPkg"] = ["dummy"]
+
+self.args = "-R %s" % p1.name
+
+self.addrule("PACMAN_RETCODE=1")
+self.addrule("PKG_EXIST=dummy")
diff --git a/test/pacman/tests/remove040.py b/test/pacman/tests/remove040.py
new file mode 100644
index 00000000..9d95b60e
--- /dev/null
+++ b/test/pacman/tests/remove040.py
@@ -0,0 +1,15 @@
+self.description = "Remove a package that requires another package"
+
+lp1 = pmpkg("pkg1")
+lp1.depends = ["imaginary"]
+self.addpkg2db("local", lp1)
+
+lp2 = pmpkg("pkg2")
+lp2.provides = ["imaginary"]
+self.addpkg2db("local", lp2)
+
+self.args = "-R %s" % lp1.name
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("!PKG_EXIST=pkg1")
+self.addrule("PKG_EXIST=pkg2")
diff --git a/test/pacman/tests/remove041.py b/test/pacman/tests/remove041.py
new file mode 100644
index 00000000..be27fd4c
--- /dev/null
+++ b/test/pacman/tests/remove041.py
@@ -0,0 +1,19 @@
+self.description = "Remove a no longer needed package (multiple provision)"
+
+lp1 = pmpkg("pkg1")
+lp1.provides = ["imaginary"]
+self.addpkg2db("local", lp1)
+
+lp2 = pmpkg("pkg2")
+lp2.provides = ["imaginary"]
+self.addpkg2db("local", lp2)
+
+lp3 = pmpkg("pkg3")
+lp3.depends = ["imaginary"]
+self.addpkg2db("local", lp3)
+
+self.args = "-R %s" % lp1.name
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("!PKG_EXIST=pkg1")
+self.addrule("PKG_EXIST=pkg2")
diff --git a/test/pacman/tests/remove042.py b/test/pacman/tests/remove042.py
new file mode 100644
index 00000000..796d0406
--- /dev/null
+++ b/test/pacman/tests/remove042.py
@@ -0,0 +1,15 @@
+self.description = "Cascade remove a package required by another package"
+
+lp1 = pmpkg("pkg1")
+lp1.depends = ["imaginary"]
+self.addpkg2db("local", lp1)
+
+lp2 = pmpkg("pkg2")
+lp2.provides = ["imaginary"]
+self.addpkg2db("local", lp2)
+
+self.args = "-Rc %s" % lp2.name
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("!PKG_EXIST=pkg1")
+self.addrule("!PKG_EXIST=pkg2")
diff --git a/test/pacman/tests/remove043.py b/test/pacman/tests/remove043.py
new file mode 100644
index 00000000..0d448d0d
--- /dev/null
+++ b/test/pacman/tests/remove043.py
@@ -0,0 +1,15 @@
+self.description = "Remove a package required by another package"
+
+lp1 = pmpkg("pkg1")
+lp1.depends = ["imaginary"]
+self.addpkg2db("local", lp1)
+
+lp2 = pmpkg("pkg2")
+lp2.provides = ["imaginary"]
+self.addpkg2db("local", lp2)
+
+self.args = "-R %s" % lp2.name
+
+self.addrule("!PACMAN_RETCODE=0")
+self.addrule("PKG_EXIST=pkg1")
+self.addrule("PKG_EXIST=pkg2")
diff --git a/test/pacman/tests/remove044.py b/test/pacman/tests/remove044.py
new file mode 100644
index 00000000..720c1fe7
--- /dev/null
+++ b/test/pacman/tests/remove044.py
@@ -0,0 +1,16 @@
+self.description = "-Rs test"
+
+lp1 = pmpkg("pkg1")
+lp1.depends = ["pkg2=1.1-1"]
+self.addpkg2db("local", lp1)
+
+lp2 = pmpkg("pkg2", "1.0-1")
+lp2.reason = 1
+self.addpkg2db("local", lp2)
+
+
+self.args = "-Rs %s" % lp1.name
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("!PKG_EXIST=pkg1")
+self.addrule("PKG_EXIST=pkg2")
diff --git a/test/pacman/tests/remove045.py b/test/pacman/tests/remove045.py
new file mode 100644
index 00000000..f42e58f2
--- /dev/null
+++ b/test/pacman/tests/remove045.py
@@ -0,0 +1,27 @@
+self.description = "-Rs advanced test"
+
+lp1 = pmpkg("pkg1")
+lp1.depends = ["pkg2" , "pkg3"]
+self.addpkg2db("local", lp1)
+
+lp2 = pmpkg("pkg2")
+lp2.reason = 1
+lp2.depends = ["pkg4"]
+self.addpkg2db("local", lp2)
+
+lp3 = pmpkg("pkg3")
+lp3.reason = 1
+self.addpkg2db("local", lp3)
+
+lp4 = pmpkg("pkg4")
+lp4.reason = 1
+lp4.depends = ["pkg3"]
+self.addpkg2db("local", lp4)
+
+self.args = "-Rs %s" % lp1.name
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("!PKG_EXIST=pkg1")
+self.addrule("!PKG_EXIST=pkg2")
+self.addrule("!PKG_EXIST=pkg3")
+self.addrule("!PKG_EXIST=pkg4")
diff --git a/test/pacman/tests/remove047.py b/test/pacman/tests/remove047.py
new file mode 100644
index 00000000..8bb1a63a
--- /dev/null
+++ b/test/pacman/tests/remove047.py
@@ -0,0 +1,24 @@
+self.description = "Remove a package required by other packages"
+
+lp1 = pmpkg("pkg1")
+self.addpkg2db("local", lp1)
+
+lp2 = pmpkg("pkg2")
+lp2.depends = ["pkg1"]
+self.addpkg2db("local", lp2)
+
+lp3 = pmpkg("pkg3")
+lp3.depends = ["pkg1"]
+self.addpkg2db("local", lp3)
+
+lp4 = pmpkg("pkg4")
+lp4.depends = ["pkg1"]
+self.addpkg2db("local", lp4)
+
+self.args = "-R pkg1 pkg2"
+
+self.addrule("!PACMAN_RETCODE=0")
+self.addrule("PKG_EXIST=pkg1")
+self.addrule("PKG_EXIST=pkg2")
+self.addrule("PKG_EXIST=pkg3")
+self.addrule("PKG_EXIST=pkg4")
diff --git a/test/pacman/tests/remove049.py b/test/pacman/tests/remove049.py
new file mode 100644
index 00000000..a0336295
--- /dev/null
+++ b/test/pacman/tests/remove049.py
@@ -0,0 +1,18 @@
+self.description = "-Ru test"
+
+lp1 = pmpkg("pkg1")
+self.addpkg2db("local", lp1)
+
+lp2 = pmpkg("pkg2")
+self.addpkg2db("local", lp2)
+
+lp3 = pmpkg("pkg3")
+lp3.depends = [ "pkg1" ]
+self.addpkg2db("local", lp3)
+
+self.args = "-Ru pkg1 pkg2"
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_EXIST=pkg1")
+self.addrule("!PKG_EXIST=pkg2")
+self.addrule("PKG_EXIST=pkg3") \ No newline at end of file
diff --git a/test/pacman/tests/remove050.py b/test/pacman/tests/remove050.py
new file mode 100644
index 00000000..44b0d18c
--- /dev/null
+++ b/test/pacman/tests/remove050.py
@@ -0,0 +1,20 @@
+self.description = "-Rs test (exclude explicit)"
+
+lp1 = pmpkg("pkg1")
+lp1.depends = ["pkg2" , "pkg3"]
+self.addpkg2db("local", lp1)
+
+lp2 = pmpkg("pkg2")
+lp2.reason = 1
+self.addpkg2db("local", lp2)
+
+lp3 = pmpkg("pkg3")
+lp3.reason = 0
+self.addpkg2db("local", lp3)
+
+self.args = "-Rs %s" % lp1.name
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("!PKG_EXIST=pkg1")
+self.addrule("!PKG_EXIST=pkg2")
+self.addrule("PKG_EXIST=pkg3")
diff --git a/test/pacman/tests/remove051.py b/test/pacman/tests/remove051.py
new file mode 100644
index 00000000..bba87bba
--- /dev/null
+++ b/test/pacman/tests/remove051.py
@@ -0,0 +1,20 @@
+self.description = "-Rss test (include explicit)"
+
+lp1 = pmpkg("pkg1")
+lp1.depends = ["pkg2" , "pkg3"]
+self.addpkg2db("local", lp1)
+
+lp2 = pmpkg("pkg2")
+lp2.reason = 1
+self.addpkg2db("local", lp2)
+
+lp3 = pmpkg("pkg3")
+lp3.reason = 0
+self.addpkg2db("local", lp3)
+
+self.args = "-Rss %s" % lp1.name
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("!PKG_EXIST=pkg1")
+self.addrule("!PKG_EXIST=pkg2")
+self.addrule("!PKG_EXIST=pkg3")
diff --git a/test/pacman/tests/remove052.py b/test/pacman/tests/remove052.py
new file mode 100644
index 00000000..df1e0db1
--- /dev/null
+++ b/test/pacman/tests/remove052.py
@@ -0,0 +1,21 @@
+self.description = "-Rs test (dependency chain)"
+
+lp1 = pmpkg("pkg1")
+lp1.depends = ["pkg2"]
+self.addpkg2db("local", lp1)
+
+lp2 = pmpkg("pkg2")
+lp2.depends = ["pkg3"]
+lp2.reason = 1
+self.addpkg2db("local", lp2)
+
+lp3 = pmpkg("pkg3")
+lp3.reason = 1
+self.addpkg2db("local", lp3)
+
+self.args = "-Rs %s" % " ".join([p.name for p in lp1, lp3])
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("!PKG_EXIST=pkg1")
+self.addrule("!PKG_EXIST=pkg2")
+self.addrule("!PKG_EXIST=pkg3")
diff --git a/test/pacman/tests/remove060.py b/test/pacman/tests/remove060.py
new file mode 100644
index 00000000..7f705519
--- /dev/null
+++ b/test/pacman/tests/remove060.py
@@ -0,0 +1,19 @@
+self.description = "Remove a group"
+
+lp1 = pmpkg("pkg1")
+lp1.groups = ["grp"]
+
+lp2 = pmpkg("pkg2")
+
+lp3 = pmpkg("pkg3")
+lp3.groups = ["grp"]
+
+for p in lp1, lp2, lp3:
+ self.addpkg2db("local", p);
+
+self.args = "-R grp"
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("!PKG_EXIST=pkg1")
+self.addrule("PKG_EXIST=pkg2")
+self.addrule("!PKG_EXIST=pkg3")
diff --git a/test/pacman/tests/scriptlet001.py b/test/pacman/tests/scriptlet001.py
new file mode 100644
index 00000000..ff7fcd20
--- /dev/null
+++ b/test/pacman/tests/scriptlet001.py
@@ -0,0 +1,20 @@
+self.description = "Scriptlet test (pre/post install)"
+
+p1 = pmpkg("dummy")
+p1.files = ['etc/dummy.conf']
+pre = "OUTPUT FROM PRE_INSTALL"
+post = "OUTPUT FROM POST_INSTALL"
+p1.install['pre_install'] = "echo " + pre
+p1.install['post_install'] = "echo " + post
+self.addpkg(p1)
+
+# --debug is necessary to check PACMAN_OUTPUT
+self.args = "--debug -U %s" % p1.filename()
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PACMAN_OUTPUT=" + pre)
+self.addrule("PACMAN_OUTPUT=" + post)
+
+fakechroot = which("fakechroot")
+if not fakechroot:
+ self.expectfailure = True
diff --git a/test/pacman/tests/scriptlet002.py b/test/pacman/tests/scriptlet002.py
new file mode 100644
index 00000000..cc316a10
--- /dev/null
+++ b/test/pacman/tests/scriptlet002.py
@@ -0,0 +1,20 @@
+self.description = "Scriptlet test (pre/post remove)"
+
+p1 = pmpkg("dummy")
+p1.files = ['etc/dummy.conf']
+pre = "OUTPUT FROM PRE_REMOVE";
+post = "OUTPUT FROM POST_REMOVE";
+p1.install['pre_remove'] = "echo " + pre
+p1.install['post_remove'] = "echo " + post
+self.addpkg2db("local", p1)
+
+# --debug is necessary to check PACMAN_OUTPUT
+self.args = "--debug -R %s" % p1.name
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PACMAN_OUTPUT=" + pre)
+self.addrule("PACMAN_OUTPUT=" + post)
+
+fakechroot = which("fakechroot")
+if not fakechroot:
+ self.expectfailure = True
diff --git a/test/pacman/tests/smoke001.py b/test/pacman/tests/smoke001.py
new file mode 100644
index 00000000..c6636391
--- /dev/null
+++ b/test/pacman/tests/smoke001.py
@@ -0,0 +1,23 @@
+self.description = "Install a thousand packages in a single transaction"
+
+p = pmpkg("pkg1000")
+
+self.addpkg2db("local", p)
+
+for i in range(1000):
+ p = pmpkg("pkg%03d" % i)
+ p.depends = ["pkg%03d" % (i+1)]
+ p.files = ["usr/share/pkg%03d" % i]
+ self.addpkg(p)
+
+_list = []
+[_list.append(p.filename()) for p in self.localpkgs]
+self.args = "-U %s" % " ".join(_list)
+
+self.addrule("PACMAN_RETCODE=0")
+#for i in range(1000):
+# self.addrule("PKG_EXIST=pkg%03d" %i)
+# picked 3 random packages to test for, since the loop is too much to handle
+self.addrule("PKG_EXIST=pkg050")
+self.addrule("PKG_EXIST=pkg674")
+self.addrule("PKG_EXIST=pkg999")
diff --git a/test/pacman/tests/symlink001.py b/test/pacman/tests/symlink001.py
new file mode 100644
index 00000000..cbf71ccc
--- /dev/null
+++ b/test/pacman/tests/symlink001.py
@@ -0,0 +1,20 @@
+self.description = "Dir symlinks overwritten on install (the perl/git bug)"
+
+lp = pmpkg("dummy")
+lp.files = ["dir/realdir/",
+ "dir/symdir -> realdir"]
+self.addpkg2db("local", lp)
+
+p = pmpkg("pkg1")
+p.files = ["dir/symdir/tmp"]
+self.addpkg(p)
+
+self.args = "-U %s" % p.filename()
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_EXIST=pkg1")
+self.addrule("FILE_EXIST=dir/symdir/tmp")
+self.addrule("FILE_EXIST=dir/realdir/tmp")
+self.addrule("FILE_TYPE=dir/symdir/tmp|file")
+self.addrule("FILE_TYPE=dir/symdir|link")
+self.addrule("FILE_TYPE=dir/realdir|dir")
diff --git a/test/pacman/tests/sync001.py b/test/pacman/tests/sync001.py
new file mode 100644
index 00000000..0f5fdcfb
--- /dev/null
+++ b/test/pacman/tests/sync001.py
@@ -0,0 +1,13 @@
+self.description = "Install a package from a sync db"
+
+sp = pmpkg("dummy")
+sp.files = ["bin/dummy",
+ "usr/man/man1/dummy.1"]
+self.addpkg2db("sync", sp)
+
+self.args = "-S %s" % sp.name
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_EXIST=dummy")
+for f in sp.files:
+ self.addrule("FILE_EXIST=%s" % f)
diff --git a/test/pacman/tests/sync002.py b/test/pacman/tests/sync002.py
new file mode 100644
index 00000000..a183f911
--- /dev/null
+++ b/test/pacman/tests/sync002.py
@@ -0,0 +1,18 @@
+self.description = "Upgrade a package from a sync db"
+
+sp = pmpkg("dummy", "1.0-2")
+sp.files = ["bin/dummy",
+ "usr/man/man1/dummy.1"]
+self.addpkg2db("sync", sp)
+
+lp = pmpkg("dummy")
+lp.files = ["bin/dummy",
+ "usr/man/man1/dummy.1"]
+self.addpkg2db("local", lp)
+
+self.args = "-S %s" % sp.name
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_VERSION=dummy|1.0-2")
+for f in lp.files:
+ self.addrule("FILE_MODIFIED=%s" % f)
diff --git a/test/pacman/tests/sync003.py b/test/pacman/tests/sync003.py
new file mode 100644
index 00000000..b21cbcaa
--- /dev/null
+++ b/test/pacman/tests/sync003.py
@@ -0,0 +1,13 @@
+self.description = "Install a package from a sync db, with a filesystem conflict"
+
+sp = pmpkg("dummy")
+sp.files = ["bin/dummy",
+ "usr/man/man1/dummy.1"]
+self.addpkg2db("sync", sp)
+
+self.filesystem = ["bin/dummy"]
+
+self.args = "-S %s" % sp.name
+
+self.addrule("PACMAN_RETCODE=1")
+self.addrule("!PKG_EXIST=dummy")
diff --git a/test/pacman/tests/sync009.py b/test/pacman/tests/sync009.py
new file mode 100644
index 00000000..0f5fdcfb
--- /dev/null
+++ b/test/pacman/tests/sync009.py
@@ -0,0 +1,13 @@
+self.description = "Install a package from a sync db"
+
+sp = pmpkg("dummy")
+sp.files = ["bin/dummy",
+ "usr/man/man1/dummy.1"]
+self.addpkg2db("sync", sp)
+
+self.args = "-S %s" % sp.name
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_EXIST=dummy")
+for f in sp.files:
+ self.addrule("FILE_EXIST=%s" % f)
diff --git a/test/pacman/tests/sync010.py b/test/pacman/tests/sync010.py
new file mode 100644
index 00000000..df407a32
--- /dev/null
+++ b/test/pacman/tests/sync010.py
@@ -0,0 +1,27 @@
+self.description = "Install a package from a sync db with cascaded dependencies"
+
+sp1 = pmpkg("dummy", "1.0-2")
+sp1.files = ["bin/dummy",
+ "usr/man/man1/dummy.1"]
+sp1.depends = ["dep1"]
+
+sp2 = pmpkg("dep1")
+sp2.files = ["bin/dep1"]
+sp2.depends = ["dep2"]
+
+sp3 = pmpkg("dep2")
+sp3.files = ["bin/dep2"]
+
+for p in sp1, sp2, sp3:
+ self.addpkg2db("sync", p);
+
+self.args = "-S %s" % sp1.name
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_VERSION=dummy|1.0-2")
+self.addrule("PKG_DEPENDS=dummy|dep1")
+for p in sp1, sp2, sp3:
+ self.addrule("PKG_EXIST=%s" % p.name)
+ for f in p.files:
+ self.addrule("FILE_EXIST=%s" % f)
+self.addrule("PKG_DEPENDS=dep1|dep2")
diff --git a/test/pacman/tests/sync011.py b/test/pacman/tests/sync011.py
new file mode 100644
index 00000000..f5b1943a
--- /dev/null
+++ b/test/pacman/tests/sync011.py
@@ -0,0 +1,20 @@
+self.description = "Install a package from a sync db with cascaded dependencies + provides"
+
+sp1 = pmpkg("dummy", "1.0-2")
+sp1.depends = ["dep1", "dep2=1.0-2"]
+
+sp2 = pmpkg("dep1")
+sp2.files = ["bin/dep1"]
+sp2.provides = ["dep2"]
+
+sp3 = pmpkg("dep2", "1.0-2")
+
+for p in sp1, sp2, sp3:
+ self.addpkg2db("sync", p);
+
+self.args = "-S %s" % sp1.name
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_VERSION=dummy|1.0-2")
+self.addrule("PKG_EXIST=dep1")
+self.addrule("PKG_EXIST=dep2")
diff --git a/test/pacman/tests/sync012.py b/test/pacman/tests/sync012.py
new file mode 100644
index 00000000..3aaba376
--- /dev/null
+++ b/test/pacman/tests/sync012.py
@@ -0,0 +1,20 @@
+self.description = "Install packages from a sync db with circular dependencies"
+
+sp1 = pmpkg("pkg1")
+sp1.depends = ["pkg2"]
+
+sp2 = pmpkg("pkg2")
+sp2.depends = ["pkg3"]
+
+sp3 = pmpkg("pkg3")
+sp3.depends = ["pkg1"]
+
+for p in sp1, sp2, sp3:
+ self.addpkg2db("sync", p);
+
+self.args = "-S %s" % sp1.name
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_EXIST=pkg1")
+self.addrule("PKG_EXIST=pkg2")
+self.addrule("PKG_EXIST=pkg3")
diff --git a/test/pacman/tests/sync020.py b/test/pacman/tests/sync020.py
new file mode 100644
index 00000000..0f2a0413
--- /dev/null
+++ b/test/pacman/tests/sync020.py
@@ -0,0 +1,19 @@
+self.description = "Install a group from a sync db"
+
+sp1 = pmpkg("pkg1")
+sp1.groups = ["grp"]
+
+sp2 = pmpkg("pkg2")
+sp2.groups = ["grp"]
+
+sp3 = pmpkg("pkg3")
+sp3.groups = ["grp"]
+
+for p in sp1, sp2, sp3:
+ self.addpkg2db("sync", p);
+
+self.args = "-S %s" % "grp"
+
+self.addrule("PACMAN_RETCODE=0")
+for p in sp1, sp2, sp3:
+ self.addrule("PKG_EXIST=%s" % p.name)
diff --git a/test/pacman/tests/sync021.py b/test/pacman/tests/sync021.py
new file mode 100644
index 00000000..4c664d8e
--- /dev/null
+++ b/test/pacman/tests/sync021.py
@@ -0,0 +1,21 @@
+self.description = "Install a group from a sync db with a package in IgnorePkg"
+
+sp1 = pmpkg("pkg1")
+sp1.groups = ["grp"]
+
+sp2 = pmpkg("pkg2")
+sp2.groups = ["grp"]
+
+sp3 = pmpkg("pkg3")
+sp3.groups = ["grp"]
+
+for p in sp1, sp2, sp3:
+ self.addpkg2db("sync", p);
+
+self.option["IgnorePkg"] = ["pkg2"]
+
+self.args = "-S grp"
+
+self.addrule("PACMAN_RETCODE=0")
+for p in sp1, sp2, sp3:
+ self.addrule("PKG_EXIST=%s" % p.name)
diff --git a/test/pacman/tests/sync030.py b/test/pacman/tests/sync030.py
new file mode 100644
index 00000000..1fd97500
--- /dev/null
+++ b/test/pacman/tests/sync030.py
@@ -0,0 +1,19 @@
+self.description = "Sync packages non-explicitly"
+
+lp1 = pmpkg("pkg1")
+lp1.reason = 0
+self.addpkg2db("local", lp1)
+
+p1 = pmpkg("pkg1", "1.0-2")
+p2 = pmpkg("pkg2", "1.0-2")
+
+for p in p1, p2:
+ self.addpkg2db("sync", p)
+
+self.args = "-S --asdeps %s" % " ".join([p.name for p in p1, p2])
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_VERSION=pkg1|1.0-2")
+self.addrule("PKG_VERSION=pkg2|1.0-2")
+self.addrule("PKG_REASON=pkg1|1")
+self.addrule("PKG_REASON=pkg2|1")
diff --git a/test/pacman/tests/sync031.py b/test/pacman/tests/sync031.py
new file mode 100644
index 00000000..4aa2ee39
--- /dev/null
+++ b/test/pacman/tests/sync031.py
@@ -0,0 +1,19 @@
+self.description = "Sync packages explicitly"
+
+lp1 = pmpkg("pkg1")
+lp1.reason = 1
+self.addpkg2db("local", lp1)
+
+p1 = pmpkg("pkg1", "1.0-2")
+p2 = pmpkg("pkg2", "1.0-2")
+
+for p in p1, p2:
+ self.addpkg2db("sync", p)
+
+self.args = "-S --asexplicit %s" % " ".join([p.name for p in p1, p2])
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_VERSION=pkg1|1.0-2")
+self.addrule("PKG_VERSION=pkg2|1.0-2")
+self.addrule("PKG_REASON=pkg1|0")
+self.addrule("PKG_REASON=pkg2|0")
diff --git a/test/pacman/tests/sync040.py b/test/pacman/tests/sync040.py
new file mode 100644
index 00000000..e5641fe0
--- /dev/null
+++ b/test/pacman/tests/sync040.py
@@ -0,0 +1,15 @@
+self.description = "Install two targets from a sync db with a conflict"
+
+sp1 = pmpkg("pkg1")
+sp1.conflicts = ["pkg2"]
+
+sp2 = pmpkg("pkg2")
+
+for p in sp1, sp2:
+ self.addpkg2db("sync", p);
+
+self.args = "-S %s" % " ".join([p.name for p in sp1, sp2])
+
+self.addrule("PACMAN_RETCODE=1")
+for p in sp1, sp2:
+ self.addrule("!PKG_EXIST=%s" % p.name)
diff --git a/test/pacman/tests/sync041.py b/test/pacman/tests/sync041.py
new file mode 100644
index 00000000..328728e2
--- /dev/null
+++ b/test/pacman/tests/sync041.py
@@ -0,0 +1,16 @@
+self.description = "Install two conflicting targets"
+
+sp1 = pmpkg("pkg1")
+sp1.conflicts = ["pkg2"]
+
+sp2 = pmpkg("pkg2")
+sp2.conflicts = ["pkg1"]
+
+for p in sp1, sp2:
+ self.addpkg2db("sync", p);
+
+self.args = "-S %s" % " ".join([p.name for p in sp1, sp2])
+
+self.addrule("PACMAN_RETCODE=1")
+self.addrule("!PKG_EXIST=pkg1")
+self.addrule("!PKG_EXIST=pkg2")
diff --git a/test/pacman/tests/sync042.py b/test/pacman/tests/sync042.py
new file mode 100644
index 00000000..7c3498d3
--- /dev/null
+++ b/test/pacman/tests/sync042.py
@@ -0,0 +1,14 @@
+self.description = "Install a sync package conflicting with a local one"
+
+sp = pmpkg("pkg1")
+sp.conflicts = ["pkg2"]
+self.addpkg2db("sync", sp);
+
+lp = pmpkg("pkg2")
+self.addpkg2db("local", lp);
+
+self.args = "-S %s" % sp.name
+
+self.addrule("PACMAN_RETCODE=1")
+self.addrule("!PKG_EXIST=pkg1")
+self.addrule("PKG_EXIST=pkg2")
diff --git a/test/pacman/tests/sync043.py b/test/pacman/tests/sync043.py
new file mode 100644
index 00000000..8461e9f9
--- /dev/null
+++ b/test/pacman/tests/sync043.py
@@ -0,0 +1,18 @@
+self.description = "Install a sync package conflicting with two local ones"
+
+sp = pmpkg("pkg1")
+sp.conflicts = ["pkg2", "pkg3"]
+self.addpkg2db("sync", sp);
+
+lp1 = pmpkg("pkg2")
+self.addpkg2db("local", lp1);
+
+lp2 = pmpkg("pkg3")
+self.addpkg2db("local", lp2);
+
+self.args = "-S %s --ask=4" % sp.name
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_EXIST=pkg1")
+self.addrule("!PKG_EXIST=pkg2")
+self.addrule("!PKG_EXIST=pkg3")
diff --git a/test/pacman/tests/sync044.py b/test/pacman/tests/sync044.py
new file mode 100644
index 00000000..0c8fd2e9
--- /dev/null
+++ b/test/pacman/tests/sync044.py
@@ -0,0 +1,20 @@
+self.description = "A dependency induces a replacement"
+
+lp1 = pmpkg("pkg1")
+self.addpkg2db("local", lp1);
+
+sp2 = pmpkg("pkg2")
+sp2.depends = ["pkg3"]
+self.addpkg2db("sync", sp2);
+
+sp3 = pmpkg("pkg3")
+sp3.conflicts = ["pkg1"]
+self.addpkg2db("sync", sp3);
+
+self.args = "-S pkg2 --ask=4"
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("!PKG_EXIST=pkg1")
+self.addrule("PKG_EXIST=pkg2")
+self.addrule("PKG_EXIST=pkg3")
+self.addrule("PKG_REASON=pkg3|1")
diff --git a/test/pacman/tests/sync045.py b/test/pacman/tests/sync045.py
new file mode 100644
index 00000000..574c0a52
--- /dev/null
+++ b/test/pacman/tests/sync045.py
@@ -0,0 +1,18 @@
+self.description = "Install a sync package conflicting with two local ones (-d)"
+
+sp = pmpkg("pkg1")
+sp.conflicts = ["pkg2", "pkg3"]
+self.addpkg2db("sync", sp);
+
+lp1 = pmpkg("pkg2")
+self.addpkg2db("local", lp1);
+
+lp2 = pmpkg("pkg3")
+self.addpkg2db("local", lp2);
+
+self.args = "-Sd %s --ask=4" % sp.name
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_EXIST=pkg1")
+self.addrule("!PKG_EXIST=pkg2")
+self.addrule("!PKG_EXIST=pkg3")
diff --git a/test/pacman/tests/sync050.py b/test/pacman/tests/sync050.py
new file mode 100644
index 00000000..1ed697f3
--- /dev/null
+++ b/test/pacman/tests/sync050.py
@@ -0,0 +1,11 @@
+self.description = "Install a virtual target (provided by a sync package)"
+
+sp1 = pmpkg("pkg1")
+sp1.provides = ["pkg2"]
+self.addpkg2db("sync", sp1);
+
+self.args = "-S %s" % sp1.name
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_EXIST=pkg1")
+self.addrule("!PKG_EXIST=pkg2")
diff --git a/test/pacman/tests/sync100.py b/test/pacman/tests/sync100.py
new file mode 100644
index 00000000..a4997fb1
--- /dev/null
+++ b/test/pacman/tests/sync100.py
@@ -0,0 +1,12 @@
+self.description = "Sysupgrade with a newer sync package"
+
+sp = pmpkg("dummy", "1.0-2")
+lp = pmpkg("dummy")
+
+self.addpkg2db("sync", sp)
+self.addpkg2db("local", lp)
+
+self.args = "-Su"
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_VERSION=dummy|1.0-2")
diff --git a/test/pacman/tests/sync1000.py b/test/pacman/tests/sync1000.py
new file mode 100644
index 00000000..e7f43263
--- /dev/null
+++ b/test/pacman/tests/sync1000.py
@@ -0,0 +1,17 @@
+# If someone else can come up with a better name, please do so
+self.description = "stonecrest's problem"
+
+sp = pmpkg("dummy", "1.1-1")
+self.addpkg2db("sync", sp)
+
+lp1 = pmpkg("dummy", "1.0-1")
+self.addpkg2db("local", lp1)
+
+lp2 = pmpkg("pkg")
+lp2.depends = [ "dummy=1.0" ]
+self.addpkg2db("local", lp2)
+
+self.args = "-Su"
+
+self.addrule("!PACMAN_RETCODE=0")
+self.addrule("!PKG_VERSION=dummy|1.1-1")
diff --git a/test/pacman/tests/sync1003.py b/test/pacman/tests/sync1003.py
new file mode 100644
index 00000000..cd980637
--- /dev/null
+++ b/test/pacman/tests/sync1003.py
@@ -0,0 +1,21 @@
+self.description = "Induced removal would break dependency"
+
+sp1 = pmpkg("pkg1", "1.0-2")
+sp1.replaces = [ "pkg2" ]
+self.addpkg2db("sync", sp1)
+
+lp2 = pmpkg("pkg2", "1.0-1")
+self.addpkg2db("local", lp2)
+
+lp3 = pmpkg("pkg3", "1.0-1")
+lp3.depends = [ "pkg2=1.0" ]
+self.addpkg2db("local", lp3)
+
+self.args = "-Su"
+
+self.addrule("PACMAN_RETCODE=1")
+self.addrule("!PKG_EXIST=pkg1")
+self.addrule("PKG_EXIST=pkg2")
+self.addrule("PKG_EXIST=pkg3")
+self.addrule("PKG_VERSION=pkg2|1.0-1")
+self.addrule("PKG_VERSION=pkg3|1.0-1")
diff --git a/test/pacman/tests/sync1004.py b/test/pacman/tests/sync1004.py
new file mode 100644
index 00000000..a9cee49c
--- /dev/null
+++ b/test/pacman/tests/sync1004.py
@@ -0,0 +1,18 @@
+self.description = "Induced removal would break dependency (2)"
+
+sp1 = pmpkg("pkg1")
+sp1.conflicts = [ "depend" ]
+self.addpkg2db("sync", sp1)
+
+sp2 = pmpkg("pkg2")
+sp2.depends = ["depend"]
+self.addpkg2db("sync", sp2)
+
+lp = pmpkg("depend")
+self.addpkg2db("local", lp)
+
+self.args = "-S pkg1 pkg2 --ask=4"
+
+self.addrule("PACMAN_RETCODE=1")
+self.addrule("PKG_EXIST=depend")
+
diff --git a/test/pacman/tests/sync1008.py b/test/pacman/tests/sync1008.py
new file mode 100644
index 00000000..a6064597
--- /dev/null
+++ b/test/pacman/tests/sync1008.py
@@ -0,0 +1,19 @@
+self.description = "Conflicting package names in sync repos"
+
+sp1 = pmpkg("cpkg", "1.0-1")
+sp1.provides = [ "provision1" ]
+self.addpkg2db("sync1", sp1)
+
+sp2 = pmpkg("cpkg", "2.0-1")
+sp2.provides = [ "provision2" ]
+self.addpkg2db("sync2", sp2)
+
+sp3 = pmpkg("pkg")
+sp3.depends = [ "provision1" , "provision2" ]
+self.addpkg2db("sync1", sp3)
+
+self.args = "-S pkg"
+
+self.addrule("PACMAN_RETCODE=1")
+self.addrule("!PKG_EXIST=pkg")
+self.addrule("!PKG_EXIST=cpkg")
diff --git a/test/pacman/tests/sync101.py b/test/pacman/tests/sync101.py
new file mode 100644
index 00000000..5d39ecb9
--- /dev/null
+++ b/test/pacman/tests/sync101.py
@@ -0,0 +1,12 @@
+self.description = "Sysupgrade with same version for local and sync packages"
+
+sp = pmpkg("dummy")
+lp = pmpkg("dummy")
+
+self.addpkg2db("sync", sp)
+self.addpkg2db("local", lp)
+
+self.args = "-Su"
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("!PKG_MODIFIED=dummy")
diff --git a/test/pacman/tests/sync102.py b/test/pacman/tests/sync102.py
new file mode 100644
index 00000000..40a7ec99
--- /dev/null
+++ b/test/pacman/tests/sync102.py
@@ -0,0 +1,12 @@
+self.description = "Sysupgrade with a newer local package"
+
+sp = pmpkg("dummy", "0.9-1")
+lp = pmpkg("dummy")
+
+self.addpkg2db("sync", sp)
+self.addpkg2db("local", lp)
+
+self.args = "-Su"
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("!PKG_MODIFIED=dummy")
diff --git a/test/pacman/tests/sync103.py b/test/pacman/tests/sync103.py
new file mode 100644
index 00000000..15e7c8e1
--- /dev/null
+++ b/test/pacman/tests/sync103.py
@@ -0,0 +1,13 @@
+self.description = "Sysupgrade with a local package not existing in sync db"
+
+sp = pmpkg("spkg")
+self.addpkg2db("sync", sp)
+
+lp = pmpkg("lpkg")
+self.addpkg2db("local", lp)
+
+self.args = "-Su"
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("!PKG_MODIFIED=lpkg")
+self.addrule("!PKG_EXIST=spkg")
diff --git a/test/pacman/tests/sync104.py b/test/pacman/tests/sync104.py
new file mode 100644
index 00000000..6d51b85a
--- /dev/null
+++ b/test/pacman/tests/sync104.py
@@ -0,0 +1,12 @@
+self.description = "-Suu"
+
+sp = pmpkg("dummy", "0.9-1")
+lp = pmpkg("dummy", "1.0-1")
+
+self.addpkg2db("sync", sp)
+self.addpkg2db("local", lp)
+
+self.args = "-Suu"
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_VERSION=dummy|0.9-1")
diff --git a/test/pacman/tests/sync110.py b/test/pacman/tests/sync110.py
new file mode 100644
index 00000000..08a1a890
--- /dev/null
+++ b/test/pacman/tests/sync110.py
@@ -0,0 +1,22 @@
+self.description = "Sysupgrade of a package pulling new dependencies"
+
+sp1 = pmpkg("pkg1", "1.0-2")
+sp1.depends = ["pkg2"]
+
+sp2 = pmpkg("pkg2")
+sp2.depends = ["pkg3"]
+
+sp3 = pmpkg("pkg3")
+
+for p in sp1, sp2, sp3:
+ self.addpkg2db("sync", p)
+
+lp1 = pmpkg("pkg1")
+self.addpkg2db("local", lp1)
+
+self.args = "-Su"
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_VERSION=pkg1|1.0-2")
+for p in sp2, sp3:
+ self.addrule("PKG_REASON=%s|1" % p.name)
diff --git a/test/pacman/tests/sync1100.py b/test/pacman/tests/sync1100.py
new file mode 100644
index 00000000..887b85e8
--- /dev/null
+++ b/test/pacman/tests/sync1100.py
@@ -0,0 +1,23 @@
+self.description = "Get info on package from a sync db"
+
+sp = pmpkg("dummy")
+sp.files = ["bin/dummy",
+ "usr/man/man1/dummy.1"]
+sp.desc = "test description"
+sp.groups = ["foo"]
+sp.url = "http://www.archlinux.org"
+sp.license = "GPL2"
+sp.arch = "i686"
+# test both old style and new style dates
+sp.builddate = "Mon Oct 1 01:40:21 2007 UTC"
+sp.packager = "Arch Linux"
+sp.md5sum = "00000000000000000000000000000000"
+
+self.addpkg2db("sync", sp)
+
+self.args = "-Si %s" % sp.name
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PACMAN_OUTPUT=%s" % sp.name)
+self.addrule("PACMAN_OUTPUT=%s" % sp.desc)
+self.addrule("PACMAN_OUTPUT=2007")
diff --git a/test/pacman/tests/sync1101.py b/test/pacman/tests/sync1101.py
new file mode 100644
index 00000000..e3ed0f0f
--- /dev/null
+++ b/test/pacman/tests/sync1101.py
@@ -0,0 +1,12 @@
+self.description = "Search for package from a sync db"
+
+sp = pmpkg("dummy")
+sp.groups = ["group1", "group2"]
+sp.files = ["bin/dummy",
+ "usr/man/man1/dummy.1"]
+self.addpkg2db("sync", sp)
+
+self.args = "-Ss %s" % sp.name
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PACMAN_OUTPUT=%s" % sp.name)
diff --git a/test/pacman/tests/sync1102.py b/test/pacman/tests/sync1102.py
new file mode 100644
index 00000000..3a27238f
--- /dev/null
+++ b/test/pacman/tests/sync1102.py
@@ -0,0 +1,12 @@
+self.description = "Get URL on package from a sync db"
+
+sp = pmpkg("dummy")
+sp.files = ["bin/dummy",
+ "usr/man/man1/dummy.1"]
+self.addpkg2db("sync", sp)
+
+self.args = "-Sp %s" % sp.name
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PACMAN_OUTPUT=%s" % sp.name)
+self.addrule("PACMAN_OUTPUT=file://")
diff --git a/test/pacman/tests/sync1103.py b/test/pacman/tests/sync1103.py
new file mode 100644
index 00000000..052c7236
--- /dev/null
+++ b/test/pacman/tests/sync1103.py
@@ -0,0 +1,11 @@
+self.description = "Get package list from sync dbs"
+
+sp = pmpkg("dummy")
+sp.files = ["bin/dummy",
+ "usr/man/man1/dummy.1"]
+self.addpkg2db("sync", sp)
+
+self.args = "-Sl"
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PACMAN_OUTPUT=%s" % sp.name)
diff --git a/test/pacman/tests/sync120.py b/test/pacman/tests/sync120.py
new file mode 100644
index 00000000..994e440e
--- /dev/null
+++ b/test/pacman/tests/sync120.py
@@ -0,0 +1,21 @@
+self.description = "Sysupgrade of packages in 'IgnorePkg'"
+
+sp1 = pmpkg("pkg1", "1.0-2")
+sp2 = pmpkg("pkg2", "1.0-2")
+
+for p in sp1, sp2:
+ self.addpkg2db("sync", p)
+
+lp1 = pmpkg("pkg1")
+lp2 = pmpkg("pkg2")
+
+for p in lp1, lp2:
+ self.addpkg2db("local", p)
+
+self.option["IgnorePkg"] = ["pkg2"]
+
+self.args = "-Su"
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_VERSION=pkg1|1.0-2")
+self.addrule("!PKG_MODIFIED=pkg2")
diff --git a/test/pacman/tests/sync130.py b/test/pacman/tests/sync130.py
new file mode 100644
index 00000000..afd196d1
--- /dev/null
+++ b/test/pacman/tests/sync130.py
@@ -0,0 +1,16 @@
+self.description = "Sysupgrade with a sync package replacing a local one"
+
+sp = pmpkg("pkg2")
+sp.replaces = ["pkg1"]
+
+self.addpkg2db("sync", sp)
+
+lp = pmpkg("pkg1")
+
+self.addpkg2db("local", lp)
+
+self.args = "-Su"
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("!PKG_EXIST=pkg1")
+self.addrule("PKG_EXIST=pkg2")
diff --git a/test/pacman/tests/sync131.py b/test/pacman/tests/sync131.py
new file mode 100644
index 00000000..6d70d609
--- /dev/null
+++ b/test/pacman/tests/sync131.py
@@ -0,0 +1,18 @@
+self.description = "Sysupgrade with a sync package replacing a set of local ones"
+
+sp = pmpkg("pkg4")
+sp.replaces = ["pkg1", "pkg2", "pkg3"]
+self.addpkg2db("sync", sp)
+
+lp1 = pmpkg("pkg1")
+self.addpkg2db("local", lp1)
+
+lp2 = pmpkg("pkg2")
+self.addpkg2db("local", lp2)
+
+self.args = "-Su"
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_EXIST=pkg4")
+self.addrule("!PKG_EXIST=pkg1")
+self.addrule("!PKG_EXIST=pkg2")
diff --git a/test/pacman/tests/sync132.py b/test/pacman/tests/sync132.py
new file mode 100644
index 00000000..2d671c73
--- /dev/null
+++ b/test/pacman/tests/sync132.py
@@ -0,0 +1,18 @@
+self.description = "Sysupgrade with a replacement for a local package out of date"
+
+sp1 = pmpkg("pkg1")
+sp1.replaces = ["pkg2"]
+sp2 = pmpkg("pkg2", "2.0-1")
+
+for p in sp1, sp2:
+ self.addpkg2db("sync", p)
+
+lp = pmpkg("pkg2")
+
+self.addpkg2db("local", lp)
+
+self.args = "-Su"
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("!PKG_EXIST=pkg1")
+self.addrule("PKG_EXIST=pkg2")
diff --git a/test/pacman/tests/sync133.py b/test/pacman/tests/sync133.py
new file mode 100644
index 00000000..cea603b8
--- /dev/null
+++ b/test/pacman/tests/sync133.py
@@ -0,0 +1,18 @@
+self.description = "Sysupgrade with a sync package replacing a local one in 'IgnorePkg'"
+
+sp = pmpkg("pkg2")
+sp.replaces = ["pkg1"]
+
+self.addpkg2db("sync", sp)
+
+lp = pmpkg("pkg1")
+
+self.addpkg2db("local", lp)
+
+self.option["IgnorePkg"] = ["pkg1"]
+
+self.args = "-Su"
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_EXIST=pkg1")
+self.addrule("!PKG_EXIST=pkg2")
diff --git a/test/pacman/tests/sync134.py b/test/pacman/tests/sync134.py
new file mode 100644
index 00000000..572ab326
--- /dev/null
+++ b/test/pacman/tests/sync134.py
@@ -0,0 +1,21 @@
+self.description = "Sysupgrade with a set of sync packages replacing a set local one"
+
+sp1 = pmpkg("pkg2")
+sp1.replaces = ["pkg1"]
+
+sp2 = pmpkg("pkg3")
+sp2.replaces = ["pkg1"]
+
+for p in sp1, sp2:
+ self.addpkg2db("sync", p)
+
+lp = pmpkg("pkg1")
+
+self.addpkg2db("local", lp)
+
+self.args = "-Su"
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("!PKG_EXIST=pkg1")
+for p in sp1, sp2:
+ self.addrule("PKG_EXIST=%s" % p.name)
diff --git a/test/pacman/tests/sync135.py b/test/pacman/tests/sync135.py
new file mode 100644
index 00000000..18c412aa
--- /dev/null
+++ b/test/pacman/tests/sync135.py
@@ -0,0 +1,31 @@
+self.description = "Sysupgrade with a set of sync packages replacing a set of local ones"
+
+sp1 = pmpkg("pkg2")
+sp1.replaces = ["pkg1"]
+
+sp2 = pmpkg("pkg3")
+sp2.replaces = ["pkg1"]
+
+sp3 = pmpkg("pkg4")
+sp3.replaces = ["pkg1", "pkg0"]
+
+sp4 = pmpkg("pkg5")
+sp4.replaces = ["pkg0"]
+
+for p in sp1, sp2, sp3, sp4:
+ self.addpkg2db("sync", p)
+
+lp1 = pmpkg("pkg1")
+
+lp2 = pmpkg("pkg0")
+
+for p in lp1, lp2:
+ self.addpkg2db("local", p)
+
+self.args = "-Su"
+
+self.addrule("PACMAN_RETCODE=0")
+for p in lp1, lp2:
+ self.addrule("!PKG_EXIST=%s" % p.name)
+for p in sp1, sp2, sp3, sp4:
+ self.addrule("PKG_EXIST=%s" % p.name)
diff --git a/test/pacman/tests/sync136.py b/test/pacman/tests/sync136.py
new file mode 100644
index 00000000..58d08eb0
--- /dev/null
+++ b/test/pacman/tests/sync136.py
@@ -0,0 +1,15 @@
+self.description = "Sysupgrade with a sync package forcing a downgrade"
+
+sp = pmpkg("dummy", "1.0-1")
+sp.force = 1
+
+self.addpkg2db("sync", sp)
+
+lp = pmpkg("dummy", "1.0-2")
+
+self.addpkg2db("local", lp)
+
+self.args = "-Su"
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_VERSION=dummy|1.0-1")
diff --git a/test/pacman/tests/sync137.py b/test/pacman/tests/sync137.py
new file mode 100644
index 00000000..94caca70
--- /dev/null
+++ b/test/pacman/tests/sync137.py
@@ -0,0 +1,14 @@
+self.description = "Sysupgrade with a force and ignore on same package"
+
+lp = pmpkg("dummy", "1.0-1")
+
+self.addpkg2db("local", lp)
+
+sp = pmpkg("dummy", "1.0-2")
+sp.force = 1
+self.addpkg2db("sync", sp)
+
+self.args = "-Su --ignore %s" % lp.name
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_VERSION=dummy|1.0-1")
diff --git a/test/pacman/tests/sync138.py b/test/pacman/tests/sync138.py
new file mode 100644
index 00000000..e67c4f46
--- /dev/null
+++ b/test/pacman/tests/sync138.py
@@ -0,0 +1,22 @@
+self.description = "Sysupgrade of packages in 'IgnoreGroup'"
+
+sp1 = pmpkg("pkg1", "1.0-2")
+sp2 = pmpkg("pkg2", "1.0-2")
+sp2.groups = ["grp"]
+
+for p in sp1, sp2:
+ self.addpkg2db("sync", p)
+
+lp1 = pmpkg("pkg1")
+lp2 = pmpkg("pkg2")
+
+for p in lp1, lp2:
+ self.addpkg2db("local", p)
+
+self.option["IgnoreGroup"] = ["grp"]
+
+self.args = "-Su"
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_VERSION=pkg1|1.0-2")
+self.addrule("!PKG_MODIFIED=pkg2")
diff --git a/test/pacman/tests/sync150.py b/test/pacman/tests/sync150.py
new file mode 100644
index 00000000..b62bd984
--- /dev/null
+++ b/test/pacman/tests/sync150.py
@@ -0,0 +1,25 @@
+self.description = "-Su foo"
+
+sp1 = pmpkg("pkg1", "1.0-2")
+sp1.depends = ["pkg2"]
+
+sp2 = pmpkg("pkg2")
+sp2.depends = ["pkg3"]
+
+sp3 = pmpkg("pkg3")
+
+sp4 = pmpkg("pkg4")
+
+for p in sp1, sp2, sp3, sp4:
+ self.addpkg2db("sync", p)
+
+lp1 = pmpkg("pkg1")
+self.addpkg2db("local", lp1)
+
+self.args = "-Su %s" % sp4.name
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_VERSION=pkg1|1.0-2")
+for p in sp2, sp3:
+ self.addrule("PKG_REASON=%s|1" % p.name)
+self.addrule("PKG_REASON=%s|0" % sp4.name)
diff --git a/test/pacman/tests/sync200.py.in b/test/pacman/tests/sync200.py.in
new file mode 100644
index 00000000..c83e9ac7
--- /dev/null
+++ b/test/pacman/tests/sync200.py.in
@@ -0,0 +1,18 @@
+self.description = "Synchronize the local database"
+
+if not "fetch" in "@LIBS@":
+ self.option['XferCommand'] = ['/usr/bin/curl %u > %o']
+
+sp1 = pmpkg("spkg1", "1.0-1")
+sp1.depends = ["spkg2"]
+sp2 = pmpkg("spkg2", "2.0-1")
+sp2.depends = ["spkg3"]
+sp3 = pmpkg("spkg3", "3.0-1")
+sp3.depends = ["spkg1"]
+
+for sp in sp1, sp2, sp3:
+ self.addpkg2db("sync", sp)
+
+self.args = "-Sy"
+
+self.addrule("PACMAN_RETCODE=0")
diff --git a/test/pacman/tests/sync300.py b/test/pacman/tests/sync300.py
new file mode 100644
index 00000000..31b520a8
--- /dev/null
+++ b/test/pacman/tests/sync300.py
@@ -0,0 +1,14 @@
+self.description = "Sync with corrupt database (broken deps)"
+
+sp1 = pmpkg("pkg1")
+sp1.depends = ["pkg2=1.1"]
+self.addpkg2db("sync", sp1)
+
+sp2 = pmpkg("pkg2", "1.0-1")
+self.addpkg2db("sync", sp2)
+
+self.args = "-S %s" % sp1.name
+
+self.addrule("PACMAN_RETCODE=1")
+self.addrule("!PKG_EXIST=pkg1")
+self.addrule("!PKG_EXIST=pkg2")
diff --git a/test/pacman/tests/sync301.py b/test/pacman/tests/sync301.py
new file mode 100644
index 00000000..96402fc3
--- /dev/null
+++ b/test/pacman/tests/sync301.py
@@ -0,0 +1,27 @@
+self.description = "Sysupgrade : pacman needs to be upgraded and has new deps"
+
+sp = pmpkg("pacman", "1.0-2")
+sp.depends = ["dep"]
+self.addpkg2db("sync", sp)
+
+spdep = pmpkg("dep")
+self.addpkg2db("sync", spdep)
+
+sp1 = pmpkg("pkg1", "1.0-2")
+self.addpkg2db("sync", sp1)
+
+lp = pmpkg("pacman", "1.0-1")
+self.addpkg2db("local", lp)
+
+lp1 = pmpkg("pkg1", "1.0-1")
+self.addpkg2db("local", lp1)
+
+self.option["SyncFirst"] = ["pacman"]
+
+self.args = "-Su"
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_EXIST=pacman")
+self.addrule("PKG_VERSION=pacman|1.0-2")
+self.addrule("PKG_VERSION=pkg1|1.0-1")
+self.addrule("PKG_EXIST=dep")
diff --git a/test/pacman/tests/sync400.py b/test/pacman/tests/sync400.py
new file mode 100644
index 00000000..dd6aaf4e
--- /dev/null
+++ b/test/pacman/tests/sync400.py
@@ -0,0 +1,24 @@
+self.description = "Install package with dep that conflicts with older version of package"
+
+sp1 = pmpkg("pkg1", "1.0-2")
+sp1.depends = ["pkg2=1.0-2"]
+self.addpkg2db("sync", sp1)
+
+sp2 = pmpkg("pkg2", "1.0-2")
+sp2.conflicts = [ "pkg1=1.0-1" ]
+self.addpkg2db("sync", sp2)
+
+lp1 = pmpkg("pkg1", "1.0-1")
+lp1.depends = ["pkg2=1.0-1"]
+self.addpkg2db("local", lp1)
+
+lp2 = pmpkg("pkg2", "1.0-1")
+self.addpkg2db("local", lp2)
+
+self.args = "-S pkg1"
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_EXIST=pkg1")
+self.addrule("PKG_VERSION=pkg1|1.0-2")
+self.addrule("PKG_EXIST=pkg2")
+self.addrule("PKG_VERSION=pkg2|1.0-2")
diff --git a/test/pacman/tests/sync401.py b/test/pacman/tests/sync401.py
new file mode 100644
index 00000000..eb816377
--- /dev/null
+++ b/test/pacman/tests/sync401.py
@@ -0,0 +1,21 @@
+self.description = "Ensure we choose provider already in target list"
+
+sp1 = pmpkg("pkg1")
+sp1.depends = ["dep"]
+self.addpkg2db("sync", sp1)
+
+sp2 = pmpkg("pkg2")
+sp2.provides = ["dep"]
+self.addpkg2db("sync", sp2)
+
+sp3 = pmpkg("pkg3")
+sp3.conflicts = ["pkg2"]
+sp3.provides = ["dep"]
+self.addpkg2db("sync", sp3)
+
+self.args = "-S pkg1 pkg2"
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_EXIST=pkg1")
+self.addrule("PKG_EXIST=pkg2")
+self.addrule("!PKG_EXIST=pkg3")
diff --git a/test/pacman/tests/sync402.py b/test/pacman/tests/sync402.py
new file mode 100644
index 00000000..6d82f735
--- /dev/null
+++ b/test/pacman/tests/sync402.py
@@ -0,0 +1,21 @@
+self.description = "Choice between two providers (1)"
+
+sp1 = pmpkg("pkg1")
+sp1.depends = ["dep"]
+self.addpkg2db("sync", sp1)
+
+sp2 = pmpkg("pkg2")
+sp2.provides = ["dep"]
+self.addpkg2db("sync", sp2)
+
+sp3 = pmpkg("pkg3")
+sp3.conflicts = ["pkg1"]
+sp3.provides = ["dep"]
+self.addpkg2db("sync", sp3)
+
+self.args = "-S pkg1"
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_EXIST=pkg1")
+self.addrule("PKG_EXIST=pkg2")
+self.addrule("!PKG_EXIST=pkg3")
diff --git a/test/pacman/tests/sync403.py b/test/pacman/tests/sync403.py
new file mode 100644
index 00000000..d8ab763c
--- /dev/null
+++ b/test/pacman/tests/sync403.py
@@ -0,0 +1,23 @@
+self.description = "Choice between two providers (2)"
+
+sp1 = pmpkg("pkg1")
+sp1.depends = ["dep"]
+self.addpkg2db("sync", sp1)
+
+sp2 = pmpkg("pkg2")
+sp2.conflicts = [ "pkg1" ]
+sp2.provides = [ "dep" ]
+self.addpkg2db("sync", sp2)
+
+sp3 = pmpkg("pkg3")
+sp3.provides = [ "dep" ]
+self.addpkg2db("sync", sp3)
+
+self.args = "-S pkg1"
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_EXIST=pkg1")
+self.addrule("!PKG_EXIST=pkg2")
+self.addrule("PKG_EXIST=pkg3")
+
+self.expectfailure = True
diff --git a/test/pacman/tests/sync404.py b/test/pacman/tests/sync404.py
new file mode 100644
index 00000000..118f9e9d
--- /dev/null
+++ b/test/pacman/tests/sync404.py
@@ -0,0 +1,26 @@
+self.description = "FS#9024"
+
+sp = pmpkg("xorg-server")
+sp.depends = [ "libgl" ]
+self.addpkg2db("sync", sp)
+
+sp1 = pmpkg("nvidia-utils")
+sp1.provides = [ "libgl" ]
+sp1.conflicts = [ "libgl", "libgl-dri" ]
+self.addpkg2db("sync", sp1)
+
+sp2 = pmpkg("libgl")
+sp2.provides = [ "libgl-dri" ]
+self.addpkg2db("sync", sp2)
+
+sp3 = pmpkg("nvidia")
+sp3.depends = [ "nvidia-utils" ]
+self.addpkg2db("sync", sp3)
+
+self.args = "-S xorg-server nvidia"
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_EXIST=xorg-server")
+self.addrule("PKG_EXIST=nvidia")
+self.addrule("PKG_EXIST=nvidia-utils")
+self.addrule("!PKG_EXIST=libgl")
diff --git a/test/pacman/tests/sync405.py b/test/pacman/tests/sync405.py
new file mode 100644
index 00000000..941a1af4
--- /dev/null
+++ b/test/pacman/tests/sync405.py
@@ -0,0 +1,24 @@
+self.description = "phonon/qt issue"
+
+sp1 = pmpkg("kdelibs")
+sp1.depends = ["phonon"]
+self.addpkg2db("sync", sp1);
+
+sp2 = pmpkg("qt", "4.6.1-1")
+self.addpkg2db("sync", sp2)
+
+sp3 = pmpkg("phonon")
+self.addpkg2db("sync", sp3)
+
+lp = pmpkg("qt", "4.5.3-1")
+lp.provides = ["phonon"]
+lp.conflicts = ["phonon"]
+self.addpkg2db("local", lp)
+
+self.args = "-S %s" % " ".join([p.name for p in sp1, sp2])
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_EXIST=kdelibs")
+self.addrule("PKG_EXIST=qt")
+self.addrule("PKG_EXIST=phonon")
+self.addrule("PKG_VERSION=qt|4.6.1-1")
diff --git a/test/pacman/tests/sync406.py b/test/pacman/tests/sync406.py
new file mode 100644
index 00000000..c15862fd
--- /dev/null
+++ b/test/pacman/tests/sync406.py
@@ -0,0 +1,31 @@
+self.description = "phonon/qt issue (2)"
+
+sp1 = pmpkg("kdelibs")
+sp1.depends = ["phonon"]
+self.addpkg2db("sync", sp1);
+
+sp2 = pmpkg("qt", "4.6.1-1")
+self.addpkg2db("sync", sp2)
+
+sp3 = pmpkg("phonon")
+self.addpkg2db("sync", sp3)
+
+sp4 = pmpkg("kdeapp")
+sp4.depends = ["qt>=4.6"]
+self.addpkg2db("sync", sp4)
+
+lp = pmpkg("qt", "4.5.3-1")
+lp.provides = ["phonon"]
+lp.conflicts = ["phonon"]
+self.addpkg2db("local", lp)
+
+self.args = "-S %s" % " ".join([p.name for p in sp1, sp4])
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_EXIST=kdelibs")
+self.addrule("PKG_EXIST=qt")
+self.addrule("PKG_EXIST=phonon")
+self.addrule("PKG_EXIST=kdeapp")
+self.addrule("PKG_VERSION=qt|4.6.1-1")
+
+self.expectfailure = True
diff --git a/test/pacman/tests/sync500.py b/test/pacman/tests/sync500.py
new file mode 100644
index 00000000..ccfffa7c
--- /dev/null
+++ b/test/pacman/tests/sync500.py
@@ -0,0 +1,15 @@
+self.description = "Install a package from a sync db with NoExtract"
+
+sp = pmpkg("dummy")
+sp.files = ["bin/dummy",
+ "usr/man/man1/dummy.1"]
+self.addpkg2db("sync", sp)
+
+self.option["NoExtract"] = ["usr/man/man1/dummy.1"]
+
+self.args = "-S %s" % sp.name
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_EXIST=dummy")
+self.addrule("FILE_EXIST=bin/dummy")
+self.addrule("!FILE_EXIST=usr/man/man1/dummy.1")
diff --git a/test/pacman/tests/sync501.py b/test/pacman/tests/sync501.py
new file mode 100644
index 00000000..eb826e21
--- /dev/null
+++ b/test/pacman/tests/sync501.py
@@ -0,0 +1,18 @@
+self.description = "Upgrade a package, with a file in NoUpgrade"
+
+sp = pmpkg("dummy", "1.0-2")
+sp.files = ["etc/dummy.conf"]
+self.addpkg2db("sync", sp)
+
+lp = pmpkg("dummy")
+lp.files = ["etc/dummy.conf"]
+self.addpkg2db("local", lp)
+
+self.option["NoUpgrade"] = ["etc/dummy.conf"]
+
+self.args = "-S %s" % sp.name
+
+self.addrule("PKG_VERSION=dummy|1.0-2")
+self.addrule("!FILE_MODIFIED=etc/dummy.conf")
+self.addrule("FILE_PACNEW=etc/dummy.conf")
+self.addrule("!FILE_PACSAVE=etc/dummy.conf")
diff --git a/test/pacman/tests/sync890.py b/test/pacman/tests/sync890.py
new file mode 100644
index 00000000..e8380b79
--- /dev/null
+++ b/test/pacman/tests/sync890.py
@@ -0,0 +1,20 @@
+self.description = "conflict 'db vs targ'"
+
+sp = pmpkg("pkg3")
+
+self.addpkg2db("sync", sp)
+
+lp1 = pmpkg("pkg1")
+
+lp2 = pmpkg("pkg2")
+lp2.conflicts = ["pkg3"]
+
+for p in lp1, lp2:
+ self.addpkg2db("local", p)
+
+self.args = "-S %s --ask=4" % sp.name
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_EXIST=pkg1")
+self.addrule("!PKG_EXIST=pkg2")
+self.addrule("PKG_EXIST=pkg3")
diff --git a/test/pacman/tests/sync891.py b/test/pacman/tests/sync891.py
new file mode 100644
index 00000000..9b99e94a
--- /dev/null
+++ b/test/pacman/tests/sync891.py
@@ -0,0 +1,22 @@
+self.description = "conflict 'db vs targ'"
+
+sp1 = pmpkg("pkg2")
+sp2 = pmpkg("pkg3")
+
+for p in sp1, sp2:
+ self.addpkg2db("sync", p)
+
+lp1 = pmpkg("pkg1")
+
+lp2 = pmpkg("pkg2")
+lp2.conflicts = ["pkg3"]
+
+for p in lp1, lp2:
+ self.addpkg2db("local", p)
+
+self.args = "-S %s" % " ".join([p.name for p in sp1, sp2])
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_EXIST=pkg1")
+self.addrule("PKG_EXIST=pkg2")
+self.addrule("PKG_EXIST=pkg3")
diff --git a/test/pacman/tests/sync892.py b/test/pacman/tests/sync892.py
new file mode 100644
index 00000000..dfd889ea
--- /dev/null
+++ b/test/pacman/tests/sync892.py
@@ -0,0 +1,24 @@
+self.description = "conflict 'targ vs targ' and 'db vs targ'"
+
+sp1 = pmpkg("pkg2")
+sp1.conflicts = ["pkg1"]
+
+sp2 = pmpkg("pkg3")
+
+for p in sp1, sp2:
+ self.addpkg2db("sync", p)
+
+lp1 = pmpkg("pkg1")
+
+lp2 = pmpkg("pkg2")
+lp2.conflicts = ["pkg3"]
+
+for p in lp1, lp2:
+ self.addpkg2db("local", p)
+
+self.args = "-S %s --ask=4" % " ".join([p.name for p in sp1, sp2])
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("!PKG_EXIST=pkg1")
+self.addrule("PKG_EXIST=pkg2")
+self.addrule("PKG_EXIST=pkg3")
diff --git a/test/pacman/tests/sync893.py b/test/pacman/tests/sync893.py
new file mode 100644
index 00000000..e96bb7b6
--- /dev/null
+++ b/test/pacman/tests/sync893.py
@@ -0,0 +1,20 @@
+self.description = "conflict 'db vs db'"
+
+sp1 = pmpkg("pkg1", "1.0-2")
+sp1.conflicts = ["pkg2"]
+self.addpkg2db("sync", sp1);
+
+sp2 = pmpkg("pkg2", "1.0-2")
+self.addpkg2db("sync", sp2)
+
+lp1 = pmpkg("pkg1")
+self.addpkg2db("local", lp1)
+
+lp2 = pmpkg("pkg2")
+self.addpkg2db("local", lp2)
+
+self.args = "-S %s --ask=4" % " ".join([p.name for p in sp1, sp2])
+
+self.addrule("PACMAN_RETCODE=1")
+self.addrule("PKG_EXIST=pkg1")
+self.addrule("PKG_EXIST=pkg2")
diff --git a/test/pacman/tests/sync895.py b/test/pacman/tests/sync895.py
new file mode 100644
index 00000000..fd987864
--- /dev/null
+++ b/test/pacman/tests/sync895.py
@@ -0,0 +1,20 @@
+self.description = "Sync causes single package removal of a provide (failure)"
+
+sp = pmpkg("pkg3")
+sp.conflicts = ["pkg1"]
+self.addpkg2db("sync", sp)
+
+lp1 = pmpkg("pkg1")
+lp1.provides = ["foo"]
+self.addpkg2db("local", lp1)
+
+lp2 = pmpkg("pkg2")
+lp2.depends = ["foo"]
+self.addpkg2db("local", lp2)
+
+self.args = "-S %s --ask=4" % sp.name
+
+self.addrule("PACMAN_RETCODE=1")
+self.addrule("PKG_EXIST=pkg1")
+self.addrule("PKG_EXIST=pkg2")
+self.addrule("!PKG_EXIST=pkg3")
diff --git a/test/pacman/tests/sync896.py b/test/pacman/tests/sync896.py
new file mode 100644
index 00000000..492bd7b4
--- /dev/null
+++ b/test/pacman/tests/sync896.py
@@ -0,0 +1,21 @@
+self.description = "Sync causes single package removal of a provide (success)"
+
+sp = pmpkg("pkg3")
+sp.conflicts = ["pkg1"]
+sp.provides = ["foo"]
+self.addpkg2db("sync", sp)
+
+lp1 = pmpkg("pkg1")
+lp1.provides = ["foo"]
+self.addpkg2db("local", lp1)
+
+lp2 = pmpkg("pkg2")
+lp2.depends = ["foo"]
+self.addpkg2db("local", lp2)
+
+self.args = "-S %s --ask=4" % sp.name
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("!PKG_EXIST=pkg1")
+self.addrule("PKG_EXIST=pkg2")
+self.addrule("PKG_EXIST=pkg3")
diff --git a/test/pacman/tests/sync897.py b/test/pacman/tests/sync897.py
new file mode 100644
index 00000000..8a1c5a7c
--- /dev/null
+++ b/test/pacman/tests/sync897.py
@@ -0,0 +1,24 @@
+self.description = "System upgrade with package conflicts"
+
+sp1 = pmpkg("pkg1", "1.0-2")
+sp1.conflicts = ["pkg2", "pkg3"]
+self.addpkg2db("sync", sp1);
+
+sp2 = pmpkg("pkg2", "1.0-2")
+self.addpkg2db("sync", sp2)
+
+lp1 = pmpkg("pkg1")
+self.addpkg2db("local", lp1)
+
+lp2 = pmpkg("pkg2")
+self.addpkg2db("local", lp2)
+
+lp3 = pmpkg("pkg3")
+self.addpkg2db("local", lp3)
+
+self.args = "-Su --ask=4"
+
+self.addrule("PACMAN_RETCODE=1")
+self.addrule("PKG_EXIST=pkg1")
+self.addrule("PKG_EXIST=pkg2")
+self.addrule("PKG_EXIST=pkg3")
diff --git a/test/pacman/tests/sync898.py b/test/pacman/tests/sync898.py
new file mode 100644
index 00000000..af16801d
--- /dev/null
+++ b/test/pacman/tests/sync898.py
@@ -0,0 +1,18 @@
+self.description = "System upgrade with conflicts and provides"
+
+sp1 = pmpkg("pkg1", "1.0-2")
+sp1.conflicts = ["pkg2"]
+sp1.provides = ["pkg2"]
+self.addpkg2db("sync", sp1);
+
+sp2 = pmpkg("pkg2", "1.0-2")
+self.addpkg2db("sync", sp2)
+
+lp1 = pmpkg("pkg1")
+self.addpkg2db("local", lp1)
+
+self.args = "-S %s" % " ".join([p.name for p in sp1, sp2])
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_MODIFIED=pkg1")
+self.addrule("!PKG_EXIST=pkg2")
diff --git a/test/pacman/tests/sync899.py b/test/pacman/tests/sync899.py
new file mode 100644
index 00000000..fd308050
--- /dev/null
+++ b/test/pacman/tests/sync899.py
@@ -0,0 +1,18 @@
+self.description = "System upgrade - conflict/provide with an installed package"
+
+sp1 = pmpkg("pkg1", "1.0-2")
+sp1.conflicts = ["pkg2"]
+sp1.provides = ["pkg2"]
+self.addpkg2db("sync", sp1);
+
+lp1 = pmpkg("pkg1")
+self.addpkg2db("local", lp1)
+
+lp2 = pmpkg("pkg2")
+self.addpkg2db("local", lp2)
+
+self.args = "-Su --ask=4"
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_EXIST=pkg1")
+self.addrule("!PKG_EXIST=pkg2")
diff --git a/test/pacman/tests/sync900.py b/test/pacman/tests/sync900.py
new file mode 100644
index 00000000..744fad03
--- /dev/null
+++ b/test/pacman/tests/sync900.py
@@ -0,0 +1,25 @@
+self.description = "Replace one package with another providing it"
+
+sp = pmpkg("bar")
+sp.provides = ["foo"]
+sp.conflicts = ["foo"]
+self.addpkg2db("sync", sp)
+
+lp = pmpkg("foo")
+self.addpkg2db("local", lp)
+
+lp1 = pmpkg("pkg1")
+lp1.depends = ["foo"]
+self.addpkg2db("local", lp1)
+
+lp2 = pmpkg("pkg2")
+lp2.depends = ["foo"]
+self.addpkg2db("local", lp2)
+
+self.args = "-S %s --ask=4" % sp.name
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("!PKG_EXIST=foo")
+self.addrule("PKG_EXIST=bar")
+self.addrule("PKG_EXIST=pkg1")
+self.addrule("PKG_EXIST=pkg2")
diff --git a/test/pacman/tests/sync901.py b/test/pacman/tests/sync901.py
new file mode 100644
index 00000000..f5834533
--- /dev/null
+++ b/test/pacman/tests/sync901.py
@@ -0,0 +1,25 @@
+self.description = "Replace a package providing package with actual package"
+
+sp = pmpkg("foo")
+self.addpkg2db("sync", sp)
+
+lp = pmpkg("bar")
+lp.provides = ["foo"]
+lp.conflicts = ["foo"]
+self.addpkg2db("local", lp)
+
+lp1 = pmpkg("pkg1")
+lp1.depends = ["foo"]
+self.addpkg2db("local", lp1)
+
+lp2 = pmpkg("pkg2")
+lp2.depends = ["foo"]
+self.addpkg2db("local", lp2)
+
+self.args = "-S %s --ask=4" % sp.name
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_EXIST=foo")
+self.addrule("!PKG_EXIST=bar")
+self.addrule("PKG_EXIST=pkg1")
+self.addrule("PKG_EXIST=pkg2")
diff --git a/test/pacman/tests/sync990.py b/test/pacman/tests/sync990.py
new file mode 100644
index 00000000..6ac5a1f6
--- /dev/null
+++ b/test/pacman/tests/sync990.py
@@ -0,0 +1,19 @@
+self.description = "Sync a package pulling a dependency conflicting with a target"
+
+sp1 = pmpkg("pkg1")
+sp1.depends = ["pkg3"]
+
+sp2 = pmpkg("pkg2")
+
+sp3 = pmpkg("pkg3")
+sp3.conflicts = ["pkg2"]
+
+for p in sp1, sp2, sp3:
+ self.addpkg2db("sync", p)
+
+self.args = "-S %s" % " ".join([p.name for p in sp1, sp2])
+
+self.addrule("PACMAN_RETCODE=1")
+self.addrule("!PKG_EXIST=pkg1")
+self.addrule("!PKG_EXIST=pkg2")
+self.addrule("!PKG_EXIST=pkg3")
diff --git a/test/pacman/tests/sync992.py b/test/pacman/tests/sync992.py
new file mode 100644
index 00000000..63faaaba
--- /dev/null
+++ b/test/pacman/tests/sync992.py
@@ -0,0 +1,23 @@
+self.description = "Sync a package pulling a conflicting dependency"
+
+sp1 = pmpkg("pkg1")
+sp1.depends = ["pkg3"]
+
+sp2 = pmpkg("pkg2")
+
+sp3 = pmpkg("pkg3")
+sp3.conflicts = ["pkg2"]
+sp3.provides = ["pkg2"]
+
+for p in sp1, sp2, sp3:
+ self.addpkg2db("sync", p)
+
+lp1 = pmpkg("pkg2", "0.1-1")
+self.addpkg2db("local", lp1)
+
+self.args = "-S %s --ask=4" % " ".join([p.name for p in sp1, sp2])
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_EXIST=pkg1")
+self.addrule("!PKG_EXIST=pkg2")
+self.addrule("PKG_EXIST=pkg3")
diff --git a/test/pacman/tests/sync993.py b/test/pacman/tests/sync993.py
new file mode 100644
index 00000000..82cc803a
--- /dev/null
+++ b/test/pacman/tests/sync993.py
@@ -0,0 +1,20 @@
+self.description = "Choose a dependency satisfier (target-list vs. database)"
+
+sp1 = pmpkg("pkg1")
+sp1.depends = ["dep"]
+
+sp2 = pmpkg("pkg2")
+sp2.provides = ["dep"]
+
+sp3 = pmpkg("pkg3")
+sp3.provides = ["dep"]
+
+for p in sp1, sp2, sp3:
+ self.addpkg2db("sync", p)
+
+self.args = "-S pkg1 pkg3"
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_EXIST=pkg1")
+self.addrule("!PKG_EXIST=pkg2")
+self.addrule("PKG_EXIST=pkg3")
diff --git a/test/pacman/tests/sync999.py b/test/pacman/tests/sync999.py
new file mode 100644
index 00000000..89447cad
--- /dev/null
+++ b/test/pacman/tests/sync999.py
@@ -0,0 +1,21 @@
+self.description = "System upgrade"
+
+sp1 = pmpkg("pkg1", "1.0-2")
+sp1.conflicts = ["pkg2"]
+sp1.provides = ["pkg2"]
+self.addpkg2db("sync", sp1);
+
+sp2 = pmpkg("pkg2", "1.0-2")
+self.addpkg2db("sync", sp2)
+
+lp1 = pmpkg("pkg1")
+self.addpkg2db("local", lp1)
+
+lp2 = pmpkg("pkg2")
+self.addpkg2db("local", lp2)
+
+self.args = "-Su --ask=4"
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_EXIST=pkg1")
+self.addrule("!PKG_EXIST=pkg2")
diff --git a/test/pacman/tests/trans001.py b/test/pacman/tests/trans001.py
new file mode 100644
index 00000000..b9889b14
--- /dev/null
+++ b/test/pacman/tests/trans001.py
@@ -0,0 +1,20 @@
+self.description = "fileconflict error cancels the sync transaction after the removal part"
+
+sp = pmpkg("pkg1")
+sp.replaces = ["pkg3"]
+sp.files = ["dir/file"]
+self.addpkg2db("sync", sp)
+
+lp1 = pmpkg("pkg3")
+self.addpkg2db("local", lp1)
+
+lp2 = pmpkg("pkg2")
+lp2.files = ["dir/file"]
+self.addpkg2db("local", lp2)
+
+self.args = "-Su"
+
+self.addrule("PACMAN_RETCODE=1")
+self.addrule("!PKG_EXIST=pkg1")
+self.addrule("PKG_EXIST=pkg2")
+self.addrule("PKG_EXIST=pkg3")
diff --git a/test/pacman/tests/type001.py b/test/pacman/tests/type001.py
new file mode 100644
index 00000000..d55dcc11
--- /dev/null
+++ b/test/pacman/tests/type001.py
@@ -0,0 +1,17 @@
+self.description = "Check the types of default files in a package"
+
+p = pmpkg("pkg1")
+p.files = ["foo/file1",
+ "foo/file2",
+ "foo/dir/",
+ "foo/symdir -> dir"]
+self.addpkg(p)
+
+self.args = "-U %s" % p.filename()
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("FILE_TYPE=foo/|dir")
+self.addrule("FILE_TYPE=foo/file1|file")
+self.addrule("FILE_TYPE=foo/file2|file")
+self.addrule("FILE_TYPE=foo/dir|dir")
+self.addrule("FILE_TYPE=foo/symdir|link")
diff --git a/test/pacman/tests/unresolvable001.py b/test/pacman/tests/unresolvable001.py
new file mode 100644
index 00000000..c98a4c02
--- /dev/null
+++ b/test/pacman/tests/unresolvable001.py
@@ -0,0 +1,21 @@
+self.description = "An unresolvable dependency"
+
+packageA1 = pmpkg("dep")
+self.addpkg2db("local", packageA1)
+
+packageA1up = pmpkg("dep", "2.0-1")
+packageA1up.depends = ["fake"];
+self.addpkg2db("sync", packageA1up)
+
+packageA2up = pmpkg("package")
+packageA2up.depends = ["dep"];
+self.addpkg2db("sync", packageA2up)
+
+self.args = "-S package dep --ask=32"
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_EXIST=package")
+self.addrule("PKG_EXIST=dep")
+self.addrule("PKG_VERSION=dep|1.0-1")
+
+self.expectfailure = True
diff --git a/test/pacman/tests/upgrade001.py b/test/pacman/tests/upgrade001.py
new file mode 100644
index 00000000..2a9538e0
--- /dev/null
+++ b/test/pacman/tests/upgrade001.py
@@ -0,0 +1,18 @@
+self.description = "Upgrade a package (newer version)"
+
+lp = pmpkg("dummy")
+lp.files = ["bin/dummy",
+ "usr/man/man1/dummy.1"]
+self.addpkg2db("local", lp)
+
+p = pmpkg("dummy", "1.0-2")
+p.files = ["bin/dummy",
+ "usr/man/man1/dummy.1"]
+self.addpkg(p)
+
+self.args = "-U %s" % p.filename()
+
+self.addrule("PKG_MODIFIED=dummy")
+self.addrule("PKG_VERSION=dummy|1.0-2")
+for f in lp.files:
+ self.addrule("FILE_MODIFIED=%s" % f)
diff --git a/test/pacman/tests/upgrade002.py b/test/pacman/tests/upgrade002.py
new file mode 100644
index 00000000..d561d894
--- /dev/null
+++ b/test/pacman/tests/upgrade002.py
@@ -0,0 +1,18 @@
+self.description = "Upgrade a package (same version)"
+
+lp = pmpkg("dummy")
+lp.files = ["bin/dummy",
+ "usr/man/man1/dummy.1"]
+self.addpkg2db("local", lp)
+
+p = pmpkg("dummy")
+p.files = ["bin/dummy",
+ "usr/man/man1/dummy.1"]
+self.addpkg(p)
+
+self.args = "-U %s" % p.filename()
+
+self.addrule("PKG_MODIFIED=dummy")
+self.addrule("PKG_VERSION=dummy|1.0-1")
+for f in lp.files:
+ self.addrule("FILE_MODIFIED=%s" % f)
diff --git a/test/pacman/tests/upgrade003.py b/test/pacman/tests/upgrade003.py
new file mode 100644
index 00000000..a67a2653
--- /dev/null
+++ b/test/pacman/tests/upgrade003.py
@@ -0,0 +1,18 @@
+self.description = "Upgrade a package (older version)"
+
+lp = pmpkg("dummy", "1.0-2")
+lp.files = ["bin/dummy",
+ "usr/man/man1/dummy.1"]
+self.addpkg2db("local", lp)
+
+p = pmpkg("dummy")
+p.files = ["bin/dummy",
+ "usr/man/man1/dummy.1"]
+self.addpkg(p)
+
+self.args = "-U %s" % p.filename()
+
+self.addrule("PKG_MODIFIED=dummy")
+self.addrule("PKG_VERSION=dummy|1.0-1")
+for f in lp.files:
+ self.addrule("FILE_MODIFIED=%s" % f)
diff --git a/test/pacman/tests/upgrade004.py b/test/pacman/tests/upgrade004.py
new file mode 100644
index 00000000..31daf915
--- /dev/null
+++ b/test/pacman/tests/upgrade004.py
@@ -0,0 +1,12 @@
+self.description = "Upgrade a package (not installed)"
+
+p = pmpkg("dummy")
+p.files = ["bin/dummy",
+ "usr/man/man1/dummy.1"]
+self.addpkg(p)
+
+self.args = "-U %s" % p.filename()
+
+self.addrule("PKG_EXIST=dummy")
+for f in p.files:
+ self.addrule("FILE_EXIST=%s" % f)
diff --git a/test/pacman/tests/upgrade005.py b/test/pacman/tests/upgrade005.py
new file mode 100644
index 00000000..0f8c13ef
--- /dev/null
+++ b/test/pacman/tests/upgrade005.py
@@ -0,0 +1,23 @@
+self.description = "Install a set of three packages"
+
+p1 = pmpkg("pkg1")
+p1.files = ["bin/pkg1",
+ "usr/man/man1/pkg1.1"]
+
+p2 = pmpkg("pkg2", "2.0-1")
+p2.files = ["bin/pkg2",
+ "usr/man/man1/pkg2.1"]
+
+p3 = pmpkg("pkg3", "3.0-1")
+p3.files = ["bin/pkg3", "usr/man/man1/pkg3.1"]
+
+for p in p1, p2, p3:
+ self.addpkg(p)
+
+self.args = "-U %s" % " ".join([p.filename() for p in p1, p2, p3])
+
+self.addrule("PACMAN_RETCODE=0")
+for p in p1, p2, p3:
+ self.addrule("PKG_EXIST=%s" % p.name)
+ for f in p.files:
+ self.addrule("FILE_EXIST=%s" % f)
diff --git a/test/pacman/tests/upgrade010.py b/test/pacman/tests/upgrade010.py
new file mode 100644
index 00000000..3d8b21e1
--- /dev/null
+++ b/test/pacman/tests/upgrade010.py
@@ -0,0 +1,18 @@
+self.description = "Upgrade a package, with a file in NoUpgrade"
+
+lp = pmpkg("dummy")
+lp.files = ["etc/dummy.conf"]
+self.addpkg2db("local", lp)
+
+p = pmpkg("dummy", "1.0-2")
+p.files = ["etc/dummy.conf"]
+self.addpkg(p)
+
+self.option["NoUpgrade"] = ["etc/dummy.conf"]
+
+self.args = "-U %s" % p.filename()
+
+self.addrule("PKG_VERSION=dummy|1.0-2")
+self.addrule("!FILE_MODIFIED=etc/dummy.conf")
+self.addrule("FILE_PACNEW=etc/dummy.conf")
+self.addrule("!FILE_PACSAVE=etc/dummy.conf")
diff --git a/test/pacman/tests/upgrade011.py b/test/pacman/tests/upgrade011.py
new file mode 100644
index 00000000..d8ed8734
--- /dev/null
+++ b/test/pacman/tests/upgrade011.py
@@ -0,0 +1,16 @@
+self.description = "Upgrade a package with a filesystem conflict"
+
+p = pmpkg("dummy", "2.0-1")
+p.files = ["bin/dummy", "usr/share/file"]
+self.addpkg(p)
+
+lp = pmpkg("dummy", "1.0-1")
+lp.files = ["bin/dummy"]
+self.addpkg2db("local", lp)
+
+self.filesystem = ["usr/share/file"]
+
+self.args = "-U %s" % p.filename()
+
+self.addrule("PACMAN_RETCODE=1")
+self.addrule("PKG_VERSION=dummy|1.0-1")
diff --git a/test/pacman/tests/upgrade012.py b/test/pacman/tests/upgrade012.py
new file mode 100644
index 00000000..dba8dc18
--- /dev/null
+++ b/test/pacman/tests/upgrade012.py
@@ -0,0 +1,14 @@
+self.description = "Install a package with a filesystem conflict (--force)"
+
+p = pmpkg("dummy")
+p.files = ["bin/dummy", "usr/man/man1/dummy.1"]
+self.addpkg(p)
+
+self.filesystem = ["bin/dummy"]
+
+self.args = "-Uf %s" % p.filename()
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_EXIST=dummy")
+self.addrule("FILE_MODIFIED=bin/dummy")
+self.addrule("FILE_EXIST=usr/man/man1/dummy.1")
diff --git a/test/pacman/tests/upgrade013.py b/test/pacman/tests/upgrade013.py
new file mode 100644
index 00000000..5a327599
--- /dev/null
+++ b/test/pacman/tests/upgrade013.py
@@ -0,0 +1,20 @@
+self.description = "Install two packages with a conflicting file"
+
+p1 = pmpkg("dummy")
+p1.files = ["bin/dummy",
+ "usr/man/man1/dummy.1",
+ "usr/common"]
+
+p2 = pmpkg("foobar")
+p2.files = ["bin/foobar",
+ "usr/man/man1/foobar.1",
+ "usr/common"]
+
+for p in p1, p2:
+ self.addpkg(p)
+
+self.args = "-U %s" % " ".join([p.filename() for p in p1, p2])
+
+self.addrule("PACMAN_RETCODE=1")
+self.addrule("!PKG_EXIST=dummy")
+self.addrule("!PKG_EXIST=foobar")
diff --git a/test/pacman/tests/upgrade014.py b/test/pacman/tests/upgrade014.py
new file mode 100644
index 00000000..1632dd36
--- /dev/null
+++ b/test/pacman/tests/upgrade014.py
@@ -0,0 +1,23 @@
+self.description = "Install two packages with a conflicting file (--force)"
+
+p1 = pmpkg("dummy")
+p1.files = ["bin/dummy",
+ "usr/man/man1/dummy.1",
+ "usr/common"]
+
+p2 = pmpkg("foobar")
+p2.files = ["bin/foobar",
+ "usr/man/man1/foobar.1",
+ "usr/common"]
+
+for p in p1, p2:
+ self.addpkg(p)
+
+self.args = "-Uf %s" % " ".join([p.filename() for p in p1, p2])
+
+self.addrule("PACMAN_RETCODE=0")
+for p in p1, p2:
+ self.addrule("PKG_EXIST=%s" % p.name)
+ self.addrule("PKG_FILES=%s|usr/common" % p.name)
+ for f in p.files:
+ self.addrule("FILE_EXIST=%s" % f)
diff --git a/test/pacman/tests/upgrade015.py b/test/pacman/tests/upgrade015.py
new file mode 100644
index 00000000..22f7c36b
--- /dev/null
+++ b/test/pacman/tests/upgrade015.py
@@ -0,0 +1,15 @@
+self.description = "Install a package with an existing file (--force)"
+
+p = pmpkg("dummy")
+p.files = ["etc/dummy.conf"]
+self.addpkg(p)
+
+self.filesystem = ["etc/dummy.conf"]
+
+self.args = "-Uf %s" % p.filename()
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_EXIST=dummy")
+self.addrule("FILE_MODIFIED=etc/dummy.conf")
+self.addrule("!FILE_PACNEW=etc/dummy.conf")
+self.addrule("!FILE_PACORIG=etc/dummy.conf")
diff --git a/test/pacman/tests/upgrade016.py b/test/pacman/tests/upgrade016.py
new file mode 100644
index 00000000..dd31c9ab
--- /dev/null
+++ b/test/pacman/tests/upgrade016.py
@@ -0,0 +1,16 @@
+self.description = "Install a package with an existing file (--force, new modified)"
+
+p = pmpkg("dummy")
+p.files = ["etc/dummy.conf*"]
+p.backup = ["etc/dummy.conf"]
+self.addpkg(p)
+
+self.filesystem = ["etc/dummy.conf"]
+
+self.args = "-Uf %s" % p.filename()
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_EXIST=dummy")
+self.addrule("FILE_MODIFIED=etc/dummy.conf")
+self.addrule("!FILE_PACNEW=etc/dummy.conf")
+self.addrule("FILE_PACORIG=etc/dummy.conf")
diff --git a/test/pacman/tests/upgrade020.py b/test/pacman/tests/upgrade020.py
new file mode 100644
index 00000000..6a7994bb
--- /dev/null
+++ b/test/pacman/tests/upgrade020.py
@@ -0,0 +1,18 @@
+self.description = "Upgrade a package, with a file in 'backup' (local unchanged, new modified)"
+
+lp = pmpkg("dummy")
+lp.files = ["etc/dummy.conf"]
+lp.backup = ["etc/dummy.conf"]
+self.addpkg2db("local", lp)
+
+p = pmpkg("dummy", "1.0-2")
+p.files = ["etc/dummy.conf*"]
+p.backup = ["etc/dummy.conf"]
+self.addpkg(p)
+
+self.args = "-U %s" % p.filename()
+
+self.addrule("PKG_VERSION=dummy|1.0-2")
+self.addrule("FILE_MODIFIED=etc/dummy.conf")
+self.addrule("!FILE_PACNEW=etc/dummy.conf")
+self.addrule("!FILE_PACSAVE=etc/dummy.conf")
diff --git a/test/pacman/tests/upgrade021.py b/test/pacman/tests/upgrade021.py
new file mode 100644
index 00000000..b45ea18a
--- /dev/null
+++ b/test/pacman/tests/upgrade021.py
@@ -0,0 +1,18 @@
+self.description = "Upgrade a package, with a file in 'backup' (local modified, new unchanged)"
+
+lp = pmpkg("dummy")
+lp.files = ["etc/dummy.conf*"]
+lp.backup = ["etc/dummy.conf"]
+self.addpkg2db("local", lp)
+
+p = pmpkg("dummy", "1.0-2")
+p.files = ["etc/dummy.conf"]
+p.backup = ["etc/dummy.conf"]
+self.addpkg(p)
+
+self.args = "-U %s" % p.filename()
+
+self.addrule("PKG_VERSION=dummy|1.0-2")
+self.addrule("!FILE_MODIFIED=etc/dummy.conf")
+self.addrule("!FILE_PACNEW=etc/dummy.conf")
+self.addrule("!FILE_PACSAVE=etc/dummy.conf")
diff --git a/test/pacman/tests/upgrade022.py b/test/pacman/tests/upgrade022.py
new file mode 100644
index 00000000..dcf7ae01
--- /dev/null
+++ b/test/pacman/tests/upgrade022.py
@@ -0,0 +1,18 @@
+self.description = "Upgrade a package, with a file in 'backup' (local and new modified)"
+
+lp = pmpkg("dummy")
+lp.files = ["etc/dummy.conf"]
+lp.backup = ["etc/dummy.conf*"]
+self.addpkg2db("local", lp)
+
+p = pmpkg("dummy", "1.0-2")
+p.files = ["etc/dummy.conf**"]
+p.backup = ["etc/dummy.conf"]
+self.addpkg(p)
+
+self.args = "-U %s" % p.filename()
+
+self.addrule("PKG_VERSION=dummy|1.0-2")
+self.addrule("!FILE_MODIFIED=etc/dummy.conf")
+self.addrule("FILE_PACNEW=etc/dummy.conf")
+self.addrule("!FILE_PACSAVE=etc/dummy.conf")
diff --git a/test/pacman/tests/upgrade023.py b/test/pacman/tests/upgrade023.py
new file mode 100644
index 00000000..d1d2e314
--- /dev/null
+++ b/test/pacman/tests/upgrade023.py
@@ -0,0 +1,18 @@
+self.description = "Upgrade a package, with a backup file in the NEW package only"
+
+lp = pmpkg("dummy")
+lp.files = ["etc/dummy.conf*"]
+self.addpkg2db("local", lp)
+
+p = pmpkg("dummy", "1.1-1")
+p.files = ["etc/dummy.conf"]
+p.backup = ["etc/dummy.conf"]
+self.addpkg(p)
+
+self.args = "-U %s" % p.filename()
+
+self.addrule("PKG_VERSION=dummy|1.1-1")
+self.addrule("!FILE_MODIFIED=etc/dummy.conf")
+# Do we want this pacnew or not?
+self.addrule("FILE_PACNEW=etc/dummy.conf")
+self.addrule("!FILE_PACSAVE=etc/dummy.conf")
diff --git a/test/pacman/tests/upgrade024.py b/test/pacman/tests/upgrade024.py
new file mode 100644
index 00000000..ec2f7623
--- /dev/null
+++ b/test/pacman/tests/upgrade024.py
@@ -0,0 +1,15 @@
+self.description = "Upgrade a package, with a file leaving 'backup'"
+
+lp = pmpkg("dummy")
+lp.files = ["etc/dummy.conf*"]
+lp.backup = ["etc/dummy.conf"]
+self.addpkg2db("local", lp)
+
+p = pmpkg("dummy", "1.0-2")
+self.addpkg(p)
+
+self.args = "-U %s" % p.filename()
+
+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
new file mode 100644
index 00000000..2c9c06f3
--- /dev/null
+++ b/test/pacman/tests/upgrade025.py
@@ -0,0 +1,17 @@
+self.description = "Upgrade a package, with a file leaving 'backup' but staying in the pkg"
+
+lp = pmpkg("dummy")
+lp.files = ["etc/dummy.conf*"]
+lp.backup = ["etc/dummy.conf"]
+self.addpkg2db("local", lp)
+
+p = pmpkg("dummy", "1.0-2")
+p.files = ["etc/dummy.conf"]
+self.addpkg(p)
+
+self.args = "-U %s" % p.filename()
+
+self.addrule("PKG_VERSION=dummy|1.0-2")
+self.addrule("FILE_PACSAVE=etc/dummy.conf")
+self.addrule("!FILE_PACNEW=etc/dummy.conf")
+self.addrule("FILE_EXIST=etc/dummy.conf")
diff --git a/test/pacman/tests/upgrade026.py b/test/pacman/tests/upgrade026.py
new file mode 100644
index 00000000..8e3ef239
--- /dev/null
+++ b/test/pacman/tests/upgrade026.py
@@ -0,0 +1,17 @@
+self.description = "Upgrade a package, with a file leaving the pkg but staying in 'backup'"
+
+lp = pmpkg("dummy")
+lp.files = ["etc/dummy.conf*"]
+lp.backup = ["etc/dummy.conf"]
+self.addpkg2db("local", lp)
+
+p = pmpkg("dummy", "1.0-2")
+p.backup = ["etc/dummy.conf"]
+self.addpkg(p)
+
+self.args = "-U %s" % p.filename()
+
+self.addrule("PKG_VERSION=dummy|1.0-2")
+self.addrule("FILE_PACSAVE=etc/dummy.conf")
+self.addrule("!FILE_PACNEW=etc/dummy.conf")
+self.addrule("!FILE_EXIST=etc/dummy.conf")
diff --git a/test/pacman/tests/upgrade030.py b/test/pacman/tests/upgrade030.py
new file mode 100644
index 00000000..8a6c473b
--- /dev/null
+++ b/test/pacman/tests/upgrade030.py
@@ -0,0 +1,21 @@
+self.description = "Upgrade packages with various reasons"
+
+lp1 = pmpkg("pkg1")
+lp1.reason = 0
+lp2 = pmpkg("pkg2")
+lp2.reason = 1
+
+for p in lp1, lp2:
+ self.addpkg2db("local", p)
+
+p1 = pmpkg("pkg1", "1.0-2")
+p2 = pmpkg("pkg2", "1.0-2")
+
+for p in p1, p2:
+ self.addpkg(p)
+
+self.args = "-U %s" % " ".join([p.filename() for p in p1, p2])
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_REASON=pkg1|0")
+self.addrule("PKG_REASON=pkg2|1")
diff --git a/test/pacman/tests/upgrade031.py b/test/pacman/tests/upgrade031.py
new file mode 100644
index 00000000..856de983
--- /dev/null
+++ b/test/pacman/tests/upgrade031.py
@@ -0,0 +1,19 @@
+self.description = "Install packages non-explicitly"
+
+lp1 = pmpkg("pkg1")
+lp1.reason = 0
+self.addpkg2db("local", lp1)
+
+p1 = pmpkg("pkg1", "1.0-2")
+p2 = pmpkg("pkg2", "1.0-2")
+
+for p in p1, p2:
+ self.addpkg(p)
+
+self.args = "-U --asdeps %s" % " ".join([p.filename() for p in p1, p2])
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_VERSION=pkg1|1.0-2")
+self.addrule("PKG_VERSION=pkg2|1.0-2")
+self.addrule("PKG_REASON=pkg1|1")
+self.addrule("PKG_REASON=pkg2|1")
diff --git a/test/pacman/tests/upgrade032.py b/test/pacman/tests/upgrade032.py
new file mode 100644
index 00000000..85e048e0
--- /dev/null
+++ b/test/pacman/tests/upgrade032.py
@@ -0,0 +1,19 @@
+self.description = "Install packages explicitly"
+
+lp1 = pmpkg("pkg1")
+lp1.reason = 1
+self.addpkg2db("local", lp1)
+
+p1 = pmpkg("pkg1", "1.0-2")
+p2 = pmpkg("pkg2", "1.0-2")
+
+for p in p1, p2:
+ self.addpkg(p)
+
+self.args = "-U --asexplicit %s" % " ".join([p.filename() for p in p1, p2])
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_VERSION=pkg1|1.0-2")
+self.addrule("PKG_VERSION=pkg2|1.0-2")
+self.addrule("PKG_REASON=pkg1|0")
+self.addrule("PKG_REASON=pkg2|0")
diff --git a/test/pacman/tests/upgrade040.py b/test/pacman/tests/upgrade040.py
new file mode 100644
index 00000000..e17c7176
--- /dev/null
+++ b/test/pacman/tests/upgrade040.py
@@ -0,0 +1,31 @@
+self.description = "File relocation between two packages"
+
+lp1 = pmpkg("dummy")
+lp1.files = ["bin/dummy",
+ "usr/share/file"]
+
+lp2 = pmpkg("foobar")
+lp2.files = ["bin/foobar"]
+
+for p in lp1, lp2:
+ self.addpkg2db("local", p)
+
+p1 = pmpkg("dummy")
+p1.files = ["bin/dummy"]
+
+p2 = pmpkg("foobar")
+p2.files = ["bin/foobar",
+ "usr/share/file"]
+
+for p in p1, p2:
+ self.addpkg(p)
+
+self.args = "-U %s" % " ".join([p.filename() for p in p1, p2])
+
+self.addrule("PACMAN_RETCODE=0")
+for p in p1, p2:
+ self.addrule("PKG_EXIST=%s" % p.name)
+self.addrule("FILE_MODIFIED=bin/dummy")
+self.addrule("FILE_MODIFIED=bin/foobar")
+self.addrule("FILE_EXIST=usr/share/file")
+self.addrule("FILE_MODIFIED=usr/share/file")
diff --git a/test/pacman/tests/upgrade041.py b/test/pacman/tests/upgrade041.py
new file mode 100644
index 00000000..20da4f14
--- /dev/null
+++ b/test/pacman/tests/upgrade041.py
@@ -0,0 +1,31 @@
+self.description = "File relocation between two packages (reverse order)"
+
+lp1 = pmpkg("dummy")
+lp1.files = ["bin/dummy"]
+
+lp2 = pmpkg("foobar")
+lp2.files = ["bin/foobar",
+ "usr/share/file"]
+
+for p in lp1, lp2:
+ self.addpkg2db("local", p)
+
+p1 = pmpkg("dummy")
+p1.files = ["bin/dummy",
+ "usr/share/file"]
+
+p2 = pmpkg("foobar")
+p2.files = ["bin/foobar"]
+
+for p in p1, p2:
+ self.addpkg(p)
+
+self.args = "-U %s" % " ".join([p.filename() for p in p1, p2])
+
+self.addrule("PACMAN_RETCODE=0")
+for p in p1, p2:
+ self.addrule("PKG_EXIST=%s" % p.name)
+self.addrule("FILE_MODIFIED=bin/dummy")
+self.addrule("FILE_MODIFIED=bin/foobar")
+self.addrule("FILE_EXIST=usr/share/file")
+self.addrule("FILE_MODIFIED=usr/share/file")
diff --git a/test/pacman/tests/upgrade042.py b/test/pacman/tests/upgrade042.py
new file mode 100644
index 00000000..d6140d45
--- /dev/null
+++ b/test/pacman/tests/upgrade042.py
@@ -0,0 +1,28 @@
+self.description = "Backup file relocation"
+
+lp1 = pmpkg("bash")
+lp1.files = ["etc/profile*"]
+lp1.backup = ["etc/profile"]
+self.addpkg2db("local", lp1)
+
+p1 = pmpkg("bash", "1.0-2")
+self.addpkg(p1)
+
+lp2 = pmpkg("filesystem")
+self.addpkg2db("local", lp2)
+
+p2 = pmpkg("filesystem", "1.0-2")
+p2.files = ["etc/profile**"]
+p2.backup = ["etc/profile"]
+p2.depends = [ "bash" ]
+self.addpkg(p2)
+
+self.args = "-U %s" % " ".join([p.filename() for p in p1, p2])
+
+self.filesystem = ["etc/profile"]
+
+self.addrule("PKG_VERSION=bash|1.0-2")
+self.addrule("PKG_VERSION=filesystem|1.0-2")
+self.addrule("!FILE_PACSAVE=etc/profile")
+self.addrule("FILE_PACNEW=etc/profile")
+self.addrule("FILE_EXIST=etc/profile")
diff --git a/test/pacman/tests/upgrade043.py b/test/pacman/tests/upgrade043.py
new file mode 100644
index 00000000..e76dc463
--- /dev/null
+++ b/test/pacman/tests/upgrade043.py
@@ -0,0 +1,28 @@
+self.description = "Backup file relocation (reverse order)"
+
+lp1 = pmpkg("bash")
+lp1.files = ["etc/profile*"]
+lp1.backup = ["etc/profile"]
+self.addpkg2db("local", lp1)
+
+p1 = pmpkg("bash", "1.0-2")
+p1.depends = [ "filesystem" ]
+self.addpkg(p1)
+
+lp2 = pmpkg("filesystem")
+self.addpkg2db("local", lp2)
+
+p2 = pmpkg("filesystem", "1.0-2")
+p2.files = ["etc/profile**"]
+p2.backup = ["etc/profile"]
+self.addpkg(p2)
+
+self.args = "-U %s" % " ".join([p.filename() for p in p1, p2])
+
+self.filesystem = ["etc/profile"]
+
+self.addrule("PKG_VERSION=bash|1.0-2")
+self.addrule("PKG_VERSION=filesystem|1.0-2")
+self.addrule("!FILE_PACSAVE=etc/profile")
+self.addrule("FILE_PACNEW=etc/profile")
+self.addrule("FILE_EXIST=etc/profile")
diff --git a/test/pacman/tests/upgrade045.py b/test/pacman/tests/upgrade045.py
new file mode 100644
index 00000000..b2f81274
--- /dev/null
+++ b/test/pacman/tests/upgrade045.py
@@ -0,0 +1,16 @@
+self.description = "FS#9235"
+
+lp = pmpkg("foo")
+lp.files = ["etc/foo.cfg -> etc/foo.cfg"]
+lp.backup = ["etc/foo.cfg"]
+self.addpkg2db("local", lp)
+
+p1 = pmpkg("foo", "1.0-2")
+p1.files = ["etc/foo.cfg*"]
+p1.backup = ["etc/foo.cfg"]
+self.addpkg(p1)
+
+self.args = "-U %s" % p1.filename()
+
+self.addrule("PKG_VERSION=foo|1.0-2")
+self.addrule("FILE_EXIST=etc/foo.cfg")
diff --git a/test/pacman/tests/upgrade046.py b/test/pacman/tests/upgrade046.py
new file mode 100644
index 00000000..12390647
--- /dev/null
+++ b/test/pacman/tests/upgrade046.py
@@ -0,0 +1,33 @@
+self.description = "File relocation between two packages (reverse order, --force)"
+
+lp1 = pmpkg("dummy")
+lp1.files = ["bin/dummy"]
+
+lp2 = pmpkg("foobar")
+lp2.files = ["bin/foobar",
+ "usr/share/file"]
+
+for p in lp1, lp2:
+ self.addpkg2db("local", p)
+
+p1 = pmpkg("dummy")
+p1.files = ["bin/dummy",
+ "usr/share/file"]
+
+p2 = pmpkg("foobar")
+p2.files = ["bin/foobar"]
+
+for p in p1, p2:
+ self.addpkg(p)
+
+self.args = "-Uf %s" % " ".join([p.filename() for p in p1, p2])
+
+self.addrule("PACMAN_RETCODE=0")
+for p in p1, p2:
+ self.addrule("PKG_EXIST=%s" % p.name)
+self.addrule("FILE_MODIFIED=bin/dummy")
+self.addrule("FILE_MODIFIED=bin/foobar")
+self.addrule("FILE_EXIST=usr/share/file")
+self.addrule("FILE_MODIFIED=usr/share/file")
+
+self.expectfailure = True
diff --git a/test/pacman/tests/upgrade050.py b/test/pacman/tests/upgrade050.py
new file mode 100644
index 00000000..f05b0b62
--- /dev/null
+++ b/test/pacman/tests/upgrade050.py
@@ -0,0 +1,15 @@
+self.description = "Upgrade package with a conflict == depend (not installed)"
+
+p1 = pmpkg("pkg1")
+p1.conflicts = ["pkg2"]
+p1.depends = ["pkg2"]
+self.addpkg(p1)
+
+p2 = pmpkg("pkg2")
+self.addpkg(p2)
+
+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")
diff --git a/test/pacman/tests/upgrade051.py b/test/pacman/tests/upgrade051.py
new file mode 100644
index 00000000..1d173218
--- /dev/null
+++ b/test/pacman/tests/upgrade051.py
@@ -0,0 +1,15 @@
+self.description = "Upgrade to a package that provides another package"
+
+lp = pmpkg("pkg1")
+self.addpkg2db("local", lp)
+
+p = pmpkg("pkg2")
+p.conflicts = ["pkg1"]
+p.provides = ["pkg1"]
+self.addpkg(p)
+
+self.args = "-U %s --ask=4" % p.filename()
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("!PKG_EXIST=pkg1")
+self.addrule("PKG_EXIST=pkg2")
diff --git a/test/pacman/tests/upgrade052.py b/test/pacman/tests/upgrade052.py
new file mode 100644
index 00000000..7000a12f
--- /dev/null
+++ b/test/pacman/tests/upgrade052.py
@@ -0,0 +1,20 @@
+self.description = "Upgrade to a package that provides less than before"
+
+lp1 = pmpkg("pkg1")
+lp1.depends = ["imaginary"]
+self.addpkg2db("local", lp1)
+
+lp2 = pmpkg("pkg2")
+lp2.provides = ["imaginary", "real"]
+self.addpkg2db("local", lp2)
+
+p = pmpkg("pkg2", "1.0-2")
+p.provides = ["real"]
+self.addpkg(p)
+
+self.args = "-U %s" % p.filename()
+
+self.addrule("PACMAN_RETCODE=1")
+self.addrule("PKG_EXIST=pkg1")
+self.addrule("PKG_VERSION=pkg2|1.0-1")
+self.addrule("PKG_PROVIDES=pkg2|imaginary")
diff --git a/test/pacman/tests/upgrade053.py b/test/pacman/tests/upgrade053.py
new file mode 100644
index 00000000..78de0b5e
--- /dev/null
+++ b/test/pacman/tests/upgrade053.py
@@ -0,0 +1,19 @@
+self.description = "Upgrade a package with dependency on provided package (same)"
+
+lp1 = pmpkg("pkg1")
+lp1.depends = ["imaginary"]
+self.addpkg2db("local", lp1)
+
+lp2 = pmpkg("pkg2")
+lp2.provides = ["imaginary", "real"]
+self.addpkg2db("local", lp2)
+
+p = pmpkg("pkg1", "1.0-2")
+p.depends = ["imaginary"]
+self.addpkg(p)
+
+self.args = "-U %s" % p.filename()
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_VERSION=pkg1|1.0-2")
+self.addrule("PKG_EXIST=pkg2")
diff --git a/test/pacman/tests/upgrade054.py b/test/pacman/tests/upgrade054.py
new file mode 100644
index 00000000..817d1b3d
--- /dev/null
+++ b/test/pacman/tests/upgrade054.py
@@ -0,0 +1,19 @@
+self.description = "Upgrade a package with dependency on provided package (different)"
+
+lp1 = pmpkg("pkg1")
+lp1.depends = ["imaginary"]
+self.addpkg2db("local", lp1)
+
+lp2 = pmpkg("pkg2")
+lp2.provides = ["imaginary", "real"]
+self.addpkg2db("local", lp2)
+
+p = pmpkg("pkg1", "1.0-2")
+p.depends = ["real"]
+self.addpkg(p)
+
+self.args = "-U %s" % p.filename()
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_VERSION=pkg1|1.0-2")
+self.addrule("PKG_EXIST=pkg2")
diff --git a/test/pacman/tests/upgrade055.py b/test/pacman/tests/upgrade055.py
new file mode 100644
index 00000000..25083962
--- /dev/null
+++ b/test/pacman/tests/upgrade055.py
@@ -0,0 +1,25 @@
+self.description = "Upgrade a package that provides one of two imaginary packages"
+
+lp1 = pmpkg("pkg1")
+lp1.depends = ["imaginary", "imaginary2"]
+self.addpkg2db("local", lp1)
+
+lp2 = pmpkg("pkg2")
+lp2.provides = ["imaginary"]
+self.addpkg2db("local", lp2)
+
+lp3 = pmpkg("pkg3")
+lp3.provides = ["imaginary2"]
+self.addpkg2db("local", lp3)
+
+p = pmpkg("pkg2", "1.0-2")
+p.provides = ["imaginary"]
+self.addpkg(p)
+
+self.args = "-U %s" % p.filename()
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_EXIST=pkg1")
+self.addrule("PKG_VERSION=pkg2|1.0-2")
+self.addrule("PKG_EXIST=pkg3")
+self.addrule("PKG_DEPENDS=pkg1|imaginary")
diff --git a/test/pacman/tests/upgrade056.py b/test/pacman/tests/upgrade056.py
new file mode 100644
index 00000000..908fa30c
--- /dev/null
+++ b/test/pacman/tests/upgrade056.py
@@ -0,0 +1,23 @@
+self.description = "Upgrade a package that removes a provide but another package still provides it"
+
+lp1 = pmpkg("pkg1")
+lp1.depends = ["imaginary"]
+self.addpkg2db("local", lp1)
+
+lp2 = pmpkg("pkg2")
+lp2.provides = ["imaginary"]
+self.addpkg2db("local", lp2)
+
+lp3 = pmpkg("pkg3")
+lp3.provides = ["imaginary"]
+self.addpkg2db("local", lp3)
+
+p = pmpkg("pkg2", "1.0-2")
+self.addpkg(p)
+
+self.args = "-U %s" % p.filename()
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_EXIST=pkg1")
+self.addrule("PKG_VERSION=pkg2|1.0-2")
+self.addrule("PKG_EXIST=pkg3")
diff --git a/test/pacman/tests/upgrade057.py b/test/pacman/tests/upgrade057.py
new file mode 100644
index 00000000..b1eb5029
--- /dev/null
+++ b/test/pacman/tests/upgrade057.py
@@ -0,0 +1,21 @@
+self.description = "Upgrade a package that both provides and is a dependency"
+
+lp1 = pmpkg("pkg1")
+lp1.depends = ["pkg2", "imag3"]
+self.addpkg2db("local", lp1)
+
+lp2 = pmpkg("pkg2")
+lp2.provides = ["imag3"]
+self.addpkg2db("local", lp2)
+
+p = pmpkg("pkg2", "1.0-2")
+p.provides = ["imag3"]
+self.addpkg(p)
+
+self.args = "-U %s" % p.filename()
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_EXIST=pkg1")
+self.addrule("PKG_VERSION=pkg2|1.0-2")
+self.addrule("PKG_DEPENDS=pkg1|pkg2")
+self.addrule("PKG_DEPENDS=pkg1|imag3")
diff --git a/test/pacman/tests/upgrade058.py b/test/pacman/tests/upgrade058.py
new file mode 100644
index 00000000..38576fff
--- /dev/null
+++ b/test/pacman/tests/upgrade058.py
@@ -0,0 +1,16 @@
+self.description = "Upgrade a package that's older version is required by another package."
+
+lp1 = pmpkg("pkg1")
+lp1.depends = [ "pkg2=1.0" ]
+self.addpkg2db("local", lp1)
+
+lp2 = pmpkg("pkg2", "1.0-1")
+self.addpkg2db("local", lp2)
+
+p = pmpkg("pkg2", "1.1-1")
+self.addpkg(p)
+
+self.args = "-U %s" % p.filename()
+
+self.addrule("PACMAN_RETCODE=1")
+self.addrule("!PKG_VERSION=pkg2|1.1-1")
diff --git a/test/pacman/tests/upgrade059.py b/test/pacman/tests/upgrade059.py
new file mode 100644
index 00000000..9cd9f1f0
--- /dev/null
+++ b/test/pacman/tests/upgrade059.py
@@ -0,0 +1,26 @@
+self.description = "Upgrade packages which would break a multiple-depend"
+
+lp1 = pmpkg("pkg1")
+lp1.depends = ["imaginary"]
+self.addpkg2db("local", lp1)
+
+lp2 = pmpkg("pkg2", "1.0-1")
+lp2.provides = ["imaginary"]
+self.addpkg2db("local", lp2)
+
+lp3 = pmpkg("pkg3", "1.0-1")
+lp3.provides = ["imaginary"]
+self.addpkg2db("local", lp3)
+
+p2 = pmpkg("pkg2", "1.0-2")
+self.addpkg(p2)
+
+p3 = pmpkg("pkg3", "1.0-2")
+self.addpkg(p3)
+
+self.args = "-U %s" % " ".join([p.filename() for p in p2, p3])
+
+self.addrule("PACMAN_RETCODE=1")
+self.addrule("PKG_EXIST=pkg1")
+self.addrule("PKG_VERSION=pkg2|1.0-1")
+self.addrule("PKG_VERSION=pkg3|1.0-1")
diff --git a/test/pacman/tests/upgrade060.py b/test/pacman/tests/upgrade060.py
new file mode 100644
index 00000000..7a28f3eb
--- /dev/null
+++ b/test/pacman/tests/upgrade060.py
@@ -0,0 +1,21 @@
+self.description = "Try to upgrade two packages which would break deps"
+
+lp1 = pmpkg("pkg1")
+lp1.depends = ["pkg2=1.0"]
+self.addpkg2db("local", lp1)
+
+lp2 = pmpkg("pkg2", "1.0-1")
+self.addpkg2db("local", lp2)
+
+p1 = pmpkg("pkg1", "1.1-1")
+p1.depends = ["pkg2=1.0-1"]
+self.addpkg(p1)
+
+p2 = pmpkg("pkg2", "1.1-1")
+self.addpkg(p2)
+
+self.args = "-U %s" % " ".join([p.filename() for p in p1, p2])
+
+self.addrule("PACMAN_RETCODE=1")
+self.addrule("PKG_VERSION=pkg1|1.0-1")
+self.addrule("PKG_VERSION=pkg2|1.0-1")
diff --git a/test/pacman/tests/upgrade061.py b/test/pacman/tests/upgrade061.py
new file mode 100644
index 00000000..310e5043
--- /dev/null
+++ b/test/pacman/tests/upgrade061.py
@@ -0,0 +1,22 @@
+self.description = "Try to upgrade two packages which would break deps"
+
+lp1 = pmpkg("pkg1", "1.0-1")
+lp1.depends = ["imaginary"]
+self.addpkg2db("local", lp1)
+
+lp2 = pmpkg("pkg2", "1.0-1")
+lp2.provides = ["imaginary"]
+self.addpkg2db("local", lp2)
+
+p1 = pmpkg("pkg1", "1.0-2")
+p1.depends = ["imaginary"]
+self.addpkg(p1)
+
+p2 = pmpkg("pkg2", "1.0-2")
+self.addpkg(p2)
+
+self.args = "-U %s" % " ".join([p.filename() for p in p1, p2])
+
+self.addrule("PACMAN_RETCODE=1")
+self.addrule("PKG_VERSION=pkg1|1.0-1")
+self.addrule("PKG_VERSION=pkg2|1.0-1")
diff --git a/test/pacman/tests/upgrade070.py b/test/pacman/tests/upgrade070.py
new file mode 100644
index 00000000..01f0ba48
--- /dev/null
+++ b/test/pacman/tests/upgrade070.py
@@ -0,0 +1,15 @@
+self.description = "Install a package with a file in NoExtract"
+
+p = pmpkg("dummy")
+p.files = ["bin/dummy",
+ "usr/man/man1/dummy.1"]
+self.addpkg(p)
+
+self.option["NoExtract"] = ["usr/man/man1/dummy.1"]
+
+self.args = "-U %s" % p.filename()
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_EXIST=dummy")
+self.addrule("FILE_EXIST=bin/dummy")
+self.addrule("!FILE_EXIST=usr/man/man1/dummy.1")
diff --git a/test/pacman/tests/upgrade071.py b/test/pacman/tests/upgrade071.py
new file mode 100644
index 00000000..1f21c558
--- /dev/null
+++ b/test/pacman/tests/upgrade071.py
@@ -0,0 +1,14 @@
+self.description = "Install a package with a missing dependency"
+
+p = pmpkg("dummy")
+p.files = ["bin/dummy",
+ "usr/man/man1/dummy.1"]
+p.depends = ["dep1"]
+self.addpkg(p)
+
+self.args = "-U %s" % p.filename()
+
+self.addrule("PACMAN_RETCODE=1")
+self.addrule("!PKG_EXIST=dummy")
+for f in p.files:
+ self.addrule("!FILE_EXIST=%s" % f)
diff --git a/test/pacman/tests/upgrade072.py b/test/pacman/tests/upgrade072.py
new file mode 100644
index 00000000..f88e150c
--- /dev/null
+++ b/test/pacman/tests/upgrade072.py
@@ -0,0 +1,15 @@
+self.description = "Install a package with a missing dependency (nodeps)"
+
+p = pmpkg("dummy")
+p.files = ["bin/dummy",
+ "usr/man/man1/dummy.1"]
+p.depends = ["dep1"]
+self.addpkg(p)
+
+self.args = "-Ud %s" % p.filename()
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_EXIST=dummy")
+self.addrule("PKG_DEPENDS=dummy|dep1")
+for f in p.files:
+ self.addrule("FILE_EXIST=%s" % f)
diff --git a/test/pacman/tests/upgrade073.py b/test/pacman/tests/upgrade073.py
new file mode 100644
index 00000000..752a2336
--- /dev/null
+++ b/test/pacman/tests/upgrade073.py
@@ -0,0 +1,27 @@
+self.description = "Install a package with cascaded dependencies"
+
+p1 = pmpkg("dummy", "1.0-2")
+p1.files = ["bin/dummy",
+ "usr/man/man1/dummy.1"]
+p1.depends = ["dep1"]
+
+p2 = pmpkg("dep1")
+p2.files = ["bin/dep1"]
+p2.depends = ["dep2"]
+
+p3 = pmpkg("dep2")
+p3.files = ["bin/dep2"]
+
+for p in p1, p2, p3:
+ self.addpkg(p)
+
+self.args = "-U %s" % " ".join([p.filename() for p in p1, p2, p3])
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_VERSION=dummy|1.0-2")
+self.addrule("PKG_DEPENDS=dummy|dep1")
+self.addrule("PKG_DEPENDS=dep1|dep2")
+for p in p1, p2, p3:
+ self.addrule("PKG_EXIST=%s" % p.name)
+ for f in p.files:
+ self.addrule("FILE_EXIST=%s" % f)
diff --git a/test/pacman/tests/upgrade074.py b/test/pacman/tests/upgrade074.py
new file mode 100644
index 00000000..ca052855
--- /dev/null
+++ b/test/pacman/tests/upgrade074.py
@@ -0,0 +1,14 @@
+self.description = "pkg2<2.0 dependency (satisfy)"
+
+p = pmpkg("pkg1")
+p.depends = ["pkg2<2.0"]
+self.addpkg(p)
+
+lp = pmpkg("pkg2", "1.9b-3")
+self.addpkg2db("local", lp)
+
+self.args = "-U %s" % p.filename()
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_EXIST=pkg1")
+self.addrule("PKG_EXIST=pkg2")
diff --git a/test/pacman/tests/upgrade075.py b/test/pacman/tests/upgrade075.py
new file mode 100644
index 00000000..8d2f3fc4
--- /dev/null
+++ b/test/pacman/tests/upgrade075.py
@@ -0,0 +1,14 @@
+self.description = "pkg2<2.0 dependency (not satisfy)"
+
+p = pmpkg("pkg1")
+p.depends = ["pkg2<2.0"]
+self.addpkg(p)
+
+lp = pmpkg("pkg2", "2.0-3")
+self.addpkg2db("local", lp)
+
+self.args = "-U %s" % p.filename()
+
+self.addrule("PACMAN_RETCODE=1")
+self.addrule("!PKG_EXIST=pkg1")
+self.addrule("PKG_EXIST=pkg2")
diff --git a/test/pacman/tests/upgrade076.py b/test/pacman/tests/upgrade076.py
new file mode 100644
index 00000000..87ccbddf
--- /dev/null
+++ b/test/pacman/tests/upgrade076.py
@@ -0,0 +1,18 @@
+self.description = "Package downgrade (failure)"
+
+lp1 = pmpkg("pkg1")
+lp1.depends = ["pkg2=1.1"]
+self.addpkg2db("local", lp1)
+
+lp2 = pmpkg("pkg2", "1.1-1")
+self.addpkg2db("local", lp2)
+
+p = pmpkg("pkg2", "1.0-1")
+self.addpkg(p)
+
+self.args = "-U %s" % p.filename()
+
+self.addrule("PACMAN_RETCODE=1")
+self.addrule("PKG_EXIST=pkg1")
+self.addrule("PKG_EXIST=pkg2")
+self.addrule("PKG_VERSION=pkg2|1.1-1")
diff --git a/test/pacman/tests/upgrade080.py b/test/pacman/tests/upgrade080.py
new file mode 100644
index 00000000..9ddbd708
--- /dev/null
+++ b/test/pacman/tests/upgrade080.py
@@ -0,0 +1,16 @@
+self.description = "Install a package (correct architecture)"
+
+p = pmpkg("dummy")
+p.files = ["bin/dummy",
+ "usr/man/man1/dummy.1"]
+p.arch = 'testarch'
+self.addpkg(p)
+
+self.option["Architecture"] = ['testarch']
+
+self.args = "-U %s" % p.filename()
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_EXIST=dummy")
+for f in p.files:
+ self.addrule("FILE_EXIST=%s" % f)
diff --git a/test/pacman/tests/upgrade081.py b/test/pacman/tests/upgrade081.py
new file mode 100644
index 00000000..99e22311
--- /dev/null
+++ b/test/pacman/tests/upgrade081.py
@@ -0,0 +1,16 @@
+self.description = "Install a package (wrong architecture)"
+
+p = pmpkg("dummy")
+p.files = ["bin/dummy",
+ "usr/man/man1/dummy.1"]
+p.arch = 'testarch'
+self.addpkg(p)
+
+self.option["Architecture"] = ['nottestarch']
+
+self.args = "-U %s" % p.filename()
+
+self.addrule("PACMAN_RETCODE=1")
+self.addrule("!PKG_EXIST=dummy")
+for f in p.files:
+ self.addrule("!FILE_EXIST=%s" % f)
diff --git a/test/pacman/tests/upgrade082.py b/test/pacman/tests/upgrade082.py
new file mode 100644
index 00000000..0bdbdf71
--- /dev/null
+++ b/test/pacman/tests/upgrade082.py
@@ -0,0 +1,19 @@
+self.description = "Install a package (correct architecture, auto)"
+
+import os
+machine = os.uname()[4]
+
+p = pmpkg("dummy")
+p.files = ["bin/dummy",
+ "usr/man/man1/dummy.1"]
+p.arch = machine
+self.addpkg(p)
+
+self.option["Architecture"] = ['auto']
+
+self.args = "-U %s" % p.filename()
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_EXIST=dummy")
+for f in p.files:
+ self.addrule("FILE_EXIST=%s" % f)
diff --git a/test/pacman/tests/upgrade083.py b/test/pacman/tests/upgrade083.py
new file mode 100644
index 00000000..097ae02c
--- /dev/null
+++ b/test/pacman/tests/upgrade083.py
@@ -0,0 +1,19 @@
+self.description = "Install a package (wrong architecture, auto)"
+
+import os
+machine = os.uname()[4]
+
+p = pmpkg("dummy")
+p.files = ["bin/dummy",
+ "usr/man/man1/dummy.1"]
+p.arch = machine + 'wrong'
+self.addpkg(p)
+
+self.option["Architecture"] = ['auto']
+
+self.args = "-U %s" % p.filename()
+
+self.addrule("PACMAN_RETCODE=1")
+self.addrule("!PKG_EXIST=dummy")
+for f in p.files:
+ self.addrule("!FILE_EXIST=%s" % f)
diff --git a/test/pacman/tests/upgrade084.py b/test/pacman/tests/upgrade084.py
new file mode 100644
index 00000000..8268e3ff
--- /dev/null
+++ b/test/pacman/tests/upgrade084.py
@@ -0,0 +1,16 @@
+self.description = "Install a package ('any' architecture)"
+
+p = pmpkg("dummy")
+p.files = ["bin/dummy",
+ "usr/man/man1/dummy.1"]
+p.arch = 'any'
+self.addpkg(p)
+
+self.option["Architecture"] = ['auto']
+
+self.args = "-U %s" % p.filename()
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_EXIST=dummy")
+for f in p.files:
+ self.addrule("FILE_EXIST=%s" % f)
diff --git a/test/pacman/tests/upgrade090.py b/test/pacman/tests/upgrade090.py
new file mode 100644
index 00000000..26e531c9
--- /dev/null
+++ b/test/pacman/tests/upgrade090.py
@@ -0,0 +1,28 @@
+self.description = "-U syncdeps test"
+
+p1 = pmpkg("pkg1", "1.0-2")
+p1.files = ["bin/pkg1"]
+
+p2 = pmpkg("pkg2", "1.0-2")
+p2.depends = ["dep"]
+
+p3 = pmpkg("pkg3", "1.0-2")
+p3.depends = ["unres"]
+
+for p in p1, p2, p3:
+ self.addpkg(p)
+
+sp = pmpkg("dep")
+sp.files = ["bin/dep"]
+self.addpkg2db("sync", sp)
+
+self.args = "-U %s --ask=32" % " ".join([p.filename() for p in p1, p2, p3])
+
+self.addrule("PACMAN_RETCODE=0")
+for p in p1, p2, sp:
+ self.addrule("PKG_EXIST=%s" % p.name)
+ for f in p.files:
+ self.addrule("FILE_EXIST=%s" % f)
+self.addrule("PKG_VERSION=pkg1|1.0-2")
+self.addrule("PKG_VERSION=pkg2|1.0-2")
+self.addrule("!PKG_EXIST=pkg3")
diff --git a/test/pacman/tests/xfercommand001.py b/test/pacman/tests/xfercommand001.py
new file mode 100644
index 00000000..a645cf7f
--- /dev/null
+++ b/test/pacman/tests/xfercommand001.py
@@ -0,0 +1,20 @@
+self.description = "Quick check for using XferCommand"
+
+# this setting forces us to download packages
+self.cachepkgs = False
+#wget doesn't support file:// urls. curl does
+self.option['XferCommand'] = ['/usr/bin/curl %u > %o']
+
+numpkgs = 10
+pkgnames = []
+for i in xrange(numpkgs):
+ name = "pkg_%s" % i
+ pkgnames.append(name)
+ p = pmpkg(name)
+ p.files = ["usr/bin/foo-%s" % i]
+ self.addpkg2db("sync", p)
+
+self.args = "-S %s" % ' '.join(pkgnames)
+
+for name in pkgnames:
+ self.addrule("PKG_EXIST=%s" % name)
diff --git a/test/pacman/util.py b/test/pacman/util.py
new file mode 100755
index 00000000..e01a3b8f
--- /dev/null
+++ b/test/pacman/util.py
@@ -0,0 +1,276 @@
+#! /usr/bin/python
+#
+# Copyright (c) 2006 by Aurelien Foret <orelien@chez.com>
+#
+# 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/>.
+
+
+import sys
+import os
+import hashlib
+import stat
+
+
+# ALPM
+PM_ROOT = "/"
+PM_DBPATH = "var/lib/pacman"
+PM_LOCK = "var/lib/pacman/db.lck"
+PM_CACHEDIR = "var/cache/pacman/pkg"
+PM_EXT_PKG = ".pkg.tar.gz"
+PM_EXT_DB = ".db.tar.gz"
+PM_PACNEW = ".pacnew"
+PM_PACORIG = ".pacorig"
+PM_PACSAVE = ".pacsave"
+
+# Pacman
+PACCONF = "etc/pacman.conf"
+
+# Pactest
+TMPDIR = "tmp"
+SYNCREPO = "var/pub"
+LOGFILE = "var/log/pactest.log"
+
+verbose = 0
+
+def vprint(msg):
+ if verbose:
+ print msg
+
+#
+# Methods to generate files
+#
+
+def getfilename(name):
+ """
+ """
+ filename = name
+ extra = ""
+ 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 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(" -> ")
+ elif filename.find("|") != -1:
+ setperms = 1
+ filename, perms = filename.split("|")
+ if filename[-1] == "/":
+ isdir = 1
+
+ if isdir:
+ path = filename
+ else:
+ path = os.path.dirname(filename)
+ try:
+ if path and not os.path.isdir(path):
+ os.makedirs(path, 0755)
+ except:
+ error("mkfile: could not create directory hierarchy '%s'" % path)
+
+ if isdir:
+ return
+ if islink:
+ curdir = os.getcwd()
+ if path:
+ os.chdir(path)
+ os.symlink(link, os.path.basename(filename))
+ os.chdir(curdir)
+ 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 mkdescfile(filename, pkg):
+ """
+ """
+
+ data = []
+
+ # desc
+ #data.append("pkgname = %s" % pkg.name)
+ #data.append("pkgver = %s" % pkg.version)
+ if pkg.desc:
+ data.append("pkgdesc = %s" % pkg.desc)
+ if pkg.url:
+ data.append("url = %s" % pkg.url)
+ if pkg.builddate:
+ data.append("builddate = %s" % pkg.builddate)
+ if pkg.packager:
+ data.append("packager = %s" % pkg.packager)
+ if pkg.size:
+ data.append("size = %s" % pkg.size)
+ if pkg.arch:
+ data.append("arch = %s" % pkg.arch)
+ for i in pkg.groups:
+ data.append("group = %s" % i)
+ for i in pkg.license:
+ data.append("license = %s" % i)
+ if pkg.md5sum:
+ data.append("md5sum = %s" % pkg.md5sum)
+
+ # depends
+ for i in pkg.replaces:
+ data.append("replaces = %s" % i)
+ for i in pkg.depends:
+ data.append("depend = %s" % i)
+ for i in pkg.optdepends:
+ data.append("optdepend = %s" % i)
+ for i in pkg.conflicts:
+ data.append("conflict = %s" % i)
+ for i in pkg.provides:
+ data.append("provides = %s" % i)
+ for i in pkg.backup:
+ data.append("backup = %s" % i)
+ if pkg.force:
+ data.append("force = 1")
+
+ mkfile(filename, "\n".join(data))
+
+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))
+
+def mkcfgfile(filename, root, option, db):
+ """
+ """
+ # Options
+ data = ["[options]"]
+ for key, value in option.iteritems():
+ data.extend(["%s = %s" % (key, j) for j in value])
+
+ # Repositories
+ for key, value in db.iteritems():
+ if key != "local":
+ data.append("[%s]\n" \
+ "Server = file://%s" \
+ % (value.treename,
+ 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))
+
+
+#
+# MD5 helpers
+#
+
+def getmd5sum(filename):
+ """
+ """
+ if not os.path.isfile(filename):
+ print "file %s does not exist!" % filename
+ return ""
+ fd = open(filename, "rb")
+ checksum = hashlib.md5()
+ while 1:
+ block = fd.read(1048576)
+ if not block:
+ break
+ checksum.update(block)
+ fd.close()
+ digest = checksum.digest()
+ return "%02x"*len(digest) % tuple(map(ord, digest))
+
+def mkmd5sum(data):
+ """
+ """
+ checksum = hashlib.md5()
+ checksum.update("%s\n" % data)
+ digest = checksum.digest()
+ return "%02x"*len(digest) % tuple(map(ord, digest))
+
+
+#
+# Mtime helpers
+#
+
+def getmtime(filename):
+ """
+ """
+ if not os.path.exists(filename):
+ print "path %s does not exist!" % filename
+ return 0, 0, 0
+ st = os.stat(filename)
+ return st[stat.ST_ATIME], st[stat.ST_MTIME], st[stat.ST_CTIME]
+
+def diffmtime(mt1, mt2):
+ """ORE: TBD
+ """
+ return not mt1 == mt2
+
+
+#
+# Miscellaneous
+#
+
+def which(filename):
+ path = os.environ["PATH"].split(':')
+ for p in path:
+ f = os.path.join(p, filename)
+ if os.access(f, os.F_OK):
+ return f
+ return None
+
+def grep(filename, pattern):
+ lines = file(filename, 'r').readlines()
+ for line in lines:
+ if not line: break
+ if line.find(pattern) != -1:
+ return True
+ return False
+
+def mkdir(dir):
+ if os.path.isdir(dir):
+ return
+ elif os.path.isfile(dir):
+ raise OSError("'%s' already exists and is not a directory" % dir)
+ else:
+ parent, thisdir = os.path.split(dir)
+ if parent: mkdir(parent) #recurse to make all parents
+ vprint("making dir %s" % thisdir)
+ if thisdir: os.mkdir(dir)
+
+if __name__ == "__main__":
+ pass
+
+# vim: set ts=4 sw=4 et:
diff --git a/test/pacman/vercmptest.sh b/test/pacman/vercmptest.sh
new file mode 100755
index 00000000..fca06578
--- /dev/null
+++ b/test/pacman/vercmptest.sh
@@ -0,0 +1,130 @@
+#!/bin/sh
+#
+# vercmptest - a test suite for the vercmp/libalpm program
+#
+# Copyright (c) 2008 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='vercmp'
+# holds counts of tests
+total=0
+failure=0
+
+# args:
+# pass ver1 ver2 ret expected
+pass() {
+ #echo "test: ver1: $1 ver2: $2 ret: $3 expected: $4"
+ #echo " --> pass"
+ echo -n
+}
+
+# args:
+# fail ver1 ver2 ret expected
+fail() {
+ echo "test: ver1: $1 ver2: $2 ret: $3 expected: $4"
+ echo " ==> FAILURE"
+ failure=$(expr $failure + 1)
+}
+
+# args:
+# runtest ver1 ver2 expected
+runtest() {
+ # run the test
+ ret=$($bin $1 $2)
+ func='pass'
+ [ $ret -eq $3 ] || func='fail'
+ $func $1 $2 $ret $3
+ total=$(expr $total + 1)
+ # and run its mirror case just to be sure
+ reverse=0
+ [ $3 -eq 1 ] && reverse=-1
+ [ $3 -eq -1 ] && reverse=1
+ ret=$($bin $2 $1)
+ func='pass'
+ [ $ret -eq $reverse ] || func='fail'
+ $func $2 $1 $ret $reverse
+ total=$(expr $total + 1)
+}
+
+# use first arg as our binary if specified
+[ -n "$1" ] && bin="$1"
+
+if [ ! $(type -p "$bin") ]; then
+ echo "vercmp binary ($bin) could not be located"
+ exit 1
+fi
+
+echo "Beginning vercmp tests"
+
+# BEGIN TESTS
+
+# all similar length, no pkgrel
+runtest 1.5.0 1.5.0 0
+runtest 1.5.1 1.5.0 1
+
+# mixed length
+runtest 1.5.1 1.5 1
+
+# with pkgrel, simple
+runtest 1.5.0-1 1.5.0-1 0
+runtest 1.5.0-1 1.5.0-2 -1
+runtest 1.5.0-1 1.5.1-1 -1
+runtest 1.5.0-2 1.5.1-1 -1
+
+# with pkgrel, mixed lengths
+runtest 1.5-1 1.5.1-1 -1
+runtest 1.5-2 1.5.1-1 -1
+runtest 1.5-2 1.5.1-2 -1
+
+# mixed pkgrel inclusion
+runtest 1.5 1.5-1 0
+runtest 1.5-1 1.5 0
+runtest 1.1-1 1.1 0
+runtest 1.0-1 1.1 -1
+runtest 1.1-1 1.0 1
+
+# alphanumeric versions
+runtest 1.5b-1 1.5-1 -1
+runtest 1.5b 1.5 -1
+runtest 1.5b-1 1.5 -1
+runtest 1.5b 1.5.1 -1
+
+# from the manpage
+runtest 1.0a 1.0alpha -1
+runtest 1.0alpha 1.0b -1
+runtest 1.0b 1.0beta -1
+runtest 1.0beta 1.0rc -1
+runtest 1.0rc 1.0 -1
+
+# going crazy? alpha-dotted versions
+runtest 1.5.a 1.5 1
+runtest 1.5.b 1.5.a 1
+runtest 1.5.1 1.5.b 1
+
+# alpha dots and dashes
+runtest 1.5.b-1 1.5.b 0
+runtest 1.5-1 1.5.b -1
+
+#END TESTS
+
+echo
+if [ $failure -eq 0 ]; then
+ echo "All $total tests successful"
+ exit 0
+fi
+
+echo "$failure of $total tests failed"
+exit 1