From f28fabe6ef6008e65896d73659255abc81d56d27 Mon Sep 17 00:00:00 2001 From: Matt Clay Date: Fri, 10 Jul 2020 18:48:51 -0700 Subject: [PATCH] [stable-2.10] Add integration tests for test plugins. (#70576) (cherry picked from commit df45dcdae02e24122428cfc70b9f4f987672e0bb) Co-authored-by: Matt Clay --- test/integration/targets/test_core/inventory | 1 + test/integration/targets/test_core/runme.sh | 5 + test/integration/targets/test_core/runme.yml | 4 + .../targets/test_core/tasks/main.yml | 268 ++++++++++++++++++ .../targets/test_core/vault-password | 1 + test/integration/targets/test_files/aliases | 2 + .../targets/test_files/tasks/main.yml | 60 ++++ .../targets/test_mathstuff/aliases | 2 + .../targets/test_mathstuff/tasks/main.yml | 38 +++ 9 files changed, 381 insertions(+) create mode 100644 test/integration/targets/test_core/inventory create mode 100755 test/integration/targets/test_core/runme.sh create mode 100644 test/integration/targets/test_core/runme.yml create mode 100644 test/integration/targets/test_core/vault-password create mode 100644 test/integration/targets/test_files/aliases create mode 100644 test/integration/targets/test_files/tasks/main.yml create mode 100644 test/integration/targets/test_mathstuff/aliases create mode 100644 test/integration/targets/test_mathstuff/tasks/main.yml diff --git a/test/integration/targets/test_core/inventory b/test/integration/targets/test_core/inventory new file mode 100644 index 00000000000..0fdd8ae35fc --- /dev/null +++ b/test/integration/targets/test_core/inventory @@ -0,0 +1 @@ +unreachable ansible_connection=ssh ansible_host=127.0.0.1 ansible_port=1011 # IANA Reserved port diff --git a/test/integration/targets/test_core/runme.sh b/test/integration/targets/test_core/runme.sh new file mode 100755 index 00000000000..c20c174132c --- /dev/null +++ b/test/integration/targets/test_core/runme.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash + +set -eu + +ANSIBLE_ROLES_PATH=../ ansible-playbook --vault-password-file vault-password runme.yml -i inventory "${@}" diff --git a/test/integration/targets/test_core/runme.yml b/test/integration/targets/test_core/runme.yml new file mode 100644 index 00000000000..20a94672edb --- /dev/null +++ b/test/integration/targets/test_core/runme.yml @@ -0,0 +1,4 @@ +- hosts: localhost + gather_facts: no + roles: + - test_core diff --git a/test/integration/targets/test_core/tasks/main.yml b/test/integration/targets/test_core/tasks/main.yml index 739675066ce..50c435815bc 100644 --- a/test/integration/targets/test_core/tasks/main.yml +++ b/test/integration/targets/test_core/tasks/main.yml @@ -1,3 +1,254 @@ +- name: Failure + set_fact: + hello: world + failed_when: true + ignore_errors: yes + register: intentional_failure + +- name: Success + set_fact: + hello: world + register: intentional_success + +- name: Try failure test on non-dictionary + set_fact: + hello: "{{ 'nope' is failure }}" + ignore_errors: yes + register: misuse_of_failure + +- name: Assert failure tests work + assert: + that: + - intentional_failure is failed # old name + - intentional_failure is failure + - intentional_success is not failure + - misuse_of_failure is failed + +- name: Assert successful tests work + assert: + that: + - intentional_success is succeeded # old name + - intentional_success is success # old name + - intentional_success is successful + - intentional_failure is not successful + +- name: Try reachable host + command: id + register: reachable_host + +- name: Try unreachable host + command: id + delegate_to: unreachable + ignore_unreachable: yes + ignore_errors: yes + register: unreachable_host + +- name: Try reachable test on non-dictionary + set_fact: + hello: "{{ 'nope' is reachable }}" + ignore_errors: yes + register: misuse_of_reachable + +- name: Assert reachable tests work + assert: + that: + - misuse_of_reachable is failed + - reachable_host is reachable + - unreachable_host is not reachable + +- name: Try unreachable test on non-dictionary + set_fact: + hello: "{{ 'nope' is unreachable }}" + ignore_errors: yes + register: misuse_of_unreachable + +- name: Assert unreachable tests work + assert: + that: + - misuse_of_unreachable is failed + - reachable_host is not unreachable + - unreachable_host is unreachable + +- name: Make changes + file: + path: dir_for_changed + state: directory + register: directory_created + +- name: Make no changes + file: + path: dir_for_changed + state: directory + register: directory_unchanged + +- name: Try changed test on non-dictionary + set_fact: + hello: "{{ 'nope' is changed }}" + ignore_errors: yes + register: misuse_of_changed + +# providing artificial task results since there are no modules in ansible-base that provide a 'results' list instead of 'changed' +- name: Prepare artificial task results + set_fact: + results_all_changed: + results: + - changed: true + - changed: true + results_some_changed: + results: + - changed: true + - changed: false + results_none_changed: + results: + - changed: false + - changed: false + results_missing_changed: {} + +- name: Assert changed tests work + assert: + that: + - directory_created is changed + - directory_unchanged is not changed + - misuse_of_changed is failed + - results_all_changed is changed + - results_some_changed is changed + - results_none_changed is not changed + - results_missing_changed is not changed + +- name: Skip me + set_fact: + hello: world + when: false + register: skipped_task + +- name: Don't skip me + set_fact: + hello: world + register: executed_task + +- name: Try skipped test on non-dictionary + set_fact: + hello: "{{ 'nope' is skipped }}" + ignore_errors: yes + register: misuse_of_skipped + +- name: Assert skipped tests work + assert: + that: + - skipped_task is skipped + - executed_task is not skipped + - misuse_of_skipped is failure + +- name: Not an async task + set_fact: + hello: world + register: non_async_task + +- name: Complete an async task + command: id + async: 10 + poll: 1 + register: async_completed + +- name: Start an async task without waiting for completion + shell: sleep 3 + async: 10 + poll: 0 + register: async_incomplete + +- name: Try finished test on non-dictionary + set_fact: + hello: "{{ 'nope' is finished }}" + ignore_errors: yes + register: misuse_of_finished + +- name: Assert finished tests work (warning expected) + assert: + that: + - non_async_task is finished + - misuse_of_finished is failed + - async_completed is finished + - async_incomplete is not finished + +- name: Try started test on non-dictionary + set_fact: + hello: "{{ 'nope' is started }}" + ignore_errors: yes + register: misuse_of_started + +- name: Assert started tests work (warning expected) + assert: + that: + - non_async_task is started + - misuse_of_started is failed + - async_completed is started + - async_incomplete is started + +- name: Assert match tests work + assert: + that: + - "'hello' is match('h.ll.')" + - "'hello' is not match('.ll.')" + +- name: Assert search tests work + assert: + that: + - "'hello' is search('.l')" + - "'hello' is not search('nope')" + +- name: Assert regex tests work + assert: + that: + - "'hello' is regex('.l')" + - "'hello' is regex('.L', ignorecase=true)" + - "'hello\nAnsible' is regex('^Ansible', multiline=true)" + - "'hello' is not regex('.L')" + - "'hello\nAnsible' is not regex('^Ansible')" + +- name: Try version tests with bad operator + set_fact: + result: "{{ '1.0' is version('1.0', 'equals') }}" + ignore_errors: yes + register: version_bad_operator + +- name: Try version tests with bad value + set_fact: + result: "{{ '1.0' is version('nope', '==', true) }}" + ignore_errors: yes + register: version_bad_value + +- name: Assert version tests work + assert: + that: + - "'1.0' is version_compare('1.0', '==')" # old name + - "'1.0' is version('1.0', '==')" + - "'1.0' is version('2.0', '!=')" + - "'1.0' is version('2.0', '<')" + - "'2.0' is version('1.0', '>')" + - "'1.0' is version('1.0', '<=')" + - "'1.0' is version('1.0', '>=')" + - "'1.0' is version_compare('1.0', '==', true)" # old name + - "'1.0' is version('1.0', '==', true)" + - "'1.0' is version('2.0', '!=', true)" + - "'1.0' is version('2.0', '<', true)" + - "'2.0' is version('1.0', '>', true)" + - "'1.0' is version('1.0', '<=', true)" + - "'1.0' is version('1.0', '>=', true)" + - version_bad_operator is failed + - version_bad_value is failed + +- name: Assert any tests work + assert: + that: + - "[true, false] is any" + - "[false] is not any" + +- name: Assert all tests work + assert: + that: + - "[true] is all" + - "[true, false] is not all" + - name: Assert truthy tests work assert: that: @@ -13,6 +264,7 @@ - '[] is not truthy' - '"on" is truthy(convert_bool=True)' - '"off" is not truthy(convert_bool=True)' + - '"fred" is truthy(convert_bool=True)' - '{} is not truthy' - '{"key": "value"} is truthy' @@ -33,3 +285,19 @@ - '"off" is falsy(convert_bool=True)' - '{} is falsy' - '{"key": "value"} is not falsy' + +- name: Create vaulted variable for vault_encrypted test + set_fact: + vaulted_value: !vault | + $ANSIBLE_VAULT;1.1;AES256 + 35323961353038346165643738646465376139363061353835303739663538343266303232326635 + 3365353662646236356665323135633630656238316530640a663362363763633436373439663031 + 33663433383037396438656464636433653837376361313638366362333037323961316364363363 + 3835616438623261650a636164376534376661393134326662326362323131373964313961623365 + 3833 + +- name: Assert vault_encrypted tests work + assert: + that: + - vaulted_value is vault_encrypted + - inventory_hostname is not vault_encrypted diff --git a/test/integration/targets/test_core/vault-password b/test/integration/targets/test_core/vault-password new file mode 100644 index 00000000000..969739294df --- /dev/null +++ b/test/integration/targets/test_core/vault-password @@ -0,0 +1 @@ +test-vault-password diff --git a/test/integration/targets/test_files/aliases b/test/integration/targets/test_files/aliases new file mode 100644 index 00000000000..041b0cc7bc7 --- /dev/null +++ b/test/integration/targets/test_files/aliases @@ -0,0 +1,2 @@ +shippable/posix/group5 +skip/python2.6 # tests are controller only, and we no longer support Python 2.6 on the controller diff --git a/test/integration/targets/test_files/tasks/main.yml b/test/integration/targets/test_files/tasks/main.yml new file mode 100644 index 00000000000..0d51fc9582e --- /dev/null +++ b/test/integration/targets/test_files/tasks/main.yml @@ -0,0 +1,60 @@ +- name: Create a broken symbolic link + file: + src: does_not_exist + dest: link_to_nonexistent_file + state: link + force: yes + follow: no + +- name: Assert directory tests work + assert: + that: + - "'.' is is_dir" # old name + - "'.' is directory" + - "'does_not_exist' is not directory" + +- name: Assert file tests work + assert: + that: + - "(role_path + '/aliases') is is_file" # old name + - "(role_path + '/aliases') is file" + - "'does_not_exist' is not file" + +- name: Assert link tests work + assert: + that: + - "'link_to_nonexistent_file' is link" + - "'.' is not link" + +- name: Assert exists tests work + assert: + that: + - "(role_path + '/aliases') is exists" + - "'link_to_nonexistent_file' is not exists" + +- name: Assert link_exists tests work + assert: + that: + - "'link_to_nonexistent_file' is link_exists" + - "'does_not_exist' is not link_exists" + +- name: Assert abs tests work + assert: + that: + - "'/' is is_abs" # old name + - "'/' is abs" + - "'../' is not abs" + +- name: Assert same_file tests work + assert: + that: + - "'/' is is_same_file('/')" # old name + - "'/' is same_file('/')" + - "'/' is not same_file(role_path + '/aliases')" + +- name: Assert mount tests work + assert: + that: + - "'/' is is_mount" # old name + - "'/' is mount" + - "'/does_not_exist' is not mount" diff --git a/test/integration/targets/test_mathstuff/aliases b/test/integration/targets/test_mathstuff/aliases new file mode 100644 index 00000000000..041b0cc7bc7 --- /dev/null +++ b/test/integration/targets/test_mathstuff/aliases @@ -0,0 +1,2 @@ +shippable/posix/group5 +skip/python2.6 # tests are controller only, and we no longer support Python 2.6 on the controller diff --git a/test/integration/targets/test_mathstuff/tasks/main.yml b/test/integration/targets/test_mathstuff/tasks/main.yml new file mode 100644 index 00000000000..dd379ce263b --- /dev/null +++ b/test/integration/targets/test_mathstuff/tasks/main.yml @@ -0,0 +1,38 @@ +- name: Get Jinja2 version + set_fact: + jinja2_version: >- + {{ lookup('pipe', '{{ ansible_playbook_python }} -c "import jinja2; print(jinja2.__version__)"') }} + +- name: Assert subset tests work + assert: + that: + - "[1] is issubset([1, 2])" # old name + - "[1] is subset([1, 2])" + - "[1] is not subset([2])" + +- name: Assert superset tests work + assert: + that: + - "[1, 2] is issuperset([1])" # old name + - "[1, 2] is superset([1])" + - "[2] is not superset([1])" + +- name: Assert contains tests work + assert: + that: + - "[1] is contains(1)" + - "[1] is not contains(2)" + +- name: Assert nan tests work + assert: + that: + - "'bad' is not nan" + - "1.1 | float is not nan" + +# Jinja2 versions prior to 2.10 will traceback when using: 'nan' | float +- name: Assert nan tests work (Jinja2 2.10+) + assert: + that: + - "'nan' | float is isnan" # old name + - "'nan' | float is nan" + when: jinja2_version is version('2.10', '>=')