Skip to content

Commit 2034137

Browse files
committed
test: ensure role gathers the facts it uses by having test clear_facts before include_role
The role gathers the facts it uses. For example, if the user uses `ANSIBLE_GATHERING=explicit`, the role uses the `setup` module with the facts and subsets it requires. This change allows us to test this. Before every role invocation, the test will use `meta: clear_facts` so that the role starts with no facts. Create a task file tests/tasks/run_role_with_clear_facts.yml to do the tasks to clear the facts and run the role. Note that this means we don't need to use `gather_facts` for the tests. Some vars defined using `ansible_facts` have been changed to be defined with `set_fact` instead. This is because of the fact that `vars` are lazily evaluated - the var might be referenced when the facts have been cleared, and will issue an error like `ansible_facts["distribution"] is undefined`. This is typically done for blocks that have a `when` condition that uses `ansible_facts` and the block has a role invocation using run_role_with_clear_facts.yml These have been rewritten to define the `when` condition using `set_fact`. This is because the `when` condition is evaluated every time a task is invoked in the block, and if the facts are cleared, this will raise an undefined variable error. Signed-off-by: Rich Megginson <rmeggins@redhat.com>
1 parent c84b103 commit 2034137

8 files changed

Lines changed: 89 additions & 58 deletions

.ansible-lint

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ exclude_paths:
2020
- .github/
2121
- .markdownlint.yaml
2222
- examples/roles/
23+
- .collection/
2324
mock_roles:
2425
- linux-system-roles.trustee_server
2526
supported_ansible_also:

.github/workflows/ansible-lint.yml

Lines changed: 22 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,15 @@ jobs:
2222
!((github.event_name == 'pull_request' && contains(github.event.pull_request.title, '[citest_skip]')) ||
2323
(github.event_name == 'push' && contains(github.event.head_commit.message, '[citest_skip]')))
2424
runs-on: ubuntu-latest
25+
strategy:
26+
fail-fast: false
27+
matrix:
28+
# There should be one version which is the one used by the Automation Hub gating, and
29+
# one for the latest version.
30+
# https://github.com/ansible-collections/partner-certification-checker/blob/main/.github/workflows/certification-reusable.yml#L108
31+
versions:
32+
- { ansible_lint: "24.*", ansible: "2.16.*", python: "3.12" }
33+
- { ansible_lint: "26.*", ansible: "2.20.*", python: "3.13" }
2534
steps:
2635
- name: Update pip, git
2736
run: |
@@ -35,53 +44,20 @@ jobs:
3544
- name: Install tox, tox-lsr
3645
run: |
3746
set -euxo pipefail
38-
pip3 install "git+https://github.com/linux-system-roles/tox-lsr@3.17.1"
47+
pip3 install "git+https://github.com/linux-system-roles/tox-lsr@3.18.1"
48+
49+
- name: Set up Python
50+
uses: actions/setup-python@v6
51+
with:
52+
python-version: ${{ matrix.versions.python }}
3953

4054
- name: Convert role to collection format
41-
id: collection
42-
run: |
43-
set -euxo pipefail
44-
TOXENV=collection lsr_ci_runtox
45-
coll_dir=".tox/ansible_collections/$LSR_ROLE2COLL_NAMESPACE/$LSR_ROLE2COLL_NAME"
46-
# cleanup after collection conversion
47-
rm -rf "$coll_dir/.ansible" .tox/ansible-plugin-scan "$coll_dir/.collection"
48-
# ansible-lint action requires a .git directory???
49-
# https://github.com/ansible/ansible-lint/blob/main/action.yml#L45
50-
mkdir -p "$coll_dir/.git"
51-
meta_req_file="${{ github.workspace }}/meta/collection-requirements.yml"
52-
test_req_file="${{ github.workspace }}/tests/collection-requirements.yml"
53-
if [ -f "$meta_req_file" ] && [ -f "$test_req_file" ]; then
54-
coll_req_file="${{ github.workspace }}/req.yml"
55-
python -c 'import sys; import yaml
56-
hsh1 = yaml.safe_load(open(sys.argv[1]))
57-
hsh2 = yaml.safe_load(open(sys.argv[2]))
58-
coll = {}
59-
for item in hsh1["collections"] + hsh2["collections"]:
60-
if isinstance(item, dict):
61-
name = item["name"]
62-
rec = item
63-
else:
64-
name = item # assume string
65-
rec = {"name": name}
66-
if name not in coll:
67-
coll[name] = rec
68-
hsh1["collections"] = list(coll.values())
69-
yaml.safe_dump(hsh1, open(sys.argv[3], "w"))' "$meta_req_file" "$test_req_file" "$coll_req_file"
70-
echo merged "$coll_req_file"
71-
cat "$coll_req_file"
72-
elif [ -f "$meta_req_file" ]; then
73-
coll_req_file="$meta_req_file"
74-
elif [ -f "$test_req_file" ]; then
75-
coll_req_file="$test_req_file"
76-
else
77-
coll_req_file=""
78-
fi
79-
echo "coll_req_file=$coll_req_file" >> $GITHUB_OUTPUT
55+
run: tox -e collection
8056

