tests: Check and/or suppress stderr of subprocesses, reduce shell=True uses

pull/949/head
Alex Willmer 2 years ago
parent 216e7c9150
commit c32577295a

@ -2,13 +2,15 @@ from __future__ import absolute_import
from __future__ import print_function from __future__ import print_function
import atexit import atexit
import errno
import os import os
import shlex import shlex
import shutil import shutil
import subprocess
import sys import sys
import tempfile import tempfile
import subprocess32 as subprocess
try: try:
import urlparse import urlparse
except ImportError: except ImportError:
@ -30,40 +32,30 @@ def print(*args, **kwargs):
file.flush() file.flush()
# def _have_cmd(args):
# check_output() monkeypatch cutpasted from testlib.py try:
# subprocess.run(
args, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL,
def subprocess__check_output(*popenargs, **kwargs): )
# Missing from 2.6. except OSError as exc:
process = subprocess.Popen(stdout=subprocess.PIPE, *popenargs, **kwargs) if exc.errno == errno.ENOENT:
output, _ = process.communicate() return False
retcode = process.poll() raise
if retcode: except subprocess.CallProcessError:
cmd = kwargs.get("args") return False
if cmd is None: return True
cmd = popenargs[0]
raise subprocess.CalledProcessError(retcode, cmd)
return output
if not hasattr(subprocess, 'check_output'):
subprocess.check_output = subprocess__check_output
# ------------------
def have_apt(): def have_apt():
proc = subprocess.Popen('apt --help >/dev/null 2>/dev/null', shell=True) return _have_cmd(['apt', '--help'])
return proc.wait() == 0
def have_brew(): def have_brew():
proc = subprocess.Popen('brew help >/dev/null 2>/dev/null', shell=True) return _have_cmd(['brew', 'help'])
return proc.wait() == 0
def have_docker(): def have_docker():
proc = subprocess.Popen('docker info >/dev/null 2>/dev/null', shell=True) return _have_cmd(['docker', 'info'])
return proc.wait() == 0
def _argv(s, *args): def _argv(s, *args):
@ -315,7 +307,7 @@ def get_interesting_procs(container_name=None):
args = ['docker', 'exec', container_name] + args args = ['docker', 'exec', container_name] + args
out = [] out = []
for line in subprocess__check_output(args).decode().splitlines(): for line in subprocess.check_output(args).decode().splitlines():
ppid, pid, comm, rest = line.split(None, 3) ppid, pid, comm, rest = line.split(None, 3)
if ( if (
( (

@ -1,5 +1,6 @@
import os import os
import random import random
import subprocess
import sys import sys
import unittest import unittest
@ -26,15 +27,28 @@ import plain_old_module
def _find_ssl_linux(): def _find_ssl_linux():
s = testlib.subprocess__check_output(['ldd', _ssl.__file__]) proc = subprocess.Popen(
for line in s.decode().splitlines(): ['ldd', _ssl.__file__],
stdout=subprocess.PIPE, stderr=subprocess.PIPE,
)
b_stdout, b_stderr = proc.communicate()
assert proc.returncode == 0
assert b_stderr.decode() == ''
for line in b_stdout.decode().splitlines():
bits = line.split() bits = line.split()
if bits[0].startswith('libssl'): if bits[0].startswith('libssl'):
return bits[2] return bits[2]
def _find_ssl_darwin(): def _find_ssl_darwin():
s = testlib.subprocess__check_output(['otool', '-l', _ssl.__file__]) proc = subprocess.Popen(
for line in s.decode().splitlines(): ['otool', '-l', _ssl.__file__],
stdout=subprocess.PIPE, stderr=subprocess.PIPE,
)
b_stdout, b_stderr = proc.communicate()
assert proc.returncode == 0
assert b_stderr.decode() == ''
for line in b_stdout.decode().splitlines():
bits = line.split() bits = line.split()
if bits[0] == 'name' and 'libssl' in bits[1]: if bits[0] == 'name' and 'libssl' in bits[1]:
return bits[1] return bits[1]

@ -8,6 +8,7 @@ cffi==1.14.3 # Random pin to try and fix pyparser==2.18 not having effect
pycparser==2.18 # Last version supporting 2.6. pycparser==2.18 # Last version supporting 2.6.
pytest-catchlog==1.2.2 pytest-catchlog==1.2.2
pytest==3.1.2 pytest==3.1.2
subprocess32==3.5.4
timeoutcontext==1.2.0 timeoutcontext==1.2.0
# Fix InsecurePlatformWarning while creating py26 tox environment # Fix InsecurePlatformWarning while creating py26 tox environment
# https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings # https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings

@ -93,8 +93,10 @@ class GoodModulesTest(testlib.RouterMixin, testlib.TestCase):
# Ensure a program composed of a single script can be imported # Ensure a program composed of a single script can be imported
# successfully. # successfully.
args = [sys.executable, testlib.data_path('self_contained_program.py')] args = [sys.executable, testlib.data_path('self_contained_program.py')]
output = testlib.subprocess__check_output(args).decode() proc = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
self.assertEqual(output, "['__main__', 50]\n") b_stdout, _ = proc.communicate()
self.assertEqual(proc.returncode, 0)
self.assertEqual(b_stdout.decode(), "['__main__', 50]\n")
class BrokenModulesTest(testlib.TestCase): class BrokenModulesTest(testlib.TestCase):

@ -3,9 +3,7 @@ import logging
import os import os
import random import random
import re import re
import signal
import socket import socket
import subprocess
import sys import sys
import threading import threading
import time import time
@ -13,6 +11,7 @@ import traceback
import unittest import unittest
import psutil import psutil
import subprocess32 as subprocess
import mitogen.core import mitogen.core
import mitogen.fork import mitogen.fork
@ -71,30 +70,6 @@ def data_path(suffix):
return path return path
def subprocess__check_output(*popenargs, **kwargs):
# Missing from 2.6.
process = subprocess.Popen(stdout=subprocess.PIPE, *popenargs, **kwargs)
output, _ = process.communicate()
retcode = process.poll()
if retcode:
cmd = kwargs.get("args")
if cmd is None:
cmd = popenargs[0]
raise subprocess.CalledProcessError(retcode, cmd)
return output
def Popen__terminate(proc):
os.kill(proc.pid, signal.SIGTERM)
if hasattr(subprocess, 'check_output'):
subprocess__check_output = subprocess.check_output
if hasattr(subprocess.Popen, 'terminate'):
Popen__terminate = subprocess.Popen.terminate
def threading__thread_is_alive(thread): def threading__thread_is_alive(thread):
"""Return whether the thread is alive (Python version compatibility shim). """Return whether the thread is alive (Python version compatibility shim).
@ -457,7 +432,7 @@ def get_docker_host():
class DockerizedSshDaemon(object): class DockerizedSshDaemon(object):
def _get_container_port(self): def _get_container_port(self):
s = subprocess__check_output(['docker', 'port', self.container_name]) s = subprocess.check_output(['docker', 'port', self.container_name])
for line in s.decode().splitlines(): for line in s.decode().splitlines():
m = self.PORT_RE.match(line) m = self.PORT_RE.match(line)
if not m: if not m:
@ -472,7 +447,7 @@ class DockerizedSshDaemon(object):
def start_container(self): def start_container(self):
try: try:
subprocess__check_output(['docker', '--version']) subprocess.check_output(['docker', '--version'])
except Exception: except Exception:
raise unittest.SkipTest('Docker binary is unavailable') raise unittest.SkipTest('Docker binary is unavailable')
@ -486,7 +461,7 @@ class DockerizedSshDaemon(object):
'--name', self.container_name, '--name', self.container_name,
self.image, self.image,
] ]
subprocess__check_output(args) subprocess.check_output(args)
self._get_container_port() self._get_container_port()
def __init__(self, mitogen_test_distro=os.environ.get('MITOGEN_TEST_DISTRO', 'debian9')): def __init__(self, mitogen_test_distro=os.environ.get('MITOGEN_TEST_DISTRO', 'debian9')):
@ -518,7 +493,7 @@ class DockerizedSshDaemon(object):
def check_processes(self): def check_processes(self):
args = ['docker', 'exec', self.container_name, 'ps', '-o', 'comm='] args = ['docker', 'exec', self.container_name, 'ps', '-o', 'comm=']
counts = {} counts = {}
for comm in subprocess__check_output(args).decode().splitlines(): for comm in subprocess.check_output(args).decode().splitlines():
comm = comm.strip() comm = comm.strip()
counts[comm] = counts.get(comm, 0) + 1 counts[comm] = counts.get(comm, 0) + 1
@ -533,7 +508,7 @@ class DockerizedSshDaemon(object):
def close(self): def close(self):
args = ['docker', 'rm', '-f', self.container_name] args = ['docker', 'rm', '-f', self.container_name]
subprocess__check_output(args) subprocess.check_output(args)
class BrokerMixin(object): class BrokerMixin(object):

@ -130,7 +130,8 @@ class ClientTest(testlib.TestCase):
def test_simple(self): def test_simple(self):
path = mitogen.unix.make_socket_path() path = mitogen.unix.make_socket_path()
proc = subprocess.Popen( proc = subprocess.Popen(
[sys.executable, __file__, 'ClientTest_server', path] [sys.executable, __file__, 'ClientTest_server', path],
stdout=subprocess.PIPE, stderr=subprocess.PIPE,
) )
try: try:
self._test_simple_client(path) self._test_simple_client(path)
@ -139,7 +140,9 @@ class ClientTest(testlib.TestCase):
mitogen.context_id = 0 mitogen.context_id = 0
mitogen.parent_id = None mitogen.parent_id = None
mitogen.parent_ids = [] mitogen.parent_ids = []
proc.wait() b_stdout, _ = proc.communicate()
self.assertEqual(proc.returncode, 0)
self.assertEqual(b_stdout.decode(), '')
if __name__ == '__main__': if __name__ == '__main__':

Loading…
Cancel
Save