From 6d179da480f18c469a5f364738f91c313747ac29 Mon Sep 17 00:00:00 2001 From: Steven Robertson Date: Wed, 12 Feb 2020 18:23:30 -0800 Subject: [PATCH] ported over tests from ansible validating python interpreter discovery --- .../integration/interpreter_discovery/all.yml | 2 + .../ansible_2_8_tests.yml | 155 ++++++++++++++++++ .../interpreter_discovery/complex_args.yml | 63 +++++++ tests/ansible/lib/modules/test_echo_module.py | 33 ++++ 4 files changed, 253 insertions(+) create mode 100644 tests/ansible/integration/interpreter_discovery/all.yml create mode 100644 tests/ansible/integration/interpreter_discovery/ansible_2_8_tests.yml create mode 100644 tests/ansible/integration/interpreter_discovery/complex_args.yml create mode 100644 tests/ansible/lib/modules/test_echo_module.py diff --git a/tests/ansible/integration/interpreter_discovery/all.yml b/tests/ansible/integration/interpreter_discovery/all.yml new file mode 100644 index 00000000..403fd761 --- /dev/null +++ b/tests/ansible/integration/interpreter_discovery/all.yml @@ -0,0 +1,2 @@ +- include: complex_args.yml +- include: ansible_2_8_tests.yml diff --git a/tests/ansible/integration/interpreter_discovery/ansible_2_8_tests.yml b/tests/ansible/integration/interpreter_discovery/ansible_2_8_tests.yml new file mode 100644 index 00000000..cf24167e --- /dev/null +++ b/tests/ansible/integration/interpreter_discovery/ansible_2_8_tests.yml @@ -0,0 +1,155 @@ +# ripped and ported from https://github.com/ansible/ansible/pull/50163/files, when interpreter discovery was added to ansible +--- + +- name: integration/interpreter_discovery/ansible_2_8_tests.yml + hosts: test-targets + any_errors_fatal: true + gather_facts: true + tasks: + - name: ensure we can override ansible_python_interpreter + vars: + ansible_python_interpreter: overriddenpython + assert: + that: + - ansible_python_interpreter == 'overriddenpython' + fail_msg: "'ansible_python_interpreter' appears to be set at a high precedence to {{ ansible_python_interpreter }}, + which breaks this test." + + - name: snag some facts to validate for later + set_fact: + distro: '{{ ansible_distribution | default("unknown") | lower }}' + distro_version: '{{ ansible_distribution_version | default("unknown") }}' + os_family: '{{ ansible_os_family | default("unknown") }}' + + - name: test that python discovery is working and that fact persistence makes it only run once + block: + - name: clear facts to force interpreter discovery to run + meta: clear_facts + + - name: trigger discovery with auto + vars: + ansible_python_interpreter: auto + ping: + register: auto_out + + - name: get the interpreter being used on the target to execute modules + vars: + ansible_python_interpreter: auto + test_echo_module: + register: echoout + + # can't test this assertion: + # - echoout.ansible_facts is not defined or echoout.ansible_facts.discovered_interpreter_python is not defined + # because Mitogen's ansible_python_interpreter is a connection-layer configurable that + # "must be extracted during each task execution to form the complete connection-layer configuration". + # Discovery won't be reran though; the ansible_python_interpreter is read from the cache if already discovered + - assert: + that: + - auto_out.ansible_facts.discovered_interpreter_python is defined + - echoout.running_python_interpreter == auto_out.ansible_facts.discovered_interpreter_python + + + - name: test that auto_legacy gives a dep warning when /usr/bin/python present but != auto result + block: + - name: clear facts to force interpreter discovery to run + meta: clear_facts + + - name: trigger discovery with auto_legacy + vars: + ansible_python_interpreter: auto_legacy + ping: + register: legacy + + - name: check for dep warning (only on platforms where auto result is not /usr/bin/python and legacy is) + assert: + that: + - legacy.deprecations | default([]) | length > 0 + # only check for a dep warning if legacy returned /usr/bin/python and auto didn't + when: legacy.ansible_facts.discovered_interpreter_python == '/usr/bin/python' and + auto_out.ansible_facts.discovered_interpreter_python != '/usr/bin/python' + + + - name: test that auto_silent never warns and got the same answer as auto + block: + - name: clear facts to force interpreter discovery to run + meta: clear_facts + + - name: initial task to trigger discovery + vars: + ansible_python_interpreter: auto_silent + ping: + register: auto_silent_out + + - assert: + that: + - auto_silent_out.warnings is not defined + - auto_silent_out.ansible_facts.discovered_interpreter_python == auto_out.ansible_facts.discovered_interpreter_python + + + - name: test that auto_legacy_silent never warns and got the same answer as auto_legacy + block: + - name: clear facts to force interpreter discovery to run + meta: clear_facts + + - name: trigger discovery with auto_legacy_silent + vars: + ansible_python_interpreter: auto_legacy_silent + ping: + register: legacy_silent + + - assert: + that: + - legacy_silent.warnings is not defined + - legacy_silent.ansible_facts.discovered_interpreter_python == legacy.ansible_facts.discovered_interpreter_python + + - name: ensure modules can't set discovered_interpreter_X or ansible_X_interpreter + block: + - test_echo_module: + facts: + ansible_discovered_interpreter_bogus: from module + discovered_interpreter_bogus: from_module + ansible_bogus_interpreter: from_module + test_fact: from_module + register: echoout + + - assert: + that: + - test_fact == 'from_module' + - discovered_interpreter_bogus | default('nope') == 'nope' + - ansible_bogus_interpreter | default('nope') == 'nope' + # this one will exist in facts, but with its prefix removed + - ansible_facts['ansible_bogus_interpreter'] | default('nope') == 'nope' + - ansible_facts['discovered_interpreter_bogus'] | default('nope') == 'nope' + + - name: fedora assertions + assert: + that: + - auto_out.ansible_facts.discovered_interpreter_python == '/usr/bin/python3' + when: distro == 'fedora' and distro_version is version('23', '>=') + + - name: rhel assertions + assert: + that: + # rhel 6/7 + - (auto_out.ansible_facts.discovered_interpreter_python == '/usr/bin/python' and distro_version is version('8','<')) or distro_version is version('8','>=') + # rhel 8+ + - (auto_out.ansible_facts.discovered_interpreter_python == '/usr/libexec/platform-python' and distro_version is version('8','>=')) or distro_version is version('8','<') + when: distro in ('redhat', 'centos') + + - name: ubuntu assertions + assert: + that: + # ubuntu < 16 + - (auto_out.ansible_facts.discovered_interpreter_python == '/usr/bin/python' and distro_version is version('16.04','<')) or distro_version is version('16.04','>=') + # ubuntu >= 16 + - (auto_out.ansible_facts.discovered_interpreter_python == '/usr/bin/python3' and distro_version is version('16.04','>=')) or distro_version is version('16.04','<') + when: distro == 'ubuntu' + + - name: mac assertions + assert: + that: + - auto_out.ansible_facts.discovered_interpreter_python == '/usr/bin/python' + when: os_family == 'Darwin' + + always: + - meta: clear_facts diff --git a/tests/ansible/integration/interpreter_discovery/complex_args.yml b/tests/ansible/integration/interpreter_discovery/complex_args.yml new file mode 100644 index 00000000..663d9a81 --- /dev/null +++ b/tests/ansible/integration/interpreter_discovery/complex_args.yml @@ -0,0 +1,63 @@ +# checks complex ansible_python_interpreter values as well as jinja in the ansible_python_interpreter value +--- + +- name: integration/interpreter_discovery/complex_args.yml + hosts: test-targets + any_errors_fatal: true + gather_facts: true + tasks: + - name: Run tests on either redhat or darwin only for now + block: + - name: set redhat special python + block: + - name: ensure rh-python36 is installed + package: + name: + - rh-python36 + - rh-python36-python-devel + state: present + + - name: set special python fact + set_fact: + special_python: source /opt/rh/rh-python36/enable && python + when: ansible_os_family == 'RedHat' + + - name: set darwin "special" python + block: + - name: create temp file to source + file: + path: /tmp/fake + state: touch + + - name: set python using sourced file + set_fact: + special_python: source /tmp/fake && python + when: ansible_os_family == 'Darwin' + + - name: run get_url with specially-sourced python + get_url: + url: https://camo.githubusercontent.com/65061efd40e810e88184d7d962bb079ce27d8f7f/68747470733a2f2f7472617669732d63692e6f72672f64772f6d69746f67656e2e7376673f6272616e63683d6d6173746572 + dest: "/tmp/" + mode: 0644 + vars: + ansible_python_interpreter: "{{ special_python }}" + environment: + https_proxy: "{{ lookup('env', 'https_proxy')|default('') }}" + no_proxy: "{{ lookup('env', 'no_proxy')|default('') }}" + + - name: run get_url with specially-sourced python including jinja + get_url: + url: https://camo.githubusercontent.com/65061efd40e810e88184d7d962bb079ce27d8f7f/68747470733a2f2f7472617669732d63692e6f72672f64772f6d69746f67656e2e7376673f6272616e63683d6d6173746572 + dest: "/tmp/" + mode: 0644 + vars: + ansible_python_interpreter: > + {% if "1" == "1" %} + {{ special_python }} + {% else %} + python + {% endif %} + environment: + https_proxy: "{{ lookup('env', 'https_proxy')|default('') }}" + no_proxy: "{{ lookup('env', 'no_proxy')|default('') }}" + when: ansible_os_family in ('RedHat', 'Darwin') diff --git a/tests/ansible/lib/modules/test_echo_module.py b/tests/ansible/lib/modules/test_echo_module.py new file mode 100644 index 00000000..beb4cc70 --- /dev/null +++ b/tests/ansible/lib/modules/test_echo_module.py @@ -0,0 +1,33 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# (c) 2012, Michael DeHaan +# (c) 2016, Toshio Kuratomi +# (c) 2020, Steven Robertson +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +import sys +from ansible.module_utils.basic import AnsibleModule + + +def main(): + result = dict(changed=False) + + module = AnsibleModule(argument_spec=dict( + facts=dict(type=dict, default={}) + )) + + result['ansible_facts'] = module.params['facts'] + # revert the Mitogen OSX tweak since discover_interpreter() doesn't return this info + if sys.platform == 'darwin' and sys.executable != '/usr/bin/python': + sys.executable = sys.executable[:-3] + result['running_python_interpreter'] = sys.executable + + module.exit_json(**result) + + +if __name__ == '__main__': + main() \ No newline at end of file