From 4666971ac5c2d2ac612aa085a002c1db60be09f6 Mon Sep 17 00:00:00 2001 From: Paul Belanger Date: Fri, 17 Aug 2018 12:55:10 -0400 Subject: [PATCH] Switch to molecule for testing Molecule is the defacto testing tool for ansible roles. Switch to it to make it easier for users to test. Change-Id: I881e895877c9702e62c4415d48b0f33f34f7487b Depends-On: https://review.openstack.org/593369 Signed-off-by: Paul Belanger --- .yamllint | 10 +++++ .zuul.yaml | 4 +- bindep.txt | 9 +---- meta/main.yml | 16 ++++---- molecule/default/Dockerfile.j2 | 9 +++++ molecule/default/molecule.yml | 34 ++++++++++++++++ molecule/tests/conftest.py | 27 +++++++++++++ {tests => molecule/tests}/test_role.py | 55 +++++++++++++++++++++++++- tasks/install/pip.yaml | 2 +- templates/etc/nodepool/nodepool.yaml | 1 + test-requirements.txt | 6 +-- tests/collect-logs.yaml | 1 - tests/playbooks/post.yaml | 21 +++------- tools/test-setup.sh | 21 ++++++++++ tox.ini | 24 +++++------ 15 files changed, 187 insertions(+), 53 deletions(-) create mode 100644 .yamllint create mode 100644 molecule/default/Dockerfile.j2 create mode 100644 molecule/default/molecule.yml create mode 100644 molecule/tests/conftest.py rename {tests => molecule/tests}/test_role.py (70%) create mode 100755 tools/test-setup.sh diff --git a/.yamllint b/.yamllint new file mode 100644 index 0000000..a4d53d6 --- /dev/null +++ b/.yamllint @@ -0,0 +1,10 @@ +extends: default + +rules: + braces: + max-spaces-inside: 1 + level: error + brackets: + max-spaces-inside: 1 + level: error + line-length: disable diff --git a/.zuul.yaml b/.zuul.yaml index ba9c219..11eed27 100644 --- a/.zuul.yaml +++ b/.zuul.yaml @@ -1,3 +1,4 @@ +--- - job: name: ansible-role-nodepool-base pre-run: tests/playbooks/pre.yaml @@ -7,7 +8,6 @@ - tests/collect-logs.yaml roles: - zuul: openstack/ansible-role-nodepool - - zuul: openstack/zuul-jobs # Testing for nodepool_install_method: pip - job: @@ -69,6 +69,7 @@ - ansible-role-nodepool-src-ubuntu-bionic - ansible-role-nodepool-src-ubuntu-xenial - tox-linters + - windmill-tox-molecule gate: jobs: - ansible-role-nodepool-fedora-latest @@ -78,3 +79,4 @@ - ansible-role-nodepool-src-ubuntu-bionic - ansible-role-nodepool-src-ubuntu-xenial - tox-linters + - windmill-tox-molecule diff --git a/bindep.txt b/bindep.txt index cb8c48d..a62fb2d 100644 --- a/bindep.txt +++ b/bindep.txt @@ -1,10 +1,5 @@ # This is a cross-platform list tracking distribution packages needed by tests; # see http://docs.openstack.org/infra/bindep/ for additional information. -git -libffi-devel [platform:rpm] -libffi-dev [platform:dpkg] -libselinux-python [platform:rpm] -libssl-dev [platform:dpkg] -openssl-devel [platform:rpm] -python2-dnf [platform:fedora] +docker.io [test platform:dpkg] +docker [test platform:fedora] diff --git a/meta/main.yml b/meta/main.yml index 9370487..48af3e6 100644 --- a/meta/main.yml +++ b/meta/main.yml @@ -23,13 +23,13 @@ galaxy_info: license: Apache min_ansible_version: 2.4 platforms: - - name: Fedora - versions: - - 27 - - name: Ubuntu - versions: - - 16.04 - - 18.04 + - name: Fedora + versions: + - 27 + - name: Ubuntu + versions: + - 16.04 + - 18.04 categories: - - system + - system dependencies: [] diff --git a/molecule/default/Dockerfile.j2 b/molecule/default/Dockerfile.j2 new file mode 100644 index 0000000..0a084c6 --- /dev/null +++ b/molecule/default/Dockerfile.j2 @@ -0,0 +1,9 @@ +# Molecule managed + +{% if item.registry is defined %} +FROM {{ item.registry.url }}/{{ item.image }} +{% else %} +FROM {{ item.image }} +{% endif %} + +RUN apt-get update && apt-get install -y python sudo bash ca-certificates python-pip python3-pip && apt-get clean; diff --git a/molecule/default/molecule.yml b/molecule/default/molecule.yml new file mode 100644 index 0000000..4eda9ea --- /dev/null +++ b/molecule/default/molecule.yml @@ -0,0 +1,34 @@ +--- +dependency: + name: galaxy +driver: + name: docker +lint: + name: yamllint +platforms: + - name: ubuntu-bionic + image: ubuntu:bionic +provisioner: + name: ansible + config_options: + ssh_connection: + pipelining: true + inventory: + group_vars: + all: + nodepool_service_nodepool_builder_manage: false + nodepool_service_nodepool_launcher_manage: false + lint: + name: ansible-lint + log: true + playbooks: + converge: ../../tests/playbooks/run.yaml +scenario: + name: default +verifier: + name: testinfra + directory: ../tests + options: + verbose: true + lint: + name: flake8 diff --git a/molecule/tests/conftest.py b/molecule/tests/conftest.py new file mode 100644 index 0000000..7ef1c47 --- /dev/null +++ b/molecule/tests/conftest.py @@ -0,0 +1,27 @@ +# Copyright 2018 Red Hat, Inc. +# +# 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 pytest + + +@pytest.fixture +def platform_docker(host): + return host.file('/.dockerenv').exists + + +@pytest.fixture(autouse=True) +def skip_platform_docker(request, platform_docker): + marker = request.node.get_marker('skip_if_docker') + if marker and platform_docker: + pytest.skip('Skipping docker') diff --git a/tests/test_role.py b/molecule/tests/test_role.py similarity index 70% rename from tests/test_role.py rename to molecule/tests/test_role.py index edf219e..6b87e65 100644 --- a/tests/test_role.py +++ b/molecule/tests/test_role.py @@ -12,6 +12,8 @@ # License for the specific language governing permissions and limitations # under the License. +import pytest + def test_nodepool_user(host): user = host.user('nodepool') @@ -62,6 +64,15 @@ def test_nodepool_images_directory(host): assert f.mode == 0o755 +def test_nodepool_logs_directory(host): + f = host.file('/var/log/nodepool') + assert f.exists + assert f.is_directory + assert f.user == 'nodepool' + assert f.group == 'nodepool' + assert f.mode == 0o755 + + def test_nodepool_builder_logging_config(host): f = host.file('/etc/nodepool/builder-logging.conf') assert f.exists @@ -71,14 +82,34 @@ def test_nodepool_builder_logging_config(host): assert f.mode == 0o644 -def test_nodepool_builder_service(host): +def test_nodepool_builder_service_config(host): f = host.file('/etc/systemd/system/nodepool-builder.service') assert f.exists assert f.is_file assert f.user == 'root' assert f.group == 'root' assert f.mode == 0o644 + del f + f = host.file('/etc/systemd/system/nodepool-builder.service.d') + assert f.exists + assert f.is_directory + assert f.user == 'root' + assert f.group == 'root' + assert f.mode == 0o755 + del f + + f = host.file( + '/etc/systemd/system/nodepool-builder.service.d/override.conf') + assert f.exists + assert f.is_file + assert f.user == 'root' + assert f.group == 'root' + assert f.mode == 0o644 + + +@pytest.mark.skip_if_docker() +def test_nodepool_builder_service(host): service = host.service('nodepool-builder') assert service.is_running assert service.is_enabled @@ -93,14 +124,34 @@ def test_nodepool_launcher_logging_config(host): assert f.mode == 0o644 -def test_nodepool_launcher_service(host): +def test_nodepool_launcher_service_config(host): f = host.file('/etc/systemd/system/nodepool-launcher.service') assert f.exists assert f.is_file assert f.user == 'root' assert f.group == 'root' assert f.mode == 0o644 + del f + f = host.file('/etc/systemd/system/nodepool-launcher.service.d') + assert f.exists + assert f.is_directory + assert f.user == 'root' + assert f.group == 'root' + assert f.mode == 0o755 + del f + + f = host.file( + '/etc/systemd/system/nodepool-launcher.service.d/override.conf') + assert f.exists + assert f.is_file + assert f.user == 'root' + assert f.group == 'root' + assert f.mode == 0o644 + + +@pytest.mark.skip_if_docker() +def test_nodepool_launcher_service(host): service = host.service('nodepool-launcher') assert service.is_running assert service.is_enabled diff --git a/tasks/install/pip.yaml b/tasks/install/pip.yaml index 1e7e77f..c901f7c 100644 --- a/tasks/install/pip.yaml +++ b/tasks/install/pip.yaml @@ -16,7 +16,7 @@ become: true pip: executable: "{{ nodepool_pip_executable|default(omit) }}" - editable : "{{ nodepool_pip_editable|default(omit) }}" + editable: "{{ nodepool_pip_editable|default(omit) }}" extra_args: "{{ nodepool_pip_extra_args|default(omit) }}" name: "{{ nodepool_pip_name }}" version: "{{ nodepool_pip_version|default(omit) }}" diff --git a/templates/etc/nodepool/nodepool.yaml b/templates/etc/nodepool/nodepool.yaml index a2ca430..68611b5 100644 --- a/templates/etc/nodepool/nodepool.yaml +++ b/templates/etc/nodepool/nodepool.yaml @@ -1,6 +1,7 @@ # This file is generated by Ansible # DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN # +--- images-dir: /opt/nodepool/images zookeeper-servers: diff --git a/test-requirements.txt b/test-requirements.txt index bea5a9f..6a1de18 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -1,3 +1,3 @@ -ansible-lint -hacking<0.11,>=0.10 -junit2html +ara +docker +molecule diff --git a/tests/collect-logs.yaml b/tests/collect-logs.yaml index 9bc3850..56cf33d 100644 --- a/tests/collect-logs.yaml +++ b/tests/collect-logs.yaml @@ -21,7 +21,6 @@ delegate_to: "{{ inventory_hostname }}" with_items: - "{{ ansible_user_dir }}/{{ zuul.project.src_dir }}/junit.xml" - - "{{ ansible_user_dir }}/{{ zuul.project.src_dir }}/junit.xml.html" - name: Prepare nodepool log files become: yes diff --git a/tests/playbooks/post.yaml b/tests/playbooks/post.yaml index f9d1a11..7988287 100644 --- a/tests/playbooks/post.yaml +++ b/tests/playbooks/post.yaml @@ -1,17 +1,8 @@ - hosts: all tasks: - - block: - - name: Run testinfra validation - include_role: - name: tox - vars: - tox_envlist: testinfra - tox_install_siblings: false - always: - - name: Run junit2html - include_role: - name: tox - vars: - tox_envlist: venv - tox_extra_args: -vv junit2html junit.xml - tox_install_siblings: false + - name: Run testinfra validation + include_role: + name: tox + vars: + tox_envlist: testinfra + tox_install_siblings: false diff --git a/tools/test-setup.sh b/tools/test-setup.sh new file mode 100755 index 0000000..5256b02 --- /dev/null +++ b/tools/test-setup.sh @@ -0,0 +1,21 @@ +#!/bin/bash -ex +# Copyright 2018 Red Hat, Inc. +# +# 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. + +if ! [ $(getent group docker) ]; then + sudo groupadd docker +fi +sudo gpasswd -a ${USER} docker +sudo service docker restart diff --git a/tox.ini b/tox.ini index 9c9fccf..07b53ec 100644 --- a/tox.ini +++ b/tox.ini @@ -17,10 +17,8 @@ commands= sphinx-build -b html doc/source doc/build/html [testenv:testinfra] -deps = - testinfra commands = - pytest --sudo --junit-xml junit.xml tests/test_role.py + pytest --junit-xml junit.xml --sudo --verbose molecule/tests [testenv:venv] commands = {posargs} @@ -34,16 +32,12 @@ builtins = _ exclude=.venv,.git,.tox,dist,doc,*openstack/common*,*lib/python*,*egg,build [testenv:linters] -setenv = - ANSIBLE_ROLES_PATH = .. -whitelist_externals = bash commands = - # PEP8 Lint Check - flake8 - # Ansible Lint Check - bash -c "find . -not -path '*/\.*' -type f -regex '.*.y[a]?ml' -print0 | \ - xargs -t -n1 -0 ansible-lint" - # Ansible Syntax Check - bash -c "find tests -type f -regex '.*.y[a]?ml' -print | xargs -t -n1 \ - ansible-playbook --syntax-check -i tests/inventory \ - -e rolename=$(basename $(pwd)) > /dev/null" + molecule lint + +[testenv:molecule] +sitepackages = True +setenv = + ANSIBLE_CALLBACK_PLUGINS = {envsitepackagesdir}/ara/plugins/callbacks +commands = + molecule test