Add molecule testing to the role

This adopts old functional tests to be launched with molecule.
Patch does not intend to extend or refactor set of existing tests,
but to provide a baseline to iterate on and ability to improve coverage
with important usecases.

Change-Id: Ia93b5adb313d5b930086ce90dafe6a63da092aba
Signed-off-by: Dmitriy Rabotyagov <dmitriy.rabotyagov@cleura.com>
This commit is contained in:
Dmitriy Rabotyagov
2025-08-08 17:31:02 +02:00
parent b7a011ce57
commit 711caf62e4
18 changed files with 134 additions and 249 deletions

46
Vagrantfile vendored
View File

@@ -1,46 +0,0 @@
# Note:
# This file is maintained in the openstack-ansible-tests repository.
# https://opendev.org/openstack/openstack-ansible-tests/src/Vagrantfile
#
# If you need to perform any change on it, you should modify the central file,
# then, an OpenStack CI job will propagate your changes to every OSA repository
# since every repo uses the same Vagrantfile
# Verify whether required plugins are installed.
required_plugins = [ "vagrant-disksize" ]
required_plugins.each do |plugin|
if not Vagrant.has_plugin?(plugin)
raise "The vagrant plugin #{plugin} is required. Please run `vagrant plugin install #{plugin}`"
end
end
Vagrant.configure(2) do |config|
config.vm.provider "virtualbox" do |v|
v.memory = 6144
v.cpus = 2
# https://github.com/hashicorp/vagrant/issues/9524
v.customize ["modifyvm", :id, "--audio", "none"]
end
config.vm.synced_folder ".", "/vagrant", type: "rsync"
config.vm.provision "shell",
privileged: false,
inline: <<-SHELL
cd /vagrant
./run_tests.sh
SHELL
config.vm.define "centos8" do |centos8|
centos8.vm.box = "centos/8"
end
config.vm.define "debian10" do |debian10|
debian10.vm.box = "debian/buster64"
end
config.vm.define "ubuntu2004" do |focal|
focal.disksize.size = "40GB"
focal.vm.box = "ubuntu/focal64"
end
end

View File

@@ -1,33 +0,0 @@
export VIRTUAL_ENV=$(pwd)
export ANSIBLE_HOST_KEY_CHECKING=False
export ANSIBLE_SSH_CONTROL_PATH=/tmp/%%h-%%r
# TODO (odyssey4me) These are only here as they are non-standard folder
# names for Ansible 1.9.x. We are using the standard folder names for
# Ansible v2.x. We can remove this when we move to Ansible 2.x.
export ANSIBLE_ACTION_PLUGINS=${HOME}/.ansible/plugins/action
export ANSIBLE_CALLBACK_PLUGINS=${HOME}/.ansible/plugins/callback
export ANSIBLE_FILTER_PLUGINS=${HOME}/.ansible/plugins/filter
export ANSIBLE_LOOKUP_PLUGINS=${HOME}/.ansible/plugins/lookup
# This is required as the default is the current path or a path specified
# in ansible.cfg
export ANSIBLE_LIBRARY=${HOME}/.ansible/plugins/library
# This is required as the default is '/etc/ansible/roles' or a path
# specified in ansible.cfg
export ANSIBLE_ROLES_PATH=${HOME}/.ansible/roles:$(pwd)/..
export ANSIBLE_SSH_ARGS="-o ControlMaster=no \
-o UserKnownHostsFile=/dev/null \
-o StrictHostKeyChecking=no \
-o ServerAliveInterval=64 \
-o ServerAliveCountMax=1024 \
-o Compression=no \
-o TCPKeepAlive=yes \
-o VerifyHostKeyDNS=no \
-o ForwardX11=no \
-o ForwardAgent=yes"
echo "Run manual functional tests by executing the following:"
echo "# ./.tox/functional/bin/ansible-playbook -i tests/inventory tests/test.yml"

View File

@@ -0,0 +1,47 @@
---
dependency:
name: galaxy
options:
requirements-file: requirements.yml
driver:
name: docker
platforms:
- name: "haproxy-${MOLECULE_SCENARIO_NAME}"
image: "${DOCKER_REGISTRY:-quay.io/gotmax23}/${DOCKER_IMAGE_TAG:-debian-systemd:bookworm}"
command: ${DOCKER_COMMAND:-""}
pre_build_image: true
privileged: true
systemd: true
groups:
- service_hosts
provisioner:
name: ansible
lint:
name: ansible-lint
playbooks:
prepare: ../../tests/prepare.yml
converge: ../../tests/test.yml
side_effect: ../../tests/test_service_updates.yml
config_options:
defaults:
inject_facts_as_vars: false
scenario:
name: default
test_sequence:
- dependency
- cleanup
- destroy
- syntax
- create
- prepare
- converge
- idempotence
- verify ../../tests/verify.yml
- side_effect
- verify ../../tests/verify_service_updates.yml
- cleanup
- destroy

13
requirements.yml Normal file
View File

