summaryrefslogtreecommitdiff
path: root/buildscripts/util
diff options
context:
space:
mode:
authorJonathan Abrahams <jonathan@mongodb.com>2018-06-13 15:16:50 -0400
committerJonathan Abrahams <jonathan@mongodb.com>2018-06-15 11:40:58 -0400
commit82b62cf1e513657a0c35d757cf37eab0231ebc9b (patch)
treef40ee3c6dfcd09c550355e400941ddf75692ca21 /buildscripts/util
parent76398baf84773e0e5766eb2e9d53d290933806fd (diff)
downloadmongo-82b62cf1e513657a0c35d757cf37eab0231ebc9b.tar.gz
SERVER-34711 Enable burn_in_tests to understand Evergreen task selectors
Diffstat (limited to 'buildscripts/util')
-rw-r--r--buildscripts/util/runcommand.py68
1 files changed, 68 insertions, 0 deletions
diff --git a/buildscripts/util/runcommand.py b/buildscripts/util/runcommand.py
new file mode 100644
index 00000000000..ff9e726cc3e
--- /dev/null
+++ b/buildscripts/util/runcommand.py
@@ -0,0 +1,68 @@
+"""Utility to support running a command in a subprocess."""
+
+from __future__ import print_function
+
+import os
+import pipes
+import shlex
+import sys
+
+# The subprocess32 module is untested on Windows and thus isn't recommended for use, even when it's
+# installed. See https://github.com/google/python-subprocess32/blob/3.2.7/README.md#usage.
+if os.name == "posix" and sys.version_info[0] == 2:
+ try:
+ import subprocess32 as subprocess
+ except ImportError:
+ import warnings
+ warnings.warn(("Falling back to using the subprocess module because subprocess32 isn't"
+ " available. When using the subprocess module, a child process may"
+ " trigger an invalid free(). See SERVER-22219 for more details."),
+ RuntimeWarning)
+ import subprocess # type: ignore
+else:
+ import subprocess
+
+
+def execute_cmd(cmd):
+ """Execute specified 'cmd' and return err_code and output.
+
+ If 'cmd' is specified as a string, convert it to a list of strings.
+ """
+ if isinstance(cmd, str):
+ cmd = shlex.split(cmd)
+ proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+ output, _ = proc.communicate()
+ error_code = proc.returncode
+ return error_code, output
+
+
+class RunCommand(object):
+ """Class to abstract executing a subprocess."""
+
+ def __init__(self, string=None):
+ """Initialize the RunCommand object."""
+ self._command = string
+
+ def add(self, string):
+ """Add a string to the command."""
+ self._command = "{}{}{}".format(self._command, self._space(), string)
+
+ def add_file(self, path):
+ """Add a file path to the command."""
+ # For Windows compatability, use pipes.quote around file paths.
+ self._command = "{}{}{}".format(self._command, self._space(), pipes.quote(path))
+
+ def execute(self):
+ """Execute the command. Return (error_code, output)."""
+ return execute_cmd(self._command)
+
+ @property
+ def command(self):
+ """Get the command."""
+ return self._command
+
+ def _space(self):
+ """Return a space if the command has been started to be built."""
+ if self._command:
+ return " "
+ return ""