pmrule.py 7.25 KB
Newer Older
1
#  Copyright (c) 2006 by Aurelien Foret <orelien@chez.com>
Allan McRae's avatar
Allan McRae committed
2
#  Copyright (c) 2006-2022 Pacman Development Team <pacman-dev@lists.archlinux.org>
3
#
4
5
6
7
8
9
10
11
12
13
14
#  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
15
#  along with this program.  If not, see <http://www.gnu.org/licenses/>.
16

17
import os
Dan McGee's avatar
Dan McGee committed
18
19
import stat

Andrew Gregory's avatar
Andrew Gregory committed
20
import tap
Dan McGee's avatar
Dan McGee committed
21
import util
22

23
class pmrule(object):
24
25
    """Rule object
    """
26

27
28
29
30
    def __init__(self, rule):
        self.rule = rule
        self.false = 0
        self.result = 0
31

32
    def __str__(self):
33
        return self.rule
34

35
36
37
38
39
40
    def snapshots_needed(self):
        (testname, args) = self.rule.split("=")
        if testname == "FILE_MODIFIED" or testname == "!FILE_MODIFIED":
            return [args]
        return []

41
    def check(self, test):
42
43
44
        """
        """
        success = 1
45

46
47
        [testname, args] = self.rule.split("=")
        if testname[0] == "!":
48
            self.false = 1
49
            testname = testname[1:]
50
        [kind, case] = testname.split("_")
51
52
53
54
        if "|" in args:
            [key, value] = args.split("|", 1)
        else:
            [key, value] = [args, None]
55

56
57
        if kind == "PACMAN":
            if case == "RETCODE":
58
                if test.retcode != int(key):
59
60
                    success = 0
            elif case == "OUTPUT":
61
                logfile = os.path.join(test.root, util.LOGFILE)
62
                if not os.access(logfile, os.F_OK):
Andrew Gregory's avatar
Andrew Gregory committed
63
                    tap.diag("LOGFILE not found, cannot validate 'OUTPUT' rule")
64
                    success = 0
65
                elif not util.grep(logfile, key):
66
67
                    success = 0
            else:
Andrew Gregory's avatar
Andrew Gregory committed
68
                tap.diag("PACMAN rule '%s' not found" % case)
69
70
                success = -1
        elif kind == "PKG":
71
            localdb = test.db["local"]
72
73
74
75
76
77
78
79
80
            newpkg = localdb.db_read(key)
            if not newpkg:
                success = 0
            else:
                if case == "EXIST":
                    success = 1
                elif case == "VERSION":
                    if value != newpkg.version:
                        success = 0
81
82
83
                elif case == "DESC":
                    if value != newpkg.desc:
                        success = 0
84
85
86
                elif case == "GROUPS":
                    if not value in newpkg.groups:
                        success = 0
87
88
89
                elif case == "PROVIDES":
                    if not value in newpkg.provides:
                        success = 0
90
91
92
                elif case == "DEPENDS":
                    if not value in newpkg.depends:
                        success = 0
93
                elif case == "OPTDEPENDS":
94
95
96
97
98
                    success = 0
                    for optdep in newpkg.optdepends:
                        if value == optdep.split(':', 1)[0]:
                            success = 1
                            break
99
                elif case == "REASON":
100
                    if newpkg.reason != int(value):
101
102
103
104
105
                        success = 0
                elif case == "FILES":
                    if not value in newpkg.files:
                        success = 0
                elif case == "BACKUP":
106
                    success = 0
107
                    for f in newpkg.backup:
108
109
110
                        if f.startswith(value + "\t"):
                            success = 1
                            break;
111
                else:
Andrew Gregory's avatar
Andrew Gregory committed
112
                    tap.diag("PKG rule '%s' not found" % case)
113
114
                    success = -1
        elif kind == "FILE":
115
            filename = os.path.join(test.root, key)
116
117
118
            if case == "EXIST":
                if not os.path.isfile(filename):
                    success = 0
Andrew Gregory's avatar
Andrew Gregory committed
119
120
121
122
            elif case == "EMPTY":
                if not (os.path.isfile(filename)
                        and os.path.getsize(filename) == 0):
                    success = 0
123
124
125
126
127
128
            elif case == "CONTENTS":
                try:
                    with open(filename, 'r') as f:
                        success = f.read() == value
                except:
                    success = 0
129
            elif case == "MODIFIED":
130
                for f in test.files:
131
132
133
                    if f.name == key:
                        if not f.ismodified():
                            success = 0
Dan McGee's avatar
Dan McGee committed
134
                        break
135
            elif case == "MODE":
136
                if not os.path.isfile(filename):
137
                    success = 0
138
                else:
Dan McGee's avatar
Dan McGee committed
139
140
                    mode = os.lstat(filename)[stat.ST_MODE]
                    if int(value, 8) != stat.S_IMODE(mode):
141
                        success = 0
142
143
144
            elif case == "TYPE":
                if value == "dir":
                    if not os.path.isdir(filename):
145
                        success = 0
146
147
                elif value == "file":
                    if not os.path.isfile(filename):
148
                        success = 0
149
150
                elif value == "link":
                    if not os.path.islink(filename):
151
                        success = 0
152
            elif case == "PACNEW":
Dan McGee's avatar
Dan McGee committed
153
                if not os.path.isfile("%s.pacnew" % filename):
154
155
                    success = 0
            elif case == "PACSAVE":
Dan McGee's avatar
Dan McGee committed
156
                if not os.path.isfile("%s.pacsave" % filename):
157
158
                    success = 0
            else:
Andrew Gregory's avatar
Andrew Gregory committed
159
                tap.diag("FILE rule '%s' not found" % case)
160
                success = -1
161
162
163
164
165
166
        elif kind == "DIR":
            filename = os.path.join(test.root, key)
            if case == "EXIST":
                if not os.path.isdir(filename):
                    success = 0
            else:
Andrew Gregory's avatar
Andrew Gregory committed
167
                tap.diag("DIR rule '%s' not found" % case)
168
                success = -1
169
170
171
172
173
174
        elif kind == "LINK":
            filename = os.path.join(test.root, key)
            if case == "EXIST":
                if not os.path.islink(filename):
                    success = 0
            else:
Andrew Gregory's avatar
Andrew Gregory committed
175
                tap.diag("LINK rule '%s' not found" % case)
176
                success = -1
177
178
179
180
181
182
183
        elif kind == "CACHE":
            cachedir = os.path.join(test.root, util.PM_CACHEDIR)
            if case == "EXISTS":
                pkg = test.findpkg(key, value, allow_local=True)
                if not pkg or not os.path.isfile(
                        os.path.join(cachedir, pkg.filename())):
                    success = 0
184
185
186
187
188
189
190
191
192
193
            elif case == "FEXISTS":
                if not os.path.isfile(os.path.join(cachedir, key)):
                    success = 0
            elif case == "FCONTENTS":
                filename = os.path.join(cachedir, key)
                try:
                    with open(filename, 'r') as f:
                        success = f.read() == value
                except:
                    success = 0
194
        else:
Andrew Gregory's avatar
Andrew Gregory committed
195
            tap.diag("Rule kind '%s' not found" % kind)
196
            success = -1
197

198
199
200
201
        if self.false and success != -1:
            success = not success
        self.result = success
        return success