10637.3.1
by Guilherme Salgado
Use the default python version instead of a hard-coded version |
1 |
#!/usr/bin/python -S
|
8687.15.10
by Karl Fogel
Add the copyright header block to top-level files. |
2 |
#
|
3 |
# Copyright 2009 Canonical Ltd. This software is licensed under the
|
|
4 |
# GNU Affero General Public License version 3 (see the file LICENSE).
|
|
1102
by Canonical.com Patch Queue Manager
Lucille had some XXXs which should have been NOTEs |
5 |
|
6 |
"""Tests that get run automatically on a merge."""
|
|
9722.1.1
by Gary Poster
[testfix][r=salgado][ui=none] Try to fix the buildbot problem: buildbot is starting test_on_merge in a way that no-one else is. |
7 |
import _pythonpath |
1102
by Canonical.com Patch Queue Manager
Lucille had some XXXs which should have been NOTEs |
8 |
|
10303.1.16
by Gary Poster
remove disgusting bit: we will change buildbot |
9 |
import sys, time |
10 |
import os, errno |
|
1102
by Canonical.com Patch Queue Manager
Lucille had some XXXs which should have been NOTEs |
11 |
import tabnanny |
12 |
from StringIO import StringIO |
|
5821.2.85
by James Henstridge
Add "make check_launchpad_storm_on_merge" target that runs the tests |
13 |
import psycopg2 |
3308.1.2
by Stuart Bishop
Make test_on_merge.py do incremental output |
14 |
from subprocess import Popen, PIPE, STDOUT |
2083
by Canonical.com Patch Queue Manager
[r=jamesh] testrunner improvements (?) |
15 |
from signal import SIGKILL, SIGTERM |
16 |
from select import select |
|
17 |
||
6393.2.1
by Joey Stanford
change the rather long timeout setting to something more reasonable and cleanup the explaination |
18 |
# The TIMEOUT setting (expressed in seconds) affects how long a test will run
|
19 |
# before it is deemed to be hung, and then appropriately terminated.
|
|
20 |
# It's principal use is preventing a PQM job from hanging indefinitely and
|
|
21 |
# backing up the queue.
|
|
22 |
# e.g. Usage: TIMEOUT = 60 * 15
|
|
23 |
# This will set the timeout to 15 minutes.
|
|
24 |
TIMEOUT = 60 * 15 |
|
1102
by Canonical.com Patch Queue Manager
Lucille had some XXXs which should have been NOTEs |
25 |
|
26 |
def main(): |
|
8234.1.4
by Gary Poster
test works, nominally; and bin/py is a bit more functional. problems with import warnings are more serious because they cause tests to fail. |
27 |
"""Call bin/test with whatever arguments this script was run with.
|
1102
by Canonical.com Patch Queue Manager
Lucille had some XXXs which should have been NOTEs |
28 |
|
29 |
If the tests ran ok (last line of stderr is 'OK<return>') then suppress
|
|
30 |
output and exit(0).
|
|
31 |
||
32 |
Otherwise, print output and exit(1).
|
|
33 |
"""
|
|
34 |
here = os.path.dirname(os.path.realpath(__file__)) |
|
35 |
||
36 |
# Tabnanny
|
|
6393.2.2
by Joey Stanford
working updates since I had to change the line for pyflakes |
37 |
# NB. If tabnanny raises an exception, run
|
10637.3.5
by Guilherme Salgado
Revert a couple changes left by accident |
38 |
# python /usr/lib/python2.5/tabnanny.py -vv lib/canonical
|
2976.10.114
by Stuart Bishop
Test tweaks |
39 |
# for more detailed output.
|
1102
by Canonical.com Patch Queue Manager
Lucille had some XXXs which should have been NOTEs |
40 |
org_stdout = sys.stdout |
41 |
sys.stdout = StringIO() |
|
42 |
tabnanny.check(os.path.join(here, 'lib', 'canonical')) |
|
43 |
tabnanny_results = sys.stdout.getvalue() |
|
44 |
sys.stdout = org_stdout |
|
45 |
if len(tabnanny_results) > 0: |
|
46 |
print '---- tabnanny bitching ----' |
|
47 |
print tabnanny_results |
|
48 |
print '---- end tabnanny bitching ----' |
|
49 |
return 1 |
|
50 |
||
1064.1.3
by James Henstridge
merge from marius |
51 |
# Sanity check PostgreSQL version. No point in trying to create a test
|
52 |
# database when PostgreSQL is too old.
|
|
5821.2.85
by James Henstridge
Add "make check_launchpad_storm_on_merge" target that runs the tests |
53 |
con = psycopg2.connect('dbname=template1') |
1064.1.3
by James Henstridge
merge from marius |
54 |
cur = con.cursor() |
55 |
cur.execute('show server_version') |
|
56 |
server_version = cur.fetchone()[0] |
|
57 |
try: |
|
58 |
numeric_server_version = tuple(map(int, server_version.split('.'))) |
|
59 |
except ValueError: |
|
60 |
# Skip this check if the version number is more complicated than
|
|
61 |
# we expected.
|
|
62 |
pass
|
|
63 |
else: |
|
3257.1.1
by Stuart Bishop
PostgreSQL 8.0+ required |
64 |
if numeric_server_version < (8, 0): |
65 |
print 'Your PostgreSQL version is too old. You need 8.x.x' |
|
1064.1.3
by James Henstridge
merge from marius |
66 |
print 'You have %s' % server_version |
67 |
return 1 |
|
68 |
||
1102
by Canonical.com Patch Queue Manager
Lucille had some XXXs which should have been NOTEs |
69 |
# Drop the template database if it exists - the Makefile does this
|
70 |
# too, but we can explicity check for errors here
|
|
5821.2.85
by James Henstridge
Add "make check_launchpad_storm_on_merge" target that runs the tests |
71 |
con = psycopg2.connect('dbname=template1') |
2083
by Canonical.com Patch Queue Manager
[r=jamesh] testrunner improvements (?) |
72 |
con.set_isolation_level(0) |
1102
by Canonical.com Patch Queue Manager
Lucille had some XXXs which should have been NOTEs |
73 |
cur = con.cursor() |
1064.1.3
by James Henstridge
merge from marius |
74 |
try: |
2083
by Canonical.com Patch Queue Manager
[r=jamesh] testrunner improvements (?) |
75 |
cur.execute('drop database launchpad_ftest_template') |
5821.2.85
by James Henstridge
Add "make check_launchpad_storm_on_merge" target that runs the tests |
76 |
except psycopg2.ProgrammingError, x: |
1520
by Canonical.com Patch Queue Manager
Review and fix database security update code |
77 |
if 'does not exist' not in str(x): |
78 |
raise
|
|
2083
by Canonical.com Patch Queue Manager
[r=jamesh] testrunner improvements (?) |
79 |
cur.execute(""" |
80 |
select count(*) from pg_stat_activity
|
|
81 |
where datname in ('launchpad_dev',
|
|
82 |
'launchpad_ftest_template', 'launchpad_ftest')
|
|
83 |
""") |
|
84 |
existing_connections = cur.fetchone()[0] |
|
85 |
if existing_connections > 0: |
|
86 |
print 'Cannot rebuild database. There are %d open connections.' % ( |
|
87 |
existing_connections, |
|
88 |
)
|
|
89 |
return 1 |
|
1102
by Canonical.com Patch Queue Manager
Lucille had some XXXs which should have been NOTEs |
90 |
cur.close() |
91 |
con.close() |
|
92 |
||
93 |
# Build the template database. Tests duplicate this.
|
|
94 |
here = os.path.dirname(os.path.realpath(__file__)) |
|
95 |
schema_dir = os.path.join(here, 'database', 'schema') |
|
10303.1.15
by Gary Poster
make test_on_merge.py work, so buildbot can pass |
96 |
if os.system('cd %s; make test > /dev/null' % (schema_dir)) != 0: |
1764
by Canonical.com Patch Queue Manager
Now make check fails if anything goes wrong when loading the sampledata. r=stub |
97 |
print 'Failed to create database or load sampledata.' |
1102
by Canonical.com Patch Queue Manager
Lucille had some XXXs which should have been NOTEs |
98 |
return 1 |
99 |
||
100 |
# Sanity check the database. No point running tests if the
|
|
101 |
# bedrock is crumbling.
|
|
5821.2.85
by James Henstridge
Add "make check_launchpad_storm_on_merge" target that runs the tests |
102 |
con = psycopg2.connect('dbname=launchpad_ftest_template') |
1102
by Canonical.com Patch Queue Manager
Lucille had some XXXs which should have been NOTEs |
103 |
cur = con.cursor() |
104 |
cur.execute('show search_path') |
|
105 |
search_path = cur.fetchone()[0] |
|
106 |
if search_path != '$user,public,ts2': |
|
107 |
print 'Search path incorrect.' |
|
108 |
print 'Add the following line to /etc/postgresql/postgresql.conf:' |
|
109 |
print " search_path = '$user,public,ts2'" |
|
1064.1.3
by James Henstridge
merge from marius |
110 |
print "and tell postgresql to reload its configuration file." |
1102
by Canonical.com Patch Queue Manager
Lucille had some XXXs which should have been NOTEs |
111 |
return 1 |
112 |
cur.execute(""" |
|
113 |
select pg_encoding_to_char(encoding) as encoding from pg_database
|
|
114 |
where datname='launchpad_ftest_template'
|
|
115 |
""") |
|
116 |
enc = cur.fetchone()[0] |
|
3242.1.5
by Stuart Bishop
Make test_on_merge.py work with PostgreSQL 8.1 |
117 |
if enc not in ('UNICODE', 'UTF8'): |
1102
by Canonical.com Patch Queue Manager
Lucille had some XXXs which should have been NOTEs |
118 |
print 'Database encoding incorrectly set' |
119 |
return 1 |
|
1257
by Canonical.com Patch Queue Manager
Improve database locale checks, add locale sanity check to test_on_merge.py and improve test_on_merge output |
120 |
cur.execute(r""" |
121 |
SELECT setting FROM pg_settings
|
|
122 |
WHERE context='internal' AND name='lc_ctype'
|
|
123 |
""") |
|
124 |
loc = cur.fetchone()[0] |
|
2083
by Canonical.com Patch Queue Manager
[r=jamesh] testrunner improvements (?) |
125 |
#if not (loc.startswith('en_') or loc in ('C', 'en')):
|
126 |
if loc != 'C': |
|
1257
by Canonical.com Patch Queue Manager
Improve database locale checks, add locale sanity check to test_on_merge.py and improve test_on_merge output |
127 |
print 'Database locale incorrectly set. Need to rerun initdb.' |
128 |
return 1 |
|
129 |
||
1102
by Canonical.com Patch Queue Manager
Lucille had some XXXs which should have been NOTEs |
130 |
# Explicity close our connections - things will fail if we leave open
|
131 |
# connections.
|
|
132 |
cur.close() |
|
133 |
del cur |
|
134 |
con.close() |
|
135 |
del con |
|
136 |
||
137 |
print 'Running tests.' |
|
2083
by Canonical.com Patch Queue Manager
[r=jamesh] testrunner improvements (?) |
138 |
os.chdir(here) |
10096.2.2
by Bjorn Tillenius
Run xvfb-run inside test_on_merge.py. |
139 |
cmd = [ |
140 |
'xvfb-run', |
|
141 |
'-s', |
|
142 |
"'-screen 0 1024x768x24'", |
|
143 |
os.path.join(here, 'bin', 'test')] + sys.argv[1:] |
|
10096.2.3
by Bjorn Tillenius
Use xvfb-run in test_on_merge.py |
144 |
command_line = ' '.join(cmd) |
145 |
print command_line |
|
4107.1.9
by Stuart Bishop
Increase test_on_merge timeout to one hour |
146 |
|
147 |
# Run the test suite and return the error code
|
|
148 |
#return call(cmd)
|
|
149 |
||
10096.2.3
by Bjorn Tillenius
Use xvfb-run in test_on_merge.py |
150 |
proc = Popen( |
151 |
command_line, stdin=PIPE, stdout=PIPE, stderr=STDOUT, shell=True) |
|
2083
by Canonical.com Patch Queue Manager
[r=jamesh] testrunner improvements (?) |
152 |
proc.stdin.close() |
153 |
||
3258.1.1
by Andrew Bennetts
Fix backwards timeout detection logic in test_on_merge.py |
154 |
# Do proc.communicate(), but timeout if there's no activity on stdout or
|
155 |
# stderr for too long.
|
|
3308.1.2
by Stuart Bishop
Make test_on_merge.py do incremental output |
156 |
open_readers = set([proc.stdout]) |
3308.1.4
by Stuart Bishop
Fix test_on_merge.py incremental output |
157 |
while open_readers: |
2083
by Canonical.com Patch Queue Manager
[r=jamesh] testrunner improvements (?) |
158 |
rlist, wlist, xlist = select(open_readers, [], [], TIMEOUT) |
159 |
||
4092.2.18
by Barry Warsaw
Respond to spiv's review: |
160 |
if len(rlist) == 0: |
3258.1.1
by Andrew Bennetts
Fix backwards timeout detection logic in test_on_merge.py |
161 |
if proc.poll() is not None: |
2083
by Canonical.com Patch Queue Manager
[r=jamesh] testrunner improvements (?) |
162 |
break
|
6393.2.2
by Joey Stanford
working updates since I had to change the line for pyflakes |
163 |
print ("\nA test appears to be hung. There has been no output for" |
164 |
" %d seconds. Sending SIGTERM." % TIMEOUT) |
|
2083
by Canonical.com Patch Queue Manager
[r=jamesh] testrunner improvements (?) |
165 |
killem(proc.pid, SIGTERM) |
166 |
time.sleep(3) |
|
3258.1.1
by Andrew Bennetts
Fix backwards timeout detection logic in test_on_merge.py |
167 |
if proc.poll() is not None: |
6393.2.2
by Joey Stanford
working updates since I had to change the line for pyflakes |
168 |
print ("\nSIGTERM did not work. Sending SIGKILL.") |
2083
by Canonical.com Patch Queue Manager
[r=jamesh] testrunner improvements (?) |
169 |
killem(proc.pid, SIGKILL) |
4092.2.12
by Barry Warsaw
Thanks to jamesh, do a better job of draining the subprocess's stdout and |
170 |
# Drain the subprocess's stdout and stderr.
|
171 |
sys.stdout.write(proc.stdout.read()) |
|
172 |
break
|
|
2083
by Canonical.com Patch Queue Manager
[r=jamesh] testrunner improvements (?) |
173 |
|
174 |
if proc.stdout in rlist: |
|
3308.1.2
by Stuart Bishop
Make test_on_merge.py do incremental output |
175 |
chunk = os.read(proc.stdout.fileno(), 1024) |
3367.1.2
by Stuart Bishop
Don't insert random spaces in test_on_merge.py output |
176 |
sys.stdout.write(chunk) |
3308.1.2
by Stuart Bishop
Make test_on_merge.py do incremental output |
177 |
if chunk == "": |
3308.1.4
by Stuart Bishop
Fix test_on_merge.py incremental output |
178 |
open_readers.remove(proc.stdout) |
3308.1.2
by Stuart Bishop
Make test_on_merge.py do incremental output |
179 |
|
3308.1.4
by Stuart Bishop
Fix test_on_merge.py incremental output |
180 |
rv = proc.wait() |
3308.1.2
by Stuart Bishop
Make test_on_merge.py do incremental output |
181 |
if rv == 0: |
6393.2.2
by Joey Stanford
working updates since I had to change the line for pyflakes |
182 |
print '\nSuccessfully ran all tests.' |
1102
by Canonical.com Patch Queue Manager
Lucille had some XXXs which should have been NOTEs |
183 |
else: |
3308.1.2
by Stuart Bishop
Make test_on_merge.py do incremental output |
184 |
print '\nTests failed (exit code %d)' % rv |
185 |
||
186 |
return rv |
|
187 |
||
1102
by Canonical.com Patch Queue Manager
Lucille had some XXXs which should have been NOTEs |
188 |
|
2083
by Canonical.com Patch Queue Manager
[r=jamesh] testrunner improvements (?) |
189 |
def killem(pid, signal): |
190 |
"""Kill the process group leader identified by pid and other group members
|
|
191 |
||
8234.1.4
by Gary Poster
test works, nominally; and bin/py is a bit more functional. problems with import warnings are more serious because they cause tests to fail. |
192 |
Note that bin/test sets its process to a process group leader.
|
2083
by Canonical.com Patch Queue Manager
[r=jamesh] testrunner improvements (?) |
193 |
"""
|
194 |
try: |
|
195 |
os.killpg(os.getpgid(pid), signal) |
|
196 |
except OSError, x: |
|
197 |
if x.errno == errno.ESRCH: |
|
198 |
pass
|
|
199 |
else: |
|
200 |
raise
|
|
201 |
||
1102
by Canonical.com Patch Queue Manager
Lucille had some XXXs which should have been NOTEs |
202 |
if __name__ == '__main__': |
203 |
sys.exit(main()) |