@@ -0,0 +1,13 @@
---
roles:
- name: pki
src: https://opendev.org/openstack/ansible-role-pki
scm: git
version: master
collections:
- name: community.crypto
source: https://github.com/ansible-collections/community.crypto
type: git
- name: ansible.utils
source: https://github.com/ansible-collections/ansible.utils
type: git

View File

@@ -1,88 +0,0 @@
#!/usr/bin/env bash
# Copyright 2015, Rackspace US, 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.
# PURPOSE:
# This script clones the openstack-ansible-tests repository to the
# tests/common folder in order to be able to re-use test components
# for role testing. This is intended to be the thinnest possible
# shim for test execution outside of OpenStack CI.
# WARNING:
# This file is maintained in the openstack-ansible-tests repository.
# https://opendev.org/openstack/openstack-ansible-tests/src/run_tests.sh
# If you need to modify this file, update the one in the openstack-ansible-tests
# repository and then update this file as well. The purpose of this file is to
# prepare the host and then execute all the tox tests.
#
## Shell Opts ----------------------------------------------------------------
set -xeu
## Vars ----------------------------------------------------------------------
WORKING_DIR="$(readlink -f $(dirname $0))"
OSA_PROJECT_NAME="$(sed -n 's|^project=openstack/\(.*\).git$|\1|p' $(pwd)/.gitreview)"
COMMON_TESTS_PATH="${WORKING_DIR}/tests/common"
TESTING_HOME=${TESTING_HOME:-$HOME}
ZUUL_TESTS_CLONE_LOCATION="/home/zuul/src/opendev.org/openstack/openstack-ansible-tests"
# Use .gitreview as the key to determine the appropriate
# branch to clone for tests.
TESTING_BRANCH=$(awk -F'=' '/defaultbranch/ {print $2}' "${WORKING_DIR}/.gitreview")
if [[ "${TESTING_BRANCH}" == "" ]]; then
TESTING_BRANCH="master"
fi
## Main ----------------------------------------------------------------------
# Source distribution information
source /etc/os-release || source /usr/lib/os-release
# Figure out the appropriate package install command
case ${ID,,} in
centos|rhel|fedora|rocky) pkg_mgr_cmd="dnf install -y" ;;
ubuntu|debian) pkg_mgr_cmd="apt-get install -y" ;;
*) echo "unsupported distribution: ${ID,,}"; exit 1 ;;
esac
# Install git so that we can clone the tests repo if git is not available
which git &>/dev/null || eval sudo "${pkg_mgr_cmd}" git
# Clone the tests repo for access to the common test script
if [[ ! -d "${COMMON_TESTS_PATH}" ]]; then
# The tests repo doesn't need a clone, we can just
# symlink it.
if [[ "${OSA_PROJECT_NAME}" == "openstack-ansible-tests" ]]; then
ln -s "${WORKING_DIR}" "${COMMON_TESTS_PATH}"
# In zuul v3 any dependent repository is placed into
# /home/zuul/src/opendev.org, so we check to see
# if there is a tests checkout there already. If so, we
# symlink that and use it.
elif [[ -d "${ZUUL_TESTS_CLONE_LOCATION}" ]]; then
ln -s "${ZUUL_TESTS_CLONE_LOCATION}" "${COMMON_TESTS_PATH}"
# Otherwise we're clearly not in zuul or using a previously setup
# repo in some way, so just clone it from upstream.
else
git clone -b "${TESTING_BRANCH}" \
https://opendev.org/openstack/openstack-ansible-tests \
"${COMMON_TESTS_PATH}"
fi
fi
# Execute the common test script
source tests/common/run_tests_common.sh

View File

@@ -43,13 +43,13 @@
tags:
- haproxy-user
- name: Create haproxy conf.d dir
- name: Create haproxy config directories
ansible.builtin.file:
path: "{{ item }}"
state: directory
mode: "0755"
owner: haproxy
group: haproxy
owner: root
group: root
with_items:
- /etc/haproxy/conf.d
- "{{ haproxy_ssl_cert_path }}"

View File

@@ -1,5 +0,0 @@
---
- name: apt_package_pinning
src: https://opendev.org/openstack/openstack-ansible-apt_package_pinning
scm: git
version: master

View File

@@ -1,15 +0,0 @@
---
# Copyright 2017, Rackspace US, 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.
ansible_host: 127.0.0.1

View File

@@ -1,5 +0,0 @@
[all]
localhost
[haproxy_all]
localhost

14
tests/prepare.yml Normal file
View File

@@ -0,0 +1,14 @@
---
- name: Prepare environment for testing
hosts: service_hosts
vars:
procps_package_name:
redhat: procps-ng
debian: procps
tasks:
- name: Install required packages
ansible.builtin.package:
name:
- python3-cryptography
- "{{ procps_package_name[ansible_facts['os_family'] | lower] }}"
update_cache: "{{ (ansible_facts['os_family'] | lower == 'debian') | ternary(true, omit) }}"

View File

@@ -1,6 +1,7 @@
---
external_lb_vip_address: 127.0.0.1
internal_lb_vip_address: 127.0.0.1
haproxy_pki_setup_host: "{{ inventory_hostname }}"
haproxy_service_configs:
- service:
haproxy_service_name: test_group
@@ -38,4 +39,4 @@ haproxy_service_configs:
ip_addr: "127.0.0.1"
haproxy_port: 65535
haproxy_balance_type: tcp
state: "{{ absent_service_state }}"
state: present

