--- - name: ๐Ÿ“‚ Define per-role paths for {{ application_id }} ansible.builtin.set_fact: _cli_env_template: "{{ lookup('path_absolute', 'roles', application_id, 'templates/test.env.j2') }}" _cli_stage_dir: "{{ TEST_E2E_CLI_STAGE_BASE_DIR }}/{{ application_id }}" _cli_test_script: "{{ TEST_E2E_CLI_STAGE_BASE_DIR }}/{{ application_id }}/test.sh" _cli_service_key: "{{ lookup('role_tests', application_id, 'cli.container_service_key', default='') | trim }}" - name: "๐Ÿ“ฆ Include the roles the CLI test of {{ application_id }} requires" ansible.builtin.include_role: name: "{{ required_role }}" loop: "{{ lookup('role_tests', application_id, 'cli.requires', default=[]) }}" loop_control: loop_var: required_role - name: "โœ… Assert CLI test assets exist for {{ application_id }}" ansible.builtin.stat: path: "{{ item }}" register: _cli_asset_stats delegate_to: localhost run_once: true loop: - "{{ _cli_env_template }}" - "{{ lookup('path_absolute', 'roles', application_id, 'files/test/test.sh') }}" - name: "โŒ Fail if a CLI test asset is missing for {{ application_id }}" ansible.builtin.fail: msg: "Missing CLI test asset: {{ item.item }}" when: not item.stat.exists loop: "{{ _cli_asset_stats.results }}" loop_control: label: "{{ item.item }}" - name: ๐Ÿงญ Default the CLI host to the loop host for {{ application_id }} ansible.builtin.set_fact: CLI_HOST_NODE: "{{ inventory_hostname }}" CLI_LOCAL_CID: "" - name: "๐Ÿ” Resolve the node that holds {{ application_id }}'s test container" ansible.builtin.include_tasks: "{{ lookup('path_absolute', 'roles/sys-svc-compose/tasks/utils/swarm/resolve_host_cid.yml') }}" vars: resolve_service_key: "{{ _cli_service_key }}" resolve_output_prefix: CLI resolve_compose_cid: "{{ lookup('container_address', application_id, _cli_service_key) }}" resolve_converge_retries: 30 resolve_converge_delay: 2 when: _cli_service_key | length > 0 - name: ๐Ÿ“ Create stage directory for {{ application_id }} ansible.builtin.file: path: "{{ _cli_stage_dir }}" state: directory mode: "0700" delegate_to: "{{ CLI_HOST_NODE }}" - name: ๐Ÿ“ฆ Stage CLI test assets for {{ application_id }} ansible.builtin.copy: src: "{{ lookup('path_absolute', 'roles', application_id, 'files/test') }}/" dest: "{{ _cli_stage_dir }}/" mode: "0755" delegate_to: "{{ CLI_HOST_NODE }}" - name: ๐Ÿ“ฆ Stage the shared CLI harness for {{ application_id }} ansible.builtin.copy: src: "{{ lookup('path_absolute', 'roles/test-e2e-cli/files/shared') }}/" dest: "{{ _cli_stage_dir }}/shared/" mode: "0755" delegate_to: "{{ CLI_HOST_NODE }}" - name: ๐Ÿงญ Reset the per-role deployment-mode override ansible.builtin.include_vars: file: "{{ lookup('path_absolute', 'roles/sys-svc-compose/defaults/main.yml') }}" - name: ๐Ÿ” Check optional application defaults for {{ application_id }} ansible.builtin.stat: path: "{{ lookup('path_absolute', 'roles', application_id, 'defaults/main.yml') }}" register: _cli_app_defaults_stat delegate_to: localhost run_once: true - name: ๐Ÿ“ฆ Load optional application defaults for {{ application_id }} ansible.builtin.include_vars: file: "{{ lookup('path_absolute', 'roles', application_id, 'defaults/main.yml') }}" when: _cli_app_defaults_stat.stat.exists - name: ๐Ÿ” Check optional application vars for {{ application_id }} ansible.builtin.stat: path: "{{ lookup('path_absolute', 'roles', application_id, 'vars/main.yml') }}" register: _cli_app_vars_stat delegate_to: localhost run_once: true - name: ๐Ÿ“ฆ Load optional application vars for {{ application_id }} ansible.builtin.include_vars: file: "{{ lookup('path_absolute', 'roles', application_id, 'vars/main.yml') }}" when: _cli_app_vars_stat.stat.exists - name: ๐Ÿ“„ Render test.env from templates/test.env.j2 for {{ application_id }} ansible.builtin.copy: dest: "{{ _cli_stage_dir }}/test.env" mode: "0600" content: "{{ lookup('template', _cli_env_template) }}" delegate_to: "{{ CLI_HOST_NODE }}" - name: ๐Ÿš€ Run CLI test script for {{ application_id }} ansible.builtin.shell: cmd: "set -a && . {{ _cli_stage_dir }}/test.env && set +a && timeout {{ _cli_timeout }} bash {{ _cli_test_script }}" executable: /bin/bash vars: _cli_timeout_base: "{{ lookup('role_tests', application_id, 'cli.timeout', default='') }}" _cli_timeout: >- {{ (lookup('timeout', _cli_timeout_base | int) | int) if (_cli_timeout_base | string | trim | length > 0) else (TEST_E2E_CLI_TIMEOUT | int) }} register: _cli_run changed_when: false failed_when: false delegate_to: "{{ CLI_HOST_NODE }}" throttle: 1 - name: ๐Ÿ“„ Print CLI test output on failure for {{ application_id }} ansible.builtin.debug: msg: | stdout: {{ _cli_run.stdout }} stderr: {{ _cli_run.stderr }} when: _cli_run.rc != 0 changed_when: false - name: โŒ Record failure for {{ application_id }} ansible.builtin.set_fact: _cli_failures: "{{ (_cli_failures | default([])) + [application_id] }}" when: _cli_run.rc != 0 - name: ๐Ÿงน Remove the delegated stage dir of {{ application_id }} ansible.builtin.file: path: "{{ _cli_stage_dir }}" state: absent delegate_to: "{{ CLI_HOST_NODE }}" when: CLI_HOST_NODE != inventory_hostname