1
0
Fork 0
mirror of https://github.com/ansible-collections/community.general.git synced 2024-09-14 20:13:21 +02:00

[PR #7231/517e2d48 backport][stable-7] cpanm: using yaml-specified unit tests (#7233)

cpanm: using yaml-specified unit tests (#7231)

* cpanm: using yaml-specified unit tests

* add quote around URLs to appease pyaml@py26

* add changelog frag

(cherry picked from commit 517e2d48eb)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
This commit is contained in:
patchback[bot] 2023-09-10 21:45:36 +02:00 committed by GitHub
parent 88fab247ca
commit 418589e346
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 236 additions and 269 deletions

View file

@ -0,0 +1,2 @@
minor_changes:
- cpanm - minor refactor when creating the ``CmdRunner`` object (https://github.com/ansible-collections/community.general/pull/7231).

View file

@ -183,8 +183,9 @@ class CPANMinus(ModuleHelper):
if v.name and v.from_path: if v.name and v.from_path:
self.do_raise("Parameters 'name' and 'from_path' are mutually exclusive when 'mode=new'") self.do_raise("Parameters 'name' and 'from_path' are mutually exclusive when 'mode=new'")
self.command = self.get_bin_path(v.executable if v.executable else self.command) self.command = v.executable if v.executable else self.command
self.vars.set("binary", self.command) self.runner = CmdRunner(self.module, self.command, self.command_args_formats, check_rc=True)
self.vars.binary = self.runner.binary
def _is_package_installed(self, name, locallib, version): def _is_package_installed(self, name, locallib, version):
def process(rc, out, err): def process(rc, out, err):
@ -220,8 +221,6 @@ class CPANMinus(ModuleHelper):
self.do_raise(msg=err, cmd=self.vars.cmd_args) self.do_raise(msg=err, cmd=self.vars.cmd_args)
return 'is up to date' not in err and 'is up to date' not in out return 'is up to date' not in err and 'is up to date' not in out
runner = CmdRunner(self.module, self.command, self.command_args_formats, check_rc=True)
v = self.vars v = self.vars
pkg_param = 'from_path' if v.from_path else 'name' pkg_param = 'from_path' if v.from_path else 'name'
@ -235,7 +234,7 @@ class CPANMinus(ModuleHelper):
return return
pkg_spec = self.sanitize_pkg_spec_version(v[pkg_param], v.version) pkg_spec = self.sanitize_pkg_spec_version(v[pkg_param], v.version)
with runner(['notest', 'locallib', 'mirror', 'mirror_only', 'installdeps', 'pkg_spec'], output_process=process) as ctx: with self.runner(['notest', 'locallib', 'mirror', 'mirror_only', 'installdeps', 'pkg_spec'], output_process=process) as ctx:
self.changed = ctx.run(pkg_spec=pkg_spec) self.changed = ctx.run(pkg_spec=pkg_spec)

View file

@ -12,280 +12,26 @@
from __future__ import (absolute_import, division, print_function) from __future__ import (absolute_import, division, print_function)
__metaclass__ = type __metaclass__ = type
import json
from ansible_collections.community.general.plugins.modules import cpanm
import pytest import pytest
from ansible_collections.community.general.plugins.modules import cpanm
@pytest.fixture from .cmd_runner_test_utils import CmdRunnerTestHelper
def patch_cpanm(mocker):
"""
Function used for mocking some parts of redhat_subscription module
"""
mocker.patch('ansible.module_utils.basic.AnsibleModule.get_bin_path',
return_value='/testbin/cpanm')
TEST_CASES = [ with open("tests/unit/plugins/modules/test_cpanm.yaml", "r") as TEST_CASES:
[ helper = CmdRunnerTestHelper(cpanm.main, test_cases=TEST_CASES)
{'name': 'Dancer'}, patch_bin = helper.cmd_fixture
{
'id': 'install_dancer_compatibility',
'run_command.calls': [
(
['/testbin/cpanm', '-le', 'use Dancer;'],
{'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': False},
(2, '', 'error, not installed',), # output rc, out, err
),
(
['/testbin/cpanm', 'Dancer'],
{'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': True},
(0, '', '',), # output rc, out, err
),
],
'changed': True,
}
],
[
{'name': 'Dancer'},
{
'id': 'install_dancer_already_installed_compatibility',
'run_command.calls': [
(
['/testbin/cpanm', '-le', 'use Dancer;'],
{'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': False},
(0, '', '',), # output rc, out, err
),
],
'changed': False,
}
],
[
{'name': 'Dancer', 'mode': 'new'},
{
'id': 'install_dancer',
'run_command.calls': [(
['/testbin/cpanm', 'Dancer'],
{'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': True},
(0, '', '',), # output rc, out, err
)],
'changed': True,
}
],
[
{'name': 'MIYAGAWA/Plack-0.99_05.tar.gz'},
{
'id': 'install_distribution_file_compatibility',
'run_command.calls': [(
['/testbin/cpanm', 'MIYAGAWA/Plack-0.99_05.tar.gz'],
{'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': True},
(0, '', '',), # output rc, out, err
)],
'changed': True,
}
],
[
{'name': 'MIYAGAWA/Plack-0.99_05.tar.gz', 'mode': 'new'},
{
'id': 'install_distribution_file',
'run_command.calls': [(
['/testbin/cpanm', 'MIYAGAWA/Plack-0.99_05.tar.gz'],
{'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': True},
(0, '', '',), # output rc, out, err
)],
'changed': True,
}
],
[
{'name': 'Dancer', 'locallib': '/srv/webapps/my_app/extlib', 'mode': 'new'},
{
'id': 'install_into_locallib',
'run_command.calls': [(
['/testbin/cpanm', '--local-lib', '/srv/webapps/my_app/extlib', 'Dancer'],
{'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': True},
(0, '', '',), # output rc, out, err
)],
'changed': True,
}
],
[
{'from_path': '/srv/webapps/my_app/src/', 'mode': 'new'},
{
'id': 'install_from_local_directory',
'run_command.calls': [(
['/testbin/cpanm', '/srv/webapps/my_app/src/'],
{'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': True},
(0, '', '',), # output rc, out, err
)],
'changed': True,
}
],
[
{'name': 'Dancer', 'locallib': '/srv/webapps/my_app/extlib', 'notest': True, 'mode': 'new'},
{
'id': 'install_into_locallib_no_unit_testing',
'run_command.calls': [(
['/testbin/cpanm', '--notest', '--local-lib', '/srv/webapps/my_app/extlib', 'Dancer'],
{'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': True},
(0, '', '',), # output rc, out, err
)],
'changed': True,
}
],
[
{'name': 'Dancer', 'mirror': 'http://cpan.cpantesters.org/', 'mode': 'new'},
{
'id': 'install_from_mirror',
'run_command.calls': [(
['/testbin/cpanm', '--mirror', 'http://cpan.cpantesters.org/', 'Dancer'],
{'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': True},
(0, '', '',), # output rc, out, err
)],
'changed': True,
}
],
[
{'name': 'Dancer', 'system_lib': True, 'mode': 'new'},
{
'id': 'install_into_system_lib',
'run_command.calls': [],
'changed': False,
'failed': True,
}
],
[
{'name': 'Dancer', 'version': '1.0', 'mode': 'new'},
{
'id': 'install_minversion_implicit',
'run_command.calls': [(
['/testbin/cpanm', 'Dancer~1.0'],
{'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': True},
(0, '', '',), # output rc, out, err
)],
'changed': True,
}
],
[
{'name': 'Dancer', 'version': '~1.5', 'mode': 'new'},
{
'id': 'install_minversion_explicit',
'run_command.calls': [(
['/testbin/cpanm', 'Dancer~1.5'],
{'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': True},
(0, '', '',), # output rc, out, err
)],
'changed': True,
}
],
[
{'name': 'Dancer', 'version': '@1.7', 'mode': 'new'},
{
'id': 'install_specific_version',
'run_command.calls': [(
['/testbin/cpanm', 'Dancer@1.7'],
{'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': True},
(0, '', '',), # output rc, out, err
)],
'changed': True,
'failed': False,
}
],
[
{'name': 'MIYAGAWA/Plack-0.99_05.tar.gz', 'version': '@1.7', 'mode': 'new'},
{
'id': 'install_specific_version_from_file_error',
'run_command.calls': [],
'changed': False,
'failed': True,
'msg': "parameter 'version' must not be used when installing from a file",
}
],
[
{'from_path': '~/', 'version': '@1.7', 'mode': 'new'},
{
'id': 'install_specific_version_from_directory_error',
'run_command.calls': [],
'changed': False,
'failed': True,
'msg': "parameter 'version' must not be used when installing from a directory",
}
],
[
{'name': 'git://github.com/plack/Plack.git', 'version': '@1.7', 'mode': 'new'},
{
'id': 'install_specific_version_from_git_url_explicit',
'run_command.calls': [(
['/testbin/cpanm', 'git://github.com/plack/Plack.git@1.7'],
{'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': True},
(0, '', '',), # output rc, out, err
)],
'changed': True,
'failed': False,
}
],
[
{'name': 'git://github.com/plack/Plack.git', 'version': '2.5', 'mode': 'new'},
{
'id': 'install_specific_version_from_git_url_implicit',
'run_command.calls': [(
['/testbin/cpanm', 'git://github.com/plack/Plack.git@2.5'],
{'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': True},
(0, '', '',), # output rc, out, err
)],
'changed': True,
'failed': False,
}
],
[
{'name': 'git://github.com/plack/Plack.git', 'version': '~2.5', 'mode': 'new'},
{
'id': 'install_version_operator_from_git_url_error',
'run_command.calls': [],
'changed': False,
'failed': True,
'msg': "operator '~' not allowed in version parameter when installing from git repository",
}
],
]
TEST_CASES_IDS = [item[1]['id'] for item in TEST_CASES]
@pytest.mark.parametrize('patch_ansible_module, testcase', @pytest.mark.parametrize('patch_ansible_module, testcase',
TEST_CASES, helper.testcases_params, ids=helper.testcases_ids,
ids=TEST_CASES_IDS,
indirect=['patch_ansible_module']) indirect=['patch_ansible_module'])
@pytest.mark.usefixtures('patch_ansible_module') @pytest.mark.usefixtures('patch_ansible_module')
def test_cpanm(mocker, capfd, patch_cpanm, testcase): def test_module(mocker, capfd, patch_bin, testcase):
""" """
Run unit tests for test cases listen in TEST_CASES Run unit tests for test cases listed in TEST_CASES
""" """
# Mock function used for running commands first with helper(testcase, mocker, capfd) as testcase_context:
call_results = [item[2] for item in testcase['run_command.calls']] testcase_context.run()
mock_run_command = mocker.patch(
'ansible_collections.community.general.plugins.module_utils.module_helper.AnsibleModule.run_command',
side_effect=call_results)
# Try to run test case
with pytest.raises(SystemExit):
cpanm.main()
out, err = capfd.readouterr()
results = json.loads(out)
print("results =\n%s" % results)
assert mock_run_command.call_count == len(testcase['run_command.calls'])
if mock_run_command.call_count:
call_args_list = [(item[0][0], item[1]) for item in mock_run_command.call_args_list]
expected_call_args_list = [(item[0], item[1]) for item in testcase['run_command.calls']]
print("call args list =\n%s" % call_args_list)
print("expected args list =\n%s" % expected_call_args_list)
assert call_args_list == expected_call_args_list
assert results.get('changed', False) == testcase['changed']
if 'failed' in testcase:
assert results.get('failed', False) == testcase['failed']
if 'msg' in testcase:
assert results.get('msg', '') == testcase['msg']

View file

@ -0,0 +1,220 @@
# -*- coding: utf-8 -*-
# Copyright (c) Alexei Znamensky (russoz@gmail.com)
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
---
- id: install_dancer_compatibility
input:
name: Dancer
output:
changed: true
run_command_calls:
- command: [/testbin/perl, -le, 'use Dancer;']
environ: {environ_update: {LANGUAGE: C, LC_ALL: C}, check_rc: false}
rc: 2
out: ""
err: "error, not installed"
- command: [/testbin/cpanm, Dancer]
environ: {environ_update: {LANGUAGE: C, LC_ALL: C}, check_rc: true}
rc: 0
out: ""
err: ""
- id: install_dancer_already_installed_compatibility
input:
name: Dancer
output:
changed: false
run_command_calls:
- command: [/testbin/perl, -le, 'use Dancer;']
environ: {environ_update: {LANGUAGE: C, LC_ALL: C}, check_rc: false}
rc: 0
out: ""
err: ""
- id: install_dancer
input:
name: Dancer
mode: new
output:
changed: true
run_command_calls:
- command: [/testbin/cpanm, Dancer]
environ: {environ_update: {LANGUAGE: C, LC_ALL: C}, check_rc: true}
rc: 0
out: ""
err: ""
- id: install_distribution_file_compatibility
input:
name: MIYAGAWA/Plack-0.99_05.tar.gz
output:
changed: true
run_command_calls:
- command: [/testbin/cpanm, MIYAGAWA/Plack-0.99_05.tar.gz]
environ: {environ_update: {LANGUAGE: C, LC_ALL: C}, check_rc: true}
rc: 0
out: ""
err: ""
- id: install_distribution_file
input:
name: MIYAGAWA/Plack-0.99_05.tar.gz
mode: new
output:
changed: true
run_command_calls:
- command: [/testbin/cpanm, MIYAGAWA/Plack-0.99_05.tar.gz]
environ: {environ_update: {LANGUAGE: C, LC_ALL: C}, check_rc: true}
rc: 0
out: ""
err: ""
- id: install_into_locallib
input:
name: Dancer
mode: new
locallib: /srv/webapps/my_app/extlib
output:
changed: true
run_command_calls:
- command: [/testbin/cpanm, --local-lib, /srv/webapps/my_app/extlib, Dancer]
environ: {environ_update: {LANGUAGE: C, LC_ALL: C}, check_rc: true}
rc: 0
out: ""
err: ""
- id: install_from_local_directory
input:
from_path: /srv/webapps/my_app/src/
mode: new
output:
changed: true
run_command_calls:
- command: [/testbin/cpanm, /srv/webapps/my_app/src/]
environ: {environ_update: {LANGUAGE: C, LC_ALL: C}, check_rc: true}
rc: 0
out: ""
err: ""
- id: install_into_locallib_no_unit_testing
input:
name: Dancer
notest: true
mode: new
locallib: /srv/webapps/my_app/extlib
output:
changed: true
run_command_calls:
- command: [/testbin/cpanm, --notest, --local-lib, /srv/webapps/my_app/extlib, Dancer]
environ: {environ_update: {LANGUAGE: C, LC_ALL: C}, check_rc: true}
rc: 0
out: ""
err: ""
- id: install_from_mirror
input:
name: Dancer
mode: new
mirror: "http://cpan.cpantesters.org/"
output:
changed: true
run_command_calls:
- command: [/testbin/cpanm, --mirror, "http://cpan.cpantesters.org/", Dancer]
environ: {environ_update: {LANGUAGE: C, LC_ALL: C}, check_rc: true}
rc: 0
out: ""
err: ""
- id: install_into_system_lib
input:
name: Dancer
mode: new
system_lib: true
output:
failed: true
run_command_calls: []
- id: install_minversion_implicit
input:
name: Dancer
mode: new
version: "1.0"
output:
changed: true
run_command_calls:
- command: [/testbin/cpanm, Dancer~1.0]
environ: {environ_update: {LANGUAGE: C, LC_ALL: C}, check_rc: true}
rc: 0
out: ""
err: ""
- id: install_minversion_explicit
input:
name: Dancer
mode: new
version: "~1.5"
output:
changed: true
run_command_calls:
- command: [/testbin/cpanm, Dancer~1.5]
environ: {environ_update: {LANGUAGE: C, LC_ALL: C}, check_rc: true}
rc: 0
out: ""
err: ""
- id: install_specific_version
input:
name: Dancer
mode: new
version: "@1.7"
output:
changed: true
run_command_calls:
- command: [/testbin/cpanm, Dancer@1.7]
environ: {environ_update: {LANGUAGE: C, LC_ALL: C}, check_rc: true}
rc: 0
out: ""
err: ""
- id: install_specific_version_from_file_error
input:
name: MIYAGAWA/Plack-0.99_05.tar.gz
mode: new
version: "@1.7"
output:
failed: true
msg: parameter 'version' must not be used when installing from a file
run_command_calls: []
- id: install_specific_version_from_directory_error
input:
from_path: ~/
mode: new
version: "@1.7"
output:
failed: true
msg: parameter 'version' must not be used when installing from a directory
run_command_calls: []
- id: install_specific_version_from_git_url_explicit
input:
name: "git://github.com/plack/Plack.git"
mode: new
version: "@1.7"
output:
changed: true
run_command_calls:
- command: [/testbin/cpanm, "git://github.com/plack/Plack.git@1.7"]
environ: {environ_update: {LANGUAGE: C, LC_ALL: C}, check_rc: true}
rc: 0
out: ""
err: ""
- id: install_specific_version_from_git_url_implicit
input:
name: "git://github.com/plack/Plack.git"
mode: new
version: "2.5"
output:
changed: true
run_command_calls:
- command: [/testbin/cpanm, "git://github.com/plack/Plack.git@2.5"]
environ: {environ_update: {LANGUAGE: C, LC_ALL: C}, check_rc: true}
rc: 0
out: ""
err: ""
- id: install_version_operator_from_git_url_error
input:
name: "git://github.com/plack/Plack.git"
mode: new
version: "~2.5"
output:
failed: true
msg: operator '~' not allowed in version parameter when installing from git repository
run_command_calls: []