Enforce testing consistency

The upstream OpenStack gate installs docker using the "install-docker"
from within the zuul-jobs repository. To ensure we're able to test role
consistently this change removes our internal docker install tasks
and simply uses the role as provided by zuul.

All of the requirements we were installing for molecule via built in
tox configuration  have all been moved to the unmanaged requirements
file, "molecule-requirements.txt". This file will ensure anything we
install in a virtual-environment is consistent throughout our stack.

The `run-local-test` script has been added to the scripts directory
allowing local development to be setup and executed with minimal,
to no, pre-configuration or setup. This script and its usage has
been documented in the contributing guide.

Change-Id: If7d1ba7e59a1d6918d9606c9df8bfad21c0c47da
Signed-off-by: Kevin Carter <kecarter@redhat.com>
This commit is contained in:
Kevin Carter 2019-07-01 10:42:49 -05:00
parent f16b6e0935
commit 7c23a01bd7
No known key found for this signature in database
GPG Key ID: CE94BD890A47B20A
18 changed files with 257 additions and 195 deletions

View File

@ -100,8 +100,24 @@ the virtual environment before running the playbook.
Local testing of new roles
~~~~~~~~~~~~~~~~~~~~~~~~~~
Role based testing with molecule can be executed from within the
role directory.
Local testing of new roles can be done in any number of ways, however,
the easiest way is via the script `run-local-test`. This script
will setup the local work environment to execute tests mimicking what
Zuul does.
.. warning::
This script makes the assumption the executing user has the
ability to escalate privileges and will modify the local system.
To use this script execute the following command.
.. code-block:: console
$ scripts/run-local-test ${NEWROLENAME}
Role based testing with molecule can be executed directly from within
the role directory.
.. note::

View File

@ -0,0 +1,9 @@
ansible
ansi2html
docker
pytest
pytest-cov
pytest-html
pytest-xdist
mock
molecule>=2.22rc1

65
scripts/run-local-test Executable file
View File

@ -0,0 +1,65 @@
#!/usr/bin/env bash
# Copyright 2019 Red Hat, Inc.
# All Rights Reserved.
#
# 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.
## Shell Opts ----------------------------------------------------------------
set -o pipefail
set -xeuo
## Vars ----------------------------------------------------------------------
export PROJECT_DIR="$(dirname $(readlink -f ${BASH_SOURCE[0]}))/../"
export ROLE_NAME="${ROLE_NAME:-$1}"
## Main ----------------------------------------------------------------------
# Source distribution information
source /etc/os-release || source /usr/lib/os-release
RHT_PKG_MGR=$(command -v dnf || command -v yum)
PYTHON_EXEC=$(command -v python3 || command -v python)
# Install the one requirement we need to run any local test
case "${ID,,}" in
amzn|rhel|centos|fedora)
sudo "${RHT_PKG_MGR}" install -y python*-virtualenv
;;
esac
# Create a virtual env
"${PYTHON_EXEC}" -m virtualenv --system-site-packages "${HOME}/test-python"
# Install local requirements
"${HOME}/test-python/bin/pip" install \
-r "${PROJECT_DIR}/requirements.txt" \
-r "${PROJECT_DIR}/test-requirements.txt" \
-r "${PROJECT_DIR}/molecule-requirements.txt"
# Run bindep
PS1="[\u@\h \W]\$" source "${HOME}/test-python/bin/activate"
"${PROJECT_DIR}/scripts/bindep-install"
# Run local test
source "${PROJECT_DIR}/ansible-test-env.rc"
ansible-playbook -i "${PROJECT_DIR}/tests/hosts.ini" \
-e "ansible_user=${USER}" \
-e "ansible_user_dir=${HOME}" \
"${PROJECT_DIR}/tripleo_ansible/playbooks/prepare-test-host.yml"
# Run test
pushd "${PROJECT_DIR}/tripleo_ansible/roles/${ROLE_NAME}"
molecule test --all
popd

12
tox.ini
View File

