1
0
mirror of https://github.com/moparisthebest/pacman synced 2024-11-11 20:05:07 -05:00

Added pactest to repository, from Aurelien Foret:

http://aurelien.foret.free.fr/archlinux/pactest/
This commit is contained in:
Aaron Griffin 2006-10-15 19:04:27 +00:00
parent 9ccd91701c
commit 1dc8151493
84 changed files with 3417 additions and 0 deletions

340
pactest/COPYING Normal file
View File

@ -0,0 +1,340 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
Appendix: How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) 19yy <name of author>
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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) 19yy name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

29
pactest/ChangeLog Normal file
View File

@ -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

304
pactest/README Normal file
View File

@ -0,0 +1,304 @@
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=test/*
This example will run tests from the "test" 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 dictionnary that holds the data used in the pacman configuration file.
It has 3 keys, each one of them pointing at a list of strings:
- noupgrade
- noextract
- ignorepkg
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 the RETCODE one, pactest will compare pacman return code with the value
provided as an item.
For the OUTPUT one, 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_DEPENDS=name|depname
PKG_REQUIREDBY=name|reqbyname
Example:
PKG_DEPENDS=ncurses|glibc
pactest will test the local database entry "ncurses" has "glibc" in its
DEPENDS field.
. FILE rules
FILE_EXIST=path/to/file
FILE_MODIFIED=path/to/file
FILE_PACNEW=path/to/file
FILE_PACSAVE=path/to/file
FILE_PACORIG=path/to/file

8
pactest/TODO Normal file
View File

@ -0,0 +1,8 @@
TODO
====
Features:
- implement gensync support
Tests:
- add test cases for pacman -D and pacman -T

73
pactest/pactest.py Executable file
View File

@ -0,0 +1,73 @@
#! /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, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
# USA.
import getopt
import sys
import glob
import os
import pmenv
import util
__author__ = "Aurelien FORET"
__version__ = "0.3"
def usage(retcode):
"""
"""
print "Usage: %s [options] [[--test=<path/to/testfile.py>] ...]\n\n" % __file__
sys.exit(retcode)
if __name__ == "__main__":
env = pmenv.pmenv()
testcases = []
try:
opts, args = getopt.getopt(sys.argv[1:],
"d:hp:t:v",
["debug=", "gdb", "help", "pacman=", "test=", "valgrind", "verbose", "nolog"])
except getopt.GetoptError:
usage(1)
for (cmd, param) in opts:
if cmd == "-v" or cmd == "--verbose":
util.verbose += 1
elif cmd == "-d" or cmd == "--debug":
env.pacman["debug"] = int(param)
elif cmd == "-t" or cmd == "--test":
testcases.extend(glob.glob(param))
elif cmd == "-p" or cmd == "--pacman":
env.pacman["bin"] = os.path.abspath(param)
elif cmd == "-h" or cmd == "--help":
usage(0)
elif cmd == "--nolog":
env.pacman["nolog"] = 1
elif cmd == "--gdb":
env.pacman["gdb"] = 1
elif cmd == "--valgrind":
env.pacman["valgrind"] = 1
for i in testcases:
env.addtest(i)
env.run()
env.results()

363
pactest/pmdb.py Executable file
View File

@ -0,0 +1,363 @@
#! /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, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
# USA.
import os
import tempfile
import shutil
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 = []
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")
fd = file(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")
fd = file(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")
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 == "%REQUIREDBY%":
pkg.requiredby = _getsection(fd)
elif line == "%CONFLICTS%":
pkg.conflicts = _getsection(fd)
elif line == "%PROVIDES%":
pkg.provides = _getsection(fd)
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):
"""
"""
path = os.path.join(self.dbdir, self.treename, pkg.fullname())
if not os.path.isdir(path):
os.makedirs(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 self.treename == "local":
if pkg.url:
data.append(_mksection("URL", pkg.url))
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.installdate:
data.append(_mksection("INSTALLDATE", pkg.installdate))
if pkg.packager:
data.append(_mksection("PACKAGER", pkg.packager))
if pkg.size:
data.append(_mksection("SIZE", pkg.size))
if pkg.reason:
data.append(_mksection("REASON", pkg.reason))
else:
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, requiredby, conflicts, provides
# for sync ones: depends, conflicts, provides
data = []
if pkg.depends:
data.append(_mksection("DEPENDS", pkg.depends))
if self.treename == "local":
if pkg.requiredby:
data.append(_mksection("REQUIREDBY", pkg.requiredby))
if pkg.conflicts:
data.append(_mksection("CONFLICTS", pkg.conflicts))
if pkg.provides:
data.append(_mksection("PROVIDES", pkg.provides))
if not 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
os.makedirs(path, 0755)
archive = os.path.join(path, "%s%s" % (self.treename, PM_EXT_DB))
os.system("tar zcf %s *" % archive)
os.chdir(curdir)
shutil.rmtree(tmpdir)
def ispkgmodified(self, pkg):
"""
"""
modified = 0
oldpkg = self.getpkg(pkg.name)
if not oldpkg:
return 0
dbg("oldpkg.checksum : %s" % oldpkg.checksum)
dbg("oldpkg.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 not oldpkg.mtime[key][1:3] == pkg.mtime[key][1:3]:
modified += 1
return modified
if __name__ == "__main__":
db = pmdb("local")
print db

118
pactest/pmenv.py Executable file
View File

@ -0,0 +1,118 @@
#! /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, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
# USA.
import os
import time
import pmtest
class pmenv:
"""Environment object
"""
def __init__(self, root = "root"):
self.root = os.path.abspath(root)
self.pacman = {
"bin": "pacman",
"debug": 0,
"gdb": 0,
"valgrind": 0,
"nolog": 0
}
self.testcases = []
def __str__(self):
return "root = %s\n" \
"pacman = %s" \
% (self.root, self.pacman)
def addtest(self, testcase):
"""
"""
if not os.path.isfile(testcase):
err("file %s not found" % testcase)
return
test = pmtest.pmtest(testcase, self.root)
self.testcases.append(test)
def run(self):
"""
"""
for t in self.testcases:
print "=========="*8
print "Running '%s'" % t.name.strip(".py")
t.load()
print t.description
print "----------"*8
t.generate()
# Hack for mtimes consistency
modified = 0
for i in t.rules:
if i.rule.find("MODIFIED") != -1:
modified = 1
if modified:
time.sleep(3)
t.run(self.pacman)
t.check()
print "==> Test result"
if t.result["ko"] == 0:
print "\tPASSED"
else:
print "\tFAILED"
print
def results(self):
"""
"""
passed = 0
print "=========="*8
print "Results"
print "----------"*8
for test in self.testcases:
ok = test.result["ok"]
ko = test.result["ko"]
rules = len(test.rules)
if ko == 0:
print "[PASSED]",
passed += 1
else:
print "[FAILED]",
print test.name.strip(".py").ljust(38),
print "Rules:",
print "OK = %2u KO = %2u SKIP = %2u" % (ok, ko, rules-(ok+ko))
print "----------"*8
total = len(self.testcases)
failed = total - passed
print "TOTAL = %3u" % total
if total:
print "PASSED = %3u (%6.2f%%)" % (passed, float(passed)*100/total)
print "FAILED = %3u (%6.2f%%)" % (failed, float(failed)*100/total)
print
if __name__ == "__main__":
env = pmenv("/tmp")
print env

65
pactest/pmfile.py Executable file
View File

@ -0,0 +1,65 @@
#! /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, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
# USA.
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)
if debug:
print "ismodified(%s)" % self.name
print "old: %s / %s" % (self.checksum, self.mtime)
print "new: %s / %s" % (checksum, mtime)
if not self.checksum == checksum \
or not (self.mtime[1], self.mtime[2]) == (mtime[1], mtime[2]):
retval = 1
return retval
if __name__ == "__main__":
f = pmfile("/tmp", "foobar")
print f

180
pactest/pmpkg.py Executable file
View File

@ -0,0 +1,180 @@
#! /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, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
# USA.
import os
import tempfile
import stat
import shutil
from util import *
class pmpkg:
"""Package object.
Object holding data from an ArchLinux package.
"""
def __init__(self, name, version = "1.0-1"):
# 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.requiredby = [] # local only
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.
"""
archive = 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.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))
targets = ".PKGINFO"
# .INSTALL
empty = 1
for value in self.install.values():
if value:
empty = 0
if not empty:
mkinstallfile(".INSTALL", self.install)
targets += " .INSTALL"
# .FILELIST
if self.files:
os.system("tar cvf /dev/null * | sort >.FILELIST")
targets += " .FILELIST *"
# Generate package archive
os.system("tar zcf %s %s" % (archive, targets))
os.chdir(curdir)
shutil.rmtree(tmpdir)
if __name__ == "__main__":
pkg = pmpkg("dummy")
print pkg

133
pactest/pmrule.py Executable file
View File

@ -0,0 +1,133 @@
#! /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, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
# USA.
from util 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":
if not grep(os.path.join(root, LOGFILE), key):
success = 0
else:
success = -1
elif kind == "PKG":
newpkg = localdb.db_read(key)
if not newpkg:
success = 0
else:
dbg("newpkg.checksum : %s" % newpkg.checksum)
dbg("newpkg.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 == "DEPENDS":
if not value in newpkg.depends:
success = 0
elif case == "REQUIREDBY":
if not value in newpkg.requiredby:
success = 0
elif case == "REASON":
if not 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:
success = -1
elif kind == "FILE":
filename = os.path.join(root, key)
if case == "EXIST":
if not os.path.isfile(filename):
success = 0
else:
if case == "MODIFIED":
for f in files:
if f.name == key:
if not f.ismodified():
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:
success = -1
else:
success = -1
if self.false and success != -1:
success = not success
self.result = success
return success
if __name__ != "__main__":
rule = pmrule("PKG_EXIST=dummy")

253
pactest/pmtest.py Executable file
View File

@ -0,0 +1,253 @@
#! /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, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
# USA.
import os
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.root = root
def __str__(self):
return "name = %s\n" \
"root = %s" % (self.name, 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 = {
"ok": 0,
"ko": 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 = {
"noupgrade": [],
"ignorepkg": [],
"noextract": []
}
# Test rules
self.rules = []
self.files = []
if os.path.isfile(self.name):
execfile(self.name)
else:
err("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:
archive = pkg.filename()
vprint("\t%s" % os.path.join(PM_CACHEDIR, archive))
pkg.makepkg(cachedir)
pkg.md5sum = getmd5sum(os.path.join(cachedir, archive))
pkg.csize = os.stat(os.path.join(cachedir, archive))[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 = ["fakeroot"]
if pacman["gdb"]:
cmd.append("libtool gdb --args")
if pacman["valgrind"]:
cmd.append("valgrind --tool=memcheck --leak-check=full --show-reachable=yes")
cmd.append("%s --noconfirm --config=%s --root=%s" \
% (pacman["bin"], os.path.join(self.root, PACCONF), self.root))
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))
dbg(" ".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
dbg("retcode = %s" % self.retcode)
os.chdir(curdir)
# Check if pacman failed because of bad permissions
if self.retcode \
and grep(os.path.join(self.root, LOGFILE),
"you cannot perform this operation unless you are root"):
print "\tERROR: pacman support for fakeroot is not disabled"
# 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["ok"] += 1
elif success == 0:
msg = "KO"
self.result["ko"] += 1
else:
msg = "SKIP"
print "\t[%s] %s" % (msg, i.rule)
i.result = success
if __name__ == "__main__":
test = pmtest("test1", "./root")
print test

61
pactest/tests/TESTS Normal file
View File

@ -0,0 +1,61 @@
add001: Install a package
add002: Install a package (already installed)
add003: Install a set of packages
add004: Install a set of the same package at different versions
add010: Install a package with a filesystem conflict
add011: Install a package with a filesystem conflict (--force)
add012: Install two packages with a conflicting file
add013: Install two packages with a conflicting file (--force)
add020: Install a package with an existing file
add021: Install a package with an existing file (new modified)
add030: Freshen a package
add031: Freshen a package (installed is newer)
add032: Freshen a package (installed is newer)
add040: Install a package with a missing dependency
add041: Install a package with a missing dependency (nodeps)
add042: Install a package with cascaded dependencies
add050: Install a package with a file in NoUpgrade
add060: Install a package with a file in NoExtract
query001: Query a package
remove010: Remove a package, with a file marked for backup
remove011: Remove a package, with a modified file marked for backup
remove020: Remove a package, with a file marked for backup (--nosave)
remove021: Remove a package, with a modified file marked for backup (--nosave)
smoke001: Install a thousand packages in a single transaction
sync001: Install a package from a sync db
sync002: Upgrade a package from a sync db
sync003: Install a package from a sync db, with a filesystem conflict
sync010: Install a package from a sync db, with its dependencies
sync040: Install two targets with a conflict
sync041: Install two conflicting targets
sync042: Install a sync package conflicting with a local one
sync043: Install a sync package conflicting with a local one
sync050: Install a virtual target (provided by a sync package)
sync100: Sysupgrade with a newer sync package
sync101: Sysupgrade with same version for local and sync packages
sync102: Sysupgrade with a newer local package
sync103: Sysupgrade with a local package not existing in sync db
sync110: Sysupgrade of a package pulling new dependencies
sync120: Sysupgrade of packages in 'IgnorePkg'
sync130: Sysupgrade with a sync package replacing a local one
sync131: Sysupgrade with a sync package replacing a set of local ones
sync132: Sysupgrade with a replacement for a local package out of date
sync133: Sysupgrade with a sync package replacing a local one in 'IgnorePkg'
sync134: Sysupgrade with a set of sync packages replacing a set local one
sync135: Sysupgrade with a set of sync packages replacing a set of local ones
sync897: System upgrade
sync898: System upgrade
sync899: System upgrade
sync990: Sync a package pulling a dependency conflicting with a target
sync992: Sync a package pulling a conflicting dependency
sync999: System upgrade
upgrade001: Upgrade a package (newer version)
upgrade002: Upgrade a package (same version)
upgrade003: Upgrade a package (lesser version)
upgrade004: Upgrade a package (not installed)
upgrade010: Upgrade a package, with a file in NoUpgrade
upgrade020: Upgrade a package, with a file in 'backup' (new modified)
upgrade021: Upgrade a package, with a file in 'backup' (local modified, new unchanged)
upgrade022: Upgrade a package, with a file in 'backup' (local and new modified)
upgrade030: Upgrade packages with various reasons
upgrade040: file relocation 1

13
pactest/tests/add001.py Normal file
View File

@ -0,0 +1,13 @@
self.description = "Install a package"
p = pmpkg("dummy")
p.files = ["bin/dummy",
"usr/man/man1/dummy.1"]
self.addpkg(p)
self.args = "-A %s" % p.filename()
self.addrule("PACMAN_RETCODE=0")
self.addrule("PKG_EXIST=dummy")
for f in p.files:
self.addrule("FILE_EXIST=%s" % f)

18
pactest/tests/add002.py Normal file
View File

@ -0,0 +1,18 @@
self.description = "Install a package (already installed)"
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 = "-A %s" % p.filename()
self.addrule("PACMAN_RETCODE=1")
self.addrule("!PKG_MODIFIED=dummy")
for f in lp.files:
self.addrule("!FILE_MODIFIED=%s" % f)

23
pactest/tests/add003.py Normal file
View File

@ -0,0 +1,23 @@
self.description = "Install a set of 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 = "-A %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)

12
pactest/tests/add004.py Normal file
View File

@ -0,0 +1,12 @@
self.description = "Install a set of the same package at different versions"
p1 = pmpkg("dummy", "1.0-2")
p2 = pmpkg("dummy", "2.0-1")
p3 = pmpkg("dummy")
for p in p1, p2, p3:
self.addpkg(p)
self.args = "-A %s" % " ".join([p.filename() for p in p1, p2, p3])
self.addrule("PACMAN_RETCODE=0")
self.addrule("PKG_VERSION=dummy|2.0-1")

15
pactest/tests/add010.py Normal file
View File

@ -0,0 +1,15 @@
self.description = "Install a package with a filesystem conflict"
p = pmpkg("dummy")
p.files = ["bin/dummy",
"usr/man/man1/dummy.1"]
self.addpkg(p)
self.filesystem = ["bin/dummy"]
self.args = "-A %s" % p.filename()
self.addrule("PACMAN_RETCODE=1")
self.addrule("!PKG_EXIST=dummy")
self.addrule("!FILE_MODIFIED=bin/dummy")
self.addrule("!FILE_EXIST=usr/man/man1/dummy.1")

14
pactest/tests/add011.py Normal file
View File

@ -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 = "-Af %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")

20
pactest/tests/add012.py Normal file
View File

@ -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 = "-A %s" % " ".join([p.filename() for p in p1, p2])
self.addrule("PACMAN_RETCODE=1")
self.addrule("!PKG_EXIST=dummy")
self.addrule("!PKG_EXIST=foobar")

23
pactest/tests/add013.py Normal file
View File

@ -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 = "-Af %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)

15
pactest/tests/add020.py Normal file
View File

@ -0,0 +1,15 @@
self.description = "Install a package with an existing file"
p = pmpkg("dummy")
p.files = ["etc/dummy.conf"]
self.addpkg(p)
self.filesystem = ["etc/dummy.conf"]
self.args = "-Af %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")

16
pactest/tests/add021.py Normal file
View File

@ -0,0 +1,16 @@
self.description = "Install a package with an existing file (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 = "-Af %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")

18
pactest/tests/add030.py Normal file
View File

@ -0,0 +1,18 @@
self.description = "Freshen a package"
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 = "-F %s" % p.filename()
self.addrule("PACMAN_RETCODE=0")
self.addrule("PKG_VERSION=dummy|1.0-2")
for f in p.files:
self.addrule("FILE_MODIFIED=%s" % f)

18
pactest/tests/add031.py Normal file
View File

@ -0,0 +1,18 @@
self.description = "Freshen a package (installed is newer)"
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 = "-F %s" % p.filename()
self.addrule("PACMAN_RETCODE=1")
self.addrule("!PKG_MODIFIED=dummy")
for f in p.files:
self.addrule("!FILE_MODIFIED=%s" % f)

18
pactest/tests/add032.py Normal file
View File

@ -0,0 +1,18 @@
self.description = "Freshen a package (installed is newer)"
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 = "-F %s" % p.filename()
self.addrule("PACMAN_RETCODE=1")
self.addrule("!PKG_MODIFIED=dummy")
for f in p.files:
self.addrule("!FILE_MODIFIED=%s" % f)

14
pactest/tests/add040.py Normal file
View File

@ -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 = ["missdep"]
self.addpkg(p)
self.args = "-A %s" % p.filename()
self.addrule("PACMAN_RETCODE=1")
self.addrule("!PKG_EXIST=dummy")
for f in p.files:
self.addrule("!FILE_EXIST=%s" % f)

15
pactest/tests/add041.py Normal file
View File

@ -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 = "-Ad %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)

29
pactest/tests/add042.py Normal file
View File

@ -0,0 +1,29 @@
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 = "-A %s" % " ".join([p.filename() for p in p1, p2, p3])
self.addrule("PACMAN_RETCODE=0")
self.addrule("PKG_VERSION=dummy|1.0-2")
for f in p1.files:
self.addrule("FILE_EXIST=%s" % f)
self.addrule("PKG_EXIST=dep1")
self.addrule("PKG_EXIST=dep2")
self.addrule("PKG_DEPENDS=dummy|dep1")
self.addrule("PKG_DEPENDS=dep1|dep2")
self.addrule("PKG_REQUIREDBY=dep1|dummy")
self.addrule("PKG_REQUIREDBY=dep2|dep1")

16
pactest/tests/add050.py Normal file
View File

@ -0,0 +1,16 @@
self.description = "Install a package with a file in NoUpgrade"
p = pmpkg("dummy")
p.files = ["etc/dummy.conf"]
self.addpkg(p)
self.filesystem = ["etc/dummy.conf"]
self.option["noupgrade"] = ["etc/dummy.conf"]
self.args = "-Af %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")

15
pactest/tests/add060.py Normal file
View File

@ -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 = "-A %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")

19
pactest/tests/dummy001.py Normal file
View File

@ -0,0 +1,19 @@
self.description = "dummy test case"
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()

View File

@ -0,0 +1,9 @@
self.description = "Query a package"
p = pmpkg("foobar")
p.files = ["bin/foobar"]
self.addpkg2db("local", p)
self.args = "-Q foobar"
self.addrule("PACMAN_OUTPUT=foobar")

View File

@ -0,0 +1,12 @@
self.description = "Remove a package, with a file marked for backup"
p1 = pmpkg("dummy")
p1.files = ["etc/dummy.conf"]
p1.backup = ["etc/dummy.conf"]
self.addpkg2db("local", p1)
self.args = "-R dummy"
self.addrule("!PKG_EXIST=dummy")
self.addrule("!FILE_EXIST=etc/dummy.conf")
self.addrule("FILE_PACSAVE=etc/dummy.conf")

View File

@ -0,0 +1,12 @@
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 dummy"
self.addrule("!PKG_EXIST=dummy")
self.addrule("!FILE_EXIST=etc/dummy.conf")
self.addrule("FILE_PACSAVE=etc/dummy.conf")

View File

@ -0,0 +1,12 @@
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 dummy"
self.addrule("!PKG_EXIST=dummy")
self.addrule("!FILE_EXIST=etc/dummy.conf")
self.addrule("!FILE_PACSAVE=etc/dummy.conf")

View File

@ -0,0 +1,12 @@
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 dummy"
self.addrule("!PKG_EXIST=dummy")
self.addrule("!FILE_EXIST=etc/dummy.conf")
self.addrule("!FILE_PACSAVE=etc/dummy.conf")

View File

@ -0,0 +1,12 @@
self.description = "Remove a package in HoldPkg"
p1 = pmpkg("dummy")
self.addpkg2db("local", p1)
self.option["holdpkg"] = ["dummy"]
self.args = "-R dummy"
self.addrule("!PKG_EXIST=dummy")
self.addrule("!FILE_EXIST=etc/dummy.conf")
self.addrule("!FILE_PACSAVE=etc/dummy.conf")

19
pactest/tests/smoke001.py Normal file
View File

@ -0,0 +1,19 @@
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 = "-A %s" % " ".join(_list)
self.addrule("PACMAN_RETCODE=0")
#for i in range(1000):
# self.addrule("PKG_EXIST=pkg%03d" %i)

12
pactest/tests/sync001.py Normal file
View File

@ -0,0 +1,12 @@
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 dummy"
self.addrule("PKG_EXIST=dummy")
for f in sp.files:
self.addrule("FILE_EXIST=%s" % f)

17
pactest/tests/sync002.py Normal file
View File

@ -0,0 +1,17 @@
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 dummy"
self.addrule("PKG_VERSION=dummy|1.0-2")
for f in lp.files:
self.addrule("FILE_MODIFIED=%s" % f)

12
pactest/tests/sync003.py Normal file
View File

@ -0,0 +1,12 @@
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 dummy"
self.addrule("!PKG_EXIST=dummy")

12
pactest/tests/sync009.py Normal file
View File

@ -0,0 +1,12 @@
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 dummy"
self.addrule("PKG_EXIST=dummy")
for f in sp.files:
self.addrule("FILE_EXIST=%s" % f)

26
pactest/tests/sync010.py Normal file
View File

@ -0,0 +1,26 @@
self.description = "Install a package from a sync db, with its 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 dummy"
self.addrule("PKG_VERSION=dummy|1.0-2")
self.addrule("PKG_DEPENDS=dummy|dep1")
for f in sp1.files:
self.addrule("FILE_EXIST=%s" % f)
self.addrule("PKG_DEPENDS=dep1|dep2")
self.addrule("PKG_REQUIREDBY=dep1|dummy")
self.addrule("PKG_REQUIREDBY=dep2|dep1")

19
pactest/tests/sync020.py Normal file
View File

@ -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 grp"
self.addrule("PACMAN_RETCODE=0")
for p in sp1, sp2, sp3:
self.addrule("PKG_EXIST=%s" % p.name)

21
pactest/tests/sync021.py Normal file
View File

@ -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)

15
pactest/tests/sync040.py Normal file
View File

@ -0,0 +1,15 @@
self.description = "Install two targets with a conflict"
sp1 = pmpkg("pkg1")
sp1.conflicts = ["pkg2"]
sp2 = pmpkg("pkg2")
for p in sp1, sp2:
self.addpkg2db("sync", p);
self.args = "-S pkg1 pkg2"
self.addrule("PACMAN_RETCODE=1")
for p in sp1, sp2:
self.addrule("!PKG_EXIST=%s" % p.name)

16
pactest/tests/sync041.py Normal file
View File

@ -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 pkg1 pkg2"
self.addrule("PACMAN_RETCODE=1")
self.addrule("!PKG_EXIST=pkg1")
self.addrule("!PKG_EXIST=pkg2")

14
pactest/tests/sync042.py Normal file
View File

@ -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 pkg1"
self.addrule("PACMAN_RETCODE=0")
self.addrule("PKG_EXIST=pkg1")
self.addrule("!PKG_EXIST=pkg2")

14
pactest/tests/sync043.py Normal file
View File

@ -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 pkg1"
self.addrule("PACMAN_RETCODE=0")
self.addrule("PKG_EXIST=pkg1")
self.addrule("!PKG_EXIST=pkg2")

10
pactest/tests/sync050.py Normal file
View File

@ -0,0 +1,10 @@
self.description = "Install a virtual target (provided by a sync package)"
sp1 = pmpkg("pkg1")
sp1.provides = ["pkg2"]
self.addpkg2db("sync", sp1);
self.args = "-S pkg2"
self.addrule("PACMAN_RETCODE=0")
self.addrule("PKG_EXIST=pkg1")

12
pactest/tests/sync100.py Normal file
View File

@ -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")

12
pactest/tests/sync101.py Normal file
View File

@ -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")

12
pactest/tests/sync102.py Normal file
View File

@ -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")

14
pactest/tests/sync103.py Normal file
View File

@ -0,0 +1,14 @@
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")

22
pactest/tests/sync110.py Normal file
View File

@ -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)

21
pactest/tests/sync120.py Normal file
View File

@ -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")

16
pactest/tests/sync130.py Normal file
View File

@ -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")

19
pactest/tests/sync131.py Normal file
View File

@ -0,0 +1,19 @@
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")
lp2 = pmpkg("pkg2")
for p in lp1, lp2:
self.addpkg2db("local", p)
self.args = "-Su"
self.addrule("PACMAN_RETCODE=0")
self.addrule("PKG_EXIST=pkg4")
for p in lp1, lp2:
self.addrule("!PKG_EXIST=%s" % p.name)

18
pactest/tests/sync132.py Normal file
View File

@ -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")

18
pactest/tests/sync133.py Normal file
View File

@ -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")

21
pactest/tests/sync134.py Normal file
View File

@ -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)

31
pactest/tests/sync135.py Normal file
View File

@ -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)

15
pactest/tests/sync200.py Normal file
View File

@ -0,0 +1,15 @@
self.description = "Synchronize database"
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")

20
pactest/tests/sync890.py Normal file
View File

@ -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 pkg3"
self.addrule("PACMAN_RETCODE=0")
self.addrule("PKG_EXIST=pkg1")
self.addrule("!PKG_EXIST=pkg2")
self.addrule("PKG_EXIST=pkg3")

22
pactest/tests/sync891.py Normal file
View File

@ -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 pkg2 pkg3"
self.addrule("PACMAN_RETCODE=0")
self.addrule("PKG_EXIST=pkg1")
self.addrule("PKG_EXIST=pkg2")
self.addrule("PKG_EXIST=pkg3")

24
pactest/tests/sync892.py Normal file
View File

@ -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 pkg2 pkg3"
self.addrule("PACMAN_RETCODE=0")
self.addrule("!PKG_EXIST=pkg1")
self.addrule("PKG_EXIST=pkg2")
self.addrule("PKG_EXIST=pkg3")

20
pactest/tests/sync893.py Normal file
View File

@ -0,0 +1,20 @@
self.description = "conflict (bug)"
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 pkg1 pkg2"
self.addrule("PACMAN_RETCODE=0")
self.addrule("PKG_EXIST=pkg1")
self.addrule("!PKG_EXIST=pkg2")

26
pactest/tests/sync897.py Normal file
View File

@ -0,0 +1,26 @@
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")
lp1.conflicts = ["pkg2"]
self.addpkg2db("local", lp1)
lp2 = pmpkg("pkg2")
self.addpkg2db("local", lp2)
lp3 = pmpkg("pkg3")
lp3.conflicts = ["pkg1"]
self.addpkg2db("local", lp3)
self.args = "-Su"
self.addrule("PACMAN_RETCODE=0")
self.addrule("PKG_EXIST=pkg1")
self.addrule("!PKG_EXIST=pkg2")

18
pactest/tests/sync898.py Normal file
View File

@ -0,0 +1,18 @@
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)
self.args = "-S pkg1 pkg2"
self.addrule("PACMAN_RETCODE=1")
self.addrule("!PKG_MODIFIED=pkg1")
self.addrule("!PKG_EXIST=pkg2")

18
pactest/tests/sync899.py Normal file
View File

@ -0,0 +1,18 @@
self.description = "System upgrade"
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"
self.addrule("PACMAN_RETCODE=0")
self.addrule("PKG_EXIST=pkg1")
self.addrule("!PKG_EXIST=pkg2")

20
pactest/tests/sync990.py Normal file
View File

@ -0,0 +1,20 @@
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"]
sp3.provides = ["pkg2"]
for p in sp1, sp2, sp3:
self.addpkg2db("sync", p)
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")

23
pactest/tests/sync992.py Normal file
View File

@ -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 pkg1 pkg2"
self.addrule("PACMAN_RETCODE=0")
self.addrule("PKG_EXIST=pkg1")
self.addrule("!PKG_EXIST=pkg2")
self.addrule("PKG_EXIST=pkg3")

21
pactest/tests/sync999.py Normal file
View File

@ -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"
self.addrule("PACMAN_RETCODE=0")
self.addrule("PKG_EXIST=pkg1")
self.addrule("!PKG_EXIST=pkg2")

View File

@ -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)

View File

@ -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)

View File

@ -0,0 +1,18 @@
self.description = "Upgrade a package (lesser 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)

View File

@ -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)

View File

@ -0,0 +1,17 @@
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")

View File

@ -0,0 +1,17 @@
self.description = "Upgrade a package, with a file in 'backup' (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")

View File

@ -0,0 +1,17 @@
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")

View File

@ -0,0 +1,17 @@
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")

View File

@ -0,0 +1,22 @@
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.args = "-Qi %s" % " ".join([p.name for p in lp1, lp2])
self.addrule("PACMAN_RETCODE=0")
self.addrule("PKG_REASON=pkg1|0")
self.addrule("PKG_REASON=pkg2|1")

View File

@ -0,0 +1,25 @@
self.description = "file relocation 1"
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")

259
pactest/util.py Executable file
View File

@ -0,0 +1,259 @@
#! /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, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
# USA.
import sys
import os
import md5
import stat
# ALPM
PM_ROOT = "/"
PM_DBPATH = "var/lib/pacman"
PM_CACHEDIR = "var/cache/pacman/pkg"
PM_LOCK = "/tmp/pacman.lck"
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
debug = 1
def err(msg):
print "error: " + msg
sys.exit(1)
def vprint(msg):
if verbose:
print msg
def dbg(msg):
if debug:
print msg
#
# Methods to generate files
#
def getfilename(name):
"""
"""
filename = ""
link = ""
if not name.find(" -> ") == -1:
filename, link = name.split(" -> ")
elif name[-1] == "*":
filename = name.rstrip("*")
else:
filename = name
return filename
def mkfile(name, data = ""):
"""
"""
isaltered = 0
isdir = 0
islink = 0
link = ""
filename = ""
if not name.find(" -> ") == -1:
islink = 1
filename, link = name.split(" -> ")
elif name[-1] == "*":
isaltered = 1
filename = name.rstrip("*")
else:
filename = name
if name[-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()
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()
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.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
data.extend(["[%s]\n" \
"server = file://%s\n" \
% (value.treename, os.path.join(root, SYNCREPO, value.treename)) \
for key, value in db.iteritems() if not key == "local"])
mkfile(os.path.join(root, filename), "\n".join(data))
#
# MD5 helpers
#
def getmd5sum(filename):
"""
"""
fd = open(filename, "rb")
checksum = md5.new()
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 = md5.new()
checksum.update("%s\n" % data)
digest = checksum.digest()
return "%02x"*len(digest) % tuple(map(ord, digest))
#
# Mtime helpers
#
def getmtime(filename):
"""
"""
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 grep(filename, pattern):
found = 0
fd = file(filename, "r")
while 1 and not found:
line = fd.readline()
if not line:
break
if line.find(pattern) != -1:
found = 1
fd.close()
return found
if __name__ == "__main__":
pass