diff --git a/roles/tripleo-repos/molecule/Dockerfile.j2 b/roles/tripleo-repos/molecule/Dockerfile.j2 new file mode 100644 index 000000000..e585c8d91 --- /dev/null +++ b/roles/tripleo-repos/molecule/Dockerfile.j2 @@ -0,0 +1,21 @@ +# Molecule managed + +{% if item.registry is defined %} +FROM {{ item.registry.url }}/{{ item.image }} +{% else %} +FROM {{ item.image }} +{% endif %} + +RUN if [ $(command -v apt-get) ]; then apt-get update && apt-get install -y python sudo bash ca-certificates && apt-get clean; \ + elif [ $(command -v dnf) ]; then dnf makecache && dnf --assumeyes install python sudo python-devel python*-dnf bash {{ item.pkg_extras | default('') }} && dnf clean all; \ + elif [ $(command -v yum) ]; then yum makecache fast && yum install -y python sudo yum-plugin-ovl python-setuptools bash {{ item.pkg_extras | default('') }} && sed -i 's/plugins=0/plugins=1/g' /etc/yum.conf && yum clean all; \ + elif [ $(command -v zypper) ]; then zypper refresh && zypper install -y python sudo bash python-xml {{ item.pkg_extras | default('') }} && zypper clean -a; \ + elif [ $(command -v apk) ]; then apk update && apk add --no-cache python sudo bash ca-certificates {{ item.pkg_extras | default('') }}; \ + elif [ $(command -v xbps-install) ]; then xbps-install -Syu && xbps-install -y python sudo bash ca-certificates {{ item.pkg_extras | default('') }} && xbps-remove -O; fi + +{% for pkg in item.easy_install | default([]) %} +# install pip for centos where there is no python-pip rpm in default repos +RUN easy_install {{ pkg }} +{% endfor %} + +CMD ["sh", "-c", "while true; do sleep 10000; done"] diff --git a/roles/tripleo-repos/molecule/default/molecule.yml b/roles/tripleo-repos/molecule/default/molecule.yml new file mode 100644 index 000000000..1b54eaafe --- /dev/null +++ b/roles/tripleo-repos/molecule/default/molecule.yml @@ -0,0 +1,37 @@ +--- +driver: + name: docker +log: true +platforms: + + - name: centos7-master + hostname: centos7-master + image: centos:7 + dockerfile: ../Dockerfile.j2 + pkg_extras: python-setuptools + easy_install: [pip] + environment: &env + http_proxy: "{{ lookup('env', 'http_proxy') }}" + https_proxy: "{{ lookup('env', 'https_proxy') }}" + + - name: fedora28-master + hostname: fedora28-master + image: fedora:28 + dockerfile: ../Dockerfile.j2 + pkg_extras: python*-setuptools + environment: + <<: *env + +provisioner: + name: ansible + env: + ANSIBLE_STDOUT_CALLBACK: yaml + ANSIBLE_VERBOSITY: "2" +scenario: + test_sequence: + - destroy + - create + - converge + - destroy +lint: + enabled: false diff --git a/roles/tripleo-repos/molecule/default/playbook.yml b/roles/tripleo-repos/molecule/default/playbook.yml new file mode 100644 index 000000000..c930f6da0 --- /dev/null +++ b/roles/tripleo-repos/molecule/default/playbook.yml @@ -0,0 +1,14 @@ +--- + +- name: Converge + hosts: all + tasks: + + - name: import tripleo-repos role + include_role: + name: tripleo-repos + + - name: validate that we can install openstack-tripleo-common + package: + name: openstack-tripleo-common + state: latest diff --git a/tests/test_molecule.py b/tests/test_molecule.py new file mode 100644 index 000000000..ff9d62659 --- /dev/null +++ b/tests/test_molecule.py @@ -0,0 +1,51 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import os +import pytest +import subprocess + + +# detect if we have a working docker setup and skip with warning if not +docker_skip = False +docker_reason = '' +try: + import docker + client = docker.from_env(timeout=5) + if not client.ping(): + raise Exception("Failed to ping docker server.") +except Exception as e: + docker_reason = "Skipping molecule tests due: %s" % e + docker_skip = True + + +def pytest_generate_tests(metafunc): + # detects all molecule scenarios inside the project + matches = [] + if 'testdata' in metafunc.fixturenames: + for role in os.listdir("./roles"): + role_path = os.path.abspath('./roles/%s' % role) + for _, dirnames, _ in os.walk(role_path + '/molecule'): + for scenario in dirnames: + if os.path.isfile('%s/molecule/%s/molecule.yml' % + (role_path, scenario)): + matches.append([role_path, scenario]) + metafunc.parametrize('testdata', matches) + + +@pytest.mark.skipif(docker_skip, reason=docker_reason) +def test_molecule(testdata): + cwd, scenario = testdata + cmd = ['python', '-m', 'molecule', 'test', '-s', scenario] + print("running: %s (from %s)" % (" " .join(cmd), cwd)) + r = subprocess.call(cmd, cwd=cwd) + assert r == 0 diff --git a/tox.ini b/tox.ini index 7b8eeb197..f5803f108 100644 --- a/tox.ini +++ b/tox.ini @@ -1,6 +1,6 @@ [tox] # keep py3 before py2 to assure they are preffered for envs like linters: -envlist = linters,py{37,36,35,27} +envlist = linters,py{37,36,35,27},mol minversion = 3.4.0 ignore_basepython_conflict = True skip_missing_interpreters = True @@ -8,10 +8,23 @@ skip_missing_interpreters = True [testenv] usedevelop = True setenv = + ANSIBLE_FORCE_COLOR=1 + ANSIBLE_INVENTORY={toxinidir}/test/hosts.ini + ANSIBLE_NOCOWS=1 + ANSIBLE_RETRY_FILES_ENABLED=0 + ANSIBLE_STDOUT_CALLBACK=debug + PY_COLORS=1 VIRTUAL_ENV={envdir} # Avoid 2020-01-01 warnings: https://github.com/pypa/pip/issues/6207 PYTHONWARNINGS=ignore:DEPRECATION::pip._internal.cli.base_command PIP_DISABLE_PIP_VERSION_CHECK=1 +passenv = + ANSIBLE_* + DOCKER_* + MOLECULE_* + SSH_AUTH_SOCK + TERM + deps = -r{toxinidir}/test-requirements.txt -r{toxinidir}/requirements.txt whitelist_externals = @@ -20,7 +33,7 @@ commands_pre = pip install -q bindep bindep test commands = - python -m pytest --html={envlogdir}/reports.html --self-contained-html {posargs:--cov=emit_releases_file} + python -m pytest --html={envlogdir}/reports.html --self-contained-html {posargs:--cov=emit_releases_file} scripts [testenv:venv] commands = {posargs} @@ -36,6 +49,17 @@ whitelist_externals = {[testenv]whitelist_externals} commands = {[testenv:linters]commands} [testenv:cireport] -passenv = - SSH_AUTH_SOCK commands = python scripts/tripleo-jobs-gerrit.py {posargs} + +[testenv:molecule] +deps = + ansi2html # GPL (soft-dependency of pytest-html) + docker>=3.7 # Apache + molecule>=2.22rc1 # MIT + paramiko>=2.5.0 # LGPL (soft-dependency of docker that enables ssh protocol) + pytest # MIT + pytest-cov # MIT + pytest-html # MPL 2.0 + pytest-xdist # MIT +commands = + python -m pytest -ra --html={envlogdir}/reports.html --self-contained-html {tty:-s} {posargs} tests diff --git a/zuul.d/layout.yaml b/zuul.d/layout.yaml index 0b066ddd2..606cfc21c 100644 --- a/zuul.d/layout.yaml +++ b/zuul.d/layout.yaml @@ -14,6 +14,7 @@ - tripleo-standalone-scenarios-full - tripleo-undercloud-jobs - tripleo-periodic + - openstack-tox-molecule check: jobs: - openstack-tox-linters