@ -25,6 +25,7 @@ setenv =
# paramiko CryptographyDeprecationWarning: https://github.com/ansible/ansible/issues/52598
PYTHONWARNINGS=ignore:DEPRECATION::pip._internal.cli.base_command,ignore::UserWarning
PIP_DISABLE_PIP_VERSION_CHECK=1
sitepackages = True
deps = -r {toxinidir}/test-requirements.txt
whitelist_externals = bash
@ -121,16 +122,7 @@ commands =
# python versions like pyenv ones
basepython=python
deps =
ansible
ansi2html
docker>=3.7
pytest
pytest-cov
pytest-html
pytest-xdist
mock
molecule>=2.22rc1
selinux
-r {toxinidir}/molecule-requirements.txt
[testenv:mol-aide]
basepython = {[testenv:mol]basepython}

View File

@ -0,0 +1,68 @@
---
# Copyright 2019 Red Hat, Inc.
# All Rights Reserved.
#
# 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.
- name: pre prepare
hosts: all
gather_facts: false
tasks:
- name: set basic user fact
fail:
msg: >-
The variable `ansible_user` set this option and try again. On the
CLI this can be defined with "-e ansible_user=${USER}"
when:
- ansible_user is undefined
- name: set basic home fact
fail:
msg: >-
The variable `ansible_user_dir` set this option and try again. On
the CLI this can be defined with "-e ansible_user_dir=${HOME}"
when:
- ansible_user_dir is undefined
- name: Ensure the user has a .ssh directory
file:
path: "{{ ansible_user_dir }}/.ssh"
state: directory
owner: "{{ ansible_user }}"
group: "{{ ansible_user }}"
mode: "0700"
- name: Create ssh key pair
user:
name: "{{ ansible_user }}"
generate_ssh_key: true
ssh_key_bits: 2048
ssh_key_file: "{{ ansible_user_dir }}/.ssh/id_rsa"
- name: Slurp pub key
slurp:
src: "{{ ansible_user_dir ~ '/.ssh/id_rsa.pub' }}"
register: pub_key
- name: Ensure can ssh to can connect to localhost
authorized_key:
user: "{{ ansible_user }}"
key: "{{ pub_key['content'] | b64decode }}"
- name: Get the zuul/zuul-jobs repo
git:
repo: https://opendev.org/zuul/zuul-jobs
dest: "{{ ansible_user_dir }}/zuul-jobs"
version: master
force: true

View File

@ -23,6 +23,10 @@ platforms:
provisioner:
name: ansible
config_options:
defaults:
fact_caching: jsonfile
fact_caching_connection: /tmp/molecule/facts
inventory:
hosts:
all:
@ -32,6 +36,7 @@ provisioner:
log: true
env:
ANSIBLE_STDOUT_CALLBACK: yaml
ANSIBLE_ROLES_PATH: "${ANSIBLE_ROLES_PATH}:${HOME}/zuul-jobs/roles"
scenario:
name: default

View File

@ -26,4 +26,4 @@
tripleo_container_cli: docker
vars:
ansible_python_interpreter: /opt/tripleo-ansible/bin/python
ansible_python_interpreter: "{{ ansible_user_dir }}/test-python/bin/python"

View File