View File

@@ -14,54 +14,8 @@
# limitations under the License.
- name: Playbook for role testing
hosts: localhost
connection: local
user: root
become: true
hosts: service_hosts
vars_files:
- test-vars.yml
tasks:
- name: Create marker file for idempotence
copy:
content: mark
dest: /tmp/haproxy_pass1
register: haproxy_pass1
- name: Set fact for idempotence test
set_fact:
idempotence_pass_1: "{{ haproxy_pass1 is changed }}"
- name: Set fact for absent service state
set_fact:
absent_service_state: "{{ (haproxy_pass1 is changed) | ternary('present', 'absent') }}"
- name: Run the haproxy_server role
include_role:
name: "haproxy_server"
- name: Run role again on first pass
when:
- "idempotence_pass_1 | bool"
block:
- name: Ensure the absent service is present
stat:
path: "/etc/haproxy/conf.d/test_absent_service"
register: absent_services
failed_when: not absent_services.stat.exists
- name: Set fact for absent service state
set_fact:
absent_service_state: "absent"
- name: Run the haproxy_server role (again)
include_role:
name: "haproxy_server"
- name: Ensure the absent service is missing
stat:
path: "/etc/haproxy/conf.d/test_absent_service"
register: absent_services
when:
- "not (idempotence_pass_1 | bool)"
failed_when: absent_services.stat.exists
roles:
- "{{ playbook_dir | dirname | basename }}"

View File

@@ -0,0 +1,12 @@
---
- name: Playbook for role testing
hosts: service_hosts
vars:
external_lb_vip_address: 127.0.0.1
internal_lb_vip_address: 127.0.0.1
haproxy_pki_setup_host: "{{ inventory_hostname }}"
haproxy_service_configs:
- haproxy_service_name: test_absent_service
state: absent
roles:
- "{{ playbook_dir | dirname | basename }}"

9
tests/verify.yml Normal file
View File

@@ -0,0 +1,9 @@
---
- name: Testing result after role re-run
hosts: service_hosts
tasks:
- name: Ensure the absent service is present
ansible.builtin.stat:
path: "/etc/haproxy/conf.d/test_absent_service"
register: absent_services
failed_when: not absent_services.stat.exists

View File

@@ -0,0 +1,9 @@
---
- name: Testing result after role re-run
hosts: service_hosts
tasks:
- name: Ensure the absent service is missing
ansible.builtin.stat:
path: "/etc/haproxy/conf.d/test_absent_service"
register: absent_services
failed_when: absent_services.stat.exists

17
tox.ini
View File

@@ -94,3 +94,20 @@ commands =
{[testenv:bashate]commands}
{[testenv:ansible-lint]commands}
{[testenv:ansible-syntax]commands}
[testenv:molecule]
# You can use DOCKER_REGISTRY and DOCKER_IMAGE_TAG to switch between
# tested distros. I.e:
# DOCKER_IMAGE_TAG=ubuntu-systemd:jammy tox -e molecule
deps =
-c{env:TOX_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/master}
-r{env:OSA_TEST_REQUIREMENTS_FILE:https://opendev.org/openstack/openstack-ansible/raw/branch/{env:TEST_BRANCH:master}/test-requirements.txt}
commands =
molecule test
passenv =
{[testenv]passenv}
DOCKER_REGISTRY
DOCKER_IMAGE_TAG
DOCKER_COMMAND

View File

@@ -65,7 +65,7 @@ _haproxy_pki_install_certificates: |
'src': haproxy_user_ssl_cert | default(haproxy_pki_certs_path ~ _cert_basename ~ '.crt'),
'dest': haproxy_ssl_temp_path ~ _cert_basename ~ '.crt',
'owner': 'root',
'group': 'root',
'group': 'haproxy',
'mode': '0644'
}
)
@@ -75,8 +75,8 @@ _haproxy_pki_install_certificates: |
'src': haproxy_user_ssl_key | default(haproxy_pki_keys_path ~ _cert_basename ~ '.key.pem'),
'dest': haproxy_ssl_temp_path ~ _cert_basename ~ '.key',
'owner': 'root',
'group': 'root',
'mode': '0644'
'group': 'haproxy',
'mode': '0640'
}
)
%}
@@ -87,7 +87,7 @@ _haproxy_pki_install_certificates: |
'src': haproxy_user_ssl_ca_cert | default(haproxy_pki_intermediate_cert_path),
'dest': haproxy_ssl_temp_path ~ _cert_basename ~ '-ca.crt',
'owner': 'root',
'group': 'root',
'group': 'haproxy',
'mode': '0644'
})
%}

View File

@@ -16,6 +16,7 @@
- project:
templates:
- openstack-ansible-linters-jobs
- openstack-ansible-molecule
- openstack-ansible-deploy-infra_lxc-jobs
- openstack-ansible-deploy-aio_metal-jobs
- openstack-ansible-upgrade-infra_lxc-jobs