diff options
author | Wayne Witzel III <wwitzel@redhat.com> | 2016-01-27 19:42:58 +0100 |
---|---|---|
committer | Wayne Witzel III <wwitzel@redhat.com> | 2016-02-02 00:37:56 +0100 |
commit | 3d4580611eedec18fa9928732dea44f77e1d6d57 (patch) | |
tree | ad470126309ff45baca11b9f37234a2f01f2577f | |
parent | reorganzing tests folder (diff) | |
download | awx-3d4580611eedec18fa9928732dea44f77e1d6d57.tar.xz awx-3d4580611eedec18fa9928732dea44f77e1d6d57.zip |
added pytest to requirements_dev
reworking test strucutre
reworked pytest.ini, removed functional imports, updated req_dev
remove unneeded __init__ files
add testing checker to local_settings examples
adding testing packages to system Python for docker
-rw-r--r-- | Makefile | 6 | ||||
-rw-r--r-- | awx/main/models/credential.py | 3 | ||||
-rw-r--r-- | awx/main/tests/__init__.py | 0 | ||||
-rw-r--r-- | awx/main/tests/functional/__init__.py | 24 | ||||
-rw-r--r-- | awx/main/tests/functional/commands/__init__.py | 13 | ||||
-rw-r--r-- | awx/main/tests/functional/fact/__init__.py | 6 | ||||
-rw-r--r-- | awx/main/tests/functional/jobs/__init__.py | 11 | ||||
-rw-r--r-- | awx/main/tests/unit/utils/__init__.py | 0 | ||||
-rw-r--r-- | awx/main/utils.py | 122 | ||||
-rw-r--r-- | awx/settings/local_settings.py.docker_compose | 9 | ||||
-rw-r--r-- | awx/settings/local_settings.py.example | 9 | ||||
-rw-r--r-- | pytest.ini | 5 | ||||
-rw-r--r-- | requirements/requirements_dev.txt | 4 | ||||
-rw-r--r-- | tools/docker-compose/Dockerfile | 4 |
14 files changed, 35 insertions, 181 deletions
@@ -357,17 +357,17 @@ pylint: reports @(set -o pipefail && $@ | reports/$@.report) check: flake8 pep8 # pyflakes pylint - + # Run all API unit tests. test: - $(PYTHON) manage.py test -v2 awx.main.tests + $(PYTHON) -m py.test awx/main/tests test_unit: $(PYTHON) -m py.test awx/main/tests/unit # Run all API unit tests with coverage enabled. test_coverage: - coverage run manage.py test -v2 awx.main.tests + $(PYTHON) -m py.test --cov=awx awx/main/tests # Output test coverage as HTML (into htmlcov directory). coverage_html: diff --git a/awx/main/models/credential.py b/awx/main/models/credential.py index e0d75dc182..c72c67b715 100644 --- a/awx/main/models/credential.py +++ b/awx/main/models/credential.py @@ -1,6 +1,9 @@ # Copyright (c) 2015 Ansible, Inc. # All Rights Reserved. +import base64 +import re + # Django from django.db import models from django.utils.translation import ugettext_lazy as _ diff --git a/awx/main/tests/__init__.py b/awx/main/tests/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 --- a/awx/main/tests/__init__.py +++ /dev/null diff --git a/awx/main/tests/functional/__init__.py b/awx/main/tests/functional/__init__.py deleted file mode 100644 index 37a6f1e643..0000000000 --- a/awx/main/tests/functional/__init__.py +++ /dev/null @@ -1,24 +0,0 @@ -# Copyright (c) 2015 Ansible, Inc. -# All Rights Reserved. -import logging -logging.disable(logging.CRITICAL) - -from .organizations import * # noqa -from .users import * # noqa -from .inventory import * # noqa -from .projects import ProjectsTest, ProjectUpdatesTest # noqa -from .commands import * # noqa -from .scripts import * # noqa -from .tasks import RunJobTest # noqa -from .ad_hoc import * # noqa -from .licenses import LicenseTests # noqa -from .jobs import * # noqa -from .activity_stream import * # noqa -from .schedules import * # noqa -from .redact import * # noqa -from .views import * # noqa -from .commands import * # noqa -from .fact import * # noqa -from .unified_jobs import * # noqa -from .ha import * # noqa -from .settings import * # noqa diff --git a/awx/main/tests/functional/commands/__init__.py b/awx/main/tests/functional/commands/__init__.py deleted file mode 100644 index 84212dd2fb..0000000000 --- a/awx/main/tests/functional/commands/__init__.py +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright (c) 2015 Ansible, Inc. -# All Rights Reserved - -from __future__ import absolute_import - -from .run_fact_cache_receiver import * # noqa -from .commands_monolithic import * # noqa -from .cleanup_facts import * # noqa -from .age_deleted import * # noqa -from .remove_instance import * # noqa -from .run_socketio_service import * # noqa -from .update_password import * # noqa - diff --git a/awx/main/tests/functional/fact/__init__.py b/awx/main/tests/functional/fact/__init__.py deleted file mode 100644 index 234499d6e9..0000000000 --- a/awx/main/tests/functional/fact/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -# Copyright (c) 2015 Ansible, Inc. -# All Rights Reserved - -from __future__ import absolute_import - -from .fact_api import * # noqa diff --git a/awx/main/tests/functional/jobs/__init__.py b/awx/main/tests/functional/jobs/__init__.py deleted file mode 100644 index 092826ccf0..0000000000 --- a/awx/main/tests/functional/jobs/__init__.py +++ /dev/null @@ -1,11 +0,0 @@ -# Copyright (c) 2015 Ansible, Inc. -# All Rights Reserved - -from __future__ import absolute_import - -from .jobs_monolithic import * # noqa -from .job_launch import * # noqa -from .job_relaunch import * # noqa -from .survey_password import * # noqa -from .start_cancel import * # noqa -from .base import * # noqa diff --git a/awx/main/tests/unit/utils/__init__.py b/awx/main/tests/unit/utils/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 --- a/awx/main/tests/unit/utils/__init__.py +++ /dev/null diff --git a/awx/main/utils.py b/awx/main/utils.py index 96df62b379..5b9b7a1f46 100644 --- a/awx/main/utils.py +++ b/awx/main/utils.py @@ -523,125 +523,3 @@ def timedelta_total_seconds(timedelta): timedelta.microseconds + 0.0 + (timedelta.seconds + timedelta.days * 24 * 3600) * 10 ** 6) / 10 ** 6 -def validate_ssh_private_key(data): - """Validate that the given SSH private key or certificate is, - in fact, valid. - """ - # Map the X in BEGIN X PRIVATE KEY to the key type (ssh-keygen -t). - # Tower jobs using OPENSSH format private keys may still fail if the - # system SSH implementation lacks support for this format. - key_types = { - 'RSA': 'rsa', - 'DSA': 'dsa', - 'EC': 'ecdsa', - 'OPENSSH': 'ed25519', - '': 'rsa1', - } - # Key properties to return if valid. - key_data = { - 'key_type': None, # Key type (from above mapping). - 'key_seg': '', # Key segment (all text including begin/end). - 'key_b64': '', # Key data as base64. - 'key_bin': '', # Key data as binary. - 'key_enc': None, # Boolean, whether key is encrypted. - 'cert_seg': '', # Cert segment (all text including begin/end). - 'cert_b64': '', # Cert data as base64. - 'cert_bin': '', # Cert data as binary. - } - data = data.strip() - validation_error = ValidationError('Invalid private key') - - # Sanity check: We may potentially receive a full PEM certificate, - # and we want to accept these. - cert_begin_re = r'(-{4,})\s*BEGIN\s+CERTIFICATE\s*(-{4,})' - cert_end_re = r'(-{4,})\s*END\s+CERTIFICATE\s*(-{4,})' - cert_begin_match = re.search(cert_begin_re, data) - cert_end_match = re.search(cert_end_re, data) - if cert_begin_match and not cert_end_match: - raise validation_error - elif not cert_begin_match and cert_end_match: - raise validation_error - elif cert_begin_match and cert_end_match: - cert_dashes = set([cert_begin_match.groups()[0], cert_begin_match.groups()[1], - cert_end_match.groups()[0], cert_end_match.groups()[1]]) - if len(cert_dashes) != 1: - raise validation_error - key_data['cert_seg'] = data[cert_begin_match.start():cert_end_match.end()] - - # Find the private key, and also ensure that it internally matches - # itself. - # Set up the valid private key header and footer. - begin_re = r'(-{4,})\s*BEGIN\s+([A-Z0-9]+)?\s*PRIVATE\sKEY\s*(-{4,})' - end_re = r'(-{4,})\s*END\s+([A-Z0-9]+)?\s*PRIVATE\sKEY\s*(-{4,})' - begin_match = re.search(begin_re, data) - end_match = re.search(end_re, data) - if not begin_match or not end_match: - raise validation_error - - # Ensure that everything, such as dash counts and key type, lines up, - # and raise an error if it does not. - dashes = set([begin_match.groups()[0], begin_match.groups()[2], - end_match.groups()[0], end_match.groups()[2]]) - if len(dashes) != 1: - raise validation_error - if begin_match.groups()[1] != end_match.groups()[1]: - raise validation_error - key_type = begin_match.groups()[1] or '' - try: - key_data['key_type'] = key_types[key_type] - except KeyError: - raise ValidationError('Invalid private key: unsupported type %s' % key_type) - - # The private key data begins and ends with the private key. - key_data['key_seg'] = data[begin_match.start():end_match.end()] - - # Establish that we are able to base64 decode the private key; - # if we can't, then it's not a valid key. - # - # If we got a certificate, validate that also, in the same way. - header_re = re.compile(r'^(.+?):\s*?(.+?)(\\??)$') - for segment_name in ('cert', 'key'): - segment_to_validate = key_data['%s_seg' % segment_name] - # If we have nothing; skip this one. - # We've already validated that we have a private key above, - # so we don't need to do it again. - if not segment_to_validate: - continue - - # Ensure that this segment is valid base64 data. - base64_data = '' - line_continues = False - lines = segment_to_validate.splitlines() - for line in lines[1:-1]: - line = line.strip() - if not line: - continue - if line_continues: - line_continues = line.endswith('\\') - continue - line_match = header_re.match(line) - if line_match: - line_continues = line.endswith('\\') - continue - base64_data += line - try: - decoded_data = base64.b64decode(base64_data) - if not decoded_data: - raise validation_error - key_data['%s_b64' % segment_name] = base64_data - key_data['%s_bin' % segment_name] = decoded_data - except TypeError: - raise validation_error - - # Determine if key is encrypted. - if key_data['key_type'] == 'ed25519': - # See https://github.com/openssh/openssh-portable/blob/master/sshkey.c#L3218 - # Decoded key data starts with magic string (null-terminated), four byte - # length field, followed by the ciphername -- if ciphername is anything - # other than 'none' the key is encrypted. - key_data['key_enc'] = not bool(key_data['key_bin'].startswith('openssh-key-v1\x00\x00\x00\x00\x04none')) - else: - key_data['key_enc'] = bool('ENCRYPTED' in key_data['key_seg']) - - return key_data - diff --git a/awx/settings/local_settings.py.docker_compose b/awx/settings/local_settings.py.docker_compose index 905e26857f..794d3ce073 100644 --- a/awx/settings/local_settings.py.docker_compose +++ b/awx/settings/local_settings.py.docker_compose @@ -30,10 +30,17 @@ DATABASES = { } } +def is_testing(argv): + if "py.test" in argv[0] or "py/test.py" in argv[0]: + return True + elif argv[1] == "test": + return True + return False + # 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 len(sys.argv) >= 2 and sys.argv[1] == 'test': +if len(sys.argv) >= 2 and is_testing(sys.argv): DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', diff --git a/awx/settings/local_settings.py.example b/awx/settings/local_settings.py.example index 2fb0c745fc..52648798fe 100644 --- a/awx/settings/local_settings.py.example +++ b/awx/settings/local_settings.py.example @@ -30,10 +30,17 @@ DATABASES = { } } +def is_testing(argv): + if "py.test" in argv[0] or "py/test.py" in argv[0]: + return True + elif argv[1] == "test": + return True + return False + # 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 len(sys.argv) >= 2 and sys.argv[1] == 'test': +if len(sys.argv) >= 2 and is_testing(sys.argv): DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', diff --git a/pytest.ini b/pytest.ini new file mode 100644 index 0000000000..751ebbb85f --- /dev/null +++ b/pytest.ini @@ -0,0 +1,5 @@ +[pytest] +DJANGO_SETTINGS_MODULE = awx.settings.development +python_paths = awx/lib/site-packages +python_files = *.py +addopts = --create-db diff --git a/requirements/requirements_dev.txt b/requirements/requirements_dev.txt index a2ff6cf11a..bd7d5f54c8 100644 --- a/requirements/requirements_dev.txt +++ b/requirements/requirements_dev.txt @@ -4,3 +4,7 @@ django-debug-toolbar==1.3.2 unittest2 pep8 flake8 +pytest +pytest-cov +pytest-django +pytest-pythonpath diff --git a/tools/docker-compose/Dockerfile b/tools/docker-compose/Dockerfile index 32be28ca01..e2e57fd4a1 100644 --- a/tools/docker-compose/Dockerfile +++ b/tools/docker-compose/Dockerfile @@ -12,6 +12,10 @@ RUN echo "deb http://repo.mongodb.org/apt/ubuntu "$(lsb_release -sc)"/mongodb-or RUN apt-get update RUN apt-get install -y openssh-server ansible mg vim tmux git mercurial subversion python-dev python-psycopg2 make postgresql-client libpq-dev nodejs python-psutil libxml2-dev libxslt-dev lib32z1-dev libsasl2-dev libldap2-dev libffi-dev libzmq-dev proot python-pip libxmlsec1-dev swig redis-server && rm -rf /var/lib/apt/lists/* RUN pip install flake8 +RUN pip install pytest +RUN pip install pytest-pythonpath +RUN pip install pytest-django +RUN pip install pytest-cov RUN /usr/bin/ssh-keygen -q -t rsa -N "" -f /root/.ssh/id_rsa RUN mkdir -p /etc/tower RUN mkdir -p /data/db |