@ -15,65 +15,55 @@
# under the License.
- import_playbook: ../pre-prepare.yml
- name: Prepare
hosts: all
become: true
gather_facts: true
vars:
required_packages:
- docker
- python-docker-py
- python-virtualenv
pre_tasks:
- name: Set current user fact
- name: Check for docker cli
command: "command -v docker"
register: docker_cli
failed_when: false
changed_when: false
- name: Check for docker connection
command: "docker ps"
register: docker_ps
failed_when: false
changed_when: false
- name: set basic user fact
set_fact:
current_user: "{{ lookup('env','USER') }}"
ansible_user: "{{ lookup('env', 'USER') }}"
when:
- ansible_user is undefined
- name: set basic home fact
set_fact:
ansible_user_dir: "{{ lookup('env', 'HOME') }}"
when:
- ansible_user_dir is undefined
roles:
- role: test_deps
- role: install-docker
when:
- (docker_cli.rc != 0) or
(docker_ps.rc != 0)
post_tasks:
- name: Docker block
block:
- name: Install docker
package:
name: "{{ required_packages }}"
state: latest
- name: Ensure "docker" group exists
group:
name: docker
state: present
- name: Ensure the ansible user can access docker
user:
name: "{{ ansible_user | default(current_user) }}"
groups: docker
- name: Start docker
systemd:
name: docker
state: started
- name: Install python-docker in venv
pip:
name: "docker"
virtualenv: /opt/tripleo-ansible
virtualenv_site_packages: true
- name: reset ssh connection to allow user changes to take affect
meta: reset_connection
- name: Install docker-sdk
pip:
name: docker
virtualenv: "{{ ansible_user_dir }}/test-python"
virtualenv_site_packages: true
- name: pull an image
vars:
ansible_python_interpreter: /opt/tripleo-ansible/bin/python
docker_image:
name: fedora:28
source: pull
vars:
ansible_python_interpreter: "{{ ansible_user_dir }}/test-python/bin/python"
- name: Create a data container
vars:
ansible_python_interpreter: /opt/tripleo-ansible/bin/python
docker_container:
name: "{{ item }}"
image: fedora:28
@ -82,3 +72,5 @@
with_items:
- docker-container1
- docker-container2
vars:
ansible_python_interpreter: "{{ ansible_user_dir }}/test-python/bin/python"

View File

@ -23,6 +23,10 @@ platforms:
provisioner:
name: ansible
config_options:
defaults:
fact_caching: jsonfile
fact_caching_connection: /tmp/molecule/facts
inventory:
hosts:
all:
@ -32,6 +36,7 @@ provisioner:
log: true
env:
ANSIBLE_STDOUT_CALLBACK: yaml
ANSIBLE_ROLES_PATH: "${ANSIBLE_ROLES_PATH}:${HOME}/zuul-jobs/roles"
scenario:
name: docker

View File

@ -28,3 +28,6 @@
containers_to_rm:
- docker-container1
- docker-container2
vars:
ansible_python_interpreter: "{{ ansible_user_dir }}/test-python/bin/python"

View File

@ -20,6 +20,7 @@
hosts: all
roles:
- role: tripleo-container-rm
containers_to_rm:
tripleo_container_cli: podman
tripleo_containers_to_rm:
- podman-container1
- podman-container2

View File

@ -15,8 +15,6 @@
# under the License.
- import_playbook: ../pre-prepare.yml
- name: Prepare
hosts: all
become: true

View File

@ -1,46 +0,0 @@
---
# Copyright 2019 Red Hat, Inc.
# All Rights Reserved.
#
# 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.
- name: pre prepare
connection: local
hosts: all
gather_facts: false
tasks:
- name: Set current user fact
set_fact:
current_user_home: "{{ lookup('env','HOME') }}"
current_user: "{{ lookup('env','USER') }}"
- name: Ensure the user has a .ssh directory
file:
path: "{{ current_user_home }}/.ssh"
state: directory
owner: "{{ ansible_user | default(current_user) }}"
group: "{{ ansible_user | default(current_user) }}"
mode: "0700"
- name: Create ssh key pair
user:
name: "{{ ansible_user | default(current_user) }}"
generate_ssh_key: true
ssh_key_bits: 2048
ssh_key_file: "{{ current_user_home }}/.ssh/id_rsa"
- name: Ensure can ssh to can connect to localhost
authorized_key:
user: "{{ ansible_user | default(current_user) }}"
key: "{{ lookup('file', (current_user_home ~ '/.ssh/id_rsa.pub')) }}"

View File

@ -23,6 +23,10 @@ platforms:
provisioner:
name: ansible
config_options:
defaults:
fact_caching: jsonfile
fact_caching_connection: /tmp/molecule/facts
inventory:
hosts:
all:
@ -32,6 +36,7 @@ provisioner:
log: true
env:
ANSIBLE_STDOUT_CALLBACK: yaml
ANSIBLE_ROLES_PATH: "${ANSIBLE_ROLES_PATH}:${HOME}/zuul-jobs/roles"
scenario:
test_sequence:

View File

