Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(11)

Side by Side Diff: tools/purify/common.py

Issue 20165: Periodically log while waiting for subprocess to complete so that the bot doe... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 11 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/bin/env python 1 #!/bin/env python
2 # Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 2 # Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 5
6 # common.py 6 # common.py
7 7
8 """ Common code used by purify_test.py and quantify_test.py in order to automate 8 """ Common code used by purify_test.py and quantify_test.py in order to automate
9 running of Rational Purify and Quantify in a consistent manner. 9 running of Rational Purify and Quantify in a consistent manner.
10 """ 10 """
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
51 51
52 def _print_line(line, flush=True): 52 def _print_line(line, flush=True):
53 # Printing to a text file (including stdout) on Windows always winds up 53 # Printing to a text file (including stdout) on Windows always winds up
54 # using \r\n automatically. On buildbot, this winds up being read by a master 54 # using \r\n automatically. On buildbot, this winds up being read by a master
55 # running on Linux, so we manually convert crlf to '\n' 55 # running on Linux, so we manually convert crlf to '\n'
56 print line.rstrip() + '\n', 56 print line.rstrip() + '\n',
57 if flush: 57 if flush:
58 sys.stdout.flush() 58 sys.stdout.flush()
59 59
60 def RunSubprocess(proc, timeout=0, detach=False): 60 def RunSubprocess(proc, timeout=0, detach=False):
61 """ Runs a subprocess, polling every .2 seconds until it finishes or until 61 """ Runs a subprocess, until it finishes or |timeout| is exceeded and the
62 timeout is reached. Then kills the process with taskkill. A timeout <= 0 62 process is killed with taskkill. A |timeout| <= 0 means no timeout.
63 means no timeout.
64 63
65 Args: 64 Args:
66 proc: list of process components (exe + args) 65 proc: list of process components (exe + args)
67 timeout: how long to wait before killing, <= 0 means wait forever 66 timeout: how long to wait before killing, <= 0 means wait forever
68 detach: Whether to pass the DETACHED_PROCESS argument to CreateProcess 67 detach: Whether to pass the DETACHED_PROCESS argument to CreateProcess
69 on Windows. This is used by Purify subprocesses on buildbot which 68 on Windows. This is used by Purify subprocesses on buildbot which
70 seem to get confused by the parent console that buildbot sets up. 69 seem to get confused by the parent console that buildbot sets up.
71 """ 70 """
72 logging.info("running %s" % (" ".join(proc))) 71 logging.info("running %s" % (" ".join(proc)))
73 if detach: 72 if detach:
74 # see MSDN docs for "Process Creation Flags" 73 # see MSDN docs for "Process Creation Flags"
75 DETACHED_PROCESS = 0x8 74 DETACHED_PROCESS = 0x8
76 p = subprocess.Popen(proc, creationflags=DETACHED_PROCESS) 75 p = subprocess.Popen(proc, creationflags=DETACHED_PROCESS)
77 else: 76 else:
78 # For non-detached processes, manually read and print out stdout and stderr. 77 # For non-detached processes, manually read and print out stdout and stderr.
79 # By default, the subprocess is supposed to inherit these from its parent, 78 # By default, the subprocess is supposed to inherit these from its parent,
80 # however when run under buildbot, it seems unable to read data from a 79 # however when run under buildbot, it seems unable to read data from a
81 # grandchild process, so we have to read the child and print the data as if 80 # grandchild process, so we have to read the child and print the data as if
82 # it came from us for buildbot to read it. We're not sure why this is 81 # it came from us for buildbot to read it. We're not sure why this is
83 # necessary. 82 # necessary.
84 # TODO(erikkay): should we buffer stderr and stdout separately? 83 # TODO(erikkay): should we buffer stderr and stdout separately?
85 p = subprocess.Popen(proc, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) 84 p = subprocess.Popen(proc, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
86 if timeout <= 0: 85
87 while p.poll() is None: 86 # How long to wait (in seconds) before printing progress log messages.
88 if not detach: 87 progress_delay = 300
88 progress_delay_time = time.time() + progress_delay
89 did_timeout = False
90 if timeout > 0:
91 wait_until = time.time() + timeout
92 while p.poll() is None and not did_timeout:
93 if not detach:
94 line = p.stdout.readline()
95 while line:
96 _print_line(line)
89 line = p.stdout.readline() 97 line = p.stdout.readline()
90 while line: 98 else:
91 _print_line(line) 99 # When we detach, blocking on reading stdout doesn't work, so we sleep
92 line = p.stdout.readline() 100 # a short time and poll.
93 time.sleep(0.2) 101 time.sleep(0.5)
94 else: 102 if time.time() >= progress_delay_time:
95 wait_until = time.time() + timeout 103 # Force output on a periodic basis to avoid getting killed off by the
96 while p.poll() is None and time.time() < wait_until: 104 # buildbot.
97 if not detach: 105 # TODO(erikkay): I'd prefer a less obtrusive 'print ".",' with a flush
98 line = p.stdout.readline() 106 # but because of how we're doing subprocesses, this doesn't appear to
99 while line: 107 # work reliably.
100 _print_line(line) 108 logging.info("%s still running..." % os.path.basename(proc[0]))
101 line = p.stdout.readline() 109 progress_delay_time = time.time() + progress_delay
102 time.sleep(0.2) 110 if timeout > 0:
103 if not detach: 111 did_timeout = time.time() > wait_until
112
113 if did_timeout:
114 subprocess.call(["taskkill", "/T", "/F", "/PID", str(p.pid)])
115 logging.error("KILLED %d" % p.pid)
116 # Give the process a chance to actually die before continuing
117 # so that cleanup can happen safely.
118 time.sleep(1.0)
119 logging.error("TIMEOUT waiting for %s" % proc[0])
120 raise TimeoutError(proc[0])
121 elif not detach:
104 for line in p.stdout.readlines(): 122 for line in p.stdout.readlines():
105 _print_line(line, False) 123 _print_line(line, False)
106 p.stdout.flush() 124 p.stdout.flush()
125
107 result = p.poll() 126 result = p.poll()
108 if result is None:
109 subprocess.call(["taskkill", "/T", "/F", "/PID", str(p.pid)])
110 logging.error("KILLED %d" % p.pid)
111 # give the process a chance to actually die before continuing
112 # so that cleanup can happen safely
113 time.sleep(1.0)
114 logging.error("TIMEOUT waiting for %s" % proc[0])
115 raise TimeoutError(proc[0])
116 if result: 127 if result:
117 logging.error("%s exited with non-zero result code %d" % (proc[0], result)) 128 logging.error("%s exited with non-zero result code %d" % (proc[0], result))
118 return result 129 return result
119 130
120 131
121 def FixPath(path): 132 def FixPath(path):
122 """We pass computed paths to Rational as arguments, so these paths must be 133 """We pass computed paths to Rational as arguments, so these paths must be
123 valid windows paths. When running in cygwin's python, computed paths 134 valid windows paths. When running in cygwin's python, computed paths
124 wind up looking like /cygdrive/c/..., so we need to call out to cygpath 135 wind up looking like /cygdrive/c/..., so we need to call out to cygpath
125 to fix them up. 136 to fix them up.
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
307 file = os.path.join(self._cache_dir, cfile); 318 file = os.path.join(self._cache_dir, cfile);
308 if os.path.isfile(file): 319 if os.path.isfile(file):
309 try: 320 try:
310 os.remove(file) 321 os.remove(file)
311 except: 322 except:
312 logging.warning("unable to delete file %s: %s" % (file, 323 logging.warning("unable to delete file %s: %s" % (file,
313 sys.exc_info()[0])) 324 sys.exc_info()[0]))
314 325
315 326
316 327
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698