diff --git a/bin/molecule.sh b/bin/molecule.sh index b1091d44b..87e7e4cc8 100755 --- a/bin/molecule.sh +++ b/bin/molecule.sh @@ -70,6 +70,20 @@ if [ ! -x "${venv_dir}/bin/molecule" ]; then "${venv_dir}/bin/pip" install --quiet -r "${repo_dir}/molecule-shared/requirements.txt" fi +# Galaxy content is installed with `force: true` on every run, so two scenarios +# running at once will re-extract collections and roles into the same directory +# and pull them out from under each other mid-play. It shows up as a collection +# that was working moments earlier going missing: +# +# the connection plugin 'community.docker.docker' was not found +# +# ANSIBLE_HOME relocates both `collections/` and `roles/`, so one variable is +# enough to give each role its own. The scenarios' ANSIBLE_ROLES_PATH follows it. +# +# Unset in CI, where it falls back to ~/.ansible - each role runs in its own job +# there, so there is nothing to collide with and nothing to gain from isolation. +export ANSIBLE_HOME="${ANSIBLE_HOME:-${repo_dir}/var/molecule-ansible-home/${role}}" + export MOLECULE_DISTRO="${MOLECULE_DISTRO:-ubuntu2604}" export PY_COLORS="${PY_COLORS:-1}" export ANSIBLE_FORCE_COLOR="${ANSIBLE_FORCE_COLOR:-1}" diff --git a/docs/molecule-testing.md b/docs/molecule-testing.md index d1a46f2e9..f1af28cb9 100644 --- a/docs/molecule-testing.md +++ b/docs/molecule-testing.md @@ -69,3 +69,24 @@ A suite that only waits for the systemd unit to become `active` proves very litt Give the scenario values that differ from both the role's defaults and the component's own defaults. Otherwise a passing assertion cannot distinguish "the role configured this" from "it would have happened anyway". Then try to break it. If a scenario cannot be made to fail by deliberately breaking the thing it checks, it is not testing that thing. + +## Running more than one scenario at once + +`bin/molecule.sh` points `ANSIBLE_HOME` at `var/molecule-ansible-home//`, so each role gets +its own copy of the Galaxy collections and roles. + +This is not an optimisation - it is a correctness fix. Scenarios install their dependencies with +`force: true`, so two runs sharing `~/.ansible` re-extract the same collections underneath each +other. The symptom is a collection that was working moments earlier going missing mid-play: + +``` +the connection plugin 'community.docker.docker' was not found +``` + +If you see that, a concurrent run took the collection out from under you. + +`ANSIBLE_HOME` is left alone if you have already set it, and is unset in CI - each role runs in its +own job there, so there is nothing to collide with. + +The directories are disposable; `var/` is gitignored. Delete `var/molecule-ansible-home/` to force +a fresh install. diff --git a/roles/custom/matrix-alertmanager-receiver/molecule/default/molecule.yml b/roles/custom/matrix-alertmanager-receiver/molecule/default/molecule.yml index ddf0a6781..bf458c56c 100644 --- a/roles/custom/matrix-alertmanager-receiver/molecule/default/molecule.yml +++ b/roles/custom/matrix-alertmanager-receiver/molecule/default/molecule.yml @@ -59,7 +59,7 @@ provisioner: molecule-room: "!molecule-room-id:molecule.local" env: # Workaround for https://github.com/ansible/molecule/issues/4391 - ANSIBLE_ROLES_PATH: ${MOLECULE_PROJECT_DIRECTORY}/../..:/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles:~/.ansible/roles + ANSIBLE_ROLES_PATH: ${MOLECULE_PROJECT_DIRECTORY}/../..:/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles:${ANSIBLE_HOME:-~/.ansible}/roles scenario: test_sequence: - dependency diff --git a/roles/custom/matrix-bot-baibot/molecule/default/molecule.yml b/roles/custom/matrix-bot-baibot/molecule/default/molecule.yml index 81ab33bce..11f4bf7b8 100644 --- a/roles/custom/matrix-bot-baibot/molecule/default/molecule.yml +++ b/roles/custom/matrix-bot-baibot/molecule/default/molecule.yml @@ -75,7 +75,7 @@ provisioner: matrix_bot_baibot_config_agents_static_definitions_anthropic_config_text_generation_max_context_tokens: 56789 env: # Workaround for https://github.com/ansible/molecule/issues/4391 - ANSIBLE_ROLES_PATH: ${MOLECULE_PROJECT_DIRECTORY}/../..:/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles:~/.ansible/roles + ANSIBLE_ROLES_PATH: ${MOLECULE_PROJECT_DIRECTORY}/../..:/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles:${ANSIBLE_HOME:-~/.ansible}/roles scenario: test_sequence: - dependency diff --git a/roles/custom/matrix-bot-matrix-reminder-bot/molecule/default/molecule.yml b/roles/custom/matrix-bot-matrix-reminder-bot/molecule/default/molecule.yml index d05e50785..f8c030ee8 100644 --- a/roles/custom/matrix-bot-matrix-reminder-bot/molecule/default/molecule.yml +++ b/roles/custom/matrix-bot-matrix-reminder-bot/molecule/default/molecule.yml @@ -80,7 +80,7 @@ provisioner: matrix_bot_matrix_reminder_bot_data_store_path: /matrix/matrix-reminder-bot/data/store env: # Workaround for https://github.com/ansible/molecule/issues/4391 - ANSIBLE_ROLES_PATH: ${MOLECULE_PROJECT_DIRECTORY}/../..:/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles:~/.ansible/roles + ANSIBLE_ROLES_PATH: ${MOLECULE_PROJECT_DIRECTORY}/../..:/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles:${ANSIBLE_HOME:-~/.ansible}/roles scenario: test_sequence: - dependency diff --git a/roles/custom/matrix-bridge-heisenbridge/molecule/default/molecule.yml b/roles/custom/matrix-bridge-heisenbridge/molecule/default/molecule.yml index f465908cf..249c6002c 100644 --- a/roles/custom/matrix-bridge-heisenbridge/molecule/default/molecule.yml +++ b/roles/custom/matrix-bridge-heisenbridge/molecule/default/molecule.yml @@ -57,7 +57,7 @@ provisioner: matrix_bridge_heisenbridge_base_path: /matrix/heisenbridge env: # Workaround for https://github.com/ansible/molecule/issues/4391 - ANSIBLE_ROLES_PATH: ${MOLECULE_PROJECT_DIRECTORY}/../..:/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles:~/.ansible/roles + ANSIBLE_ROLES_PATH: ${MOLECULE_PROJECT_DIRECTORY}/../..:/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles:${ANSIBLE_HOME:-~/.ansible}/roles scenario: test_sequence: - dependency diff --git a/roles/custom/matrix-bridge-hookshot/molecule/default/molecule.yml b/roles/custom/matrix-bridge-hookshot/molecule/default/molecule.yml index d259ab296..de61f61d0 100644 --- a/roles/custom/matrix-bridge-hookshot/molecule/default/molecule.yml +++ b/roles/custom/matrix-bridge-hookshot/molecule/default/molecule.yml @@ -105,7 +105,7 @@ provisioner: matrix_bridge_hookshot_identifier: matrix-hookshot env: # Workaround for https://github.com/ansible/molecule/issues/4391 - ANSIBLE_ROLES_PATH: ${MOLECULE_PROJECT_DIRECTORY}/../..:/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles:~/.ansible/roles + ANSIBLE_ROLES_PATH: ${MOLECULE_PROJECT_DIRECTORY}/../..:/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles:${ANSIBLE_HOME:-~/.ansible}/roles scenario: test_sequence: - dependency diff --git a/roles/custom/matrix-bridge-mautrix-discord/molecule/default/molecule.yml b/roles/custom/matrix-bridge-mautrix-discord/molecule/default/molecule.yml index 060d7ad26..8df7bcf73 100644 --- a/roles/custom/matrix-bridge-mautrix-discord/molecule/default/molecule.yml +++ b/roles/custom/matrix-bridge-mautrix-discord/molecule/default/molecule.yml @@ -88,7 +88,7 @@ provisioner: matrix_bridge_mautrix_discord_data_path: /matrix/mautrix-discord/data env: # Workaround for https://github.com/ansible/molecule/issues/4391 - ANSIBLE_ROLES_PATH: ${MOLECULE_PROJECT_DIRECTORY}/../..:/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles:~/.ansible/roles + ANSIBLE_ROLES_PATH: ${MOLECULE_PROJECT_DIRECTORY}/../..:/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles:${ANSIBLE_HOME:-~/.ansible}/roles scenario: test_sequence: - dependency diff --git a/roles/custom/matrix-bridge-mautrix-meta-messenger/molecule/default/molecule.yml b/roles/custom/matrix-bridge-mautrix-meta-messenger/molecule/default/molecule.yml index 97e38de8a..9eb5a8392 100644 --- a/roles/custom/matrix-bridge-mautrix-meta-messenger/molecule/default/molecule.yml +++ b/roles/custom/matrix-bridge-mautrix-meta-messenger/molecule/default/molecule.yml @@ -101,7 +101,7 @@ provisioner: matrix_bridge_mautrix_meta_messenger_data_path: /matrix/mautrix-meta-messenger/data env: # Workaround for https://github.com/ansible/molecule/issues/4391 - ANSIBLE_ROLES_PATH: ${MOLECULE_PROJECT_DIRECTORY}/../..:/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles:~/.ansible/roles + ANSIBLE_ROLES_PATH: ${MOLECULE_PROJECT_DIRECTORY}/../..:/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles:${ANSIBLE_HOME:-~/.ansible}/roles scenario: test_sequence: - dependency diff --git a/roles/custom/matrix-bridge-mautrix-whatsapp/molecule/default/molecule.yml b/roles/custom/matrix-bridge-mautrix-whatsapp/molecule/default/molecule.yml index ba83bc3d1..ecf33de90 100644 --- a/roles/custom/matrix-bridge-mautrix-whatsapp/molecule/default/molecule.yml +++ b/roles/custom/matrix-bridge-mautrix-whatsapp/molecule/default/molecule.yml @@ -63,7 +63,7 @@ provisioner: matrix_bridge_mautrix_whatsapp_data_path: /matrix/mautrix-whatsapp/data env: # Workaround for https://github.com/ansible/molecule/issues/4391 - ANSIBLE_ROLES_PATH: ${MOLECULE_PROJECT_DIRECTORY}/../..:/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles:~/.ansible/roles + ANSIBLE_ROLES_PATH: ${MOLECULE_PROJECT_DIRECTORY}/../..:/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles:${ANSIBLE_HOME:-~/.ansible}/roles scenario: test_sequence: - dependency