mirror of https://github.com/ansible/ansible.git
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
158 lines
5.9 KiB
Python
158 lines
5.9 KiB
Python
# -*- coding: utf-8 -*-
|
|
# Copyright: (c) 2017 Ansible Project
|
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
|
|
|
from __future__ import annotations
|
|
|
|
import glob
|
|
import json
|
|
import os
|
|
import pytest
|
|
from itertools import product
|
|
|
|
import builtins
|
|
|
|
# the module we are actually testing (sort of)
|
|
from ansible.module_utils.facts.system.distribution import DistributionFactCollector
|
|
|
|
# to generate the testcase data, you can use the script gen_distribution_version_testcase.py in hacking/tests
|
|
TESTSETS = []
|
|
|
|
for datafile in glob.glob(os.path.join(os.path.dirname(__file__), 'fixtures/*.json')):
|
|
with open(os.path.join(os.path.dirname(__file__), '%s' % datafile)) as f:
|
|
TESTSETS.append(json.loads(f.read()))
|
|
|
|
|
|
@pytest.mark.parametrize("stdin, testcase", product([{}], TESTSETS), ids=lambda x: x.get('name'), indirect=['stdin'])
|
|
def test_distribution_version(am, mocker, testcase):
|
|
"""tests the distribution parsing code of the Facts class
|
|
|
|
testsets have
|
|
* a name (for output/debugging only)
|
|
* input files that are faked
|
|
* those should be complete and also include "irrelevant" files that might be mistaken as coming from other distributions
|
|
* all files that are not listed here are assumed to not exist at all
|
|
* the output of ansible.module_utils.distro.linux_distribution() [called platform.dist() for historical reasons]
|
|
* results for the ansible variables distribution* and os_family
|
|
|
|
"""
|
|
|
|
# prepare some mock functions to get the testdata in
|
|
def mock_get_file_content(fname, default=None, strip=True):
|
|
"""give fake content if it exists, otherwise pretend the file is empty"""
|
|
data = default
|
|
if fname in testcase['input']:
|
|
# for debugging
|
|
print('faked %s for %s' % (fname, testcase['name']))
|
|
data = testcase['input'][fname].strip()
|
|
if strip and data is not None:
|
|
data = data.strip()
|
|
return data
|
|
|
|
def mock_get_file_lines(fname, strip=True):
|
|
"""give fake lines if file exists, otherwise return empty list"""
|
|
data = mock_get_file_content(fname=fname, strip=strip)
|
|
if data:
|
|
return [data]
|
|
return []
|
|
|
|
def mock_get_uname(am, flags):
|
|
if '-v' in flags:
|
|
return testcase.get('uname_v', None)
|
|
elif '-r' in flags:
|
|
return testcase.get('uname_r', None)
|
|
else:
|
|
return None
|
|
|
|
def mock_file_exists(fname, allow_empty=False):
|
|
if fname not in testcase['input']:
|
|
return False
|
|
|
|
if allow_empty:
|
|
return True
|
|
return bool(len(testcase['input'][fname]))
|
|
|
|
def mock_platform_system():
|
|
return testcase.get('platform.system', 'Linux')
|
|
|
|
def mock_platform_release():
|
|
return testcase.get('platform.release', '')
|
|
|
|
def mock_platform_version():
|
|
return testcase.get('platform.version', '')
|
|
|
|
def mock_distro_name():
|
|
return testcase['distro']['name']
|
|
|
|
def mock_distro_id():
|
|
return testcase['distro']['id']
|
|
|
|
def mock_distro_version(best=False):
|
|
if best:
|
|
return testcase['distro']['version_best']
|
|
return testcase['distro']['version']
|
|
|
|
def mock_distro_codename():
|
|
return testcase['distro']['codename']
|
|
|
|
def mock_distro_os_release_info():
|
|
return testcase['distro']['os_release_info']
|
|
|
|
def mock_distro_lsb_release_info():
|
|
return testcase['distro']['lsb_release_info']
|
|
|
|
def mock_open(filename, mode='r'):
|
|
if filename in testcase['input']:
|
|
file_object = mocker.mock_open(read_data=testcase['input'][filename]).return_value
|
|
file_object.__iter__.return_value = testcase['input'][filename].splitlines(True)
|
|
else:
|
|
file_object = real_open(filename, mode)
|
|
return file_object
|
|
|
|
def mock_os_path_is_file(filename):
|
|
if filename in testcase['input']:
|
|
return True
|
|
return False
|
|
|
|
def mock_run_command_output(v, command):
|
|
ret = (0, '', '')
|
|
if 'command_output' in testcase:
|
|
ret = (0, testcase['command_output'].get(command, ''), '')
|
|
return ret
|
|
|
|
mocker.patch('ansible.module_utils.facts.system.distribution.get_file_content', mock_get_file_content)
|
|
mocker.patch('ansible.module_utils.facts.system.distribution.get_file_lines', mock_get_file_lines)
|
|
mocker.patch('ansible.module_utils.facts.system.distribution.get_uname', mock_get_uname)
|
|
mocker.patch('ansible.module_utils.facts.system.distribution._file_exists', mock_file_exists)
|
|
mocker.patch('ansible.module_utils.distro.name', mock_distro_name)
|
|
mocker.patch('ansible.module_utils.distro.id', mock_distro_id)
|
|
mocker.patch('ansible.module_utils.distro.version', mock_distro_version)
|
|
mocker.patch('ansible.module_utils.distro.codename', mock_distro_codename)
|
|
mocker.patch(
|
|
'ansible.module_utils.common.sys_info.distro.os_release_info',
|
|
mock_distro_os_release_info)
|
|
mocker.patch(
|
|
'ansible.module_utils.common.sys_info.distro.lsb_release_info',
|
|
mock_distro_lsb_release_info)
|
|
mocker.patch('os.path.isfile', mock_os_path_is_file)
|
|
mocker.patch('platform.system', mock_platform_system)
|
|
mocker.patch('platform.release', mock_platform_release)
|
|
mocker.patch('platform.version', mock_platform_version)
|
|
mocker.patch('ansible.module_utils.basic.AnsibleModule.run_command', mock_run_command_output)
|
|
|
|
real_open = builtins.open
|
|
mocker.patch.object(builtins, 'open', new=mock_open)
|
|
|
|
# run Facts()
|
|
distro_collector = DistributionFactCollector()
|
|
generated_facts = distro_collector.collect(am)
|
|
|
|
# compare with the expected output
|
|
|
|
# testcase['result'] has a list of variables and values it expects Facts() to set
|
|
for key, val in testcase['result'].items():
|
|
assert key in generated_facts
|
|
msg = 'Comparing value of %s on %s, should: %s, is: %s' %\
|
|
(key, testcase['name'], val, generated_facts[key])
|
|
assert generated_facts[key] == val, msg
|