OLD | NEW |
---|---|
1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 | 4 |
5 import logging | 5 import logging |
6 import platform | 6 import platform |
7 import os | 7 import os |
8 import signal | 8 import signal |
9 import subprocess | 9 import subprocess |
10 import sys | 10 import sys |
(...skipping 17 matching lines...) Expand all Loading... | |
28 def RunSubprocess(proc, timeout=0): | 28 def RunSubprocess(proc, timeout=0): |
29 """ Runs a subprocess, until it finishes or |timeout| is exceeded and the | 29 """ Runs a subprocess, until it finishes or |timeout| is exceeded and the |
30 process is killed with taskkill. A |timeout| <= 0 means no timeout. | 30 process is killed with taskkill. A |timeout| <= 0 means no timeout. |
31 | 31 |
32 Args: | 32 Args: |
33 proc: list of process components (exe + args) | 33 proc: list of process components (exe + args) |
34 timeout: how long to wait before killing, <= 0 means wait forever | 34 timeout: how long to wait before killing, <= 0 means wait forever |
35 """ | 35 """ |
36 | 36 |
37 logging.info("running %s, timeout %d sec" % (" ".join(proc), timeout)) | 37 logging.info("running %s, timeout %d sec" % (" ".join(proc), timeout)) |
38 sys.stdout.flush() | |
39 sys.stderr.flush() | |
40 | |
38 # Manually read and print out stdout and stderr. | 41 # Manually read and print out stdout and stderr. |
39 # By default, the subprocess is supposed to inherit these from its parent, | 42 # By default, the subprocess is supposed to inherit these from its parent, |
40 # however when run under buildbot, it seems unable to read data from a | 43 # however when run under buildbot, it seems unable to read data from a |
41 # grandchild process, so we have to read the child and print the data as if | 44 # grandchild process, so we have to read the child and print the data as if |
42 # it came from us for buildbot to read it. We're not sure why this is | 45 # it came from us for buildbot to read it. We're not sure why this is |
43 # necessary. | 46 # necessary. |
44 # TODO(erikkay): should we buffer stderr and stdout separately? | 47 # TODO(erikkay): should we buffer stderr and stdout separately? |
45 p = subprocess.Popen(proc, universal_newlines=True, | 48 p = subprocess.Popen(proc, universal_newlines=True, |
46 bufsize=1, # line buffered | 49 bufsize=0, # unbuffered |
47 stdout=subprocess.PIPE, stderr=subprocess.STDOUT) | 50 stdout=subprocess.PIPE, stderr=subprocess.STDOUT) |
48 | 51 |
49 logging.info("started subprocess") | 52 logging.info("started subprocess") |
50 | 53 |
51 # How long to wait (in seconds) before printing progress log messages. | |
52 progress_delay = 300 | |
53 progress_delay_time = time.time() + progress_delay | |
54 did_timeout = False | 54 did_timeout = False |
55 if timeout > 0: | 55 if timeout > 0: |
56 wait_until = time.time() + timeout | 56 wait_until = time.time() + timeout |
57 while p.poll() is None and not did_timeout: | 57 while p.poll() is None and not did_timeout: |
58 for line in p.stdout: | 58 line = p.stdout.readline() |
59 while line and not did_timeout: | |
Nico
2013/07/15 17:16:35
Since this makes a difference and is very non-obvi
Timur Iskhodzhanov
2013/07/15 18:18:43
That was done in r202841 when I actually became su
| |
59 sys.stdout.write(line) | 60 sys.stdout.write(line) |
60 sys.stdout.flush() | 61 sys.stdout.flush() |
62 line = p.stdout.readline() | |
61 if timeout > 0: | 63 if timeout > 0: |
62 did_timeout = time.time() > wait_until | 64 did_timeout = time.time() > wait_until |
63 if did_timeout: | |
64 break | |
65 | 65 |
66 if did_timeout: | 66 if did_timeout: |
67 logging.info("process timed out") | 67 logging.info("process timed out") |
68 else: | 68 else: |
69 logging.info("process ended, did not time out") | 69 logging.info("process ended, did not time out") |
70 | 70 |
71 if did_timeout: | 71 if did_timeout: |
72 if IsWindows(): | 72 if IsWindows(): |
73 subprocess.call(["taskkill", "/T", "/F", "/PID", str(p.pid)]) | 73 subprocess.call(["taskkill", "/T", "/F", "/PID", str(p.pid)]) |
74 else: | 74 else: |
75 # Does this kill all children, too? | 75 # Does this kill all children, too? |
76 os.kill(p.pid, signal.SIGINT) | 76 os.kill(p.pid, signal.SIGINT) |
77 logging.error("KILLED %d" % p.pid) | 77 logging.error("KILLED %d" % p.pid) |
78 # Give the process a chance to actually die before continuing | 78 # Give the process a chance to actually die before continuing |
79 # so that cleanup can happen safely. | 79 # so that cleanup can happen safely. |
80 time.sleep(1.0) | 80 time.sleep(1.0) |
81 logging.error("TIMEOUT waiting for %s" % proc[0]) | 81 logging.error("TIMEOUT waiting for %s" % proc[0]) |
82 raise TimeoutError(proc[0]) | 82 raise TimeoutError(proc[0]) |
83 else: | 83 else: |
84 for line in p.stdout: | 84 for line in p.stdout: |
85 sys.stdout.write(line) | 85 sys.stdout.write(line) |
86 if not IsMac(): # stdout flush fails on Mac | 86 if not IsMac(): # stdout flush fails on Mac |
87 logging.info("flushing stdout") | 87 logging.info("flushing stdout") |
88 p.stdout.flush() | 88 sys.stdout.flush() |
Reid Kleckner
2013/05/28 13:00:27
Aha. :) Is that it?
Reid Kleckner
2013/05/28 13:01:34
Er, no, it shouldn't be.
Timur Iskhodzhanov
2013/05/28 13:01:57
Nope, I don't think so - the hangs happen when pyt
| |
89 | 89 |
90 logging.info("collecting result code") | 90 logging.info("collecting result code") |
91 result = p.poll() | 91 result = p.poll() |
92 if result: | 92 if result: |
93 logging.error("%s exited with non-zero result code %d" % (proc[0], result)) | 93 logging.error("%s exited with non-zero result code %d" % (proc[0], result)) |
94 return result | 94 return result |
95 | 95 |
96 | 96 |
97 def IsLinux(): | 97 def IsLinux(): |
98 return sys.platform.startswith('linux') | 98 return sys.platform.startswith('linux') |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
241 return False | 241 return False |
242 | 242 |
243 print "-----------------------------------------------------" | 243 print "-----------------------------------------------------" |
244 print "Suppressions used:" | 244 print "Suppressions used:" |
245 print " count name" | 245 print " count name" |
246 for (name, count) in sorted(suppcounts.items(), key=lambda (k,v): (v,k)): | 246 for (name, count) in sorted(suppcounts.items(), key=lambda (k,v): (v,k)): |
247 print "%7d %s" % (count, name) | 247 print "%7d %s" % (count, name) |
248 print "-----------------------------------------------------" | 248 print "-----------------------------------------------------" |
249 sys.stdout.flush() | 249 sys.stdout.flush() |
250 return True | 250 return True |
OLD | NEW |