From 97ab6449b9e9c2a1b778eff3cd21f019402cafd4 Mon Sep 17 00:00:00 2001 From: chris meyers Date: Sat, 12 May 2018 20:35:01 -0400 Subject: [PATCH] parallelize test running --- Makefile | 2 +- awx/main/managers.py | 2 +- awx/main/tests/conftest.py | 10 ++++++++++ awx/main/tests/functional/test_rbac_oauth.py | 8 ++++---- awx/main/tests/unit/models/test_survey_models.py | 14 ++++++++++++-- awx/main/tests/unit/test_access.py | 2 +- awx/main/tests/unit/test_tasks.py | 4 ++-- awx/network_ui/tests/conftest.py | 9 +++++++++ awx/settings/defaults.py | 8 +++++++- awx/settings/local_settings.py.docker_compose | 3 ++- requirements/requirements_dev.txt | 3 ++- 11 files changed, 51 insertions(+), 14 deletions(-) create mode 100644 awx/network_ui/tests/conftest.py diff --git a/Makefile b/Makefile index 4c5202147f..0b9cc2a61c 100644 --- a/Makefile +++ b/Makefile @@ -379,7 +379,7 @@ test: @if [ "$(VENV_BASE)" ]; then \ . $(VENV_BASE)/awx/bin/activate; \ fi; \ - py.test $(TEST_DIRS) + py.test -n auto $(TEST_DIRS) test_combined: test_ansible test diff --git a/awx/main/managers.py b/awx/main/managers.py index 274a0ef774..d2af95e2b8 100644 --- a/awx/main/managers.py +++ b/awx/main/managers.py @@ -77,7 +77,7 @@ class InstanceManager(models.Manager): def me(self): """Return the currently active instance.""" # If we are running unit tests, return a stub record. - if settings.IS_TESTING(sys.argv): + if settings.IS_TESTING(sys.argv) or hasattr(sys, '_called_from_test'): return self.model(id=1, hostname='localhost', uuid='00000000-0000-0000-0000-000000000000') diff --git a/awx/main/tests/conftest.py b/awx/main/tests/conftest.py index 679577858f..946c930dc5 100644 --- a/awx/main/tests/conftest.py +++ b/awx/main/tests/conftest.py @@ -15,6 +15,16 @@ from awx.main.tests.factories import ( ) +def pytest_configure(config): + import sys + sys._called_from_test = True + + +def pytest_unconfigure(config): + import sys + del sys._called_from_test + + @pytest.fixture def mock_access(): @contextmanager diff --git a/awx/main/tests/functional/test_rbac_oauth.py b/awx/main/tests/functional/test_rbac_oauth.py index 35b915f94d..757c55e12b 100644 --- a/awx/main/tests/functional/test_rbac_oauth.py +++ b/awx/main/tests/functional/test_rbac_oauth.py @@ -102,21 +102,21 @@ class TestOAuth2Application: assert access.can_delete(app) is can_access - def test_superuser_can_always_create(self, admin, org_admin, org_member, alice): + def test_superuser_can_always_create(self, admin, org_admin, org_member, alice, organization): access = OAuth2ApplicationAccess(admin) for user in [admin, org_admin, org_member, alice]: assert access.can_add({ 'name': 'test app', 'user': user.pk, 'client_type': 'confidential', - 'authorization_grant_type': 'password', 'organization': 1 + 'authorization_grant_type': 'password', 'organization': organization.id }) - def test_normal_user_cannot_create(self, admin, org_admin, org_member, alice): + def test_normal_user_cannot_create(self, admin, org_admin, org_member, alice, organization): for access_user in [org_member, alice]: access = OAuth2ApplicationAccess(access_user) for user in [admin, org_admin, org_member, alice]: assert not access.can_add({ 'name': 'test app', 'user': user.pk, 'client_type': 'confidential', - 'authorization_grant_type': 'password', 'organization': 1 + 'authorization_grant_type': 'password', 'organization': organization.id }) diff --git a/awx/main/tests/unit/models/test_survey_models.py b/awx/main/tests/unit/models/test_survey_models.py index 6ce19d2060..330014d481 100644 --- a/awx/main/tests/unit/models/test_survey_models.py +++ b/awx/main/tests/unit/models/test_survey_models.py @@ -1,8 +1,9 @@ import tempfile import json import yaml - import pytest +from itertools import count + from awx.main.utils.encryption import encrypt_value from awx.main.tasks import RunJob from awx.main.models import ( @@ -16,6 +17,15 @@ from awx.main.utils.safe_yaml import SafeLoader ENCRYPTED_SECRET = encrypt_value('secret') +class DistinctParametrize(object): + + def __init__(self): + self._gen = count(0) + + def __call__(self, value): + return str(next(self._gen)) + + @pytest.mark.survey class SurveyVariableValidation: @@ -243,7 +253,7 @@ def test_optional_survey_question_defaults( ('password', 'foo', 5, {'extra_vars': {'x': ''}}, {'x': ''}), ('password', ENCRYPTED_SECRET, 5, {'extra_vars': {'x': '$encrypted$'}}, {}), ('password', ENCRYPTED_SECRET, 10, {'extra_vars': {'x': '$encrypted$'}}, {'x': ENCRYPTED_SECRET}), -]) + ], ids=DistinctParametrize()) def test_survey_encryption_defaults(survey_spec_factory, question_type, default, maxlen, kwargs, expected): spec = survey_spec_factory([ { diff --git a/awx/main/tests/unit/test_access.py b/awx/main/tests/unit/test_access.py index 6b20aaaed9..02e863f47f 100644 --- a/awx/main/tests/unit/test_access.py +++ b/awx/main/tests/unit/test_access.py @@ -158,7 +158,7 @@ def test_jt_existing_values_are_nonsensitive(job_template_with_ids, user_unit): """Assure that permission checks are not required if submitted data is identical to what the job template already has.""" - data = model_to_dict(job_template_with_ids) + data = model_to_dict(job_template_with_ids, exclude=['unifiedjobtemplate_ptr']) access = JobTemplateAccess(user_unit) assert access.changes_are_non_sensitive(job_template_with_ids, data) diff --git a/awx/main/tests/unit/test_tasks.py b/awx/main/tests/unit/test_tasks.py index 39a4d52de4..c4e3abe9b9 100644 --- a/awx/main/tests/unit/test_tasks.py +++ b/awx/main/tests/unit/test_tasks.py @@ -2155,7 +2155,7 @@ def test_aquire_lock_open_fail_logged(logging_getLogger, os_open): ProjectUpdate = tasks.RunProjectUpdate() - with pytest.raises(OSError, errno=3, strerror='dummy message'): + with pytest.raises(OSError, message='dummy message'): ProjectUpdate.acquire_lock(instance) assert logger.err.called_with("I/O error({0}) while trying to open lock file [{1}]: {2}".format(3, 'this_file_does_not_exist', 'dummy message')) @@ -2181,7 +2181,7 @@ def test_aquire_lock_acquisition_fail_logged(fcntl_flock, logging_getLogger, os_ ProjectUpdate = tasks.RunProjectUpdate() - with pytest.raises(IOError, errno=3, strerror='dummy message'): + with pytest.raises(IOError, message='dummy message'): ProjectUpdate.acquire_lock(instance) os_close.assert_called_with(3) assert logger.err.called_with("I/O error({0}) while trying to aquire lock on file [{1}]: {2}".format(3, 'this_file_does_not_exist', 'dummy message')) diff --git a/awx/network_ui/tests/conftest.py b/awx/network_ui/tests/conftest.py new file mode 100644 index 0000000000..ca4f2f1cda --- /dev/null +++ b/awx/network_ui/tests/conftest.py @@ -0,0 +1,9 @@ +import pytest +from mock import PropertyMock + + +@pytest.fixture(autouse=True) +def _disable_database_settings(mocker): + m = mocker.patch('awx.conf.settings.SettingsWrapper.all_supported_settings', new_callable=PropertyMock) + m.return_value = [] + diff --git a/awx/settings/defaults.py b/awx/settings/defaults.py index 2150aa77d8..66e9c3ee9a 100644 --- a/awx/settings/defaults.py +++ b/awx/settings/defaults.py @@ -4,7 +4,6 @@ import os import re # noqa import sys -import ldap import djcelery import six from datetime import timedelta @@ -39,6 +38,13 @@ def IS_TESTING(argv=None): return is_testing(argv) +if "pytest" in sys.modules: + import mock + with mock.patch('__main__.__builtins__.dir', return_value=[]): + import ldap +else: + import ldap + DEBUG = True SQL_DEBUG = DEBUG diff --git a/awx/settings/local_settings.py.docker_compose b/awx/settings/local_settings.py.docker_compose index 8da2628e38..94d9ba0214 100644 --- a/awx/settings/local_settings.py.docker_compose +++ b/awx/settings/local_settings.py.docker_compose @@ -13,6 +13,7 @@ ############################################################################### import os import urllib +import sys def patch_broken_pipe_error(): @@ -66,7 +67,7 @@ DATABASES = { # Use SQLite for unit tests instead of PostgreSQL. If the lines below are # commented out, Django will create the test_awx-dev database in PostgreSQL to # run unit tests. -if is_testing(sys.argv): +if "pytest" in sys.modules: DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', diff --git a/requirements/requirements_dev.txt b/requirements/requirements_dev.txt index 5c5f8e30f5..29c846536b 100644 --- a/requirements/requirements_dev.txt +++ b/requirements/requirements_dev.txt @@ -6,12 +6,13 @@ unittest2 pep8 flake8 pyflakes -pytest==2.9.2 +pytest==3.5.1 pytest-cov pytest-django pytest-pythonpath pytest-mock pytest-timeout +pytest-xdist logutils flower uwsgitop