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.
ansible/test/units/module_utils/facts/system/distribution/test_distribution_version.py

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