8157
- name: Run ansible-lint
82-
uses: ansible/ansible-lint@v26
83-
with:
84-
working_directory: ${{ github.workspace }}/.tox/ansible_collections/${{ env.LSR_ROLE2COLL_NAMESPACE }}/${{ env.LSR_ROLE2COLL_NAME }}
85-
requirements_file: ${{ steps.collection.outputs.coll_req_file }}
86-
env:
87-
ANSIBLE_COLLECTIONS_PATH: ${{ github.workspace }}/.tox
58+
run: |
59+
set -euxo pipefail
60+
LSR_ANSIBLE_LINT_DEP="ansible-lint==${{ matrix.versions.ansible_lint }}" \
61+
LSR_ANSIBLE_LINT_ANSIBLE_DEP="ansible-core==${{ matrix.versions.ansible }}" \
62+
tox -x testenv:ansible-lint-collection.basepython="python${{ matrix.versions.python }}" \
63+
-e ansible-lint-collection

.github/workflows/ansible-managed-var-comment.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ jobs:
3333
- name: Install tox, tox-lsr
3434
run: |
3535
set -euxo pipefail
36-
pip3 install "git+https://github.com/linux-system-roles/tox-lsr@3.17.1"
36+
pip3 install "git+https://github.com/linux-system-roles/tox-lsr@3.18.1"
3737
3838
- name: Run ansible-plugin-scan
3939
run: |

.github/workflows/ansible-test.yml

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,17 @@ jobs:
2222
!((github.event_name == 'pull_request' && contains(github.event.pull_request.title, '[citest_skip]')) ||
2323
(github.event_name == 'push' && contains(github.event.head_commit.message, '[citest_skip]')))
2424
runs-on: ubuntu-latest
25+
strategy:
26+
fail-fast: false # get all results, not just the first failure
27+
matrix:
28+
versions:
29+
- { ansible: "2-14", python: "3.9" }
30+
- { ansible: "2-16", python: "3.11" }
31+
- { ansible: "2-17", python: "3.12" }
32+
- { ansible: "2-18", python: "3.12" }
33+
- { ansible: "2-19", python: "3.13" }
34+
- { ansible: "2-20", python: "3.13" }
35+
- { ansible: "milestone", python: "3.13" }
2536
steps:
2637
- name: Update pip, git
2738
run: |
@@ -36,16 +47,18 @@ jobs:
3647
- name: Install tox, tox-lsr
3748
run: |
3849
set -euxo pipefail
39-
pip3 install "git+https://github.com/linux-system-roles/tox-lsr@3.17.1"
50+
pip3 install "git+https://github.com/linux-system-roles/tox-lsr@3.18.1"
51+
52+
- name: Set up Python
53+
uses: actions/setup-python@v6
54+
with:
55+
python-version: ${{ matrix.versions.python }}
4056

4157
- name: Convert role to collection format
42-
run: |
43-
set -euxo pipefail
44-
TOXENV=collection lsr_ci_runtox
58+
run: tox -e collection
4559

