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

Unified Diff: slave/skia_slave_scripts/utils/shell_utils.py

Issue 344183004: Use new common utils where possible. (Closed) Base URL: https://skia.googlesource.com/buildbot.git@master
Patch Set: rebase Created 6 years, 5 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « slave/skia_slave_scripts/utils/misc.py ('k') | slave/skia_slave_scripts/utils/ssh_utils.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: slave/skia_slave_scripts/utils/shell_utils.py
diff --git a/slave/skia_slave_scripts/utils/shell_utils.py b/slave/skia_slave_scripts/utils/shell_utils.py
deleted file mode 100644
index 7f66c73c28af0eea6eafcc84ef7b164112716fb3..0000000000000000000000000000000000000000
--- a/slave/skia_slave_scripts/utils/shell_utils.py
+++ /dev/null
@@ -1,236 +0,0 @@
-#!/usr/bin/env python
-# 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.
-
-""" This module contains tools for running commands in a shell. """
-
-import datetime
-import os
-import Queue
-import select
-import subprocess
-import sys
-import threading
-import time
-
-if 'nt' in os.name:
- import ctypes
-
-
-DEFAULT_SECS_BETWEEN_ATTEMPTS = 10
-POLL_MILLIS = 250
-
-
-class CommandFailedException(Exception):
- """Exception which gets raised when a command fails."""
-
- def __init__(self, output, *args):
- """Initialize the CommandFailedException.
-
- Args:
- output: string; output from the command.
- """
- Exception.__init__(self, *args)
- self._output = output
-
- @property
- def output(self):
- """Output from the command."""
- return self._output
-
-
-class TimeoutException(CommandFailedException):
- """CommandFailedException which gets raised when a subprocess exceeds its
- timeout. """
- pass
-
-
-def run_async(cmd, echo=True, shell=False):
- """ Run 'cmd' in a subprocess, returning a Popen class instance referring to
- that process. (Non-blocking) """
- if echo:
- print cmd
- if 'nt' in os.name:
- # Windows has a bad habit of opening a dialog when a console program
- # crashes, rather than just letting it crash. Therefore, when a program
- # crashes on Windows, we don't find out until the build step times out.
- # This code prevents the dialog from appearing, so that we find out
- # immediately and don't waste time waiting around.
- SEM_NOGPFAULTERRORBOX = 0x0002
- ctypes.windll.kernel32.SetErrorMode(SEM_NOGPFAULTERRORBOX)
- flags = 0x8000000 # CREATE_NO_WINDOW
- else:
- flags = 0
- return subprocess.Popen(cmd, shell=shell, stderr=subprocess.STDOUT,
- stdout=subprocess.PIPE, creationflags=flags,
- bufsize=1)
-
-
-class EnqueueThread(threading.Thread):
- """ Reads and enqueues lines from a file. """
- def __init__(self, file_obj, queue):
- threading.Thread.__init__(self)
- self._file = file_obj
- self._queue = queue
- self._stopped = False
-
- def run(self):
- if sys.platform.startswith('linux'):
- # Use a polling object to avoid the blocking call to readline().
- poll = select.poll()
- poll.register(self._file, select.POLLIN)
- while not self._stopped:
- has_output = poll.poll(POLL_MILLIS)
- if has_output:
- line = self._file.readline()
- if line == '':
- self._stopped = True
- self._queue.put(line)
- else:
- # Only Unix supports polling objects, so just read from the file,
- # Python-style.
- for line in iter(self._file.readline, ''):
- self._queue.put(line)
- if self._stopped:
- break
-
- def stop(self):
- self._stopped = True
-
-
-def log_process_in_real_time(proc, echo=True, timeout=None, log_file=None,
- halt_on_output=None, print_timestamps=True):
- """ Log the output of proc in real time until it completes. Return a tuple
- containing the exit code of proc and the contents of stdout.
-
- proc: an instance of Popen referring to a running subprocess.
- echo: boolean indicating whether to print the output received from proc.stdout
- timeout: number of seconds allotted for the process to run. Raises a
- TimeoutException if the run time exceeds the timeout.
- log_file: an open file for writing output
- halt_on_output: string; kill the process and return if this string is found
- in the output stream from the process.
- print_timestamps: boolean indicating whether a formatted timestamp should be
- prepended to each line of output.
- """
- stdout_queue = Queue.Queue()
- log_thread = EnqueueThread(proc.stdout, stdout_queue)
- log_thread.start()
- try:
- all_output = []
- t_0 = time.time()
- while True:
- code = proc.poll()
- try:
- output = stdout_queue.get_nowait()
- all_output.append(output)
- if output and print_timestamps:
- timestamp = datetime.datetime.now().strftime('%H:%M:%S.%f')
- output = ''.join(['[%s] %s\n' % (timestamp, line)
- for line in output.splitlines()])
- if echo:
- sys.stdout.write(output)
- sys.stdout.flush()
- if log_file:
- log_file.write(output)
- log_file.flush()
- if halt_on_output and halt_on_output in output:
- proc.terminate()
- break
- except Queue.Empty:
- if code != None: # proc has finished running
- break
- time.sleep(0.5)
- if timeout and time.time() - t_0 > timeout:
- proc.terminate()
- raise TimeoutException(
- ''.join(all_output),
- 'Subprocess exceeded timeout of %ds' % timeout)
- finally:
- log_thread.stop()
- log_thread.join()
- return (code, ''.join(all_output))
-
-
-def log_process_after_completion(proc, echo=True, timeout=None, log_file=None):
- """ Wait for proc to complete and return a tuple containing the exit code of
- proc and the contents of stdout. Unlike log_process_in_real_time, does not
- attempt to read stdout from proc in real time.
-
- proc: an instance of Popen referring to a running subprocess.
- echo: boolean indicating whether to print the output received from proc.stdout
- timeout: number of seconds allotted for the process to run. Raises a
- TimeoutException if the run time exceeds the timeout.
- log_file: an open file for writing outout
- """
- t_0 = time.time()
- code = None
- while code is None:
- if timeout and time.time() - t_0 > timeout:
- raise TimeoutException(
- proc.communicate()[0],
- 'Subprocess exceeded timeout of %ds' % timeout)
- time.sleep(0.5)
- code = proc.poll()
- output = proc.communicate()[0]
- if echo:
- print output
- if log_file:
- log_file.write(output)
- log_file.flush()
- return (code, output)
-
-
-def run(cmd, echo=True, shell=False, timeout=None, print_timestamps=True,
- log_in_real_time=True):
- """ Run 'cmd' in a shell and return the combined contents of stdout and
- stderr (Blocking). Throws an exception if the command exits non-zero.
-
- cmd: list of strings (or single string, iff shell==True) indicating the
- command to run
- echo: boolean indicating whether we should print the command and log output
- shell: boolean indicating whether we are using advanced shell features. Use
- only when absolutely necessary, since this allows a lot more freedom which
- could be exploited by malicious code. See the warning here:
- http://docs.python.org/library/subprocess.html#popen-constructor
- timeout: optional, integer indicating the maximum elapsed time in seconds
- print_timestamps: boolean indicating whether a formatted timestamp should be
- prepended to each line of output. Unused if echo or log_in_real_time is
- False.
- log_in_real_time: boolean indicating whether to read stdout from the
- subprocess in real time instead of when the process finishes. If echo is
- False, we never log in real time, even if log_in_real_time is True.
- """
- proc = run_async(cmd, echo=echo, shell=shell)
- # If we're not printing the output, we don't care if the output shows up in
- # real time, so don't bother.
- if log_in_real_time and echo:
- (returncode, output) = log_process_in_real_time(proc, echo=echo,
- timeout=timeout, print_timestamps=print_timestamps)
- else:
- (returncode, output) = log_process_after_completion(proc, echo=echo,
- timeout=timeout)
- if returncode != 0:
- raise CommandFailedException(
- output,
- 'Command failed with code %d: %s' % (returncode, cmd))
- return output
-
-
-def run_retry(cmd, echo=True, shell=False, attempts=1,
- secs_between_attempts=DEFAULT_SECS_BETWEEN_ATTEMPTS,
- timeout=None, print_timestamps=True):
- """ Wrapper for run() which makes multiple attempts until either the command
- succeeds or the maximum number of attempts is reached. """
- attempt = 1
- while True:
- try:
- return run(cmd, echo=echo, shell=shell, timeout=timeout,
- print_timestamps=print_timestamps)
- except CommandFailedException:
- if attempt >= attempts:
- raise
- print 'Command failed. Retrying in %d seconds...' % secs_between_attempts
- time.sleep(secs_between_attempts)
- attempt += 1
« no previous file with comments | « slave/skia_slave_scripts/utils/misc.py ('k') | slave/skia_slave_scripts/utils/ssh_utils.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698