Skip to content

[Enabler] refactor_parse_and_validate_args_to_optimize_invalid_arguments_testing #2359

@AndreMarcel99

Description

@AndreMarcel99

Is there an existing issue for this?

  • There are no existing issues.

Enhancement or feature description

Right now to test not valid parameters we execute the module on testing. Old modules use mocker function to validate arguments validation.
Require to move parse_and_validate_args out of the run module to test and reduce time.
zos_backup_restore

def parse_and_validate_args(params):
    """Parse and validate arguments to be used by remainder of module.

    Parameters
    ----------
    params : dict
        The params as returned from AnsibleModule instantiation.

    Returns
    -------
    dict
        The updated params after additional parsing and validation.
    """
    arg_defs = dict(
        operation=dict(type="str", required=True, choices=["backup", "restore"]),
        data_sets=dict(
            required=False,
            type="dict",
            options=dict(
                include=dict(type=data_set_pattern_type, required=False),
                exclude=dict(type=data_set_pattern_type, required=False),
            ),
        ),
        space=dict(
            type=space_type,
            required=False,
            aliases=["size"],
            dependencies=["full_volume"],
        ),
        space_type=dict(
            type=space_type_type,
            required=False,
            aliases=["unit"],
            dependencies=["full_volume"],
        ),
        volume=dict(type="volume", required=False, dependencies=["data_sets"]),
        full_volume=dict(type=full_volume_type, default=False, dependencies=["volume"]),
        temp_volume=dict(type="volume", required=False, aliases=["dest_volume"]),
        backup_name=dict(type=backup_name_type, required=False),
        recover=dict(type="bool", default=False),
        overwrite=dict(type="bool", default=False),
        compress=dict(type="bool", default=False),
        terse=dict(type="bool", default=True),
        sms_storage_class=dict(type=sms_type, required=False),
        sms_management_class=dict(type=sms_type, required=False),
        hlq=dict(type=hlq_type, default=None, dependencies=["operation"]),
        tmp_hlq=dict(type=hlq_type, required=False),
    )

    parsed_args = BetterArgParser(arg_defs).parse_args(params)
    parsed_args = {
        key: value for key, value in parsed_args.items() if value is not None
    }
    return parsed_args

and the unit test for validate parameters is

IMPORT_NAME = "ibm_zos_core.plugins.modules.zos_backup_restore"


class DummyModule(object):
    """Used in place of Ansible's module
    so we can easily mock the desired behavior."""

    def __init__(self, rc=0, stdout="", stderr=""):
        self.rc = rc
        self.stdout = stdout
        self.stderr = stderr

    def run_command(self, *args, **kwargs):
        return (self.rc, self.stdout, self.stderr)


@pytest.fixture(scope="function")
def zos_backup_restore_mocker(zos_import_mocker):
    """Pytest fixture in charge of patching unavailable imports
    so we can run z/OS module test cases on x86 for zos_backup_restore.

    Args:
        zos_import_mocker (zos_import_mocker): A pytest fixture

    Yields:
        object: The zos_backup_restore module object
    """
    mocker, importer = zos_import_mocker
    zos_backup_restore = importer(IMPORT_NAME)
    mocker.patch(
        "{0}.AnsibleModule".format(IMPORT_NAME),
        create=True,
        return_value=DummyModule(),
    )
    mocker.patch(
        "{0}.AnsibleModuleHelper".format(IMPORT_NAME),
        create=True,
        return_value=DummyModule(),
    )
    yield zos_backup_restore


def assert_args_valid(zos_backup_restore, arguments):
    """Asserts arguments DO NOT cause parser to raise exception.

    Args:
        zos_backup_restore (zos_backup_restore_mocker): Mocker object which provides access to functions in zos_backup_restore module.
        valid_args (dict): The arguments to pass to parser.
    """
    error_raised = False
    try:
        zos_backup_restore.parse_and_validate_args(arguments)
    except Exception as e:
        print(str(e))
        error_raised = True
    assert not error_raised


def assert_args_invalid(zos_backup_restore, arguments):
    """Asserts arguments DO cause parser to raise exception.

    Args:
        zos_backup_restore (zos_backup_restore_mocker): Mocker object which provides access to functions in zos_backup_restore module.
        valid_args (dict): The arguments to pass to parser.
    """
    error_raised = False
    try:
        zos_backup_restore.parse_and_validate_args(arguments)
    except Exception as e:
        print(repr(e))
        error_raised = True
    assert error_raised


@pytest.mark.parametrize(
    "space_type", ["k", "m", "g", "trk", "cyl"]
)
def test_valid_space_types(zos_backup_restore_mocker, space_type):
    valid_args = dict(
        operation="backup",
        data_sets=dict(include="user.*"),
        space=10,
        space_type=space_type,
        backup_name="backup.name.here",
    )
    assert_args_valid(zos_backup_restore_mocker, valid_args)

Execute on local making faster and optimal testing.

Ansible module

zos_archive

Metadata

Metadata

Assignees

Labels

EnablerEnabler taskNeeds TriageIssue need assessment by a team member(s)

Type

No type

Projects

Status

No status

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions