Don't buffer stdout/stderr in command_wrapper.py Otherwise, commands that take a long time to complete, but produce some status output, such as gsutil cp, will cause the buildbot's timeout to trigger. BUG=none TEST=manually, works on linux :) Review URL: http://codereview.chromium.org/10085001 git-svn-id: svn://svn.chromium.org/chrome/trunk/tools/command_wrapper/bin@134087 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/command_wrapper.py b/command_wrapper.py index 249db31..91f9b6e 100755 --- a/command_wrapper.py +++ b/command_wrapper.py
@@ -1,6 +1,6 @@ #!/usr/bin/python # -# Copyright (c) 2011 The Chromium Authors. All rights reserved. +# Copyright (c) 2012 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. @@ -25,6 +25,7 @@ LOG_TIMEOUT = 10 +ON_POSIX = 'posix' in sys.builtin_module_names def LogCommand(options, command_id, @@ -81,6 +82,15 @@ return wrapper['result'] +def Tee(fd, string_buffer, forward_fd): + """Read characters from fd and both append them to a buffer and write them to + forward_fd.""" + for char in iter(lambda: fd.read(1), ''): + string_buffer += char + forward_fd.write(char) + fd.close() + + def main(argv): parser = optparse.OptionParser() parser.add_option('-r', '--retries', dest='retries', @@ -113,10 +123,24 @@ tm = time.time() p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - (p_stdout, p_stderr) = p.communicate() - sys.stdout.write(p_stdout) - sys.stderr.write(p_stderr) + stderr=subprocess.PIPE, + close_fds=ON_POSIX) + p_stdout = '' + t_stdout = threading.Thread(target=Tee, + args=(p.stdout, p_stdout, sys.stdout)) + t_stdout.start() + + p_stderr = '' + t_stderr = threading.Thread(target=Tee, + args=(p.stderr, p_stderr, sys.stderr)) + t_stderr.start() + + p.wait() + + t_stdout.join() + t_stderr.join() + + runtime = time.time() - tm accept = RunWithTimeout(LOG_TIMEOUT, LogCommand, options, command_id, r, cmd,