testing.py 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. """
  2. Helper for testing.
  3. """
  4. import sys
  5. import warnings
  6. import os.path
  7. import re
  8. import subprocess
  9. import threading
  10. import pytest
  11. import _pytest
  12. raises = pytest.raises
  13. warns = pytest.warns
  14. SkipTest = _pytest.runner.Skipped
  15. skipif = pytest.mark.skipif
  16. fixture = pytest.fixture
  17. parametrize = pytest.mark.parametrize
  18. timeout = pytest.mark.timeout
  19. xfail = pytest.mark.xfail
  20. param = pytest.param
  21. def warnings_to_stdout():
  22. """ Redirect all warnings to stdout.
  23. """
  24. showwarning_orig = warnings.showwarning
  25. def showwarning(msg, cat, fname, lno, file=None, line=0):
  26. showwarning_orig(msg, cat, os.path.basename(fname), line, sys.stdout)
  27. warnings.showwarning = showwarning
  28. # warnings.simplefilter('always')
  29. def check_subprocess_call(cmd, timeout=5, stdout_regex=None,
  30. stderr_regex=None):
  31. """Runs a command in a subprocess with timeout in seconds.
  32. Also checks returncode is zero, stdout if stdout_regex is set, and
  33. stderr if stderr_regex is set.
  34. """
  35. proc = subprocess.Popen(cmd, stdout=subprocess.PIPE,
  36. stderr=subprocess.PIPE)
  37. def kill_process():
  38. warnings.warn("Timeout running {}".format(cmd))
  39. proc.kill()
  40. timer = threading.Timer(timeout, kill_process)
  41. try:
  42. timer.start()
  43. stdout, stderr = proc.communicate()
  44. stdout, stderr = stdout.decode(), stderr.decode()
  45. if proc.returncode != 0:
  46. message = (
  47. 'Non-zero return code: {}.\nStdout:\n{}\n'
  48. 'Stderr:\n{}').format(
  49. proc.returncode, stdout, stderr)
  50. raise ValueError(message)
  51. if (stdout_regex is not None and
  52. not re.search(stdout_regex, stdout)):
  53. raise ValueError(
  54. "Unexpected stdout: {!r} does not match:\n{!r}".format(
  55. stdout_regex, stdout))
  56. if (stderr_regex is not None and
  57. not re.search(stderr_regex, stderr)):
  58. raise ValueError(
  59. "Unexpected stderr: {!r} does not match:\n{!r}".format(
  60. stderr_regex, stderr))
  61. finally:
  62. timer.cancel()