4660
- name: Run ansible-test
47-
uses: ansible-community/ansible-test-gh-action@release/v1
48-
with:
49-
testing-type: sanity # wokeignore:rule=sanity
50-
ansible-core-version: stable-2.17
51-
collection-src-directory: ${{ github.workspace }}/.tox/ansible_collections/${{ env.LSR_ROLE2COLL_NAMESPACE }}/${{ env.LSR_ROLE2COLL_NAME }}
61+
run: |
62+
tox \
63+
-x testenv:ansible-test-${{ matrix.versions.ansible }}.basepython="python${{ matrix.versions.python }}" \
64+
-e ansible-test-${{ matrix.versions.ansible }}

.github/workflows/qemu-kvm-integration-tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ jobs:
110110
python3 -m pip install --upgrade pip
111111
sudo apt update
112112
sudo apt install -y --no-install-recommends git ansible-core genisoimage qemu-system-x86
113-
pip3 install "git+https://github.com/linux-system-roles/tox-lsr@3.17.1"
113+
pip3 install "git+https://github.com/linux-system-roles/tox-lsr@3.18.1"
114114
115115
# HACK: Drop this when moving this workflow to 26.04 LTS
116116
- name: Update podman to 5.x for compatibility with bootc-image-builder's podman 5

plans/test_playbooks_parallel.fmf

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ prepare:
3030
if grep -q 'CentOS Linux release 7.9' /etc/redhat-release; then
3131
sed -i '/^mirror/d;s/#\?\(baseurl=http:\/\/\)mirror/\1vault/' /etc/yum.repos.d/*.repo
3232
fi
33+
- name: Ensure use of devel site for yum repos
34+
script: |
35+
sed -i -e 's|\.lab\.bos\.|.devel.|g' -e 's|\.eng\.bos\.|.devel.|g' /etc/yum.repos.d/*.repo
3336
discover:
3437
- name: Prepare managed node
3538
how: fmf
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
---
2+
# DO NOT EDIT THIS FILE - managed by linux-system-roles/.github
3+
# Task file: clear_facts, run linux-system-roles.trustee_server.
4+
# Include this with include_tasks or import_tasks
5+
# Input:
6+
# - __sr_tasks_from: tasks_from to run - same as tasks_from in include_role
7+
# - __sr_public: export private vars from role - same as public in include_role
8+
# - __sr_failed_when: set to false to ignore role errors - same as failed_when in include_role
9+
- name: Clear facts
10+
meta: clear_facts
11+
12+
# note that you can use failed_when with import_role but not with include_role
13+
# so this simulates the __sr_failed_when false case
14+
# Q: Why do we need a separate task to run the role normally? Why not just
15+
# run the role in the block and rethrow the error in the rescue block?
16+
# A: Because you cannot rethrow the error in exactly the same way as the role does.
17+
# It might be possible to exactly reconstruct ansible_failed_result but it's not worth the effort.
18+
- name: Run the role with __sr_failed_when false
19+
when:
20+
- __sr_failed_when is defined
21+
- not __sr_failed_when
22+
block:
23+
- name: Run the role
24+
include_role:
25+
name: linux-system-roles.trustee_server
26+
tasks_from: "{{ __sr_tasks_from | default('main') }}"
27+
public: "{{ __sr_public | default(false) }}"
28+
rescue:
29+
- name: Ignore the failure when __sr_failed_when is false
30+
debug:
31+
msg: Ignoring failure when __sr_failed_when is false
32+
33+
- name: Run the role normally
34+
include_role:
35+
name: linux-system-roles.trustee_server
36+
tasks_from: "{{ __sr_tasks_from | default('main') }}"
37+
public: "{{ __sr_public | default(false) }}"
38+
when: __sr_failed_when | d(true)

tests/vars/rh_distros_vars.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# vars for handling conditionals for RedHat and clones
22
# DO NOT EDIT - file is auto-generated
33
# repo is https://github.com/linux-system-roles/.github
4-
# file is playbooks/trustee_server/tests/vars/rh_distros_vars.yml
4+
# file is playbooks/templates/tests/vars/rh_distros_vars.yml
55
---
66
# Ansible distribution identifiers that the role treats like RHEL
77
__trustee_server_rh_distros:

0 commit comments

Comments
 (0)