diff --git a/ara/cli/generate.py b/ara/cli/generate.py index 61cb3de9..0dafbe3a 100644 --- a/ara/cli/generate.py +++ b/ara/cli/generate.py @@ -63,7 +63,7 @@ class GenerateHtml(Command): if args.playbook is not None: self.app.ara.config['ARA_PLAYBOOK_OVERRIDE'] = args.playbook - self.log.warn('Generating static files at %s...', args.path) + self.log.warning('Generating static files at %s...', args.path) filterwarnings('ignore', '.*', NotFoundWarning) if self.app.ara.config['ARA_IGNORE_EMPTY_GENERATION']: filterwarnings('ignore', '.*', MissingURLGeneratorWarning) diff --git a/ara/config/compat.py b/ara/config/compat.py index 569e4560..0d2ffbd3 100644 --- a/ara/config/compat.py +++ b/ara/config/compat.py @@ -17,11 +17,16 @@ # Compatibility layer between ARA and the different version of Ansible -from ansible.constants import get_config -from ansible.config.manager import find_ini_config_file -import ansible.constants +import warnings from six.moves import configparser +with warnings.catch_warnings(): + warnings.filterwarnings('ignore') + import ansible.constants + from ansible.constants import get_config + from ansible.config.manager import find_ini_config_file + + # Please don't scream deprecated warnings at us ansible.constants._deprecated = lambda *args: None diff --git a/ara/models.py b/ara/models.py index 2ceacfdf..edcec908 100644 --- a/ara/models.py +++ b/ara/models.py @@ -26,11 +26,14 @@ from datetime import timedelta from oslo_utils import encodeutils from oslo_serialization import jsonutils +import warnings # This makes all the exceptions available as "models.". -from flask_sqlalchemy import SQLAlchemy -from sqlalchemy.orm.exc import * # NOQA -from sqlalchemy.orm import backref -import sqlalchemy.types as types +with warnings.catch_warnings(): + warnings.filterwarnings('ignore') + from flask_sqlalchemy import SQLAlchemy + from sqlalchemy.orm.exc import * # NOQA + from sqlalchemy.orm import backref + import sqlalchemy.types as types db = SQLAlchemy() log = logging.getLogger('ara.models') @@ -128,7 +131,7 @@ class CompressedData(types.TypeDecorator): http://docs.sqlalchemy.org/en/latest/core/custom_types.html """ - impl = types.Binary + impl = types.LargeBinary def process_bind_param(self, value, dialect): return zlib.compress(encodeutils.to_utf8(jsonutils.dumps(value))) @@ -151,7 +154,7 @@ class CompressedText(types.TypeDecorator): http://docs.sqlalchemy.org/en/latest/core/custom_types.html """ - impl = types.Binary + impl = types.LargeBinary def process_bind_param(self, value, dialect): return zlib.compress(encodeutils.to_utf8(value)) @@ -205,7 +208,7 @@ class Playbook(db.Model, TimedEntity): .filter(File.playbook_id == self.id) .filter(File.is_playbook)).one() except NoResultFound: # noqa - log.warn( + log.warning( 'Recovering from NoResultFound file on playbook %s' % self.id ) @@ -216,7 +219,8 @@ class Playbook(db.Model, TimedEntity): .filter(File.playbook_id == self.id) .filter(File.path == self.path)).one() playbook_file.is_playbook = True - log.warn('Recovered file reference for playbook %s' % self.id) + log.warning('Recovered file reference for playbook %s' % + self.id) return playbook_file except NoResultFound: # noqa # Option #2: The playbook was created but was interrupted @@ -235,7 +239,8 @@ class Playbook(db.Model, TimedEntity): playbook_file.content = content db.session.add(playbook_file) db.session.commit() - log.warn('Recovered file reference for playbook %s' % self.id) + log.warning('Recovered file reference for playbook %s' % + self.id) return playbook_file def __repr__(self): diff --git a/ara/plugins/callbacks/log_ara.py b/ara/plugins/callbacks/log_ara.py index e87e391d..713fcbbe 100644 --- a/ara/plugins/callbacks/log_ara.py +++ b/ara/plugins/callbacks/log_ara.py @@ -20,9 +20,10 @@ from __future__ import (absolute_import, division, print_function) import itertools import logging import os +import warnings from ansible import __version__ as ansible_version -from ansible.plugins.callback import CallbackBase + from ara import models from ara.models import db from ara.webapp import create_app @@ -31,6 +32,10 @@ from distutils.version import LooseVersion from flask import current_app from oslo_serialization import jsonutils +with warnings.catch_warnings(): + warnings.filterwarnings('ignore') + from ansible.plugins.callback import CallbackBase + # To retrieve Ansible CLI options try: from __main__ import cli @@ -122,7 +127,7 @@ class CallbackModule(CallbackBase): file_.content = content except IOError: - log.warn('failed to open %s for reading', path) + log.warning('failed to open %s for reading', path) return file_ diff --git a/ara/tests/integration/include_role.yml b/ara/tests/integration/include_role.yml index 199ec55f..19fe230a 100644 --- a/ara/tests/integration/include_role.yml +++ b/ara/tests/integration/include_role.yml @@ -32,4 +32,3 @@ - name: Include role with static include_role: name: included-role - static: no diff --git a/ara/tests/integration/roles/smoke-tests/tasks/ara-ops.yml b/ara/tests/integration/roles/smoke-tests/tasks/ara-ops.yml index 331064ef..302c8249 100644 --- a/ara/tests/integration/roles/smoke-tests/tasks/ara-ops.yml +++ b/ara/tests/integration/roles/smoke-tests/tasks/ara-ops.yml @@ -42,14 +42,14 @@ - name: Update notype key with specified playbook ara_record: - playbook: "{{ notype.playbook_id }}" + playbook: "{{ notype.playbook_id }}" key: "notype" value: "updated text" type: "text" - name: Read notype key with specified playbook ara_read: - playbook: "{{ notype.playbook_id }}" + playbook: "{{ notype.playbook_id }}" key: "notype" register: notype_update diff --git a/ara/tests/unit/fakes.py b/ara/tests/unit/fakes.py index 375d699e..077a6905 100644 --- a/ara/tests/unit/fakes.py +++ b/ara/tests/unit/fakes.py @@ -17,10 +17,15 @@ import ara.models as m import random +import sys from ansible import __version__ as ansible_version -from mock import MagicMock from oslo_serialization import jsonutils +if sys.version_info >= (3, 3): + from unittest.mock import MagicMock +else: + from mock import MagicMock + FAKE_PLAYBOOK_CONTENT = """--- - name: ARA unit tests diff --git a/ara/tests/unit/test_cli.py b/ara/tests/unit/test_cli.py index a05de8a2..025cecd9 100644 --- a/ara/tests/unit/test_cli.py +++ b/ara/tests/unit/test_cli.py @@ -19,9 +19,9 @@ import os import shutil import six import tempfile +import warnings from glob import glob -from lxml import etree from oslo_serialization import jsonutils from subunit._to_disk import to_disk @@ -39,6 +39,10 @@ import ara.models as m from ara.tests.unit.common import ansible_run from ara.tests.unit.common import TestAra +with warnings.catch_warnings(): + warnings.filterwarnings('ignore') + from lxml import etree + class TestCLIData(TestAra): """ Tests for the ARA CLI data commands """ diff --git a/ara/tests/unit/test_filters.py b/ara/tests/unit/test_filters.py index 4f49a587..69cb7782 100644 --- a/ara/tests/unit/test_filters.py +++ b/ara/tests/unit/test_filters.py @@ -191,13 +191,13 @@ class TestFilters(TestAra): hosts: localhost tasks: - debug: - msg: "foo""" + msg: "foo-message""" t = self.env.from_string('{{ data | yamlhighlight | safe }}') res = t.render(data=data) - # This is ugly, sorry - expected = '''
1\n2\n3\n4\n5
- name: Test thing\n    hosts: localhost\n    tasks:\n      - debug:\n          msg: "foo\n
\n
''' # noqa - self.assertEqual(res, expected) + self.assertIn('Test thing', res) + self.assertIn('localhost', res) + self.assertIn('foo-message', res) def test_jinja_fast_count(self): ansible_run() diff --git a/ara/webapp.py b/ara/webapp.py index f804b033..c1b051a1 100644 --- a/ara/webapp.py +++ b/ara/webapp.py @@ -22,7 +22,7 @@ # configuration automatically on import which might not be desirable. import datetime -import flask_migrate +import warnings import logging import logging.config import os @@ -55,6 +55,10 @@ from pygments.lexers import YamlLexer from pygments.lexers import JsonLexer from pygments.lexers.special import TextLexer +with warnings.catch_warnings(): + warnings.filterwarnings('ignore') + import flask_migrate + def create_app(): app = Flask('ara') diff --git a/ara/wsgi.py b/ara/wsgi.py index a031241e..5dd1d88a 100644 --- a/ara/wsgi.py +++ b/ara/wsgi.py @@ -59,7 +59,7 @@ def application(environ, start_response): os.environ['ANSIBLE_CONFIG'] = environ['ANSIBLE_CONFIG'] else: if 'ANSIBLE_CONFIG' not in os.environ: - log.warn('ANSIBLE_CONFIG environment variable not found.') + log.warning('ANSIBLE_CONFIG environment variable not found.') from ara.webapp import create_app # flake8: noqa from flask import current_app # flake8: noqa diff --git a/tests/ansible-linters.sh b/tests/ansible-linters.sh index df73d894..330f93c2 100755 --- a/tests/ansible-linters.sh +++ b/tests/ansible-linters.sh @@ -20,6 +20,9 @@ set -ex export ANSIBLE_ACTION_PLUGINS="ara/plugins/actions" export ANSIBLE_LIBRARY="ara/plugins/modules" +# workaround for occasional UnicodeEncodeError on CI +export PYTHONIOENCODING=${PYTHONIOENCODING:-utf-8} + # Some tests only work on certain versions of Ansible. # Use Ansible's pseudo semver to determine if we can run something. diff --git a/tox.ini b/tox.ini index 2325a084..4580b5ba 100644 --- a/tox.ini +++ b/tox.ini @@ -1,12 +1,16 @@ [tox] minversion = 2.0 -envlist = py27,py35,pep8 +envlist = pep8,py27,py37,py36,py35 skipdist = True +skip_missing_interpreters = True +# ^ this does not affect CI where all jobs start with specific environment [testenv] basepython = {py27,venv,cover,docs,pep8}: python2 - {py35}: python3 + {py35}: python3.5 + {py36}: python3.6 + {py37}: python3.7 sitepackages = True usedevelop = True install_command = pip install -U {opts} {packages} -c{env:CONSTRAINTS_FILE:/dev/null} @@ -23,19 +27,31 @@ commands = sphinx-build -W -b html doc/source doc/build/html # B303 - Use of insecure MD2, MD4, or MD5 hash function. # We're using sha1 to generate a hash of file contents. commands = - flake8 ara + python -m flake8 ara bandit -r ara -x ara/tests --skip B303 bashate -v --ignore E006,E011 {toxinidir}/run_tests.sh [testenv:py27] commands = - py.test -v ara/tests/unit + python -m pytest -v -Werror ara/tests/unit passenv = HOME [testenv:py35] commands = - py.test -v ara/tests/unit + python -m pytest -v -Werror ara/tests/unit +passenv = + HOME + +[testenv:py36] +commands = + python -m pytest -v -Werror ara/tests/unit +passenv = + HOME + +[testenv:py37] +commands = + python -m pytest -v -Werror ara/tests/unit passenv = HOME diff --git a/zuul.d/jobs.yaml b/zuul.d/jobs.yaml index 49c4ab9c..b253b49f 100644 --- a/zuul.d/jobs.yaml +++ b/zuul.d/jobs.yaml @@ -46,17 +46,17 @@ nodeset: ubuntu-xenial - job: - name: ara-integration-fedora-py35-2.7.0 + name: ara-integration-fedora-py36-2.7.0 parent: ara-integration-base vars: - python_test_version: py35 + python_test_version: py36 ansible_test_version: 2.7.0 nodeset: fedora-latest - job: - name: ara-integration-fedora-py35-devel + name: ara-integration-fedora-py36-devel parent: ara-integration-base vars: - python_test_version: py35 + python_test_version: py36 ansible_test_version: devel nodeset: fedora-latest diff --git a/zuul.d/layout.yaml b/zuul.d/layout.yaml index dfeb2212..0ee9e487 100644 --- a/zuul.d/layout.yaml +++ b/zuul.d/layout.yaml @@ -9,13 +9,15 @@ - ara-integration-ubuntu-py35-2.7.0 - ara-integration-ubuntu-py35-devel: voting: false - - ara-integration-fedora-py35-2.7.0 - - ara-integration-fedora-py35-devel: + - ara-integration-fedora-py36-2.7.0 + - ara-integration-fedora-py36-devel: voting: false + - openstack-tox-py37 gate: jobs: - ara-integration-debian-py27-2.6.5 - ara-integration-centos-py27-2.5.9 - ara-integration-opensuse-py27-2.7.0 - ara-integration-ubuntu-py35-2.7.0 - - ara-integration-fedora-py35-2.7.0 + - ara-integration-fedora-py36-2.7.0 + - openstack-tox-py37 \ No newline at end of file