~launchpad-pqm/launchpad/devel

« back to all changes in this revision

Viewing changes to test_on_merge.py

  • Committer: Maris Fogels
  • Date: 2010-05-25 16:24:39 UTC
  • mto: This revision was merged to the branch mainline in revision 11372.
  • Revision ID: maris.fogels@canonical.com-20100525162439-lbbrntigyhpfmouw
Tidied the code for review.

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
from select import select
17
17
 
18
18
 
19
 
__metaclass__ = type
20
 
 
21
 
 
22
19
# The TIMEOUT setting (expressed in seconds) affects how long a test will run
23
20
# before it is deemed to be hung, and then appropriately terminated.
24
21
# It's principal use is preventing a PQM job from hanging indefinitely and
174
171
    # the process group number matching our PID.
175
172
    os.setpgid(0, original_process_group)
176
173
 
177
 
    # This code is very similar to what takes place in proc._communicate(),
 
174
    # This code is very similar to what takes place in Popen._communicate(),
178
175
    # but this code times out if there is no activity on STDOUT for too long.
179
176
    open_readers = set([xvfb_proc.stdout])
180
177
    while open_readers:
187
184
                # The process we were watching died.
188
185
                break
189
186
 
190
 
            print
191
 
            print ("WARNING: A test appears to be hung. There has been no "
192
 
                "output for %d seconds." % TIMEOUT)
193
 
            print "Forcibly shutting down the test suite:"
194
 
 
195
 
            # This guarantees the processes the group will die.  In rare cases
196
 
            # a child process may survive this if they are in a different
197
 
            # process group and they ignore the signals we send their parent.
198
 
            nice_killpg(xvfb_proc)
199
 
 
200
 
            # Drain the subprocess's stdout and stderr.
201
 
            print "The dying processes left behind the following output:"
202
 
            print "--------------- BEGIN OUTPUT ---------------"
203
 
            sys.stdout.write(xvfb_proc.stdout.read())
204
 
            print "---------------- END OUTPUT ----------------"
205
 
 
 
187
            cleanup_hung_testrunner_process(xvfb_proc)
206
188
            break
207
189
 
208
190
        if xvfb_proc.stdout in rlist:
213
195
                # Gracefully exit the loop if STDOUT is empty.
214
196
                open_readers.remove(xvfb_proc.stdout)
215
197
 
216
 
    try:
217
 
        rv = xvfb_proc.wait()
218
 
    except OSError, exc:
219
 
        raise
220
 
        if exc.errno == errno.ECHILD:
221
 
            # The process has already died and been collected.
222
 
            rv = xvfb_proc.returncode
223
 
        else:
224
 
            raise
 
198
    rv = xvfb_proc.wait()
225
199
 
226
200
    if rv == 0:
227
201
        print
233
207
    return rv
234
208
 
235
209
 
 
210
def cleanup_hung_testrunner_process(process):
 
211
    """Kill and clean up the testrunner process and its children."""
 
212
    print
 
213
    print
 
214
    print ("WARNING: A test appears to be hung. There has been no "
 
215
        "output for %d seconds." % TIMEOUT)
 
216
    print "Forcibly shutting down the test suite"
 
217
 
 
218
    # This guarantees the process' group will die.  In rare cases
 
219
    # a child process may survive this if they are in a different
 
220
    # process group and they ignore the signals we send their parent.
 
221
    nice_killpg(process)
 
222
 
 
223
    # Drain the subprocess's stdout and stderr.
 
224
    print "The dying processes left behind the following output:"
 
225
    print "--------------- BEGIN OUTPUT ---------------"
 
226
    sys.stdout.write(process.stdout.read())
 
227
    print
 
228
    print "---------------- END OUTPUT ----------------"
 
229
 
 
230
 
236
231
def nice_killpg(process):
237
232
    """Kill a Unix process group using increasingly harmful signals."""
238
233
    pgid = os.getpgid(process.pid)