diff --git a/.gitignore b/.gitignore index 9a539564..09a0cb67 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,14 @@ +.coverage +.tox .venv **/.DS_Store +*.pyc +*.pyd +*.pyo MANIFEST build/ dist/ docs/_build +htmlcov/ *.egg-info +__pycache__/ diff --git a/.travis.yml b/.travis.yml index a7f2f637..815192a6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,6 +4,7 @@ notifications: email: false language: python +cache: pip python: - "2.7" @@ -12,7 +13,7 @@ install: - pip install -r dev_requirements.txt script: -- MITOGEN_LOG_LEVEL=debug PYTHONPATH=. ${TRAVIS_BUILD_DIR}/test.sh +- MITOGEN_LOG_LEVEL=debug PYTHONPATH=. ${TRAVIS_BUILD_DIR}/test services: - docker diff --git a/dev_requirements.txt b/dev_requirements.txt index 7761ff4a..59bf43de 100644 --- a/dev_requirements.txt +++ b/dev_requirements.txt @@ -1,5 +1,6 @@ -r docs/docs-requirements.txt ansible==2.3.1.0 +coverage==4.5.1 Django==1.6.11; python_version < '2.7' Django==1.11.5; python_version >= '2.7' # for module_finder_test https://github.com/docker/docker-py/archive/1.10.6.tar.gz; python_version < '2.7' @@ -9,6 +10,7 @@ pytest-catchlog==1.2.2 pytest==3.1.2 PyYAML==3.11; python_version < '2.7' PyYAML==3.12; python_version >= '2.7' +timeoutcontext==1.2.0 unittest2==1.1.0 # Fix InsecurePlatformWarning while creating py26 tox environment # https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings diff --git a/setup.cfg b/setup.cfg index 44668df3..92051682 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,3 +1,10 @@ +[coverage:run] +branch = true +source = + mitogen +omit = + mitogen/compat/* + [flake8] ignore = E402,E128,W503 exclude = mitogen/compat diff --git a/test b/test new file mode 100755 index 00000000..71ce18aa --- /dev/null +++ b/test @@ -0,0 +1,14 @@ +#/bin/sh +set -o errexit +set -o nounset +set -o pipefail + +UNIT2="$(which unit2)" + +coverage erase +coverage run "${UNIT2}" discover \ + --start-directory "tests" \ + --pattern '*_test.py' \ + "$@" +coverage html +echo coverage report is at "file://$(pwd)/htmlcov/index.html" diff --git a/test.sh b/test.sh deleted file mode 100755 index ab545104..00000000 --- a/test.sh +++ /dev/null @@ -1,63 +0,0 @@ -#!/bin/bash - -timeout() -{ - python -c ' -import subprocess -import sys -import time - -deadline = time.time() + float(sys.argv[1]) -proc = subprocess.Popen(sys.argv[2:]) -while time.time() < deadline and proc.poll() is None: - time.sleep(1.0) - -if proc.poll() is not None: - sys.exit(proc.returncode) -proc.terminate() -print -print >> sys.stderr, "Timeout! Command was:", sys.argv[2:] -print -sys.exit(1) - ' "$@" -} - -trap 'sigint' INT -sigint() -{ - echo "SIGINT received, stopping.." - exit 1 -} - -run_test() -{ - echo "Running $1.." - timeout 10 python $1 || fail=$? -} - -run_test tests/ansible_helpers_test.py -run_test tests/call_error_test.py -run_test tests/call_function_test.py -run_test tests/channel_test.py -run_test tests/fakessh_test.py -run_test tests/first_stage_test.py -run_test tests/fork_test.py -run_test tests/id_allocation_test.py -run_test tests/importer_test.py -run_test tests/latch_test.py -run_test tests/local_test.py -run_test tests/master_test.py -run_test tests/module_finder_test.py -run_test tests/nested_test.py -run_test tests/parent_test.py -run_test tests/receiver_test.py -run_test tests/responder_test.py -run_test tests/router_test.py -run_test tests/select_test.py -run_test tests/ssh_test.py -run_test tests/utils_test.py - -if [ "$fail" ]; then - echo "AT LEAST ONE TEST FAILED" >&2 - exit 1 -fi diff --git a/tests/README.md b/tests/README.md index 0ac4bcb1..41c024b5 100644 --- a/tests/README.md +++ b/tests/README.md @@ -27,4 +27,4 @@ and run the tests there. 1. Build the virtual environment ``virtualenv ../venv`` 1. Enable the virtual environment we just built ``source ../venv/bin/activate`` 1. Install Mitogen in pip editable mode ``pip install -e .`` -1. Run ``test.sh`` +1. Run ``test`` diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/call_function_test.py b/tests/call_function_test.py index d66864b4..de3f1f46 100644 --- a/tests/call_function_test.py +++ b/tests/call_function_test.py @@ -64,7 +64,10 @@ class CallFunctionTest(testlib.RouterMixin, testlib.TestCase): def test_bad_return_value(self): exc = self.assertRaises(mitogen.core.StreamError, lambda: self.local.call(func_with_bad_return_value)) - self.assertEquals(exc[0], "cannot unpickle '__main__'/'CrazyType'") + self.assertEquals( + exc[0], + "cannot unpickle '%s'/'CrazyType'" % (__name__,), + ) def test_returns_dead(self): self.assertEqual(mitogen.core._DEAD, self.local.call(func_returns_dead)) diff --git a/tests/fakessh_test.py b/tests/fakessh_test.py index 6e28be1d..8711b46b 100644 --- a/tests/fakessh_test.py +++ b/tests/fakessh_test.py @@ -2,6 +2,7 @@ import os import shutil +import timeoutcontext import unittest2 import mitogen.fakessh @@ -10,6 +11,7 @@ import testlib class RsyncTest(testlib.DockerMixin, unittest2.TestCase): + @timeoutcontext.timeout(5) def test_rsync_from_master(self): context = self.docker_ssh_any() @@ -25,6 +27,7 @@ class RsyncTest(testlib.DockerMixin, unittest2.TestCase): self.assertTrue(context.call(os.path.exists, '/tmp/data')) self.assertTrue(context.call(os.path.exists, '/tmp/data/simple_pkg/a.py')) + @timeoutcontext.timeout(5) def test_rsync_between_direct_children(self): # master -> SSH -> has-sudo-pubkey -> rsync(.ssh) -> master -> # has-sudo -> rsync diff --git a/tests/master_test.py b/tests/master_test.py index 796c7084..cf16d6c5 100644 --- a/tests/master_test.py +++ b/tests/master_test.py @@ -1,3 +1,4 @@ +import inspect import unittest2 @@ -9,8 +10,10 @@ class ScanCodeImportsTest(unittest2.TestCase): func = staticmethod(mitogen.master.scan_code_imports) def test_simple(self): - co = compile(open(__file__).read(), __file__, 'exec') + source_path = inspect.getsourcefile(ScanCodeImportsTest) + co = compile(open(source_path).read(), source_path, 'exec') self.assertEquals(list(self.func(co)), [ + (-1, 'inspect', ()), (-1, 'unittest2', ()), (-1, 'testlib', ()), (-1, 'mitogen.master', ()), diff --git a/tox.ini b/tox.ini index f9eabeed..70de05df 100644 --- a/tox.ini +++ b/tox.ini @@ -8,7 +8,7 @@ deps = -r{toxinidir}/dev_requirements.txt commands = - {posargs:./test.sh} + {posargs:./test} [testenv:docs] basepython = python