@ -15,64 +15,57 @@
# under the License.
- import_playbook: ../pre-prepare.yml
- name: Prepare
hosts: all
become: true
gather_facts: true
vars:
required_packages:
- docker
- python-virtualenv
pre_tasks:
- name: Set current user fact
- name: Check for docker cli
command: "command -v docker"
register: docker_cli
failed_when: false
changed_when: false
- name: Check for docker connection
command: "docker ps"
register: docker_ps
failed_when: false
changed_when: false
- name: set basic user fact
set_fact:
current_user: "{{ lookup('env','USER') }}"
ansible_user: "{{ lookup('env', 'USER') }}"
when:
- ansible_user is undefined
- name: set basic home fact
set_fact:
ansible_user_dir: "{{ lookup('env', 'HOME') }}"
when:
- ansible_user_dir is undefined
roles:
- role: test_deps
- role: install-docker
when:
- (docker_cli.rc != 0) or
(docker_ps.rc != 0)
post_tasks:
- name: Docker block
block:
- name: Install docker
package:
name: "{{ required_packages }}"
state: latest
- name: Ensure "docker" group exists
group:
name: docker
state: present
- name: Ensure the ansible user can access docker
user:
name: "{{ ansible_user | default(current_user) }}"
groups: docker
- name: Start docker
systemd:
name: docker
state: started
- name: Install python-docker in venv
pip:
name: "docker"
virtualenv: /opt/tripleo-ansible
virtualenv_site_packages: true
- name: reset ssh connection to allow user changes to take affect
meta: reset_connection
- name: Install docker-sdk
pip:
name: docker
virtualenv: "{{ ansible_user_dir }}/test-python"
virtualenv_site_packages: true
- name: pull an image
vars:
ansible_python_interpreter: /opt/tripleo-ansible/bin/python
docker_image:
name: fedora:28
source: pull
vars:
ansible_python_interpreter: "{{ ansible_user_dir }}/test-python/bin/python"
- name: Create a data container
vars:
ansible_python_interpreter: /opt/tripleo-ansible/bin/python
docker_container:
name: test-container
image: fedora:28
vars:
ansible_python_interpreter: "{{ ansible_user_dir }}/test-python/bin/python"

View File

@ -15,8 +15,6 @@
# under the License.
- import_playbook: ../pre-prepare.yml
- name: Prepare
hosts: all
become: true

View File

@ -1,46 +0,0 @@
---
# Copyright 2019 Red Hat, Inc.
# All Rights Reserved.
#
# 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.
- name: pre prepare
connection: local
hosts: all
gather_facts: false
tasks:
- name: Set current user fact
set_fact:
current_user_home: "{{ lookup('env','HOME') }}"
current_user: "{{ lookup('env','USER') }}"
- name: Ensure the user has a .ssh directory
file:
path: "{{ current_user_home }}/.ssh"
state: directory
owner: "{{ ansible_user | default(current_user) }}"
group: "{{ ansible_user | default(current_user) }}"
mode: "0700"
- name: Create ssh key pair
user:
name: "{{ ansible_user | default(current_user) }}"
generate_ssh_key: true
ssh_key_bits: 2048
ssh_key_file: "{{ current_user_home }}/.ssh/id_rsa"
- name: Ensure can ssh to can connect to localhost
authorized_key:
user: "{{ ansible_user | default(current_user) }}"
key: "{{ lookup('file', (current_user_home ~ '/.ssh/id_rsa.pub')) }}"

View File

@ -112,6 +112,8 @@
- ^tripleo_ansible/roles/tripleo-container-tag/.*
name: tripleo-ansible-centos-7-molecule-tripleo-container-tag
parent: tripleo-ansible-centos-sudo
pre-run:
- tripleo_ansible/playbooks/prepare-test-host.yml
vars:
tox_envlist: mol-tripleo-container-tag
- job:
@ -119,6 +121,8 @@
- ^tripleo_ansible/roles/tripleo-container-rm/.*
name: tripleo-ansible-centos-7-molecule-tripleo-container-rm
parent: tripleo-ansible-centos-sudo
pre-run:
- tripleo_ansible/playbooks/prepare-test-host.yml
vars:
tox_envlist: mol-tripleo-container-rm
- job: