tests: Improve unit tests runtime performance

This patch set does 2 things:

1) Improves unit test runtime peformance via pytest-xdist [0]
2) Reduces finnicky nature of `is_connected` helpers which
   sometimes skip even when there is access to the internet;
   logic has been added to make these checks more accurate
   to avoid skipping tests

Note that while there are newer alternatives to pytest-xdist they
are only compatible with much newer versions of Python.

[0] https://pypi.org/project/pytest-xdist/

Change-Id: Ib04b48ebabca0551058e5e1065056f4e559fbfe6
This commit is contained in:
Felipe Monteiro 2018-10-17 21:32:28 +01:00
parent e3e5683765
commit b28788325f
4 changed files with 31 additions and 21 deletions

View File

@ -2,6 +2,7 @@
pytest==3.2.1 pytest==3.2.1
pytest-cov==2.5.1 pytest-cov==2.5.1
testfixtures testfixtures
pytest-xdist==1.23.2
mock==2.0.0 mock==2.0.0
# Formatting # Formatting

View File

@ -12,13 +12,14 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
import atexit
import copy import copy
import os import os
import pytest
import shutil import shutil
import tempfile import tempfile
import pytest
from pegleg import config from pegleg import config
"""Fixtures that are applied to all unit tests.""" """Fixtures that are applied to all unit tests."""
@ -35,7 +36,10 @@ def restore_config():
config.GLOBAL_CONTEXT = original_global_context config.GLOBAL_CONTEXT = original_global_context
@pytest.fixture(scope="module", autouse=True) # NOTE(felipemonteiro): This uses `atexit` rather than a `pytest.fixture`
# decorator because 1) this only needs to be run exactly once and 2) this
# works across multiple test executors via `pytest -n <num_cores>`
@atexit.register
def clean_temporary_git_repos(): def clean_temporary_git_repos():
"""Iterates through all temporarily created directories and deletes each """Iterates through all temporarily created directories and deletes each
one that was created for testing. one that was created for testing.
@ -51,8 +55,5 @@ def clean_temporary_git_repos():
if any(p.startswith('airship') for p in os.listdir(path)): if any(p.startswith('airship') for p in os.listdir(path)):
yield path yield path
try: for tempdir in temporary_git_repos():
yield shutil.rmtree(tempdir, ignore_errors=True)
finally:
for tempdir in temporary_git_repos():
shutil.rmtree(tempdir, ignore_errors=True)

View File

@ -55,11 +55,14 @@ def is_connected():
:returns: True if connected else False. :returns: True if connected else False.
""" """
try: for _ in range(3):
r = requests.get("http://www.github.com/", proxies={}, timeout=3) try:
return r.ok r = requests.get("http://www.github.com/", proxies={}, timeout=3)
except requests.exceptions.RequestException: r.raise_for_status()
return False return True
except requests.exceptions.RequestException:
pass
return False
def is_connected_behind_proxy(): def is_connected_behind_proxy():
@ -67,9 +70,12 @@ def is_connected_behind_proxy():
:returns: True if connected else False. :returns: True if connected else False.
""" """
try: for _ in range(3):
r = requests.get( try:
"http://www.github.com/", proxies=_PROXY_SERVERS, timeout=3) r = requests.get(
return r.ok "http://www.github.com/", proxies=_PROXY_SERVERS, timeout=3)
except requests.exceptions.RequestException: r.raise_for_status()
return False return True
except requests.exceptions.RequestException:
pass
return False

View File

@ -2,9 +2,11 @@
set -e set -e
posargs=$@ posargs=$@
# cross-platform way to derive the number of logical cores
readonly num_cores=$(python -c 'import multiprocessing as mp; print(mp.cpu_count())')
if [ ${#posargs} -ge 1 ]; then if [ ${#posargs} -ge 1 ]; then
pytest -k ${posargs} pytest -k ${posargs} -n $num_cores
else else
pytest pytest -n $num_cores
fi fi
set +e set +e