1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
|
# Copyright (C) 2013 Red Hat, Inc.
#
# This work is licensed under the GNU GPLv2 or later.
# See the COPYING file in the top-level directory.
import fnmatch
import glob
import imp
import importlib
import os
import sys
import unittest
import xml.etree.ElementTree as ET
_badmodules = ["gi.repository.Gtk", "gi.repository.Gdk"]
def _restore_modules(fn):
def wrap(*args, **kwargs):
origimport = __builtins__["__import__"]
def my_import(name, *iargs, **ikwargs):
if name in _badmodules:
raise AssertionError("Tried to import '%s'" % name)
return origimport(name, *iargs, **ikwargs)
try:
__builtins__["__import__"] = my_import
return fn(*args, **kwargs)
finally:
__builtins__["__import__"] = origimport
return wrap
def _find_py(dirname):
ret = []
for root, ignore, filenames in os.walk(dirname):
for filename in fnmatch.filter(filenames, "*.py"):
ret.append(os.path.join(root, filename))
ret.sort(key=lambda s: s.lower())
return ret
class TestDist(unittest.TestCase):
"""
Tests to run before release
"""
def _check_modules(self, files):
for f in files:
regular_import = f.endswith(".py")
if f.endswith("/__init__.py"):
f = f.rsplit("/", 1)[0]
name = f.rsplit(".", 1)[0].replace("/", ".")
if name in sys.modules:
continue
if regular_import:
importlib.import_module(name)
else:
imp.load_source(name, f)
found = []
for f in _badmodules:
if f in sys.modules:
found.append(f)
if found:
raise AssertionError("%s found in sys.modules" % found)
@_restore_modules
def test_no_gtk_virtinst(self):
"""
Make sure virtinst doesn't pull in any gnome modules
"""
files = ["virt-install", "virt-clone", "virt-convert"]
files += _find_py("virtinst")
files += _find_py("virtconv")
files += _find_py("virtcli")
self._check_modules(files)
def test_validate_po_files(self):
"""
Validate that po translations don't mess up python format strings,
which has broken the app in the past:
https://bugzilla.redhat.com/show_bug.cgi?id=1350185
https://bugzilla.redhat.com/show_bug.cgi?id=1433800
"""
failures = []
for pofile in glob.glob("po/*.po"):
import subprocess
proc = subprocess.Popen(["msgfmt", "--output-file=/dev/null",
"--check", pofile],
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
ignore, stderr = proc.communicate()
if proc.wait():
failures.append("%s: %s" % (pofile, stderr))
if not failures:
return
msg = "The following po files have errors:\n"
msg += "\n".join(failures)
raise AssertionError(msg)
def test_ui_minimum_version(self):
"""
Ensure all glade XML files don't _require_ UI bits later than
our minimum supported version
"""
# RHEL 7.3 has gtk 3.14, so that's our current minimum target
minimum_version_major = 3
minimum_version_minor = 14
minimum_version_str = "%s.%s" % (minimum_version_major,
minimum_version_minor)
failures = []
for filename in glob.glob("ui/*.ui"):
required_version = None
for line in open(filename).readlines():
# This is much faster than XML parsing the whole file
if not line.strip().startswith('<requires '):
continue
req = ET.fromstring(line)
if (req.tag != "requires" or
req.attrib.get("lib") != "gtk+"):
continue
required_version = req.attrib["version"]
if required_version is None:
raise AssertionError("ui file=%s doesn't have a <requires> "
"tag for gtk+")
if (int(required_version.split(".")[0]) != minimum_version_major or
int(required_version.split(".")[1]) != minimum_version_minor):
failures.append((filename, required_version))
if not failures:
return
err = ("The following files should require version of gtk-%s:\n" %
minimum_version_str)
err += "\n".join([("%s version=%s" % tup) for tup in failures])
raise AssertionError(err)
def test_ui_translatable_atknames(self):
"""
We only use accessible names for uitests, they shouldn't be
marked as translatable
"""
failures = []
atkstr = "AtkObject::accessible-name"
for filename in glob.glob("ui/*.ui"):
for line in open(filename).readlines():
if atkstr not in line:
continue
if "translatable=" in line:
failures.append(filename)
break
if not failures:
return
err = "Some files incorrectly have translatable ATK names.\n"
err += "Run this command to fix:\n\n"
err += ("""sed -i -e 's/%s" translatable="yes"/%s"/g' """ %
(atkstr, atkstr))
err += " ".join(failures)
raise AssertionError(err)
|