diff --git a/.azure-pipelines/azure-pipelines.yml b/.azure-pipelines/azure-pipelines.yml index 3059e209c1..90adf14e0d 100644 --- a/.azure-pipelines/azure-pipelines.yml +++ b/.azure-pipelines/azure-pipelines.yml @@ -43,8 +43,6 @@ variables: value: ansible_collections/community/general - name: coverageBranches value: main - - name: pipelinesCoverage - value: coverage - name: entryPoint value: tests/utils/shippable/shippable.sh - name: fetchDepth diff --git a/.azure-pipelines/templates/coverage.yml b/.azure-pipelines/templates/coverage.yml index 3c8841aa26..1bf17e053a 100644 --- a/.azure-pipelines/templates/coverage.yml +++ b/.azure-pipelines/templates/coverage.yml @@ -28,16 +28,6 @@ jobs: - bash: .azure-pipelines/scripts/report-coverage.sh displayName: Generate Coverage Report condition: gt(variables.coverageFileCount, 0) - - task: PublishCodeCoverageResults@1 - inputs: - codeCoverageTool: Cobertura - # Azure Pipelines only accepts a single coverage data file. - # That means only Python or PowerShell coverage can be uploaded, but not both. - # Set the "pipelinesCoverage" variable to determine which type is uploaded. - # Use "coverage" for Python and "coverage-powershell" for PowerShell. - summaryFileLocation: "$(outputPath)/reports/$(pipelinesCoverage).xml" - displayName: Publish to Azure Pipelines - condition: gt(variables.coverageFileCount, 0) - bash: .azure-pipelines/scripts/publish-codecov.py "$(outputPath)" displayName: Publish to codecov.io condition: gt(variables.coverageFileCount, 0) diff --git a/.github/workflows/ansible-test.yml b/.github/workflows/ansible-test.yml index ca06791a38..0f0dd132dc 100644 --- a/.github/workflows/ansible-test.yml +++ b/.github/workflows/ansible-test.yml @@ -30,11 +30,6 @@ jobs: matrix: ansible: - '2.15' - # Ansible-test on various stable branches does not yet work well with cgroups v2. - # Since ubuntu-latest now uses Ubuntu 22.04, we need to fall back to the ubuntu-20.04 - # image for these stable branches. The list of branches where this is necessary will - # shrink over time, check out https://github.com/ansible-collections/news-for-maintainers/issues/28 - # for the latest list. runs-on: ubuntu-latest steps: - name: Perform sanity testing @@ -47,11 +42,6 @@ jobs: testing-type: sanity units: - # Ansible-test on various stable branches does not yet work well with cgroups v2. - # Since ubuntu-latest now uses Ubuntu 22.04, we need to fall back to the ubuntu-20.04 - # image for these stable branches. The list of branches where this is necessary will - # shrink over time, check out https://github.com/ansible-collections/news-for-maintainers/issues/28 - # for the latest list. runs-on: ubuntu-latest name: EOL Units (Ⓐ${{ matrix.ansible }}+py${{ matrix.python }}) strategy: @@ -90,11 +80,6 @@ jobs: testing-type: units integration: - # Ansible-test on various stable branches does not yet work well with cgroups v2. - # Since ubuntu-latest now uses Ubuntu 22.04, we need to fall back to the ubuntu-20.04 - # image for these stable branches. The list of branches where this is necessary will - # shrink over time, check out https://github.com/ansible-collections/news-for-maintainers/issues/28 - # for the latest list. runs-on: ubuntu-latest name: EOL I (Ⓐ${{ matrix.ansible }}+${{ matrix.docker }}+py${{ matrix.python }}:${{ matrix.target }}) strategy: diff --git a/changelogs/fragments/6264-zfs-multiline-property-value.yml b/changelogs/fragments/6264-zfs-multiline-property-value.yml new file mode 100644 index 0000000000..30e06f7919 --- /dev/null +++ b/changelogs/fragments/6264-zfs-multiline-property-value.yml @@ -0,0 +1,2 @@ +bugfixes: + - zfs - fix handling of multi-line values of user-defined ZFS properties (https://github.com/ansible-collections/community.general/pull/6264). diff --git a/changelogs/fragments/9625-onepassword_doc.yml b/changelogs/fragments/9625-onepassword_doc.yml new file mode 100644 index 0000000000..e4c4cd5b65 --- /dev/null +++ b/changelogs/fragments/9625-onepassword_doc.yml @@ -0,0 +1,2 @@ +bugfixes: + - "onepassword_doc lookup plugin - ensure that 1Password Connect support also works for this plugin (https://github.com/ansible-collections/community.general/pull/9625)." diff --git a/changelogs/fragments/9644-kc_client-test-improvement-and-fix.yaml b/changelogs/fragments/9644-kc_client-test-improvement-and-fix.yaml new file mode 100644 index 0000000000..63cba99198 --- /dev/null +++ b/changelogs/fragments/9644-kc_client-test-improvement-and-fix.yaml @@ -0,0 +1,2 @@ +bugfixes: + - keycloak_client - fix and improve existing tests. The module showed a diff without actual changes, solved by improving the ``normalise_cr()`` function (https://github.com/ansible-collections/community.general/pull/9644). diff --git a/changelogs/fragments/9651-iocage-inventory-hooks.yml b/changelogs/fragments/9651-iocage-inventory-hooks.yml new file mode 100644 index 0000000000..268348ba3c --- /dev/null +++ b/changelogs/fragments/9651-iocage-inventory-hooks.yml @@ -0,0 +1,2 @@ +minor_changes: + - iocage inventory plugin - the new parameter ``hooks_results`` of the plugin is a list of files inside a jail that provide configuration parameters for the inventory. The inventory plugin reads the files from the jails and put the contents into the items of created variable ``iocage_hooks`` (https://github.com/ansible-collections/community.general/issues/9650, https://github.com/ansible-collections/community.general/pull/9651). diff --git a/changelogs/fragments/9658-add-vrf-commands-to-nmcli-module.yml b/changelogs/fragments/9658-add-vrf-commands-to-nmcli-module.yml new file mode 100644 index 0000000000..a62fc823c5 --- /dev/null +++ b/changelogs/fragments/9658-add-vrf-commands-to-nmcli-module.yml @@ -0,0 +1,2 @@ +minor_changes: + - nmcli - adds VRF support with new ``type`` value ``vrf`` and new ``slave_type`` value ``vrf`` as well as new ``table`` parameter (https://github.com/ansible-collections/community.general/pull/9658, https://github.com/ansible-collections/community.general/issues/8014). diff --git a/changelogs/fragments/9665-more-resilient-handling-of-homebrew-packages-names.yml b/changelogs/fragments/9665-more-resilient-handling-of-homebrew-packages-names.yml new file mode 100644 index 0000000000..4e79dd6ea2 --- /dev/null +++ b/changelogs/fragments/9665-more-resilient-handling-of-homebrew-packages-names.yml @@ -0,0 +1,2 @@ +bugfixes: + - homebrew - make package name parsing more resilient (https://github.com/ansible-collections/community.general/pull/9665, https://github.com/ansible-collections/community.general/issues/9641). diff --git a/changelogs/fragments/9691-keycloak-module-utils-replace-missing-return-in-get_role_composites.yml b/changelogs/fragments/9691-keycloak-module-utils-replace-missing-return-in-get_role_composites.yml new file mode 100644 index 0000000000..bf48f5f609 --- /dev/null +++ b/changelogs/fragments/9691-keycloak-module-utils-replace-missing-return-in-get_role_composites.yml @@ -0,0 +1,2 @@ +bugfixes: + - keycloak module utils - replaces missing return in get_role_composites method which caused it to return None instead of composite roles (https://github.com/ansible-collections/community.general/issues/9678, https://github.com/ansible-collections/community.general/pull/9691). diff --git a/changelogs/fragments/9694-ipa-host-certificate-revoked.yml b/changelogs/fragments/9694-ipa-host-certificate-revoked.yml new file mode 100644 index 0000000000..71dcbb2a17 --- /dev/null +++ b/changelogs/fragments/9694-ipa-host-certificate-revoked.yml @@ -0,0 +1,2 @@ +bugfixes: + - ipa_host - module revoked existing host certificates even if ``user_certificate`` was not given (https://github.com/ansible-collections/community.general/pull/9694). diff --git a/changelogs/fragments/9695-xml-close-file.yml b/changelogs/fragments/9695-xml-close-file.yml new file mode 100644 index 0000000000..d2a1843278 --- /dev/null +++ b/changelogs/fragments/9695-xml-close-file.yml @@ -0,0 +1,2 @@ +bugfixes: + - xml - ensure file descriptor is closed (https://github.com/ansible-collections/community.general/pull/9695). diff --git a/changelogs/fragments/9697-zfs-facts-type.yml b/changelogs/fragments/9697-zfs-facts-type.yml new file mode 100644 index 0000000000..b738d3ae9f --- /dev/null +++ b/changelogs/fragments/9697-zfs-facts-type.yml @@ -0,0 +1,2 @@ +bugfixes: + - zfs_facts - parameter ``type`` now accepts multple values as documented (https://github.com/ansible-collections/community.general/issues/5909, https://github.com/ansible-collections/community.general/pull/9697). diff --git a/changelogs/fragments/9698-lvg-remove-extra-pvs-parameter.yml b/changelogs/fragments/9698-lvg-remove-extra-pvs-parameter.yml new file mode 100644 index 0000000000..51c0423e8b --- /dev/null +++ b/changelogs/fragments/9698-lvg-remove-extra-pvs-parameter.yml @@ -0,0 +1,2 @@ +minor_changes: + - lvg - add ``remove_extra_pvs`` parameter to control if ansible should remove physical volumes which are not in the ``pvs`` parameter (https://github.com/ansible-collections/community.general/pull/9698). diff --git a/changelogs/fragments/9729-redfish-fullpowercycle-command.yml b/changelogs/fragments/9729-redfish-fullpowercycle-command.yml new file mode 100644 index 0000000000..2d9974c3d6 --- /dev/null +++ b/changelogs/fragments/9729-redfish-fullpowercycle-command.yml @@ -0,0 +1,2 @@ +minor_changes: + - redfish_command - add ``PowerFullPowerCycle`` to power command options (https://github.com/ansible-collections/community.general/pull/9729). diff --git a/changelogs/fragments/9733-profitbrick-deprecation.yml b/changelogs/fragments/9733-profitbrick-deprecation.yml new file mode 100644 index 0000000000..094f2672a4 --- /dev/null +++ b/changelogs/fragments/9733-profitbrick-deprecation.yml @@ -0,0 +1,6 @@ +deprecated_features: + - profitbricks - module is deprecated and will be removed in community.general 11.0.0 (https://github.com/ansible-collections/community.general/pull/9733). + - profitbricks_datacenter - module is deprecated and will be removed in community.general 11.0.0 (https://github.com/ansible-collections/community.general/pull/9733). + - profitbricks_nic - module is deprecated and will be removed in community.general 11.0.0 (https://github.com/ansible-collections/community.general/pull/9733). + - profitbricks_volume - module is deprecated and will be removed in community.general 11.0.0 (https://github.com/ansible-collections/community.general/pull/9733). + - profitbricks_volume_attachments - module is deprecated and will be removed in community.general 11.0.0 (https://github.com/ansible-collections/community.general/pull/9733). diff --git a/docs/docsite/rst/filter_guide_abstract_informations_lists_helper.rst b/docs/docsite/rst/filter_guide_abstract_informations_lists_helper.rst index 63db10a782..505320c79c 100644 --- a/docs/docsite/rst/filter_guide_abstract_informations_lists_helper.rst +++ b/docs/docsite/rst/filter_guide_abstract_informations_lists_helper.rst @@ -65,7 +65,7 @@ All three statements are equivalent and give: .. note:: Be aware that in most cases, filter calls without any argument require ``flatten=true``, otherwise the input is returned as result. The reason for this is, that the input is considered as a variable argument and is wrapped by an additional outer list. ``flatten=true`` ensures that this list is removed before the input is processed by the filter logic. -The filters ansplugin:`community.general.lists_difference#filter` or :ansplugin:`community.general.lists_symmetric_difference#filter` can be used in the same way as the filters in the examples above. They calculate the difference or the symmetric difference between two or more lists and preserve the item order. +The filters :ansplugin:`community.general.lists_difference#filter` or :ansplugin:`community.general.lists_symmetric_difference#filter` can be used in the same way as the filters in the examples above. They calculate the difference or the symmetric difference between two or more lists and preserve the item order. For example, the symmetric difference of ``A``, ``B`` and ``C`` may be written as: diff --git a/meta/runtime.yml b/meta/runtime.yml index 904790403a..1e27fdce1e 100644 --- a/meta/runtime.yml +++ b/meta/runtime.yml @@ -113,15 +113,15 @@ plugin_routing: atomic_container: deprecation: removal_version: 13.0.0 - warning_text: Poject Atomic was sunset by the end of 2019. + warning_text: Project Atomic was sunset by the end of 2019. atomic_host: deprecation: removal_version: 13.0.0 - warning_text: Poject Atomic was sunset by the end of 2019. + warning_text: Project Atomic was sunset by the end of 2019. atomic_image: deprecation: removal_version: 13.0.0 - warning_text: Poject Atomic was sunset by the end of 2019. + warning_text: Project Atomic was sunset by the end of 2019. cisco_spark: redirect: community.general.cisco_webex consul_acl: @@ -604,6 +604,26 @@ plugin_routing: redirect: community.postgresql.postgresql_user postgresql_user_obj_stat_info: redirect: community.postgresql.postgresql_user_obj_stat_info + profitbricks: + deprecation: + removal_version: 11.0.0 + warning_text: Supporting library is unsupported since 2021. + profitbricks_datacenter: + deprecation: + removal_version: 11.0.0 + warning_text: Supporting library is unsupported since 2021. + profitbricks_nic: + deprecation: + removal_version: 11.0.0 + warning_text: Supporting library is unsupported since 2021. + profitbricks_volume: + deprecation: + removal_version: 11.0.0 + warning_text: Supporting library is unsupported since 2021. + profitbricks_volume_attachments: + deprecation: + removal_version: 11.0.0 + warning_text: Supporting library is unsupported since 2021. purefa_facts: tombstone: removal_version: 3.0.0 diff --git a/plugins/inventory/iocage.py b/plugins/inventory/iocage.py index 31aad309f5..6edac6d005 100644 --- a/plugins/inventory/iocage.py +++ b/plugins/inventory/iocage.py @@ -6,85 +6,99 @@ from __future__ import annotations -DOCUMENTATION = ''' - name: iocage - short_description: iocage inventory source - version_added: 10.2.0 - author: - - Vladimir Botka (@vbotka) - requirements: - - iocage >= 1.8 +DOCUMENTATION = r''' +name: iocage +short_description: iocage inventory source +version_added: 10.2.0 +author: + - Vladimir Botka (@vbotka) +requirements: + - iocage >= 1.8 +description: + - Get inventory hosts from the iocage jail manager running on O(host). + - By default, O(host) is V(localhost). If O(host) is not V(localhost) it + is expected that the user running Ansible on the controller can + connect to the O(host) account O(user) with SSH non-interactively and + execute the command C(iocage list). + - Uses a configuration file as an inventory source, it must end + in C(.iocage.yml) or C(.iocage.yaml). +extends_documentation_fragment: + - ansible.builtin.constructed + - ansible.builtin.inventory_cache +options: + plugin: description: - - Get inventory hosts from the iocage jail manager running on O(host). - - By default, O(host) is V(localhost). If O(host) is not V(localhost) it - is expected that the user running Ansible on the controller can - connect to the O(host) account O(user) with SSH non-interactively and - execute the command C(iocage list). - - Uses a configuration file as an inventory source, it must end - in C(.iocage.yml) or C(.iocage.yaml). - extends_documentation_fragment: - - ansible.builtin.constructed - - ansible.builtin.inventory_cache - options: - plugin: - description: - - The name of this plugin, it should always be set to - V(community.general.iocage) for this plugin to recognize - it as its own. - required: true - choices: ['community.general.iocage'] - type: str - host: - description: The IP/hostname of the C(iocage) host. - type: str - default: localhost - user: - description: - - C(iocage) user. - It is expected that the O(user) is able to connect to the - O(host) with SSH and execute the command C(iocage list). - This option is not required if O(host) is V(localhost). - type: str - sudo: - description: - - Enable execution as root. - - This requires passwordless sudo of the command C(iocage list*). - type: bool - default: false - version_added: 10.3.0 - sudo_preserve_env: - description: - - Preserve environment if O(sudo) is enabled. - - This requires C(SETENV) sudoers tag. - type: bool - default: false - version_added: 10.3.0 - get_properties: - description: - - Get jails' properties. - Creates dictionary C(iocage_properties) for each added host. - type: bool - default: false - env: - description: - - O(user)'s environment on O(host). - - Enable O(sudo_preserve_env) if O(sudo) is enabled. - type: dict - default: {} - notes: - - You might want to test the command C(ssh user@host iocage list -l) on - the controller before using this inventory plugin with O(user) specified - and with O(host) other than V(localhost). - - If you run this inventory plugin on V(localhost) C(ssh) is not used. - In this case, test the command C(iocage list -l). - - This inventory plugin creates variables C(iocage_*) for each added host. - - The values of these variables are collected from the output of the - command C(iocage list -l). - - The names of these variables correspond to the output columns. - - The column C(NAME) is used to name the added host. + - The name of this plugin, it should always be set to + V(community.general.iocage) for this plugin to recognize + it as its own. + required: true + choices: ['community.general.iocage'] + type: str + host: + description: The IP/hostname of the C(iocage) host. + type: str + default: localhost + user: + description: + - C(iocage) user. + It is expected that the O(user) is able to connect to the + O(host) with SSH and execute the command C(iocage list). + This option is not required if O(host) is V(localhost). + type: str + sudo: + description: + - Enable execution as root. + - This requires passwordless sudo of the command C(iocage list*). + type: bool + default: false + version_added: 10.3.0 + sudo_preserve_env: + description: + - Preserve environment if O(sudo) is enabled. + - This requires C(SETENV) sudoers tag. + type: bool + default: false + version_added: 10.3.0 + get_properties: + description: + - Get jails' properties. + Creates dictionary C(iocage_properties) for each added host. + type: bool + default: false + env: + description: + - O(user)'s environment on O(host). + - Enable O(sudo_preserve_env) if O(sudo) is enabled. + type: dict + default: {} + hooks_results: + description: + - List of paths to the files in a jail. + - Content of the files is stored in the items of the list C(iocage_hooks). + - If a file is not available the item keeps the dash character C(-). + - The variable C(iocage_hooks) is not created if O(hooks_results) is empty. + type: list + elements: path + version_added: 10.4.0 +notes: + - You might want to test the command C(ssh user@host iocage list -l) on + the controller before using this inventory plugin with O(user) specified + and with O(host) other than V(localhost). + - If you run this inventory plugin on V(localhost) C(ssh) is not used. + In this case, test the command C(iocage list -l). + - This inventory plugin creates variables C(iocage_*) for each added host. + - The values of these variables are collected from the output of the + command C(iocage list -l). + - The names of these variables correspond to the output columns. + - The column C(NAME) is used to name the added host. + - The option O(hooks_results) expects the C(poolname) of a jail is mounted to + C(/poolname). For example, if you activate the pool C(iocage) this plugin + expects to find the O(hooks_results) items in the path + C(/iocage/iocage/jails//root). If you mount the C(poolname) to a + different path the easiest remedy is to create a symlink. ''' -EXAMPLES = ''' +EXAMPLES = r''' --- # file name must end with iocage.yaml or iocage.yml plugin: community.general.iocage @@ -142,6 +156,18 @@ keyed_groups: key: iocage_release - prefix: state key: iocage_state + +--- +# Read the file /var/db/dhclient-hook.address.epair0b in the jails and use it as ansible_host +plugin: community.general.iocage +host: 10.1.0.73 +user: admin +hooks_results: + - /var/db/dhclient-hook.address.epair0b +compose: + ansible_host: iocage_hooks.0 +groups: + test: inventory_hostname.startswith('test') ''' import re @@ -226,6 +252,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable): sudo_preserve_env = self.get_option('sudo_preserve_env') env = self.get_option('env') get_properties = self.get_option('get_properties') + hooks_results = self.get_option('hooks_results') cmd = [] my_env = os.environ.copy() @@ -286,6 +313,50 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable): self.get_properties(t_stdout, results, hostname) + if hooks_results: + cmd_get_pool = cmd.copy() + cmd_get_pool.append(self.IOCAGE) + cmd_get_pool.append('get') + cmd_get_pool.append('--pool') + try: + p = Popen(cmd_get_pool, stdout=PIPE, stderr=PIPE, env=my_env) + stdout, stderr = p.communicate() + if p.returncode != 0: + raise AnsibleError( + f'Failed to run cmd={cmd_get_pool}, rc={p.returncode}, stderr={to_native(stderr)}') + try: + iocage_pool = to_text(stdout, errors='surrogate_or_strict').strip() + except UnicodeError as e: + raise AnsibleError(f'Invalid (non unicode) input returned: {e}') from e + except Exception as e: + raise AnsibleError(f'Failed to get pool: {e}') from e + + for hostname, host_vars in results['_meta']['hostvars'].items(): + iocage_hooks = [] + for hook in hooks_results: + path = "/" + iocage_pool + "/iocage/jails/" + hostname + "/root" + hook + cmd_cat_hook = cmd.copy() + cmd_cat_hook.append('cat') + cmd_cat_hook.append(path) + try: + p = Popen(cmd_cat_hook, stdout=PIPE, stderr=PIPE, env=my_env) + stdout, stderr = p.communicate() + if p.returncode != 0: + iocage_hooks.append('-') + continue + + try: + iocage_hook = to_text(stdout, errors='surrogate_or_strict').strip() + except UnicodeError as e: + raise AnsibleError(f'Invalid (non unicode) input returned: {e}') from e + + except Exception: + iocage_hooks.append('-') + else: + iocage_hooks.append(iocage_hook) + + results['_meta']['hostvars'][hostname]['iocage_hooks'] = iocage_hooks + return results def get_jails(self, t_stdout, results): diff --git a/plugins/lookup/onepassword.py b/plugins/lookup/onepassword.py index 60e0b2a69c..ce0179a31e 100644 --- a/plugins/lookup/onepassword.py +++ b/plugins/lookup/onepassword.py @@ -553,9 +553,7 @@ class OnePassCLIv2(OnePassCLIBase): environment_update = {"OP_SECRET_KEY": self.secret_key} return self._run(args, command_input=to_bytes(self.master_password), environment_update=environment_update) - def get_raw(self, item_id, vault=None, token=None): - args = ["item", "get", item_id, "--format", "json"] - + def _add_parameters_and_run(self, args, vault=None, token=None): if self.account_id: args.extend(["--account", self.account_id]) @@ -582,6 +580,10 @@ class OnePassCLIv2(OnePassCLIBase): return self._run(args) + def get_raw(self, item_id, vault=None, token=None): + args = ["item", "get", item_id, "--format", "json"] + return self._add_parameters_and_run(args, vault=vault, token=token) + def signin(self): self._check_required_params(['master_password']) diff --git a/plugins/lookup/onepassword_doc.py b/plugins/lookup/onepassword_doc.py index b1728fce89..5ffcf02c69 100644 --- a/plugins/lookup/onepassword_doc.py +++ b/plugins/lookup/onepassword_doc.py @@ -46,28 +46,13 @@ RETURN = """ """ from ansible_collections.community.general.plugins.lookup.onepassword import OnePass, OnePassCLIv2 -from ansible.errors import AnsibleLookupError -from ansible.module_utils.common.text.converters import to_bytes from ansible.plugins.lookup import LookupBase class OnePassCLIv2Doc(OnePassCLIv2): def get_raw(self, item_id, vault=None, token=None): args = ["document", "get", item_id] - if vault is not None: - args = [*args, f"--vault={vault}"] - - if self.service_account_token: - if vault is None: - raise AnsibleLookupError("'vault' is required with 'service_account_token'") - - environment_update = {"OP_SERVICE_ACCOUNT_TOKEN": self.service_account_token} - return self._run(args, environment_update=environment_update) - - if token is not None: - args = [*args, to_bytes("--session=") + token] - - return self._run(args) + return self._add_parameters_and_run(args, vault=vault, token=token) class LookupModule(LookupBase): diff --git a/plugins/module_utils/identity/keycloak/keycloak.py b/plugins/module_utils/identity/keycloak/keycloak.py index 74a6b33150..3c57586940 100644 --- a/plugins/module_utils/identity/keycloak/keycloak.py +++ b/plugins/module_utils/identity/keycloak/keycloak.py @@ -1856,7 +1856,7 @@ class KeycloakAPI(object): else: composite_url = URL_REALM_ROLE_COMPOSITES.format(url=self.baseurl, realm=realm, name=quote(rolerep["name"], safe='')) # Get existing composites - self._request_and_deserialize(composite_url, method='GET') + return self._request_and_deserialize(composite_url, method='GET') except Exception as e: self.fail_request(e, msg='Could not get role %s composites in realm %s: %s' % (rolerep['name'], realm, str(e))) diff --git a/plugins/module_utils/redfish_utils.py b/plugins/module_utils/redfish_utils.py index 0a8cc37bcc..4b6345b318 100644 --- a/plugins/module_utils/redfish_utils.py +++ b/plugins/module_utils/redfish_utils.py @@ -1119,7 +1119,8 @@ class RedfishUtils(object): key = "Actions" reset_type_values = ['On', 'ForceOff', 'GracefulShutdown', 'GracefulRestart', 'ForceRestart', 'Nmi', - 'ForceOn', 'PushPowerButton', 'PowerCycle'] + 'ForceOn', 'PushPowerButton', 'PowerCycle', + 'FullPowerCycle'] # command should be PowerOn, PowerForceOff, etc. if not command.startswith('Power'): diff --git a/plugins/modules/homebrew.py b/plugins/modules/homebrew.py index c5e1c85313..168184fc68 100644 --- a/plugins/modules/homebrew.py +++ b/plugins/modules/homebrew.py @@ -385,9 +385,11 @@ class Homebrew(object): self.outdated_packages.add(package_name) def _extract_package_name(self, package_detail, is_cask): - canonical_name = package_detail["full_token"] if is_cask else package_detail["full_name"] # For ex: 'sqlite' + canonical_name = package_detail["full_token"] if is_cask else package_detail["full_name"] # For ex: 'sqlite', might contain a tap prefix. + name = package_detail["token"] if is_cask else package_detail["name"] # For ex: 'sqlite' + all_valid_names = set(package_detail.get("aliases", [])) # For ex: {'sqlite3'} - all_valid_names.add(canonical_name) + all_valid_names.update((canonical_name, name)) # Then make sure the user provided name resurface. return (all_valid_names & set(self.packages)).pop() @@ -831,7 +833,7 @@ def main(): p = module.params if p['name']: - packages = p['name'] + packages = [package_name.lower() for package_name in p['name']] else: packages = None diff --git a/plugins/modules/ipa_host.py b/plugins/modules/ipa_host.py index b2f76ac8f3..a78ea6223e 100644 --- a/plugins/modules/ipa_host.py +++ b/plugins/modules/ipa_host.py @@ -270,6 +270,10 @@ def ensure(module, client): data = {} for key in diff: data[key] = module_host.get(key) + if "usercertificate" not in data: + data["usercertificate"] = [ + cert['__base64__'] for cert in ipa_host.get("usercertificate", []) + ] ipa_host_show = client.host_show(name=name) if ipa_host_show.get('has_keytab', True) and (state == 'disabled' or module.params.get('random_password')): client.host_disable(name=name) diff --git a/plugins/modules/keycloak_client.py b/plugins/modules/keycloak_client.py index bb51a6a9b3..f02a0bfb9e 100644 --- a/plugins/modules/keycloak_client.py +++ b/plugins/modules/keycloak_client.py @@ -758,9 +758,19 @@ def normalise_cr(clientrep, remove_ids=False): if remove_ids: mapper.pop('id', None) + # Convert bool to string + if 'config' in mapper: + for key, value in mapper['config'].items(): + if isinstance(value, bool): + mapper['config'][key] = str(value).lower() + # Set to a default value. mapper['consentRequired'] = mapper.get('consentRequired', False) + if 'attributes' in clientrep: + for key, value in clientrep['attributes'].items(): + if isinstance(value, bool): + clientrep['attributes'][key] = str(value).lower() return clientrep diff --git a/plugins/modules/lvg.py b/plugins/modules/lvg.py index b4e758aca5..b16cdd87a2 100644 --- a/plugins/modules/lvg.py +++ b/plugins/modules/lvg.py @@ -34,6 +34,7 @@ options: - List of comma-separated devices to use as physical devices in this volume group. - Required when creating or resizing volume group. - The module will take care of running pvcreate if needed. + - O(remove_extra_pvs) controls whether or not unspecified physical devices are removed from the volume group. type: list elements: str pesize: @@ -88,6 +89,12 @@ options: type: bool default: false version_added: 7.1.0 + remove_extra_pvs: + description: + - Remove physical volumes from the volume group which are not in O(pvs). + type: bool + default: true + version_added: 10.4.0 seealso: - module: community.general.filesystem - module: community.general.lvol @@ -383,6 +390,7 @@ def main(): force=dict(type='bool', default=False), reset_vg_uuid=dict(type='bool', default=False), reset_pv_uuid=dict(type='bool', default=False), + remove_extra_pvs=dict(type="bool", default=True), ), required_if=[ ['reset_pv_uuid', True, ['pvs']], @@ -399,6 +407,7 @@ def main(): vgoptions = module.params['vg_options'].split() reset_vg_uuid = module.boolean(module.params['reset_vg_uuid']) reset_pv_uuid = module.boolean(module.params['reset_pv_uuid']) + remove_extra_pvs = module.boolean(module.params["remove_extra_pvs"]) this_vg = find_vg(module=module, vg=vg) present_state = state in ['present', 'active', 'inactive'] @@ -494,6 +503,9 @@ def main(): devs_to_remove = list(set(current_devs) - set(dev_list)) devs_to_add = list(set(dev_list) - set(current_devs)) + if not remove_extra_pvs: + devs_to_remove = [] + if current_devs: if present_state: for device in current_devs: diff --git a/plugins/modules/lvol.py b/plugins/modules/lvol.py index c66098c354..6166e437f2 100644 --- a/plugins/modules/lvol.py +++ b/plugins/modules/lvol.py @@ -60,7 +60,7 @@ options: default: true force: description: - - Shrink or remove operations of volumes requires this switch. Ensures that that filesystems get never corrupted/destroyed + - Shrink or remove operations of volumes requires this switch. Ensures that filesystems never get corrupted/destroyed by mistake. type: bool default: false diff --git a/plugins/modules/nmcli.py b/plugins/modules/nmcli.py index 3aff17ea6e..623546dae4 100644 --- a/plugins/modules/nmcli.py +++ b/plugins/modules/nmcli.py @@ -79,13 +79,14 @@ options: - Type V(ovs-port) is added in community.general 8.6.0. - Type V(wireguard) is added in community.general 4.3.0. - Type V(vpn) is added in community.general 5.1.0. + - Type V(vrf) is added in community.general 10.4.0. - Using V(bond-slave), V(bridge-slave), or V(team-slave) implies V(ethernet) connection type with corresponding O(slave_type) option. - If you want to control non-ethernet connection attached to V(bond), V(bridge), or V(team) consider using O(slave_type) option. type: str choices: [bond, bond-slave, bridge, bridge-slave, dummy, ethernet, generic, gre, infiniband, ipip, macvlan, sit, team, - team-slave, vlan, vxlan, wifi, gsm, wireguard, ovs-bridge, ovs-port, ovs-interface, vpn, loopback] + team-slave, vlan, vxlan, wifi, gsm, wireguard, ovs-bridge, ovs-port, ovs-interface, vpn, vrf, loopback] mode: description: - This is the type of device or network connection that you wish to create for a bond or bridge. @@ -103,7 +104,7 @@ options: - Type of the device of this slave's master connection (for example V(bond)). - Type V(ovs-port) is added in community.general 8.6.0. type: str - choices: ['bond', 'bridge', 'team', 'ovs-port'] + choices: ['bond', 'bridge', 'team', 'ovs-port', 'vrf'] version_added: 7.0.0 master: description: @@ -521,6 +522,11 @@ options: - Only used when O(type=gre). type: str version_added: 3.6.0 + table: + description: + - This is only used with VRF - VRF table number. + type: int + version_added: 10.4.0 zone: description: - The trust level of the connection. @@ -1569,6 +1575,29 @@ EXAMPLES = r""" vlanid: 5 state: present +## Creating VRF and adding VLAN interface to it +- name: Create VRF + community.general.nmcli: + type: vrf + ifname: vrf10 + table: 10 + state: present + conn_name: vrf10 + method4: disabled + method6: disabled + +- name: Create VLAN interface inside VRF + community.general.nmcli: + conn_name: "eth0.124" + type: vlan + vlanid: "124" + vlandev: "eth0" + master: "vrf10" + slave_type: vrf + state: "present" + ip4: '192.168.124.50' + gw4: '192.168.124.1' + ## Defining ip rules while setting a static IP ## table 'production' is set with id 200 in this example. - name: Set Static ips for interface with ip rules and routes @@ -1755,6 +1784,9 @@ class Nmcli(object): else: self.ipv6_method = None + if self.type == "vrf": + self.table = module.params['table'] + self.edit_commands = [] self.extra_options_validation() @@ -1787,7 +1819,8 @@ class Nmcli(object): # IP address options. # The ovs-interface type can be both ip_conn_type and have a master - if (self.ip_conn_type and not self.master) or self.type == "ovs-interface": + # An interface that has a master but is of slave type vrf can have an IP address + if (self.ip_conn_type and (not self.master or self.slave_type == "vrf")) or self.type == "ovs-interface": options.update({ 'ipv4.addresses': self.enforce_ipv4_cidr_notation(self.ip4), 'ipv4.dhcp-client-id': self.dhcp_client_id, @@ -2001,6 +2034,10 @@ class Nmcli(object): options.update({ 'infiniband.transport-mode': self.transport_mode, }) + elif self.type == 'vrf': + options.update({ + 'table': self.table, + }) if self.type == 'ethernet': if self.sriov: @@ -2057,6 +2094,7 @@ class Nmcli(object): 'vpn', 'loopback', 'ovs-interface', + 'vrf' ) @property @@ -2528,7 +2566,7 @@ def main(): conn_name=dict(type='str', required=True), conn_reload=dict(type='bool', default=False), master=dict(type='str'), - slave_type=dict(type='str', choices=['bond', 'bridge', 'team', 'ovs-port']), + slave_type=dict(type='str', choices=['bond', 'bridge', 'team', 'ovs-port', 'vrf']), ifname=dict(type='str'), type=dict(type='str', choices=[ @@ -2556,6 +2594,7 @@ def main(): 'ovs-interface', 'ovs-bridge', 'ovs-port', + 'vrf', ]), ip4=dict(type='list', elements='str'), gw4=dict(type='str'), @@ -2669,6 +2708,7 @@ def main(): vpn=dict(type='dict'), transport_mode=dict(type='str', choices=['datagram', 'connected']), sriov=dict(type='dict'), + table=dict(type='int'), ), mutually_exclusive=[['never_default4', 'gw4'], ['routes4_extended', 'routes4'], diff --git a/plugins/modules/profitbricks.py b/plugins/modules/profitbricks.py index 070c7b9f67..403757fe7e 100644 --- a/plugins/modules/profitbricks.py +++ b/plugins/modules/profitbricks.py @@ -14,6 +14,13 @@ short_description: Create, destroy, start, stop, and reboot a ProfitBricks virtu description: - Create, destroy, update, start, stop, and reboot a ProfitBricks virtual machine. When the virtual machine is created it can optionally wait for it to be 'running' before returning. This module has a dependency on profitbricks >= 1.0.0. +deprecated: + removed_in: 11.0.0 + why: Module relies on library unsupported since 2021. + alternative: > + Profitbricks has rebranded as Ionos Cloud and they provide a collection named ionoscloudsdk.ionoscloud. + Whilst it is likely it will provide the features of this module, that has not been verified. + Please refer to that collectionś documentation for more details. extends_documentation_fragment: - community.general.attributes attributes: diff --git a/plugins/modules/profitbricks_datacenter.py b/plugins/modules/profitbricks_datacenter.py index 1bd97be547..32b2996a26 100644 --- a/plugins/modules/profitbricks_datacenter.py +++ b/plugins/modules/profitbricks_datacenter.py @@ -14,6 +14,14 @@ short_description: Create or destroy a ProfitBricks Virtual Datacenter description: - This is a simple module that supports creating or removing vDCs. A vDC is required before you can create servers. This module has a dependency on profitbricks >= 1.0.0. +deprecated: + removed_in: 11.0.0 + why: Module relies on library unsupported since 2021. + alternative: > + Profitbricks has rebranded as Ionos Cloud and they provide a collection named ionoscloudsdk.ionoscloud. + Whilst it is likely it will provide the features of this module, that has not been verified. + Please refer to that collectionś documentation for more details. + extends_documentation_fragment: - community.general.attributes attributes: diff --git a/plugins/modules/profitbricks_nic.py b/plugins/modules/profitbricks_nic.py index 0b559a6fed..690a03995d 100644 --- a/plugins/modules/profitbricks_nic.py +++ b/plugins/modules/profitbricks_nic.py @@ -13,6 +13,13 @@ module: profitbricks_nic short_description: Create or Remove a NIC description: - This module allows you to create or restore a volume snapshot. This module has a dependency on profitbricks >= 1.0.0. +deprecated: + removed_in: 11.0.0 + why: Module relies on library unsupported since 2021. + alternative: > + Profitbricks has rebranded as Ionos Cloud and they provide a collection named ionoscloudsdk.ionoscloud. + Whilst it is likely it will provide the features of this module, that has not been verified. + Please refer to that collectionś documentation for more details. extends_documentation_fragment: - community.general.attributes attributes: diff --git a/plugins/modules/profitbricks_volume.py b/plugins/modules/profitbricks_volume.py index f887fa086b..adcd5cdb06 100644 --- a/plugins/modules/profitbricks_volume.py +++ b/plugins/modules/profitbricks_volume.py @@ -14,6 +14,13 @@ short_description: Create or destroy a volume description: - Allows you to create or remove a volume from a ProfitBricks datacenter. This module has a dependency on profitbricks >= 1.0.0. +deprecated: + removed_in: 11.0.0 + why: Module relies on library unsupported since 2021. + alternative: > + Profitbricks has rebranded as Ionos Cloud and they provide a collection named ionoscloudsdk.ionoscloud. + Whilst it is likely it will provide the features of this module, that has not been verified. + Please refer to that collectionś documentation for more details. extends_documentation_fragment: - community.general.attributes attributes: diff --git a/plugins/modules/profitbricks_volume_attachments.py b/plugins/modules/profitbricks_volume_attachments.py index 63ca6775ab..896d7205d7 100644 --- a/plugins/modules/profitbricks_volume_attachments.py +++ b/plugins/modules/profitbricks_volume_attachments.py @@ -13,6 +13,13 @@ module: profitbricks_volume_attachments short_description: Attach or detach a volume description: - Allows you to attach or detach a volume from a ProfitBricks server. This module has a dependency on profitbricks >= 1.0.0. +deprecated: + removed_in: 11.0.0 + why: Module relies on library unsupported since 2021. + alternative: > + Profitbricks has rebranded as Ionos Cloud and they provide a collection named ionoscloudsdk.ionoscloud. + Whilst it is likely it will provide the features of this module, that has not been verified. + Please refer to that collectionś documentation for more details. extends_documentation_fragment: - community.general.attributes attributes: diff --git a/plugins/modules/redfish_command.py b/plugins/modules/redfish_command.py index 6fac992854..545506f924 100644 --- a/plugins/modules/redfish_command.py +++ b/plugins/modules/redfish_command.py @@ -853,8 +853,10 @@ from ansible.module_utils.common.text.converters import to_native # More will be added as module features are expanded CATEGORY_COMMANDS_ALL = { "Systems": ["PowerOn", "PowerForceOff", "PowerForceRestart", "PowerGracefulRestart", - "PowerGracefulShutdown", "PowerReboot", "PowerCycle", "SetOneTimeBoot", "EnableContinuousBootOverride", "DisableBootOverride", - "IndicatorLedOn", "IndicatorLedOff", "IndicatorLedBlink", "VirtualMediaInsert", "VirtualMediaEject", "VerifyBiosAttributes"], + "PowerGracefulShutdown", "PowerReboot", "PowerCycle", "PowerFullPowerCycle", + "SetOneTimeBoot", "EnableContinuousBootOverride", "DisableBootOverride", + "IndicatorLedOn", "IndicatorLedOff", "IndicatorLedBlink", "VirtualMediaInsert", + "VirtualMediaEject", "VerifyBiosAttributes"], "Chassis": ["IndicatorLedOn", "IndicatorLedOff", "IndicatorLedBlink"], "Accounts": ["AddUser", "EnableUser", "DeleteUser", "DisableUser", "UpdateUserRole", "UpdateUserPassword", "UpdateUserName", diff --git a/plugins/modules/xml.py b/plugins/modules/xml.py index eb579e0711..483383b5d3 100644 --- a/plugins/modules/xml.py +++ b/plugins/modules/xml.py @@ -920,29 +920,34 @@ def main(): elif LooseVersion('.'.join(to_native(f) for f in etree.LXML_VERSION)) < LooseVersion('3.0.0'): module.warn('Using lxml version lower than 3.0.0 does not guarantee predictable element attribute order.') - # Check if the file exists - if xml_string: - infile = BytesIO(to_bytes(xml_string, errors='surrogate_or_strict')) - elif os.path.isfile(xml_file): - infile = open(xml_file, 'rb') - else: - module.fail_json(msg="The target XML source '%s' does not exist." % xml_file) - - # Parse and evaluate xpath expression - if xpath is not None: - try: - etree.XPath(xpath) - except etree.XPathSyntaxError as e: - module.fail_json(msg="Syntax error in xpath expression: %s (%s)" % (xpath, e)) - except etree.XPathEvalError as e: - module.fail_json(msg="Evaluation error in xpath expression: %s (%s)" % (xpath, e)) - - # Try to parse in the target XML file + infile = None try: - parser = etree.XMLParser(remove_blank_text=pretty_print, strip_cdata=strip_cdata_tags) - doc = etree.parse(infile, parser) - except etree.XMLSyntaxError as e: - module.fail_json(msg="Error while parsing document: %s (%s)" % (xml_file or 'xml_string', e)) + # Check if the file exists + if xml_string: + infile = BytesIO(to_bytes(xml_string, errors='surrogate_or_strict')) + elif os.path.isfile(xml_file): + infile = open(xml_file, 'rb') + else: + module.fail_json(msg="The target XML source '%s' does not exist." % xml_file) + + # Parse and evaluate xpath expression + if xpath is not None: + try: + etree.XPath(xpath) + except etree.XPathSyntaxError as e: + module.fail_json(msg="Syntax error in xpath expression: %s (%s)" % (xpath, e)) + except etree.XPathEvalError as e: + module.fail_json(msg="Evaluation error in xpath expression: %s (%s)" % (xpath, e)) + + # Try to parse in the target XML file + try: + parser = etree.XMLParser(remove_blank_text=pretty_print, strip_cdata=strip_cdata_tags) + doc = etree.parse(infile, parser) + except etree.XMLSyntaxError as e: + module.fail_json(msg="Error while parsing document: %s (%s)" % (xml_file or 'xml_string', e)) + finally: + if infile: + infile.close() # Ensure we have the original copy to compare global orig_doc diff --git a/plugins/modules/zfs.py b/plugins/modules/zfs.py index 55bba5b968..29910310b3 100644 --- a/plugins/modules/zfs.py +++ b/plugins/modules/zfs.py @@ -98,10 +98,10 @@ from ansible.module_utils.basic import AnsibleModule class Zfs(object): - def __init__(self, module, name, properties): + def __init__(self, module, name, extra_zfs_properties): self.module = module self.name = name - self.properties = properties + self.extra_zfs_properties = extra_zfs_properties self.changed = False self.zfs_cmd = module.get_bin_path('zfs', True) self.zpool_cmd = module.get_bin_path('zpool', True) @@ -142,7 +142,7 @@ class Zfs(object): if self.module.check_mode: self.changed = True return - properties = self.properties + extra_zfs_properties = self.extra_zfs_properties origin = self.module.params.get('origin') cmd = [self.zfs_cmd] @@ -158,8 +158,8 @@ class Zfs(object): if action in ['create', 'clone']: cmd += ['-p'] - if properties: - for prop, value in properties.items(): + if extra_zfs_properties: + for prop, value in extra_zfs_properties.items(): if prop == 'volsize': cmd += ['-V', value] elif prop == 'volblocksize': @@ -189,45 +189,62 @@ class Zfs(object): def set_properties_if_changed(self): diff = {'before': {'extra_zfs_properties': {}}, 'after': {'extra_zfs_properties': {}}} - current_properties = self.get_current_properties() - for prop, value in self.properties.items(): - current_value = current_properties.get(prop, None) + current_properties = self.list_properties() + for prop, value in self.extra_zfs_properties.items(): + current_value = self.get_property(prop, current_properties) if current_value != value: self.set_property(prop, value) diff['before']['extra_zfs_properties'][prop] = current_value diff['after']['extra_zfs_properties'][prop] = value if self.module.check_mode: return diff - updated_properties = self.get_current_properties() - for prop in self.properties: - value = updated_properties.get(prop, None) + updated_properties = self.list_properties() + for prop in self.extra_zfs_properties: + value = self.get_property(prop, updated_properties) if value is None: self.module.fail_json(msg="zfsprop was not present after being successfully set: %s" % prop) - if current_properties.get(prop, None) != value: + if self.get_property(prop, current_properties) != value: self.changed = True if prop in diff['after']['extra_zfs_properties']: diff['after']['extra_zfs_properties'][prop] = value return diff - def get_current_properties(self): - cmd = [self.zfs_cmd, 'get', '-H', '-p', '-o', "property,value,source"] + def list_properties(self): + cmd = [self.zfs_cmd, 'get', '-H', '-p', '-o', "property,source"] if self.enhanced_sharing: cmd += ['-e'] cmd += ['all', self.name] rc, out, err = self.module.run_command(cmd) - properties = dict() + properties = [] for line in out.splitlines(): - prop, value, source = line.split('\t') + prop, source = line.split('\t') # include source '-' so that creation-only properties are not removed # to avoids errors when the dataset already exists and the property is not changed # this scenario is most likely when the same playbook is run more than once if source in ('local', 'received', '-'): - properties[prop] = value + properties.append(prop) + return properties + + def get_property(self, name, list_of_properties): # Add alias for enhanced sharing properties if self.enhanced_sharing: - properties['sharenfs'] = properties.get('share.nfs', None) - properties['sharesmb'] = properties.get('share.smb', None) - return properties + if name == 'sharenfs': + name = 'share.nfs' + elif name == 'sharesmb': + name = 'share.smb' + if name not in list_of_properties: + return None + cmd = [self.zfs_cmd, 'get', '-H', '-p', '-o', "value"] + if self.enhanced_sharing: + cmd += ['-e'] + cmd += [name, self.name] + rc, out, err = self.module.run_command(cmd) + if rc != 0: + return None + # + # Strip last newline + # + return out[:-1] def main(): @@ -282,7 +299,7 @@ def main(): result['diff']['before_header'] = name result['diff']['after_header'] = name - result.update(zfs.properties) + result.update(zfs.extra_zfs_properties) result['changed'] = zfs.changed module.exit_json(**result) diff --git a/plugins/modules/zfs_facts.py b/plugins/modules/zfs_facts.py index 10f826b728..64c1c8f5ca 100644 --- a/plugins/modules/zfs_facts.py +++ b/plugins/modules/zfs_facts.py @@ -44,10 +44,12 @@ options: type: str type: description: - - Specifies which datasets types to display. Multiple values have to be provided in comma-separated form. + - Specifies which datasets types to display. Multiple values have to be provided as a list or in comma-separated form. + - Value V(all) cannot be used together with other values. choices: ['all', 'filesystem', 'volume', 'snapshot', 'bookmark'] - default: all - type: str + default: [all] + type: list + elements: str depth: description: - Specifies recursion depth. @@ -106,7 +108,6 @@ zfs_datasets: from collections import defaultdict from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.six import iteritems SUPPORTED_TYPES = ['all', 'filesystem', 'volume', 'snapshot', 'bookmark'] @@ -132,10 +133,7 @@ class ZFSFacts(object): (rc, out, err) = self.module.run_command(cmd) - if rc == 0: - return True - else: - return False + return rc == 0 def get_facts(self): cmd = [self.module.get_bin_path('zfs'), 'get', '-H'] @@ -148,41 +146,44 @@ class ZFSFacts(object): cmd.append('%s' % self.depth) if self.type: cmd.append('-t') - cmd.append(self.type) + cmd.append(','.join(self.type)) cmd.extend(['-o', 'name,property,value', self.properties, self.name]) (rc, out, err) = self.module.run_command(cmd) - if rc == 0: - for line in out.splitlines(): - dataset, property, value = line.split('\t') - - self._datasets[dataset].update({property: value}) - - for k, v in iteritems(self._datasets): - v.update({'name': k}) - self.facts.append(v) - - return {'ansible_zfs_datasets': self.facts} - else: + if rc != 0: self.module.fail_json(msg='Error while trying to get facts about ZFS dataset: %s' % self.name, stderr=err, rc=rc) + for line in out.splitlines(): + dataset, property, value = line.split('\t') + + self._datasets[dataset].update({property: value}) + + for k, v in self._datasets.items(): + v.update({'name': k}) + self.facts.append(v) + + return {'ansible_zfs_datasets': self.facts} + def main(): module = AnsibleModule( argument_spec=dict( name=dict(required=True, aliases=['ds', 'dataset'], type='str'), - recurse=dict(required=False, default=False, type='bool'), - parsable=dict(required=False, default=False, type='bool'), - properties=dict(required=False, default='all', type='str'), - type=dict(required=False, default='all', type='str', choices=SUPPORTED_TYPES), - depth=dict(required=False, default=0, type='int') + recurse=dict(default=False, type='bool'), + parsable=dict(default=False, type='bool'), + properties=dict(default='all', type='str'), + type=dict(default='all', type='list', elements='str', choices=SUPPORTED_TYPES), + depth=dict(default=0, type='int') ), supports_check_mode=True ) + if 'all' in module.params['type'] and len(module.params['type']) > 1: + module.fail_json(msg="Value 'all' for parameter 'type' is mutually exclusive with other values") + zfs_facts = ZFSFacts(module) result = {} @@ -195,11 +196,11 @@ def main(): if zfs_facts.recurse: result['recurse'] = zfs_facts.recurse - if zfs_facts.dataset_exists(): - result['ansible_facts'] = zfs_facts.get_facts() - else: + if not zfs_facts.dataset_exists(): module.fail_json(msg='ZFS dataset %s does not exist!' % zfs_facts.name) + result['ansible_facts'] = zfs_facts.get_facts() + module.exit_json(**result) diff --git a/tests/integration/targets/copr/aliases b/tests/integration/targets/copr/aliases index ed3c1af00d..2520b5578f 100644 --- a/tests/integration/targets/copr/aliases +++ b/tests/integration/targets/copr/aliases @@ -7,3 +7,4 @@ needs/root skip/macos skip/osx skip/freebsd +disabled # TODO diff --git a/tests/integration/targets/filesystem/tasks/main.yml b/tests/integration/targets/filesystem/tasks/main.yml index 51361079ce..55a513bf77 100644 --- a/tests/integration/targets/filesystem/tasks/main.yml +++ b/tests/integration/targets/filesystem/tasks/main.yml @@ -59,6 +59,8 @@ item.0.key == "reiserfs")' # reiserfs packages apparently not available with Alpine - 'not (ansible_distribution == "Alpine" and item.0.key == "reiserfs")' + # reiserfsprogs packages no longer available with Arch Linux + - 'not (ansible_distribution == "Archlinux" and item.0.key == "reiserfs")' # ocfs2 only available on Debian based distributions - 'not (item.0.key == "ocfs2" and ansible_os_family != "Debian")' # Tests use losetup which can not be used inside unprivileged container diff --git a/tests/integration/targets/filesystem/tasks/setup.yml b/tests/integration/targets/filesystem/tasks/setup.yml index 77c028acaf..aeda1e4a7f 100644 --- a/tests/integration/targets/filesystem/tasks/setup.yml +++ b/tests/integration/targets/filesystem/tasks/setup.yml @@ -75,7 +75,7 @@ state: present when: - ansible_system == 'Linux' - - ansible_os_family not in ['Suse', 'RedHat', 'Alpine'] + - ansible_os_family not in ['Suse', 'RedHat', 'Alpine', 'Archlinux'] - name: "Install reiserfs progs (FreeBSD)" ansible.builtin.package: diff --git a/tests/integration/targets/homebrew/tasks/formulae.yml b/tests/integration/targets/homebrew/tasks/formulae.yml index 56812c843c..af4acf4a45 100644 --- a/tests/integration/targets/homebrew/tasks/formulae.yml +++ b/tests/integration/targets/homebrew/tasks/formulae.yml @@ -40,7 +40,6 @@ homebrew: name: "{{ package_name }}" state: absent - update_homebrew: false become: true become_user: "{{ brew_stat.stat.pw_name }}" @@ -48,7 +47,6 @@ homebrew: name: "{{ package_name }}" state: present - update_homebrew: false become: true become_user: "{{ brew_stat.stat.pw_name }}" register: package_result @@ -64,7 +62,6 @@ homebrew: name: "{{ package_name }}" state: present - update_homebrew: false become: true become_user: "{{ brew_stat.stat.pw_name }}" register: package_result @@ -80,7 +77,6 @@ homebrew: name: "{{ package_name }}" state: unlinked - update_homebrew: false become: true become_user: "{{ brew_stat.stat.pw_name }}" register: package_result @@ -96,7 +92,6 @@ homebrew: name: "{{ package_name }}" state: linked - update_homebrew: false become: true become_user: "{{ brew_stat.stat.pw_name }}" register: package_result @@ -112,7 +107,6 @@ homebrew: name: "{{ package_name }}" state: absent - update_homebrew: false become: true become_user: "{{ brew_stat.stat.pw_name }}" register: package_result @@ -128,7 +122,6 @@ homebrew: name: "{{ package_name }}" state: absent - update_homebrew: false become: true become_user: "{{ brew_stat.stat.pw_name }}" register: package_result @@ -144,7 +137,6 @@ homebrew: name: "{{ package_name }}" state: latest - update_homebrew: false become: true become_user: "{{ brew_stat.stat.pw_name }}" register: package_result @@ -160,7 +152,6 @@ homebrew: name: "{{ package_name }}" state: latest - update_homebrew: false become: true become_user: "{{ brew_stat.stat.pw_name }}" register: package_result @@ -182,7 +173,6 @@ homebrew: name: "{{ package_names }}" state: absent - update_homebrew: false become: true become_user: "{{ brew_stat.stat.pw_name }}" @@ -190,7 +180,6 @@ homebrew: name: "{{ package_names[0] }}" state: present - update_homebrew: false become: true become_user: "{{ brew_stat.stat.pw_name }}" @@ -198,7 +187,6 @@ homebrew: name: "{{ package_names }}" state: present - update_homebrew: false become: true become_user: "{{ brew_stat.stat.pw_name }}" register: package_result @@ -214,7 +202,6 @@ homebrew: name: "{{ package_names }}" state: present - update_homebrew: false become: true become_user: "{{ brew_stat.stat.pw_name }}" register: package_result @@ -230,7 +217,6 @@ homebrew: name: "{{ package_names }}" state: unlinked - update_homebrew: false become: true become_user: "{{ brew_stat.stat.pw_name }}" register: package_result @@ -246,7 +232,6 @@ homebrew: name: "{{ package_names }}" state: linked - update_homebrew: false become: true become_user: "{{ brew_stat.stat.pw_name }}" register: package_result @@ -262,7 +247,6 @@ homebrew: name: "{{ package_names }}" state: absent - update_homebrew: false become: true become_user: "{{ brew_stat.stat.pw_name }}" register: package_result @@ -278,7 +262,6 @@ homebrew: name: "{{ package_names }}" state: absent - update_homebrew: false become: true become_user: "{{ brew_stat.stat.pw_name }}" register: package_result @@ -294,7 +277,6 @@ homebrew: name: "{{ package_names }}" state: latest - update_homebrew: false become: true become_user: "{{ brew_stat.stat.pw_name }}" register: package_result @@ -310,7 +292,6 @@ homebrew: name: "{{ package_names }}" state: latest - update_homebrew: false become: true become_user: "{{ brew_stat.stat.pw_name }}" register: package_result @@ -328,7 +309,6 @@ homebrew: name: "sqlite" state: absent - update_homebrew: false become: true become_user: "{{ brew_stat.stat.pw_name }}" @@ -336,7 +316,6 @@ homebrew: name: "sqlite3" state: present - update_homebrew: false become: true become_user: "{{ brew_stat.stat.pw_name }}" register: install_result @@ -352,7 +331,6 @@ homebrew: name: "sqlite3" state: present - update_homebrew: false become: true become_user: "{{ brew_stat.stat.pw_name }}" register: reinstall_result @@ -364,19 +342,18 @@ - "reinstall_result.changed_pkgs == []" - "reinstall_result.unchanged_pkgs == ['sqlite3']" -# Test with homebrew tap +# Test install from homebrew tap - block: - - name: Tap terraform homebrew repository + - name: Tap hashicorp repository community.general.homebrew_tap: name: hashicorp/tap become: true become_user: "{{ brew_stat.stat.pw_name }}" - - name: Install homebrew tap + - name: Install terraform from tap community.general.homebrew: name: hashicorp/tap/terraform state: latest - update_homebrew: false register: terraform_install_result become: true become_user: "{{ brew_stat.stat.pw_name }}" @@ -387,3 +364,118 @@ - "terraform_install_result.msg == 'Package upgraded: hashicorp/tap/terraform'" - "terraform_install_result.changed_pkgs == ['hashicorp/tap/terraform']" - "terraform_install_result.unchanged_pkgs == []" + + - name: Remove terraform + homebrew: + name: hashicorp/tap/terraform + state: absent + become: true + become_user: "{{ brew_stat.stat.pw_name }}" + +# Test irregular formulae name case +- block: + - name: Install terraform from full tap name with irregular case + community.general.homebrew: + name: HasHicorp/TAp/tErRaForm + state: latest + register: terraform_install_result + become: true + become_user: "{{ brew_stat.stat.pw_name }}" + + - assert: + that: + - terraform_install_result is changed + - "terraform_install_result.msg == 'Package upgraded: hashicorp/tap/terraform'" + - "terraform_install_result.changed_pkgs == ['hashicorp/tap/terraform']" + - "terraform_install_result.unchanged_pkgs == []" + +# Test tap with no public fallback +- block: + - name: Tap ascii-image-converter homebrew repository + community.general.homebrew_tap: + name: TheZoraiz/ascii-image-converter + become: true + become_user: "{{ brew_stat.stat.pw_name }}" + + - name: Install ascii from full tap name + community.general.homebrew: + name: TheZoraiz/ascii-image-converter/ascii-image-converter + state: latest + register: ascii_install_result + become: true + become_user: "{{ brew_stat.stat.pw_name }}" + + - assert: + that: + - ascii_install_result is changed + - "ascii_install_result.msg == 'Package upgraded: thezoraiz/ascii-image-converter/ascii-image-converter'" + - "ascii_install_result.changed_pkgs == ['thezoraiz/ascii-image-converter/ascii-image-converter']" + - "ascii_install_result.unchanged_pkgs == []" + + - name: Again install ascii from full tap name + community.general.homebrew: + name: TheZoraiz/ascii-image-converter/ascii-image-converter + state: latest + register: ascii_reinstall_result + become: true + become_user: "{{ brew_stat.stat.pw_name }}" + + - assert: + that: + - ascii_reinstall_result is not changed + - "ascii_reinstall_result.msg == 'Package already upgraded: thezoraiz/ascii-image-converter/ascii-image-converter'" + - "ascii_reinstall_result.changed_pkgs == []" + - "ascii_reinstall_result.unchanged_pkgs == ['thezoraiz/ascii-image-converter/ascii-image-converter']" + + - name: Remove ascii from full tap name + homebrew: + name: TheZoraiz/ascii-image-converter/ascii-image-converter + state: absent + register: ascii_uninstall_result + become: true + become_user: "{{ brew_stat.stat.pw_name }}" + + - assert: + that: + - ascii_uninstall_result is changed + - "ascii_uninstall_result.msg == 'Package uninstalled: thezoraiz/ascii-image-converter/ascii-image-converter'" + - "ascii_uninstall_result.changed_pkgs == ['thezoraiz/ascii-image-converter/ascii-image-converter']" + - "ascii_uninstall_result.unchanged_pkgs == []" + + - name: Again remove ascii from full tap name + homebrew: + name: TheZoraiz/ascii-image-converter/ascii-image-converter + state: absent + register: ascii_again_uninstall_result + + become: true + become_user: "{{ brew_stat.stat.pw_name }}" + + - assert: + that: + - ascii_again_uninstall_result is not changed + - "ascii_again_uninstall_result.msg == 'Package already uninstalled: thezoraiz/ascii-image-converter/ascii-image-converter'" + - "ascii_again_uninstall_result.changed_pkgs == []" + - "ascii_again_uninstall_result.unchanged_pkgs == ['thezoraiz/ascii-image-converter/ascii-image-converter']" + + - name: Install ascii from regular name + community.general.homebrew: + name: ascii-image-converter + state: latest + register: ascii_install_result + become: true + become_user: "{{ brew_stat.stat.pw_name }}" + + - assert: + that: + - ascii_install_result is changed + - "ascii_install_result.msg == 'Package upgraded: ascii-image-converter'" + - "ascii_install_result.changed_pkgs == ['ascii-image-converter']" + - "ascii_install_result.unchanged_pkgs == []" + + - name: Remove ascii from regular name + homebrew: + name: ascii-image-converter + state: absent + become: true + become_user: "{{ brew_stat.stat.pw_name }}" diff --git a/tests/integration/targets/keycloak_client/vars/main.yml b/tests/integration/targets/keycloak_client/vars/main.yml index 498f93e709..93f0d4d73e 100644 --- a/tests/integration/targets/keycloak_client/vars/main.yml +++ b/tests/integration/targets/keycloak_client/vars/main.yml @@ -34,9 +34,9 @@ protocol_mappers1: "claim.name": "email" "user.attribute": "email" "jsonType.label": "String" - "id.token.claim": "true" - "access.token.claim": "true" - "userinfo.token.claim": "true" + "id.token.claim": true + "access.token.claim": true + "userinfo.token.claim": true - name: 'email_verified' protocol: 'openid-connect' @@ -45,9 +45,9 @@ protocol_mappers1: "claim.name": "email_verified" "user.attribute": "emailVerified" "jsonType.label": "boolean" - "id.token.claim": "true" - "access.token.claim": "true" - "userinfo.token.claim": "true" + "id.token.claim": true + "access.token.claim": true + "userinfo.token.claim": true - name: 'family_name' protocol: 'openid-connect' diff --git a/tests/integration/targets/lvg/tasks/main.yml b/tests/integration/targets/lvg/tasks/main.yml index 15af2d08c4..6bc6944f5f 100644 --- a/tests/integration/targets/lvg/tasks/main.yml +++ b/tests/integration/targets/lvg/tasks/main.yml @@ -24,6 +24,8 @@ - import_tasks: test_grow_reduce.yml + - import_tasks: test_remove_extra_pvs.yml + - import_tasks: test_pvresize.yml - import_tasks: test_active_change.yml diff --git a/tests/integration/targets/lvg/tasks/test_remove_extra_pvs.yml b/tests/integration/targets/lvg/tasks/test_remove_extra_pvs.yml new file mode 100644 index 0000000000..830986d8da --- /dev/null +++ b/tests/integration/targets/lvg/tasks/test_remove_extra_pvs.yml @@ -0,0 +1,40 @@ +--- +# Copyright (c) Ansible Project +# 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 + +# test_grow_reduce already checks the base case with default parameters (remove additional PVs) + +- name: "Create volume group on first disk" + lvg: + vg: testvg + pvs: "{{ loop_device1 }}" + +- name: "get lvm facts" + setup: + +- debug: var=ansible_lvm + +- name: "Assert the testvg span only on first disk" + assert: + that: + - ansible_lvm.pvs[loop_device1].vg == "testvg" + - 'loop_device2 not in ansible_lvm.pvs or + ansible_lvm.pvs[loop_device2].vg == ""' + +- name: "Extend to second disk AND keep first disk" + lvg: + vg: testvg + pvs: "{{ loop_device2 }}" + remove_extra_pvs: false + +- name: "get lvm facts" + setup: + +- debug: var=ansible_lvm + +- name: "Assert the testvg spans on both disks" + assert: + that: + - ansible_lvm.pvs[loop_device1].vg == "testvg" + - ansible_lvm.pvs[loop_device2].vg == "testvg" diff --git a/tests/integration/targets/snap/aliases b/tests/integration/targets/snap/aliases index b209bbc015..34c378b729 100644 --- a/tests/integration/targets/snap/aliases +++ b/tests/integration/targets/snap/aliases @@ -11,3 +11,4 @@ skip/freebsd skip/osx skip/macos skip/docker +skip/rhel8.8 # TODO: fix diff --git a/tests/integration/targets/snap_alias/aliases b/tests/integration/targets/snap_alias/aliases index b209bbc015..34c378b729 100644 --- a/tests/integration/targets/snap_alias/aliases +++ b/tests/integration/targets/snap_alias/aliases @@ -11,3 +11,4 @@ skip/freebsd skip/osx skip/macos skip/docker +skip/rhel8.8 # TODO: fix diff --git a/tests/sanity/ignore-2.17.txt b/tests/sanity/ignore-2.17.txt index 39048d2718..97751e5a92 100644 --- a/tests/sanity/ignore-2.17.txt +++ b/tests/sanity/ignore-2.17.txt @@ -10,5 +10,5 @@ plugins/modules/udm_user.py import-3.11 # Uses deprecated stdlib library 'crypt plugins/modules/udm_user.py import-3.12 # Uses deprecated stdlib library 'crypt' plugins/modules/xfconf.py validate-modules:return-syntax-error plugins/module_utils/univention_umc.py pylint:use-yield-from # suggested construct does not work with Python 2 -tests/unit/plugins/modules/helper.py pylint:use-yield-from # suggested construct does not work with Python 2 +tests/unit/plugins/modules/uthelper.py pylint:use-yield-from # suggested construct does not work with Python 2 tests/unit/plugins/modules/test_gio_mime.yaml no-smart-quotes diff --git a/tests/sanity/ignore-2.18.txt b/tests/sanity/ignore-2.18.txt index 39048d2718..97751e5a92 100644 --- a/tests/sanity/ignore-2.18.txt +++ b/tests/sanity/ignore-2.18.txt @@ -10,5 +10,5 @@ plugins/modules/udm_user.py import-3.11 # Uses deprecated stdlib library 'crypt plugins/modules/udm_user.py import-3.12 # Uses deprecated stdlib library 'crypt' plugins/modules/xfconf.py validate-modules:return-syntax-error plugins/module_utils/univention_umc.py pylint:use-yield-from # suggested construct does not work with Python 2 -tests/unit/plugins/modules/helper.py pylint:use-yield-from # suggested construct does not work with Python 2 +tests/unit/plugins/modules/uthelper.py pylint:use-yield-from # suggested construct does not work with Python 2 tests/unit/plugins/modules/test_gio_mime.yaml no-smart-quotes diff --git a/tests/sanity/ignore-2.19.txt b/tests/sanity/ignore-2.19.txt index 39048d2718..97751e5a92 100644 --- a/tests/sanity/ignore-2.19.txt +++ b/tests/sanity/ignore-2.19.txt @@ -10,5 +10,5 @@ plugins/modules/udm_user.py import-3.11 # Uses deprecated stdlib library 'crypt plugins/modules/udm_user.py import-3.12 # Uses deprecated stdlib library 'crypt' plugins/modules/xfconf.py validate-modules:return-syntax-error plugins/module_utils/univention_umc.py pylint:use-yield-from # suggested construct does not work with Python 2 -tests/unit/plugins/modules/helper.py pylint:use-yield-from # suggested construct does not work with Python 2 +tests/unit/plugins/modules/uthelper.py pylint:use-yield-from # suggested construct does not work with Python 2 tests/unit/plugins/modules/test_gio_mime.yaml no-smart-quotes diff --git a/tests/unit/plugins/modules/test_cpanm.py b/tests/unit/plugins/modules/test_cpanm.py index ec8e9d0f7a..a5df9158da 100644 --- a/tests/unit/plugins/modules/test_cpanm.py +++ b/tests/unit/plugins/modules/test_cpanm.py @@ -14,7 +14,7 @@ __metaclass__ = type from ansible_collections.community.general.plugins.modules import cpanm -from .helper import Helper, RunCommandMock +from .uthelper import UTHelper, RunCommandMock -Helper.from_module(cpanm, __name__, mocks=[RunCommandMock]) +UTHelper.from_module(cpanm, __name__, mocks=[RunCommandMock]) diff --git a/tests/unit/plugins/modules/test_cpanm.yaml b/tests/unit/plugins/modules/test_cpanm.yaml index 5886a90f35..467429b10d 100644 --- a/tests/unit/plugins/modules/test_cpanm.yaml +++ b/tests/unit/plugins/modules/test_cpanm.yaml @@ -8,396 +8,396 @@ anchors: environ_true: &env-def-true {environ_update: {LANGUAGE: C, LC_ALL: C}, check_rc: true} environ_false: &env-def-false {environ_update: {LANGUAGE: C, LC_ALL: C}, check_rc: false} test_cases: -- id: install_dancer_compatibility - input: - name: Dancer - mode: compatibility - output: - changed: true - cpanm_version: "1.7047" - mocks: - run_command: - - command: [/testbin/cpanm, --version] - environ: *env-def-true - rc: 0 - out: | - cpanm (App::cpanminus) version 1.7047 (/usr/local/bin/cpanm) - perl version 5.041005 (/usr/local/bin/perl) - err: "" - - command: [/testbin/perl, -le, 'use Dancer;'] - environ: *env-def-false - rc: 2 - out: "" - err: "error, not installed" - - command: [/testbin/cpanm, Dancer] - environ: *env-def-true - rc: 0 - out: "" - err: "" -- id: install_dancer_already_installed_compatibility - input: - name: Dancer - mode: compatibility - output: - changed: false - mocks: - run_command: - - command: [/testbin/cpanm, --version] - environ: *env-def-true - rc: 0 - out: | - cpanm (App::cpanminus) version 1.7047 (/usr/local/bin/cpanm) - perl version 5.041005 (/usr/local/bin/perl) - err: "" - - command: [/testbin/perl, -le, 'use Dancer;'] - environ: *env-def-false - rc: 0 - out: "" - err: "" -- id: install_dancer - input: - name: Dancer - output: - changed: true - mocks: - run_command: - - command: [/testbin/cpanm, --version] - environ: *env-def-true - rc: 0 - out: | - cpanm (App::cpanminus) version 1.7047 (/usr/local/bin/cpanm) - perl version 5.041005 (/usr/local/bin/perl) - err: "" - - command: [/testbin/cpanm, Dancer] - environ: *env-def-true - rc: 0 - out: "" - err: "" -- id: install_distribution_file_compatibility - input: - name: MIYAGAWA/Plack-0.99_05.tar.gz - mode: compatibility - output: - changed: true - mocks: - run_command: - - command: [/testbin/cpanm, --version] - environ: *env-def-true - rc: 0 - out: | - cpanm (App::cpanminus) version 1.7047 (/usr/local/bin/cpanm) - perl version 5.041005 (/usr/local/bin/perl) - err: "" - - command: [/testbin/cpanm, MIYAGAWA/Plack-0.99_05.tar.gz] - environ: *env-def-true - rc: 0 - out: "" - err: "" -- id: install_distribution_file - input: - name: MIYAGAWA/Plack-0.99_05.tar.gz - output: - changed: true - mocks: - run_command: - - command: [/testbin/cpanm, --version] - environ: *env-def-true - rc: 0 - out: | - cpanm (App::cpanminus) version 1.7047 (/usr/local/bin/cpanm) - perl version 5.041005 (/usr/local/bin/perl) - err: "" - - command: [/testbin/cpanm, MIYAGAWA/Plack-0.99_05.tar.gz] - environ: *env-def-true - rc: 0 - out: "" - err: "" -- id: install_into_locallib - input: - name: Dancer - mode: new - locallib: /srv/webapps/my_app/extlib - output: - changed: true - mocks: - run_command: - - command: [/testbin/cpanm, --version] - environ: *env-def-true - rc: 0 - out: | - cpanm (App::cpanminus) version 1.7047 (/usr/local/bin/cpanm) - perl version 5.041005 (/usr/local/bin/perl) - err: "" - - command: [/testbin/cpanm, --local-lib, /srv/webapps/my_app/extlib, Dancer] - environ: *env-def-true - rc: 0 - out: "" - err: "" -- id: install_from_local_directory - input: - from_path: /srv/webapps/my_app/src/ - mode: new - output: - changed: true - mocks: - run_command: - - command: [/testbin/cpanm, --version] - environ: *env-def-true - rc: 0 - out: | - cpanm (App::cpanminus) version 1.7047 (/usr/local/bin/cpanm) - perl version 5.041005 (/usr/local/bin/perl) - err: "" - - command: [/testbin/cpanm, /srv/webapps/my_app/src/] - environ: *env-def-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 - mocks: - run_command: - - command: [/testbin/cpanm, --version] - environ: *env-def-true - rc: 0 - out: | - cpanm (App::cpanminus) version 1.7047 (/usr/local/bin/cpanm) - perl version 5.041005 (/usr/local/bin/perl) - err: "" - - command: [/testbin/cpanm, --notest, --local-lib, /srv/webapps/my_app/extlib, Dancer] - environ: *env-def-true - rc: 0 - out: "" - err: "" -- id: install_from_mirror - input: - name: Dancer - mode: new - mirror: "http://cpan.cpantesters.org/" - output: - changed: true - mocks: - run_command: - - command: [/testbin/cpanm, --version] - environ: *env-def-true - rc: 0 - out: | - cpanm (App::cpanminus) version 1.7047 (/usr/local/bin/cpanm) - perl version 5.041005 (/usr/local/bin/perl) - err: "" - - command: [/testbin/cpanm, --mirror, "http://cpan.cpantesters.org/", Dancer] - environ: *env-def-true - rc: 0 - out: "" - err: "" -- id: install_into_system_lib - input: - name: Dancer - mode: new - system_lib: true - output: - failed: true - mocks: - run_command: [] -- id: install_minversion_implicit - input: - name: Dancer - mode: new - version: "1.0" - output: - changed: true - mocks: - run_command: - - command: [/testbin/cpanm, --version] - environ: *env-def-true - rc: 0 - out: | - cpanm (App::cpanminus) version 1.7047 (/usr/local/bin/cpanm) - perl version 5.041005 (/usr/local/bin/perl) - err: "" - - command: [/testbin/cpanm, Dancer~1.0] - environ: *env-def-true - rc: 0 - out: "" - err: "" -- id: install_minversion_explicit - input: - name: Dancer - mode: new - version: "~1.5" - output: - changed: true - mocks: - run_command: - - command: [/testbin/cpanm, --version] - environ: *env-def-true - rc: 0 - out: | - cpanm (App::cpanminus) version 1.7047 (/usr/local/bin/cpanm) - perl version 5.041005 (/usr/local/bin/perl) - err: "" - - command: [/testbin/cpanm, Dancer~1.5] - environ: *env-def-true - rc: 0 - out: "" - err: "" -- id: install_specific_version - input: - name: Dancer - mode: new - version: "@1.7" - output: - changed: true - mocks: - run_command: - - command: [/testbin/cpanm, --version] - environ: *env-def-true - rc: 0 - out: | - cpanm (App::cpanminus) version 1.7047 (/usr/local/bin/cpanm) - perl version 5.041005 (/usr/local/bin/perl) - err: "" - - command: [/testbin/cpanm, Dancer@1.7] - environ: *env-def-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 - mocks: - run_command: - - command: [/testbin/cpanm, --version] - environ: *env-def-true - rc: 0 - out: | - cpanm (App::cpanminus) version 1.7047 (/usr/local/bin/cpanm) - perl version 5.041005 (/usr/local/bin/perl) - err: "" -- 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 - mocks: - run_command: - - command: [/testbin/cpanm, --version] - environ: *env-def-true - rc: 0 - out: | - cpanm (App::cpanminus) version 1.7047 (/usr/local/bin/cpanm) - perl version 5.041005 (/usr/local/bin/perl) - err: "" -- id: install_specific_version_from_git_url_explicit - input: - name: "git://github.com/plack/Plack.git" - mode: new - version: "@1.7" - output: - changed: true - mocks: - run_command: - - command: [/testbin/cpanm, --version] - environ: *env-def-true - rc: 0 - out: | - cpanm (App::cpanminus) version 1.7047 (/usr/local/bin/cpanm) - perl version 5.041005 (/usr/local/bin/perl) - err: "" - - command: [/testbin/cpanm, "git://github.com/plack/Plack.git@1.7"] - environ: *env-def-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 - mocks: - run_command: - - command: [/testbin/cpanm, --version] - environ: *env-def-true - rc: 0 - out: | - cpanm (App::cpanminus) version 1.7047 (/usr/local/bin/cpanm) - perl version 5.041005 (/usr/local/bin/perl) - err: "" - - command: [/testbin/cpanm, "git://github.com/plack/Plack.git@2.5"] - environ: *env-def-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 - mocks: - run_command: - - command: [/testbin/cpanm, --version] - environ: *env-def-true - rc: 0 - out: | - cpanm (App::cpanminus) version 1.7047 (/usr/local/bin/cpanm) - perl version 5.041005 (/usr/local/bin/perl) - err: "" -- id: install_dancer_with_recommends - input: - name: Dancer2 - install_recommendations: true - output: - changed: true - mocks: - run_command: - - command: [/testbin/cpanm, --version] - environ: *env-def-true - rc: 0 - out: | - cpanm (App::cpanminus) version 1.7047 (/usr/local/bin/cpanm) - perl version 5.041005 (/usr/local/bin/perl) - err: "" - - command: [/testbin/cpanm, --with-recommends, Dancer2] - environ: *env-def-true - rc: 0 - out: "" - err: "" -- id: install_dancer_with_suggests - input: - name: Dancer2 - install_suggestions: true - output: - changed: true - mocks: - run_command: - - command: [/testbin/cpanm, --version] - environ: *env-def-true - rc: 0 - out: | - cpanm (App::cpanminus) version 1.7047 (/usr/local/bin/cpanm) - perl version 5.041005 (/usr/local/bin/perl) - err: "" - - command: [/testbin/cpanm, --with-suggests, Dancer2] - environ: *env-def-true - rc: 0 - out: "" - err: "" + - id: install_dancer_compatibility + input: + name: Dancer + mode: compatibility + output: + changed: true + cpanm_version: '1.7047' + mocks: + run_command: + - command: [/testbin/cpanm, --version] + environ: *env-def-true + rc: 0 + out: | + cpanm (App::cpanminus) version 1.7047 (/usr/local/bin/cpanm) + perl version 5.041005 (/usr/local/bin/perl) + err: '' + - command: [/testbin/perl, -le, use Dancer;] + environ: *env-def-false + rc: 2 + out: '' + err: error, not installed + - command: [/testbin/cpanm, Dancer] + environ: *env-def-true + rc: 0 + out: '' + err: '' + - id: install_dancer_already_installed_compatibility + input: + name: Dancer + mode: compatibility + output: + changed: false + mocks: + run_command: + - command: [/testbin/cpanm, --version] + environ: *env-def-true + rc: 0 + out: | + cpanm (App::cpanminus) version 1.7047 (/usr/local/bin/cpanm) + perl version 5.041005 (/usr/local/bin/perl) + err: '' + - command: [/testbin/perl, -le, use Dancer;] + environ: *env-def-false + rc: 0 + out: '' + err: '' + - id: install_dancer + input: + name: Dancer + output: + changed: true + mocks: + run_command: + - command: [/testbin/cpanm, --version] + environ: *env-def-true + rc: 0 + out: | + cpanm (App::cpanminus) version 1.7047 (/usr/local/bin/cpanm) + perl version 5.041005 (/usr/local/bin/perl) + err: '' + - command: [/testbin/cpanm, Dancer] + environ: *env-def-true + rc: 0 + out: '' + err: '' + - id: install_distribution_file_compatibility + input: + name: MIYAGAWA/Plack-0.99_05.tar.gz + mode: compatibility + output: + changed: true + mocks: + run_command: + - command: [/testbin/cpanm, --version] + environ: *env-def-true + rc: 0 + out: | + cpanm (App::cpanminus) version 1.7047 (/usr/local/bin/cpanm) + perl version 5.041005 (/usr/local/bin/perl) + err: '' + - command: [/testbin/cpanm, MIYAGAWA/Plack-0.99_05.tar.gz] + environ: *env-def-true + rc: 0 + out: '' + err: '' + - id: install_distribution_file + input: + name: MIYAGAWA/Plack-0.99_05.tar.gz + output: + changed: true + mocks: + run_command: + - command: [/testbin/cpanm, --version] + environ: *env-def-true + rc: 0 + out: | + cpanm (App::cpanminus) version 1.7047 (/usr/local/bin/cpanm) + perl version 5.041005 (/usr/local/bin/perl) + err: '' + - command: [/testbin/cpanm, MIYAGAWA/Plack-0.99_05.tar.gz] + environ: *env-def-true + rc: 0 + out: '' + err: '' + - id: install_into_locallib + input: + name: Dancer + mode: new + locallib: /srv/webapps/my_app/extlib + output: + changed: true + mocks: + run_command: + - command: [/testbin/cpanm, --version] + environ: *env-def-true + rc: 0 + out: | + cpanm (App::cpanminus) version 1.7047 (/usr/local/bin/cpanm) + perl version 5.041005 (/usr/local/bin/perl) + err: '' + - command: [/testbin/cpanm, --local-lib, /srv/webapps/my_app/extlib, Dancer] + environ: *env-def-true + rc: 0 + out: '' + err: '' + - id: install_from_local_directory + input: + from_path: /srv/webapps/my_app/src/ + mode: new + output: + changed: true + mocks: + run_command: + - command: [/testbin/cpanm, --version] + environ: *env-def-true + rc: 0 + out: | + cpanm (App::cpanminus) version 1.7047 (/usr/local/bin/cpanm) + perl version 5.041005 (/usr/local/bin/perl) + err: '' + - command: [/testbin/cpanm, /srv/webapps/my_app/src/] + environ: *env-def-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 + mocks: + run_command: + - command: [/testbin/cpanm, --version] + environ: *env-def-true + rc: 0 + out: | + cpanm (App::cpanminus) version 1.7047 (/usr/local/bin/cpanm) + perl version 5.041005 (/usr/local/bin/perl) + err: '' + - command: [/testbin/cpanm, --notest, --local-lib, /srv/webapps/my_app/extlib, Dancer] + environ: *env-def-true + rc: 0 + out: '' + err: '' + - id: install_from_mirror + input: + name: Dancer + mode: new + mirror: http://cpan.cpantesters.org/ + output: + changed: true + mocks: + run_command: + - command: [/testbin/cpanm, --version] + environ: *env-def-true + rc: 0 + out: | + cpanm (App::cpanminus) version 1.7047 (/usr/local/bin/cpanm) + perl version 5.041005 (/usr/local/bin/perl) + err: '' + - command: [/testbin/cpanm, --mirror, http://cpan.cpantesters.org/, Dancer] + environ: *env-def-true + rc: 0 + out: '' + err: '' + - id: install_into_system_lib + input: + name: Dancer + mode: new + system_lib: true + output: + failed: true + mocks: + run_command: [] + - id: install_minversion_implicit + input: + name: Dancer + mode: new + version: '1.0' + output: + changed: true + mocks: + run_command: + - command: [/testbin/cpanm, --version] + environ: *env-def-true + rc: 0 + out: | + cpanm (App::cpanminus) version 1.7047 (/usr/local/bin/cpanm) + perl version 5.041005 (/usr/local/bin/perl) + err: '' + - command: [/testbin/cpanm, Dancer~1.0] + environ: *env-def-true + rc: 0 + out: '' + err: '' + - id: install_minversion_explicit + input: + name: Dancer + mode: new + version: ~1.5 + output: + changed: true + mocks: + run_command: + - command: [/testbin/cpanm, --version] + environ: *env-def-true + rc: 0 + out: | + cpanm (App::cpanminus) version 1.7047 (/usr/local/bin/cpanm) + perl version 5.041005 (/usr/local/bin/perl) + err: '' + - command: [/testbin/cpanm, Dancer~1.5] + environ: *env-def-true + rc: 0 + out: '' + err: '' + - id: install_specific_version + input: + name: Dancer + mode: new + version: '@1.7' + output: + changed: true + mocks: + run_command: + - command: [/testbin/cpanm, --version] + environ: *env-def-true + rc: 0 + out: | + cpanm (App::cpanminus) version 1.7047 (/usr/local/bin/cpanm) + perl version 5.041005 (/usr/local/bin/perl) + err: '' + - command: [/testbin/cpanm, Dancer@1.7] + environ: *env-def-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 + mocks: + run_command: + - command: [/testbin/cpanm, --version] + environ: *env-def-true + rc: 0 + out: | + cpanm (App::cpanminus) version 1.7047 (/usr/local/bin/cpanm) + perl version 5.041005 (/usr/local/bin/perl) + err: '' + - 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 + mocks: + run_command: + - command: [/testbin/cpanm, --version] + environ: *env-def-true + rc: 0 + out: | + cpanm (App::cpanminus) version 1.7047 (/usr/local/bin/cpanm) + perl version 5.041005 (/usr/local/bin/perl) + err: '' + - id: install_specific_version_from_git_url_explicit + input: + name: git://github.com/plack/Plack.git + mode: new + version: '@1.7' + output: + changed: true + mocks: + run_command: + - command: [/testbin/cpanm, --version] + environ: *env-def-true + rc: 0 + out: | + cpanm (App::cpanminus) version 1.7047 (/usr/local/bin/cpanm) + perl version 5.041005 (/usr/local/bin/perl) + err: '' + - command: [/testbin/cpanm, git://github.com/plack/Plack.git@1.7] + environ: *env-def-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 + mocks: + run_command: + - command: [/testbin/cpanm, --version] + environ: *env-def-true + rc: 0 + out: | + cpanm (App::cpanminus) version 1.7047 (/usr/local/bin/cpanm) + perl version 5.041005 (/usr/local/bin/perl) + err: '' + - command: [/testbin/cpanm, git://github.com/plack/Plack.git@2.5] + environ: *env-def-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 + mocks: + run_command: + - command: [/testbin/cpanm, --version] + environ: *env-def-true + rc: 0 + out: | + cpanm (App::cpanminus) version 1.7047 (/usr/local/bin/cpanm) + perl version 5.041005 (/usr/local/bin/perl) + err: '' + - id: install_dancer_with_recommends + input: + name: Dancer2 + install_recommendations: true + output: + changed: true + mocks: + run_command: + - command: [/testbin/cpanm, --version] + environ: *env-def-true + rc: 0 + out: | + cpanm (App::cpanminus) version 1.7047 (/usr/local/bin/cpanm) + perl version 5.041005 (/usr/local/bin/perl) + err: '' + - command: [/testbin/cpanm, --with-recommends, Dancer2] + environ: *env-def-true + rc: 0 + out: '' + err: '' + - id: install_dancer_with_suggests + input: + name: Dancer2 + install_suggestions: true + output: + changed: true + mocks: + run_command: + - command: [/testbin/cpanm, --version] + environ: *env-def-true + rc: 0 + out: | + cpanm (App::cpanminus) version 1.7047 (/usr/local/bin/cpanm) + perl version 5.041005 (/usr/local/bin/perl) + err: '' + - command: [/testbin/cpanm, --with-suggests, Dancer2] + environ: *env-def-true + rc: 0 + out: '' + err: '' diff --git a/tests/unit/plugins/modules/test_django_check.py b/tests/unit/plugins/modules/test_django_check.py index e65b8454d9..1562dbe8ea 100644 --- a/tests/unit/plugins/modules/test_django_check.py +++ b/tests/unit/plugins/modules/test_django_check.py @@ -7,7 +7,7 @@ __metaclass__ = type from ansible_collections.community.general.plugins.modules import django_check -from .helper import Helper, RunCommandMock +from .uthelper import UTHelper, RunCommandMock -Helper.from_module(django_check, __name__, mocks=[RunCommandMock]) +UTHelper.from_module(django_check, __name__, mocks=[RunCommandMock]) diff --git a/tests/unit/plugins/modules/test_django_check.yaml b/tests/unit/plugins/modules/test_django_check.yaml index 1b8b36a52c..fb39b6d62f 100644 --- a/tests/unit/plugins/modules/test_django_check.yaml +++ b/tests/unit/plugins/modules/test_django_check.yaml @@ -7,40 +7,40 @@ anchors: environ: &env-def {environ_update: {LANGUAGE: C, LC_ALL: C}, check_rc: true} test_cases: -- id: success - input: - settings: whatever.settings - output: - version: "5.1.2" - mocks: - run_command: - - command: [/testbin/python, -m, django, --version] - environ: *env-def - rc: 0 - out: "5.1.2\n" - err: "" - - command: [/testbin/python, -m, django, check, --no-color, --settings=whatever.settings] - environ: *env-def - rc: 0 - out: "whatever\n" - err: "" -- id: multiple_databases - input: - settings: whatever.settings - database: - - abc - - def - output: - version: "5.1.2" - mocks: - run_command: - - command: [/testbin/python, -m, django, --version] - environ: *env-def - rc: 0 - out: "5.1.2\n" - err: "" - - command: [/testbin/python, -m, django, check, --no-color, --settings=whatever.settings, --database, abc, --database, def] - environ: *env-def - rc: 0 - out: "whatever\n" - err: "" + - id: success + input: + settings: whatever.settings + output: + version: 5.1.2 + mocks: + run_command: + - command: [/testbin/python, -m, django, --version] + environ: *env-def + rc: 0 + out: "5.1.2\n" + err: '' + - command: [/testbin/python, -m, django, check, --no-color, --settings=whatever.settings] + environ: *env-def + rc: 0 + out: "whatever\n" + err: '' + - id: multiple_databases + input: + settings: whatever.settings + database: + - abc + - def + output: + version: 5.1.2 + mocks: + run_command: + - command: [/testbin/python, -m, django, --version] + environ: *env-def + rc: 0 + out: "5.1.2\n" + err: '' + - command: [/testbin/python, -m, django, check, --no-color, --settings=whatever.settings, --database, abc, --database, def] + environ: *env-def + rc: 0 + out: "whatever\n" + err: '' diff --git a/tests/unit/plugins/modules/test_django_command.py b/tests/unit/plugins/modules/test_django_command.py index f26c05498e..3be2e475d8 100644 --- a/tests/unit/plugins/modules/test_django_command.py +++ b/tests/unit/plugins/modules/test_django_command.py @@ -7,7 +7,7 @@ __metaclass__ = type from ansible_collections.community.general.plugins.modules import django_command -from .helper import Helper, RunCommandMock +from .uthelper import UTHelper, RunCommandMock -Helper.from_module(django_command, __name__, mocks=[RunCommandMock]) +UTHelper.from_module(django_command, __name__, mocks=[RunCommandMock]) diff --git a/tests/unit/plugins/modules/test_django_command.yaml b/tests/unit/plugins/modules/test_django_command.yaml index a98182385e..10da8753bd 100644 --- a/tests/unit/plugins/modules/test_django_command.yaml +++ b/tests/unit/plugins/modules/test_django_command.yaml @@ -7,47 +7,47 @@ anchors: environ: &env-def {environ_update: {LANGUAGE: C, LC_ALL: C}, check_rc: true} test_cases: -- id: command_success - input: - command: check - extra_args: - - babaloo - - yaba - - daba - - doo - settings: whatever.settings - mocks: - run_command: - - command: [/testbin/python, -m, django, --version] - environ: *env-def - rc: 0 - out: "5.1.2\n" - err: "" - - command: [/testbin/python, -m, django, check, --no-color, --settings=whatever.settings, babaloo, yaba, daba, doo] - environ: *env-def - rc: 0 - out: "whatever\n" - err: "" -- id: command_fail - input: - command: check - extra_args: - - babaloo - - yaba - - daba - - doo - settings: whatever.settings - output: - failed: true - mocks: - run_command: - - command: [/testbin/python, -m, django, --version] - environ: *env-def - rc: 0 - out: "5.1.2\n" - err: "" - - command: [/testbin/python, -m, django, check, --no-color, --settings=whatever.settings, babaloo, yaba, daba, doo] - environ: *env-def - rc: 1 - out: "whatever\n" - err: "" + - id: command_success + input: + command: check + extra_args: + - babaloo + - yaba + - daba + - doo + settings: whatever.settings + mocks: + run_command: + - command: [/testbin/python, -m, django, --version] + environ: *env-def + rc: 0 + out: "5.1.2\n" + err: '' + - command: [/testbin/python, -m, django, check, --no-color, --settings=whatever.settings, babaloo, yaba, daba, doo] + environ: *env-def + rc: 0 + out: "whatever\n" + err: '' + - id: command_fail + input: + command: check + extra_args: + - babaloo + - yaba + - daba + - doo + settings: whatever.settings + output: + failed: true + mocks: + run_command: + - command: [/testbin/python, -m, django, --version] + environ: *env-def + rc: 0 + out: "5.1.2\n" + err: '' + - command: [/testbin/python, -m, django, check, --no-color, --settings=whatever.settings, babaloo, yaba, daba, doo] + environ: *env-def + rc: 1 + out: "whatever\n" + err: '' diff --git a/tests/unit/plugins/modules/test_django_createcachetable.py b/tests/unit/plugins/modules/test_django_createcachetable.py index 6da0720d82..3ed574e949 100644 --- a/tests/unit/plugins/modules/test_django_createcachetable.py +++ b/tests/unit/plugins/modules/test_django_createcachetable.py @@ -7,7 +7,7 @@ __metaclass__ = type from ansible_collections.community.general.plugins.modules import django_createcachetable -from .helper import Helper, RunCommandMock +from .uthelper import UTHelper, RunCommandMock -Helper.from_module(django_createcachetable, __name__, mocks=[RunCommandMock]) +UTHelper.from_module(django_createcachetable, __name__, mocks=[RunCommandMock]) diff --git a/tests/unit/plugins/modules/test_django_createcachetable.yaml b/tests/unit/plugins/modules/test_django_createcachetable.yaml index e800fb65ac..b8056e1b2e 100644 --- a/tests/unit/plugins/modules/test_django_createcachetable.yaml +++ b/tests/unit/plugins/modules/test_django_createcachetable.yaml @@ -7,18 +7,18 @@ anchors: environ: &env-def {environ_update: {LANGUAGE: C, LC_ALL: C}, check_rc: true} test_cases: -- id: command_success - input: - settings: whatever.settings - mocks: - run_command: - - command: [/testbin/python, -m, django, --version] - environ: *env-def - rc: 0 - out: "5.1.2\n" - err: "" - - command: [/testbin/python, -m, django, createcachetable, --no-color, --settings=whatever.settings, --noinput, --database=default] - environ: *env-def - rc: 0 - out: "whatever\n" - err: "" + - id: command_success + input: + settings: whatever.settings + mocks: + run_command: + - command: [/testbin/python, -m, django, --version] + environ: *env-def + rc: 0 + out: "5.1.2\n" + err: '' + - command: [/testbin/python, -m, django, createcachetable, --no-color, --settings=whatever.settings, --noinput, --database=default] + environ: *env-def + rc: 0 + out: "whatever\n" + err: '' diff --git a/tests/unit/plugins/modules/test_facter_facts.py b/tests/unit/plugins/modules/test_facter_facts.py index 8d0896226b..7b2b94f08b 100644 --- a/tests/unit/plugins/modules/test_facter_facts.py +++ b/tests/unit/plugins/modules/test_facter_facts.py @@ -8,7 +8,7 @@ __metaclass__ = type from ansible_collections.community.general.plugins.modules import facter_facts -from .helper import Helper, RunCommandMock +from .uthelper import UTHelper, RunCommandMock -Helper.from_module(facter_facts, __name__, mocks=[RunCommandMock]) +UTHelper.from_module(facter_facts, __name__, mocks=[RunCommandMock]) diff --git a/tests/unit/plugins/modules/test_facter_facts.yaml b/tests/unit/plugins/modules/test_facter_facts.yaml index ffce162b27..89a98714c5 100644 --- a/tests/unit/plugins/modules/test_facter_facts.yaml +++ b/tests/unit/plugins/modules/test_facter_facts.yaml @@ -7,39 +7,39 @@ anchors: environ: &env-def {check_rc: true} test_cases: -- id: simple run - output: - ansible_facts: - facter: - a: 1 - b: 2 - c: 3 - mocks: - run_command: - - command: [/testbin/facter, --json] - environ: *env-def - rc: 0 - out: > - { "a": 1, "b": 2, "c": 3 } - err: "" -- id: with args - input: - arguments: - - -p - - system_uptime - - timezone - - is_virtual - output: - ansible_facts: - facter: - a: 1 - b: 2 - c: 3 - mocks: - run_command: - - command: [/testbin/facter, --json, -p, system_uptime, timezone, is_virtual] - environ: *env-def - rc: 0 - out: > - { "a": 1, "b": 2, "c": 3 } - err: "" + - id: simple run + output: + ansible_facts: + facter: + a: 1 + b: 2 + c: 3 + mocks: + run_command: + - command: [/testbin/facter, --json] + environ: *env-def + rc: 0 + out: > + { "a": 1, "b": 2, "c": 3 } + err: '' + - id: with args + input: + arguments: + - -p + - system_uptime + - timezone + - is_virtual + output: + ansible_facts: + facter: + a: 1 + b: 2 + c: 3 + mocks: + run_command: + - command: [/testbin/facter, --json, -p, system_uptime, timezone, is_virtual] + environ: *env-def + rc: 0 + out: > + { "a": 1, "b": 2, "c": 3 } + err: '' diff --git a/tests/unit/plugins/modules/test_gconftool2.py b/tests/unit/plugins/modules/test_gconftool2.py index 52698c5969..ed140bd3e7 100644 --- a/tests/unit/plugins/modules/test_gconftool2.py +++ b/tests/unit/plugins/modules/test_gconftool2.py @@ -8,7 +8,7 @@ __metaclass__ = type from ansible_collections.community.general.plugins.modules import gconftool2 -from .helper import Helper, RunCommandMock +from .uthelper import UTHelper, RunCommandMock -Helper.from_module(gconftool2, __name__, mocks=[RunCommandMock]) +UTHelper.from_module(gconftool2, __name__, mocks=[RunCommandMock]) diff --git a/tests/unit/plugins/modules/test_gconftool2.yaml b/tests/unit/plugins/modules/test_gconftool2.yaml index 12bf9099f4..19d389247f 100644 --- a/tests/unit/plugins/modules/test_gconftool2.yaml +++ b/tests/unit/plugins/modules/test_gconftool2.yaml @@ -7,147 +7,147 @@ anchors: environ: &env-def {environ_update: {LANGUAGE: C, LC_ALL: C}, check_rc: true} test_cases: -- id: test_simple_element_set - input: - state: present - key: /desktop/gnome/background/picture_filename - value: 200 - value_type: int - output: - new_value: '200' - changed: true - version: "3.2.6" - mocks: - run_command: - - command: [/testbin/gconftool-2, --version] - environ: *env-def - rc: 0 - out: "3.2.6\n" - err: "" - - command: [/testbin/gconftool-2, --get, /desktop/gnome/background/picture_filename] - environ: *env-def - rc: 0 - out: "100\n" - err: "" - - command: [/testbin/gconftool-2, --type, int, --set, /desktop/gnome/background/picture_filename, "200"] - environ: *env-def - rc: 0 - out: "" - err: "" - - command: [/testbin/gconftool-2, --get, /desktop/gnome/background/picture_filename] - environ: *env-def - rc: 0 - out: "200\n" - err: "" -- id: test_simple_element_set_idempotency_int - input: - state: present - key: /desktop/gnome/background/picture_filename - value: 200 - value_type: int - output: - new_value: '200' - changed: false - version: "3.2.5" - mocks: - run_command: - - command: [/testbin/gconftool-2, --version] - environ: *env-def - rc: 0 - out: "3.2.5\n" - err: "" - - command: [/testbin/gconftool-2, --get, /desktop/gnome/background/picture_filename] - environ: *env-def - rc: 0 - out: "200\n" - err: "" - - command: [/testbin/gconftool-2, --type, int, --set, /desktop/gnome/background/picture_filename, "200"] - environ: *env-def - rc: 0 - out: "" - err: "" - - command: [/testbin/gconftool-2, --get, /desktop/gnome/background/picture_filename] - environ: *env-def - rc: 0 - out: "200\n" - err: "" -- id: test_simple_element_set_idempotency_bool - input: - state: present - key: /apps/gnome_settings_daemon/screensaver/start_screensaver - value: false - value_type: bool - output: - new_value: 'false' - changed: false - version: "3.2.4" - mocks: - run_command: - - command: [/testbin/gconftool-2, --version] - environ: *env-def - rc: 0 - out: "3.2.4\n" - err: "" - - command: [/testbin/gconftool-2, --get, /apps/gnome_settings_daemon/screensaver/start_screensaver] - environ: *env-def - rc: 0 - out: "false\n" - err: "" - - command: [/testbin/gconftool-2, --type, bool, --set, /apps/gnome_settings_daemon/screensaver/start_screensaver, "False"] - environ: *env-def - rc: 0 - out: "" - err: "" - - command: [/testbin/gconftool-2, --get, /apps/gnome_settings_daemon/screensaver/start_screensaver] - environ: *env-def - rc: 0 - out: "false\n" - err: "" -- id: test_simple_element_unset - input: - state: absent - key: /desktop/gnome/background/picture_filename - output: - new_value: - changed: true - mocks: - run_command: - - command: [/testbin/gconftool-2, --version] - environ: *env-def - rc: 0 - out: "3.2.4\n" - err: "" - - command: [/testbin/gconftool-2, --get, /desktop/gnome/background/picture_filename] - environ: *env-def - rc: 0 - out: "200\n" - err: "" - - command: [/testbin/gconftool-2, --unset, /desktop/gnome/background/picture_filename] - environ: *env-def - rc: 0 - out: "" - err: "" -- id: test_simple_element_unset_idempotency - input: - state: absent - key: /apps/gnome_settings_daemon/screensaver/start_screensaver - output: - new_value: - changed: false - mocks: - run_command: - - command: [/testbin/gconftool-2, --version] - environ: *env-def - rc: 0 - out: "3.2.4\n" - err: "" - - command: [/testbin/gconftool-2, --get, /apps/gnome_settings_daemon/screensaver/start_screensaver] - environ: *env-def - rc: 0 - out: "" - err: "" - - command: [/testbin/gconftool-2, --unset, /apps/gnome_settings_daemon/screensaver/start_screensaver] - environ: *env-def - rc: 0 - out: "" - err: "" + - id: test_simple_element_set + input: + state: present + key: /desktop/gnome/background/picture_filename + value: 200 + value_type: int + output: + new_value: '200' + changed: true + version: 3.2.6 + mocks: + run_command: + - command: [/testbin/gconftool-2, --version] + environ: *env-def + rc: 0 + out: "3.2.6\n" + err: '' + - command: [/testbin/gconftool-2, --get, /desktop/gnome/background/picture_filename] + environ: *env-def + rc: 0 + out: "100\n" + err: '' + - command: [/testbin/gconftool-2, --type, int, --set, /desktop/gnome/background/picture_filename, '200'] + environ: *env-def + rc: 0 + out: '' + err: '' + - command: [/testbin/gconftool-2, --get, /desktop/gnome/background/picture_filename] + environ: *env-def + rc: 0 + out: "200\n" + err: '' + - id: test_simple_element_set_idempotency_int + input: + state: present + key: /desktop/gnome/background/picture_filename + value: 200 + value_type: int + output: + new_value: '200' + changed: false + version: 3.2.5 + mocks: + run_command: + - command: [/testbin/gconftool-2, --version] + environ: *env-def + rc: 0 + out: "3.2.5\n" + err: '' + - command: [/testbin/gconftool-2, --get, /desktop/gnome/background/picture_filename] + environ: *env-def + rc: 0 + out: "200\n" + err: '' + - command: [/testbin/gconftool-2, --type, int, --set, /desktop/gnome/background/picture_filename, '200'] + environ: *env-def + rc: 0 + out: '' + err: '' + - command: [/testbin/gconftool-2, --get, /desktop/gnome/background/picture_filename] + environ: *env-def + rc: 0 + out: "200\n" + err: '' + - id: test_simple_element_set_idempotency_bool + input: + state: present + key: /apps/gnome_settings_daemon/screensaver/start_screensaver + value: false + value_type: bool + output: + new_value: 'false' + changed: false + version: 3.2.4 + mocks: + run_command: + - command: [/testbin/gconftool-2, --version] + environ: *env-def + rc: 0 + out: "3.2.4\n" + err: '' + - command: [/testbin/gconftool-2, --get, /apps/gnome_settings_daemon/screensaver/start_screensaver] + environ: *env-def + rc: 0 + out: "false\n" + err: '' + - command: [/testbin/gconftool-2, --type, bool, --set, /apps/gnome_settings_daemon/screensaver/start_screensaver, 'False'] + environ: *env-def + rc: 0 + out: '' + err: '' + - command: [/testbin/gconftool-2, --get, /apps/gnome_settings_daemon/screensaver/start_screensaver] + environ: *env-def + rc: 0 + out: "false\n" + err: '' + - id: test_simple_element_unset + input: + state: absent + key: /desktop/gnome/background/picture_filename + output: + new_value: + changed: true + mocks: + run_command: + - command: [/testbin/gconftool-2, --version] + environ: *env-def + rc: 0 + out: "3.2.4\n" + err: '' + - command: [/testbin/gconftool-2, --get, /desktop/gnome/background/picture_filename] + environ: *env-def + rc: 0 + out: "200\n" + err: '' + - command: [/testbin/gconftool-2, --unset, /desktop/gnome/background/picture_filename] + environ: *env-def + rc: 0 + out: '' + err: '' + - id: test_simple_element_unset_idempotency + input: + state: absent + key: /apps/gnome_settings_daemon/screensaver/start_screensaver + output: + new_value: + changed: false + mocks: + run_command: + - command: [/testbin/gconftool-2, --version] + environ: *env-def + rc: 0 + out: "3.2.4\n" + err: '' + - command: [/testbin/gconftool-2, --get, /apps/gnome_settings_daemon/screensaver/start_screensaver] + environ: *env-def + rc: 0 + out: '' + err: '' + - command: [/testbin/gconftool-2, --unset, /apps/gnome_settings_daemon/screensaver/start_screensaver] + environ: *env-def + rc: 0 + out: '' + err: '' diff --git a/tests/unit/plugins/modules/test_gconftool2_info.py b/tests/unit/plugins/modules/test_gconftool2_info.py index 362f33e49a..6cbba8dbc0 100644 --- a/tests/unit/plugins/modules/test_gconftool2_info.py +++ b/tests/unit/plugins/modules/test_gconftool2_info.py @@ -8,7 +8,7 @@ __metaclass__ = type from ansible_collections.community.general.plugins.modules import gconftool2_info -from .helper import Helper, RunCommandMock +from .uthelper import UTHelper, RunCommandMock -Helper.from_module(gconftool2_info, __name__, mocks=[RunCommandMock]) +UTHelper.from_module(gconftool2_info, __name__, mocks=[RunCommandMock]) diff --git a/tests/unit/plugins/modules/test_gconftool2_info.yaml b/tests/unit/plugins/modules/test_gconftool2_info.yaml index 269f0b4ea2..141b473e35 100644 --- a/tests/unit/plugins/modules/test_gconftool2_info.yaml +++ b/tests/unit/plugins/modules/test_gconftool2_info.yaml @@ -7,37 +7,37 @@ anchors: environ: &env-def {environ_update: {LANGUAGE: C, LC_ALL: C}, check_rc: true} test_cases: -- id: test_simple_element_get - input: - key: /desktop/gnome/background/picture_filename - output: - value: '100' - mocks: - run_command: - - command: [/testbin/gconftool-2, --version] - environ: *env-def - rc: 0 - out: "3.2.6\n" - err: "" - - command: [/testbin/gconftool-2, --get, /desktop/gnome/background/picture_filename] - environ: *env-def - rc: 0 - out: "100\n" - err: "" -- id: test_simple_element_get_not_found - input: - key: /desktop/gnome/background/picture_filename - output: - value: - mocks: - run_command: - - command: [/testbin/gconftool-2, --version] - environ: *env-def - rc: 0 - out: "3.2.6\n" - err: "" - - command: [/testbin/gconftool-2, --get, /desktop/gnome/background/picture_filename] - environ: *env-def - rc: 0 - out: "" - err: "No value set for `/desktop/gnome/background/picture_filename'\n" + - id: test_simple_element_get + input: + key: /desktop/gnome/background/picture_filename + output: + value: '100' + mocks: + run_command: + - command: [/testbin/gconftool-2, --version] + environ: *env-def + rc: 0 + out: "3.2.6\n" + err: '' + - command: [/testbin/gconftool-2, --get, /desktop/gnome/background/picture_filename] + environ: *env-def + rc: 0 + out: "100\n" + err: '' + - id: test_simple_element_get_not_found + input: + key: /desktop/gnome/background/picture_filename + output: + value: + mocks: + run_command: + - command: [/testbin/gconftool-2, --version] + environ: *env-def + rc: 0 + out: "3.2.6\n" + err: '' + - command: [/testbin/gconftool-2, --get, /desktop/gnome/background/picture_filename] + environ: *env-def + rc: 0 + out: '' + err: "No value set for `/desktop/gnome/background/picture_filename'\n" diff --git a/tests/unit/plugins/modules/test_gio_mime.py b/tests/unit/plugins/modules/test_gio_mime.py index 24bac3de93..180890cc39 100644 --- a/tests/unit/plugins/modules/test_gio_mime.py +++ b/tests/unit/plugins/modules/test_gio_mime.py @@ -8,7 +8,7 @@ __metaclass__ = type from ansible_collections.community.general.plugins.modules import gio_mime -from .helper import Helper, RunCommandMock +from .uthelper import UTHelper, RunCommandMock -Helper.from_module(gio_mime, __name__, mocks=[RunCommandMock]) +UTHelper.from_module(gio_mime, __name__, mocks=[RunCommandMock]) diff --git a/tests/unit/plugins/modules/test_gio_mime.yaml b/tests/unit/plugins/modules/test_gio_mime.yaml index c1a3c5def5..0d98f25503 100644 --- a/tests/unit/plugins/modules/test_gio_mime.yaml +++ b/tests/unit/plugins/modules/test_gio_mime.yaml @@ -7,85 +7,119 @@ anchors: environ: &env-def {environ_update: {LANGUAGE: C, LC_ALL: C}, check_rc: true} test_cases: -- id: test_set_handler - input: - handler: google-chrome.desktop - mime_type: x-scheme-handler/http - output: - handler: google-chrome.desktop - changed: true - mocks: - run_command: - - command: [/testbin/gio, --version] - environ: *env-def - rc: 0 - out: "2.80.0\n" - err: "" - - command: [/testbin/gio, mime, x-scheme-handler/http] - environ: *env-def - rc: 0 - out: "" - err: > - No default applications for “x-scheme-handler/http” - - command: [/testbin/gio, mime, x-scheme-handler/http, google-chrome.desktop] - environ: *env-def - rc: 0 - out: "Set google-chrome.desktop as the default for x-scheme-handler/http\n" - err: "" -- id: test_set_handler_check - input: - handler: google-chrome.desktop - mime_type: x-scheme-handler/http - output: - handler: google-chrome.desktop - changed: true - flags: - skip: test helper does not support check mode yet - mocks: - run_command: - - command: [/testbin/gio, --version] - environ: *env-def - rc: 0 - out: "2.80.0\n" - err: "" - - command: [/testbin/gio, mime, x-scheme-handler/http] - environ: *env-def - rc: 0 - out: "" - err: > - No default applications for “x-scheme-handler/http” - - command: [/testbin/gio, mime, x-scheme-handler/http, google-chrome.desktop] - environ: *env-def - rc: 0 - out: "Set google-chrome.desktop as the default for x-scheme-handler/http\n" - err: "" -- id: test_set_handler_idempot - input: - handler: google-chrome.desktop - mime_type: x-scheme-handler/http - output: - handler: google-chrome.desktop - changed: false - mocks: - run_command: - - command: [/testbin/gio, --version] - environ: *env-def - rc: 0 - out: "2.80.0\n" - err: "" - - command: [/testbin/gio, mime, x-scheme-handler/http] - environ: *env-def - rc: 0 - out: | - Default application for “x-scheme-handler/https”: google-chrome.desktop - Registered applications: - brave-browser.desktop - firefox.desktop - google-chrome.desktop - firefox_firefox.desktop - Recommended applications: - brave-browser.desktop - firefox.desktop - google-chrome.desktop - firefox_firefox.desktop - err: "" + - id: test_set_handler + input: + handler: google-chrome.desktop + mime_type: x-scheme-handler/http + output: + handler: google-chrome.desktop + changed: true + mocks: + run_command: + - command: [/testbin/gio, --version] + environ: *env-def + rc: 0 + out: "2.80.0\n" + err: '' + - command: [/testbin/gio, mime, x-scheme-handler/http] + environ: *env-def + rc: 0 + out: '' + err: > + No default applications for “x-scheme-handler/http” + - command: [/testbin/gio, mime, x-scheme-handler/http, google-chrome.desktop] + environ: *env-def + rc: 0 + out: "Set google-chrome.desktop as the default for x-scheme-handler/http\n" + err: '' + - id: test_set_handler_check + input: + handler: google-chrome.desktop + mime_type: x-scheme-handler/http + output: + handler: google-chrome.desktop + changed: true + stdout: Module executed in check mode + diff: + before: + handler: null + after: + handler: google-chrome.desktop + flags: + check: true + diff: true + mocks: + run_command: + - command: [/testbin/gio, --version] + environ: *env-def + rc: 0 + out: "2.80.0\n" + err: '' + - command: [/testbin/gio, mime, x-scheme-handler/http] + environ: *env-def + rc: 0 + out: '' + err: > + No default applications for “x-scheme-handler/http” + - id: test_set_handler_idempot + input: + handler: google-chrome.desktop + mime_type: x-scheme-handler/http + output: + handler: google-chrome.desktop + changed: false + mocks: + run_command: + - command: [/testbin/gio, --version] + environ: *env-def + rc: 0 + out: "2.80.0\n" + err: '' + - command: [/testbin/gio, mime, x-scheme-handler/http] + environ: *env-def + rc: 0 + out: | + Default application for “x-scheme-handler/https”: google-chrome.desktop + Registered applications: + brave-browser.desktop + firefox.desktop + google-chrome.desktop + firefox_firefox.desktop + Recommended applications: + brave-browser.desktop + firefox.desktop + google-chrome.desktop + firefox_firefox.desktop + err: '' + - id: test_set_handler_idempot_check + input: + handler: google-chrome.desktop + mime_type: x-scheme-handler/http + output: + handler: google-chrome.desktop + changed: false + flags: + check: true + mocks: + run_command: + - command: [/testbin/gio, --version] + environ: *env-def + rc: 0 + out: "2.80.0\n" + err: '' + - command: [/testbin/gio, mime, x-scheme-handler/http] + environ: *env-def + rc: 0 + out: | + Default application for “x-scheme-handler/https”: google-chrome.desktop + Registered applications: + brave-browser.desktop + firefox.desktop + google-chrome.desktop + firefox_firefox.desktop + Recommended applications: + brave-browser.desktop + firefox.desktop + google-chrome.desktop + firefox_firefox.desktop + err: '' diff --git a/tests/unit/plugins/modules/test_krb_ticket.py b/tests/unit/plugins/modules/test_krb_ticket.py index 68e73159c9..99c97a4f03 100644 --- a/tests/unit/plugins/modules/test_krb_ticket.py +++ b/tests/unit/plugins/modules/test_krb_ticket.py @@ -8,7 +8,7 @@ __metaclass__ = type from ansible_collections.community.general.plugins.modules import krb_ticket -from .helper import Helper, RunCommandMock +from .uthelper import UTHelper, RunCommandMock -Helper.from_module(krb_ticket, __name__, mocks=[RunCommandMock]) +UTHelper.from_module(krb_ticket, __name__, mocks=[RunCommandMock]) diff --git a/tests/unit/plugins/modules/test_krb_ticket.yaml b/tests/unit/plugins/modules/test_krb_ticket.yaml index cfc9e212cb..d1b6d67f57 100644 --- a/tests/unit/plugins/modules/test_krb_ticket.yaml +++ b/tests/unit/plugins/modules/test_krb_ticket.yaml @@ -9,106 +9,106 @@ anchors: environ_data: &env-data {environ_update: {LANGUAGE: C, LC_ALL: C}, check_rc: true, data: cool_password} environ_norc: &env-norc {environ_update: {LANGUAGE: C, LC_ALL: C}, check_rc: true} test_cases: -- id: test_kinit_default - input: - state: present - password: cool_password - output: - changed: true - mocks: - run_command: - - command: [/testbin/klist] - environ: *env-def - rc: 1 - out: "" - err: "" - - command: [/testbin/kinit] - environ: *env-data - rc: 0 - out: "" - err: "" -- id: test_kinit_principal - input: - state: present - password: cool_password - principal: admin@IPA.TEST - output: - changed: true - mocks: - run_command: - - command: [/testbin/klist, -l] - environ: *env-def - rc: 0 - out: "" - err: "" - - command: [/testbin/kinit, admin@IPA.TEST] - environ: *env-data - rc: 0 - out: "" - err: "" -- id: test_kdestroy_default - input: - state: absent - output: - changed: true - mocks: - run_command: - - command: [/testbin/klist] - environ: *env-def - rc: 0 - out: "" - err: "" - - command: [/testbin/kdestroy] - environ: *env-norc - rc: 0 - out: "" - err: "" -- id: test_kdestroy_principal - input: - state: absent - principal: admin@IPA.TEST - output: - changed: true - mocks: - run_command: - - command: [/testbin/klist, -l] - environ: *env-def - rc: 0 - out: "admin@IPA.TEST" - err: "" - - command: [/testbin/kdestroy, -p, admin@IPA.TEST] - environ: *env-norc - rc: 0 - out: "" - err: "" -- id: test_kdestroy_cache_name - input: - state: absent - cache_name: KEYRING:persistent:0:0 - output: - changed: true - mocks: - run_command: - - command: [/testbin/klist, -l] - environ: *env-def - rc: 0 - out: "KEYRING:persistent:0:0" - err: "" - - command: [/testbin/kdestroy, -c, KEYRING:persistent:0:0] - environ: *env-norc - rc: 0 - out: "" - err: "" -- id: test_kdestroy_all - input: - state: absent - kdestroy_all: true - output: - changed: true - mocks: - run_command: - - command: [/testbin/kdestroy, -A] - environ: *env-norc - rc: 0 - out: "" - err: "" + - id: test_kinit_default + input: + state: present + password: cool_password + output: + changed: true + mocks: + run_command: + - command: [/testbin/klist] + environ: *env-def + rc: 1 + out: '' + err: '' + - command: [/testbin/kinit] + environ: *env-data + rc: 0 + out: '' + err: '' + - id: test_kinit_principal + input: + state: present + password: cool_password + principal: admin@IPA.TEST + output: + changed: true + mocks: + run_command: + - command: [/testbin/klist, -l] + environ: *env-def + rc: 0 + out: '' + err: '' + - command: [/testbin/kinit, admin@IPA.TEST] + environ: *env-data + rc: 0 + out: '' + err: '' + - id: test_kdestroy_default + input: + state: absent + output: + changed: true + mocks: + run_command: + - command: [/testbin/klist] + environ: *env-def + rc: 0 + out: '' + err: '' + - command: [/testbin/kdestroy] + environ: *env-norc + rc: 0 + out: '' + err: '' + - id: test_kdestroy_principal + input: + state: absent + principal: admin@IPA.TEST + output: + changed: true + mocks: + run_command: + - command: [/testbin/klist, -l] + environ: *env-def + rc: 0 + out: admin@IPA.TEST + err: '' + - command: [/testbin/kdestroy, -p, admin@IPA.TEST] + environ: *env-norc + rc: 0 + out: '' + err: '' + - id: test_kdestroy_cache_name + input: + state: absent + cache_name: KEYRING:persistent:0:0 + output: + changed: true + mocks: + run_command: + - command: [/testbin/klist, -l] + environ: *env-def + rc: 0 + out: KEYRING:persistent:0:0 + err: '' + - command: [/testbin/kdestroy, -c, KEYRING:persistent:0:0] + environ: *env-norc + rc: 0 + out: '' + err: '' + - id: test_kdestroy_all + input: + state: absent + kdestroy_all: true + output: + changed: true + mocks: + run_command: + - command: [/testbin/kdestroy, -A] + environ: *env-norc + rc: 0 + out: '' + err: '' diff --git a/tests/unit/plugins/modules/test_nmcli.py b/tests/unit/plugins/modules/test_nmcli.py index f7b8278b4f..45875cb15b 100644 --- a/tests/unit/plugins/modules/test_nmcli.py +++ b/tests/unit/plugins/modules/test_nmcli.py @@ -1570,6 +1570,37 @@ macvlan.promiscuous: yes macvlan.tap: no """ +TESTCASE_VRF = [ + { + 'type': 'vrf', + 'conn_name': 'non_existent_nw_device', + 'ifname': 'vrf_not_exists', + 'ip4': '10.10.10.10/24', + 'gw4': '10.10.10.1', + 'table': 10, + 'state': 'present', + '_ansible_check_mode': False, + } +] + +TESTCASE_VRF_SHOW_OUTPUT = """\ +connection.id: non_existent_nw_device +connection.interface-name: vrf_not_exists +connection.autoconnect: yes +ipv4.method: manual +ipv4.addresses: 10.10.10.10/24 +ipv4.gateway: 10.10.10.1 +ipv4.ignore-auto-dns: no +ipv4.ignore-auto-routes: no +ipv4.never-default: no +ipv4.may-fail: yes +ipv6.method: auto +ipv6.ignore-auto-dns: no +ipv6.ignore-auto-routes: no +table: 10 +802-3-ethernet.mtu: auto +""" + def mocker_set(mocker, connection_exists=False, @@ -2035,6 +2066,13 @@ def mocked_loopback_connection_modify(mocker): )) +@pytest.fixture +def mocked_vrf_connection_unchanged(mocker): + mocker_set(mocker, + connection_exists=True, + execute_return=(0, TESTCASE_VRF_SHOW_OUTPUT, "")) + + @pytest.mark.parametrize('patch_ansible_module', TESTCASE_BOND, indirect=['patch_ansible_module']) def test_bond_connection_create(mocked_generic_connection_create, capfd): """ @@ -4911,3 +4949,76 @@ def test_add_second_ip4_address_to_loopback_connection(mocked_loopback_connectio results = json.loads(out) assert not results.get('failed') assert results['changed'] + + +@pytest.mark.parametrize('patch_ansible_module', TESTCASE_VRF, indirect=['patch_ansible_module']) +def test_create_vrf_con(mocked_generic_connection_create, capfd): + """ + Test if VRF created + """ + + with pytest.raises(SystemExit): + nmcli.main() + + assert nmcli.Nmcli.execute_command.call_count == 1 + arg_list = nmcli.Nmcli.execute_command.call_args_list + args, kwargs = arg_list[0] + + assert args[0][0] == '/usr/bin/nmcli' + assert args[0][1] == 'con' + assert args[0][2] == 'add' + assert args[0][3] == 'type' + assert args[0][4] == 'vrf' + assert args[0][5] == 'con-name' + assert args[0][6] == 'non_existent_nw_device' + + args_text = list(map(to_text, args[0])) + for param in ['ipv4.addresses', '10.10.10.10/24', 'ipv4.gateway', '10.10.10.1', 'table', '10']: + assert param in args_text + + out, err = capfd.readouterr() + results = json.loads(out) + assert not results.get('failed') + assert results['changed'] + + +@pytest.mark.parametrize('patch_ansible_module', TESTCASE_VRF, indirect=['patch_ansible_module']) +def test_mod_vrf_conn(mocked_generic_connection_modify, capfd): + """ + Test if VRF modified + """ + + with pytest.raises(SystemExit): + nmcli.main() + + assert nmcli.Nmcli.execute_command.call_count == 1 + arg_list = nmcli.Nmcli.execute_command.call_args_list + args, kwargs = arg_list[0] + + assert args[0][0] == '/usr/bin/nmcli' + assert args[0][1] == 'con' + assert args[0][2] == 'modify' + assert args[0][3] == 'non_existent_nw_device' + + args_text = list(map(to_text, args[0])) + for param in ['ipv4.addresses', '10.10.10.10/24', 'ipv4.gateway', '10.10.10.1', 'table', '10']: + assert param in args_text + + out, err = capfd.readouterr() + results = json.loads(out) + assert not results.get('failed') + assert results['changed'] + + +@pytest.mark.parametrize('patch_ansible_module', TESTCASE_VRF, indirect=['patch_ansible_module']) +def test_vrf_connection_unchanged(mocked_vrf_connection_unchanged, capfd): + """ + Test : VRF connection unchanged + """ + with pytest.raises(SystemExit): + nmcli.main() + + out, err = capfd.readouterr() + results = json.loads(out) + assert not results.get('failed') + assert not results['changed'] diff --git a/tests/unit/plugins/modules/test_opkg.py b/tests/unit/plugins/modules/test_opkg.py index cdc93ee887..dad3a8d3f1 100644 --- a/tests/unit/plugins/modules/test_opkg.py +++ b/tests/unit/plugins/modules/test_opkg.py @@ -8,7 +8,7 @@ __metaclass__ = type from ansible_collections.community.general.plugins.modules import opkg -from .helper import Helper, RunCommandMock +from .uthelper import UTHelper, RunCommandMock -Helper.from_module(opkg, __name__, mocks=[RunCommandMock]) +UTHelper.from_module(opkg, __name__, mocks=[RunCommandMock]) diff --git a/tests/unit/plugins/modules/test_opkg.yaml b/tests/unit/plugins/modules/test_opkg.yaml index e6f627457d..a437e54499 100644 --- a/tests/unit/plugins/modules/test_opkg.yaml +++ b/tests/unit/plugins/modules/test_opkg.yaml @@ -7,169 +7,169 @@ anchors: environ: &env-def {environ_update: {LANGUAGE: C, LC_ALL: C}, check_rc: false} test_cases: -- id: install_zlibdev - input: - name: zlib-dev - state: present - output: - msg: installed 1 package(s) - mocks: - run_command: - - command: [/testbin/opkg, --version] - environ: *env-def - rc: 0 - out: "" - err: "" - - command: [/testbin/opkg, list-installed, zlib-dev] - environ: *env-def - rc: 0 - out: "" - err: "" - - command: [/testbin/opkg, install, zlib-dev] - environ: *env-def - rc: 0 - out: | - Installing zlib-dev (1.2.11-6) to root... - Downloading https://downloads.openwrt.org/releases/22.03.0/packages/mips_24kc/base/zlib-dev_1.2.11-6_mips_24kc.ipk - Installing zlib (1.2.11-6) to root... - Downloading https://downloads.openwrt.org/releases/22.03.0/packages/mips_24kc/base/zlib_1.2.11-6_mips_24kc.ipk - Configuring zlib. - Configuring zlib-dev. - err: "" - - command: [/testbin/opkg, list-installed, zlib-dev] - environ: *env-def - rc: 0 - out: | - zlib-dev - 1.2.11-6 - err: "" -- id: install_zlibdev_present - input: - name: zlib-dev - state: present - output: - msg: package(s) already present - mocks: - run_command: - - command: [/testbin/opkg, --version] - environ: *env-def - rc: 0 - out: "" - err: "" - - command: [/testbin/opkg, list-installed, zlib-dev] - environ: *env-def - rc: 0 - out: | - zlib-dev - 1.2.11-6 - err: "" -- id: install_zlibdev_force_reinstall - input: - name: zlib-dev - state: present - force: reinstall - output: - msg: installed 1 package(s) - mocks: - run_command: - - command: [/testbin/opkg, --version] - environ: *env-def - rc: 0 - out: "" - err: "" - - command: [/testbin/opkg, list-installed, zlib-dev] - environ: *env-def - rc: 0 - out: | - zlib-dev - 1.2.11-6 - err: "" - - command: [/testbin/opkg, install, --force-reinstall, zlib-dev] - environ: *env-def - rc: 0 - out: | - Installing zlib-dev (1.2.11-6) to root... - Downloading https://downloads.openwrt.org/releases/22.03.0/packages/mips_24kc/base/zlib-dev_1.2.11-6_mips_24kc.ipk - Configuring zlib-dev. - err: "" - - command: [/testbin/opkg, list-installed, zlib-dev] - environ: *env-def - rc: 0 - out: | - zlib-dev - 1.2.11-6 - err: "" -- id: install_zlibdev_with_version - input: - name: zlib-dev=1.2.11-6 - state: present - output: - msg: installed 1 package(s) - mocks: - run_command: - - command: [/testbin/opkg, --version] - environ: *env-def - rc: 0 - out: "" - err: "" - - command: [/testbin/opkg, list-installed, zlib-dev] - environ: *env-def - rc: 0 - out: "" - err: "" - - command: [/testbin/opkg, install, zlib-dev=1.2.11-6] - environ: *env-def - rc: 0 - out: | - Installing zlib-dev (1.2.11-6) to root... - Downloading https://downloads.openwrt.org/releases/22.03.0/packages/mips_24kc/base/zlib-dev_1.2.11-6_mips_24kc.ipk - Installing zlib (1.2.11-6) to root... - Downloading https://downloads.openwrt.org/releases/22.03.0/packages/mips_24kc/base/zlib_1.2.11-6_mips_24kc.ipk - Configuring zlib. - Configuring zlib-dev. - err: "" - - command: [/testbin/opkg, list-installed, zlib-dev] - environ: *env-def - rc: 0 - out: "zlib-dev - 1.2.11-6 \n" # This output has the extra space at the end, to satisfy the behaviour of Yocto/OpenEmbedded's opkg - err: "" -- id: install_vim_updatecache - input: - name: vim-fuller - state: present - update_cache: true - output: - msg: installed 1 package(s) - mocks: - run_command: - - command: [/testbin/opkg, --version] - environ: *env-def - rc: 0 - out: "" - err: "" - - command: [/testbin/opkg, update] - environ: *env-def - rc: 0 - out: "" - err: "" - - command: [/testbin/opkg, list-installed, vim-fuller] - environ: *env-def - rc: 0 - out: "" - err: "" - - command: [/testbin/opkg, install, vim-fuller] - environ: *env-def - rc: 0 - out: | - Multiple packages (libgcc1 and libgcc1) providing same name marked HOLD or PREFER. Using latest. - Installing vim-fuller (9.0-1) to root... - Downloading https://downloads.openwrt.org/snapshots/packages/x86_64/packages/vim-fuller_9.0-1_x86_64.ipk - Installing terminfo (6.4-2) to root... - Downloading https://downloads.openwrt.org/snapshots/packages/x86_64/base/terminfo_6.4-2_x86_64.ipk - Installing libncurses6 (6.4-2) to root... - Downloading https://downloads.openwrt.org/snapshots/packages/x86_64/base/libncurses6_6.4-2_x86_64.ipk - Configuring terminfo. - Configuring libncurses6. - Configuring vim-fuller. - err: "" - - command: [/testbin/opkg, list-installed, vim-fuller] - environ: *env-def - rc: 0 - out: "vim-fuller - 9.0-1 \n" # This output has the extra space at the end, to satisfy the behaviour of Yocto/OpenEmbedded's opkg - err: "" + - id: install_zlibdev + input: + name: zlib-dev + state: present + output: + msg: installed 1 package(s) + mocks: + run_command: + - command: [/testbin/opkg, --version] + environ: *env-def + rc: 0 + out: '' + err: '' + - command: [/testbin/opkg, list-installed, zlib-dev] + environ: *env-def + rc: 0 + out: '' + err: '' + - command: [/testbin/opkg, install, zlib-dev] + environ: *env-def + rc: 0 + out: | + Installing zlib-dev (1.2.11-6) to root... + Downloading https://downloads.openwrt.org/releases/22.03.0/packages/mips_24kc/base/zlib-dev_1.2.11-6_mips_24kc.ipk + Installing zlib (1.2.11-6) to root... + Downloading https://downloads.openwrt.org/releases/22.03.0/packages/mips_24kc/base/zlib_1.2.11-6_mips_24kc.ipk + Configuring zlib. + Configuring zlib-dev. + err: '' + - command: [/testbin/opkg, list-installed, zlib-dev] + environ: *env-def + rc: 0 + out: | + zlib-dev - 1.2.11-6 + err: '' + - id: install_zlibdev_present + input: + name: zlib-dev + state: present + output: + msg: package(s) already present + mocks: + run_command: + - command: [/testbin/opkg, --version] + environ: *env-def + rc: 0 + out: '' + err: '' + - command: [/testbin/opkg, list-installed, zlib-dev] + environ: *env-def + rc: 0 + out: | + zlib-dev - 1.2.11-6 + err: '' + - id: install_zlibdev_force_reinstall + input: + name: zlib-dev + state: present + force: reinstall + output: + msg: installed 1 package(s) + mocks: + run_command: + - command: [/testbin/opkg, --version] + environ: *env-def + rc: 0 + out: '' + err: '' + - command: [/testbin/opkg, list-installed, zlib-dev] + environ: *env-def + rc: 0 + out: | + zlib-dev - 1.2.11-6 + err: '' + - command: [/testbin/opkg, install, --force-reinstall, zlib-dev] + environ: *env-def + rc: 0 + out: | + Installing zlib-dev (1.2.11-6) to root... + Downloading https://downloads.openwrt.org/releases/22.03.0/packages/mips_24kc/base/zlib-dev_1.2.11-6_mips_24kc.ipk + Configuring zlib-dev. + err: '' + - command: [/testbin/opkg, list-installed, zlib-dev] + environ: *env-def + rc: 0 + out: | + zlib-dev - 1.2.11-6 + err: '' + - id: install_zlibdev_with_version + input: + name: zlib-dev=1.2.11-6 + state: present + output: + msg: installed 1 package(s) + mocks: + run_command: + - command: [/testbin/opkg, --version] + environ: *env-def + rc: 0 + out: '' + err: '' + - command: [/testbin/opkg, list-installed, zlib-dev] + environ: *env-def + rc: 0 + out: '' + err: '' + - command: [/testbin/opkg, install, zlib-dev=1.2.11-6] + environ: *env-def + rc: 0 + out: | + Installing zlib-dev (1.2.11-6) to root... + Downloading https://downloads.openwrt.org/releases/22.03.0/packages/mips_24kc/base/zlib-dev_1.2.11-6_mips_24kc.ipk + Installing zlib (1.2.11-6) to root... + Downloading https://downloads.openwrt.org/releases/22.03.0/packages/mips_24kc/base/zlib_1.2.11-6_mips_24kc.ipk + Configuring zlib. + Configuring zlib-dev. + err: '' + - command: [/testbin/opkg, list-installed, zlib-dev] + environ: *env-def + rc: 0 + out: "zlib-dev - 1.2.11-6 \n" # This output has the extra space at the end, to satisfy the behaviour of Yocto/OpenEmbedded's opkg + err: '' + - id: install_vim_updatecache + input: + name: vim-fuller + state: present + update_cache: true + output: + msg: installed 1 package(s) + mocks: + run_command: + - command: [/testbin/opkg, --version] + environ: *env-def + rc: 0 + out: '' + err: '' + - command: [/testbin/opkg, update] + environ: *env-def + rc: 0 + out: '' + err: '' + - command: [/testbin/opkg, list-installed, vim-fuller] + environ: *env-def + rc: 0 + out: '' + err: '' + - command: [/testbin/opkg, install, vim-fuller] + environ: *env-def + rc: 0 + out: | + Multiple packages (libgcc1 and libgcc1) providing same name marked HOLD or PREFER. Using latest. + Installing vim-fuller (9.0-1) to root... + Downloading https://downloads.openwrt.org/snapshots/packages/x86_64/packages/vim-fuller_9.0-1_x86_64.ipk + Installing terminfo (6.4-2) to root... + Downloading https://downloads.openwrt.org/snapshots/packages/x86_64/base/terminfo_6.4-2_x86_64.ipk + Installing libncurses6 (6.4-2) to root... + Downloading https://downloads.openwrt.org/snapshots/packages/x86_64/base/libncurses6_6.4-2_x86_64.ipk + Configuring terminfo. + Configuring libncurses6. + Configuring vim-fuller. + err: '' + - command: [/testbin/opkg, list-installed, vim-fuller] + environ: *env-def + rc: 0 + out: "vim-fuller - 9.0-1 \n" # This output has the extra space at the end, to satisfy the behaviour of Yocto/OpenEmbedded's opkg + err: '' diff --git a/tests/unit/plugins/modules/test_puppet.py b/tests/unit/plugins/modules/test_puppet.py index d7c8f1bd0b..7a1a231693 100644 --- a/tests/unit/plugins/modules/test_puppet.py +++ b/tests/unit/plugins/modules/test_puppet.py @@ -14,7 +14,7 @@ __metaclass__ = type from ansible_collections.community.general.plugins.modules import puppet -from .helper import Helper, RunCommandMock +from .uthelper import UTHelper, RunCommandMock -Helper.from_module(puppet, __name__, mocks=[RunCommandMock]) +UTHelper.from_module(puppet, __name__, mocks=[RunCommandMock]) diff --git a/tests/unit/plugins/modules/test_puppet.yaml b/tests/unit/plugins/modules/test_puppet.yaml index 44cfb98d6f..df813c6231 100644 --- a/tests/unit/plugins/modules/test_puppet.yaml +++ b/tests/unit/plugins/modules/test_puppet.yaml @@ -7,228 +7,228 @@ anchors: environ: &env-def {environ_update: {LANGUAGE: C, LC_ALL: C}, check_rc: false} test_cases: -- id: puppet_agent_plain - input: {} - output: - changed: false - mocks: - run_command: - - command: [/testbin/puppet, config, print, agent_disabled_lockfile] - environ: *env-def - rc: 0 - out: "blah, anything" - err: "" - - command: - - /testbin/timeout - - -s - - "9" - - 30m - - /testbin/puppet - - agent - - --onetime - - --no-daemonize - - --no-usecacheonfailure - - --no-splay - - --detailed-exitcodes - - --verbose - - --color - - "0" - environ: *env-def - rc: 0 - out: "" - err: "" -- id: puppet_agent_certname - input: - certname: potatobox - output: - changed: false - mocks: - run_command: - - command: [/testbin/puppet, config, print, agent_disabled_lockfile] - environ: *env-def - rc: 0 - out: "blah, anything" - err: "" - - command: - - /testbin/timeout - - -s - - "9" - - 30m - - /testbin/puppet - - agent - - --onetime - - --no-daemonize - - --no-usecacheonfailure - - --no-splay - - --detailed-exitcodes - - --verbose - - --color - - "0" - - --certname=potatobox - environ: *env-def - rc: 0 - out: "" - err: "" -- id: puppet_agent_tags_abc - input: - tags: [a, b, c] - output: - changed: false - mocks: - run_command: - - command: [/testbin/puppet, config, print, agent_disabled_lockfile] - environ: *env-def - rc: 0 - out: "blah, anything" - err: "" - - command: - - /testbin/timeout - - -s - - "9" - - 30m - - /testbin/puppet - - agent - - --onetime - - --no-daemonize - - --no-usecacheonfailure - - --no-splay - - --detailed-exitcodes - - --verbose - - --color - - "0" - - --tags - - a,b,c - environ: *env-def - rc: 0 - out: "" - err: "" -- id: puppet_agent_skip_tags_def - input: - skip_tags: [d, e, f] - output: - changed: false - mocks: - run_command: - - command: [/testbin/puppet, config, print, agent_disabled_lockfile] - environ: *env-def - rc: 0 - out: "blah, anything" - err: "" - - command: - - /testbin/timeout - - -s - - "9" - - 30m - - /testbin/puppet - - agent - - --onetime - - --no-daemonize - - --no-usecacheonfailure - - --no-splay - - --detailed-exitcodes - - --verbose - - --color - - "0" - - --skip_tags - - d,e,f - environ: *env-def - rc: 0 - out: "" - err: "" -- id: puppet_agent_noop_false - input: - noop: false - output: - changed: false - mocks: - run_command: - - command: [/testbin/puppet, config, print, agent_disabled_lockfile] - environ: *env-def - rc: 0 - out: "blah, anything" - err: "" - - command: - - /testbin/timeout - - -s - - "9" - - 30m - - /testbin/puppet - - agent - - --onetime - - --no-daemonize - - --no-usecacheonfailure - - --no-splay - - --detailed-exitcodes - - --verbose - - --color - - "0" - - --no-noop - environ: *env-def - rc: 0 - out: "" - err: "" -- id: puppet_agent_noop_true - input: - noop: true - output: - changed: false - mocks: - run_command: - - command: [/testbin/puppet, config, print, agent_disabled_lockfile] - environ: *env-def - rc: 0 - out: "blah, anything" - err: "" - - command: - - /testbin/timeout - - -s - - "9" - - 30m - - /testbin/puppet - - agent - - --onetime - - --no-daemonize - - --no-usecacheonfailure - - --no-splay - - --detailed-exitcodes - - --verbose - - --color - - "0" - - --noop - environ: *env-def - rc: 0 - out: "" - err: "" -- id: puppet_agent_waitforlock - input: - waitforlock: 30 - output: - changed: false - mocks: - run_command: - - command: [/testbin/puppet, config, print, agent_disabled_lockfile] - environ: *env-def - rc: 0 - out: "blah, anything" - err: "" - - command: - - /testbin/timeout - - -s - - "9" - - 30m - - /testbin/puppet - - agent - - --onetime - - --no-daemonize - - --no-usecacheonfailure - - --no-splay - - --detailed-exitcodes - - --verbose - - --color - - "0" - - --waitforlock - - "30" - environ: *env-def - rc: 0 - out: "" - err: "" + - id: puppet_agent_plain + input: {} + output: + changed: false + mocks: + run_command: + - command: [/testbin/puppet, config, print, agent_disabled_lockfile] + environ: *env-def + rc: 0 + out: blah, anything + err: '' + - command: + - /testbin/timeout + - -s + - '9' + - 30m + - /testbin/puppet + - agent + - --onetime + - --no-daemonize + - --no-usecacheonfailure + - --no-splay + - --detailed-exitcodes + - --verbose + - --color + - '0' + environ: *env-def + rc: 0 + out: '' + err: '' + - id: puppet_agent_certname + input: + certname: potatobox + output: + changed: false + mocks: + run_command: + - command: [/testbin/puppet, config, print, agent_disabled_lockfile] + environ: *env-def + rc: 0 + out: blah, anything + err: '' + - command: + - /testbin/timeout + - -s + - '9' + - 30m + - /testbin/puppet + - agent + - --onetime + - --no-daemonize + - --no-usecacheonfailure + - --no-splay + - --detailed-exitcodes + - --verbose + - --color + - '0' + - --certname=potatobox + environ: *env-def + rc: 0 + out: '' + err: '' + - id: puppet_agent_tags_abc + input: + tags: [a, b, c] + output: + changed: false + mocks: + run_command: + - command: [/testbin/puppet, config, print, agent_disabled_lockfile] + environ: *env-def + rc: 0 + out: blah, anything + err: '' + - command: + - /testbin/timeout + - -s + - '9' + - 30m + - /testbin/puppet + - agent + - --onetime + - --no-daemonize + - --no-usecacheonfailure + - --no-splay + - --detailed-exitcodes + - --verbose + - --color + - '0' + - --tags + - a,b,c + environ: *env-def + rc: 0 + out: '' + err: '' + - id: puppet_agent_skip_tags_def + input: + skip_tags: [d, e, f] + output: + changed: false + mocks: + run_command: + - command: [/testbin/puppet, config, print, agent_disabled_lockfile] + environ: *env-def + rc: 0 + out: blah, anything + err: '' + - command: + - /testbin/timeout + - -s + - '9' + - 30m + - /testbin/puppet + - agent + - --onetime + - --no-daemonize + - --no-usecacheonfailure + - --no-splay + - --detailed-exitcodes + - --verbose + - --color + - '0' + - --skip_tags + - d,e,f + environ: *env-def + rc: 0 + out: '' + err: '' + - id: puppet_agent_noop_false + input: + noop: false + output: + changed: false + mocks: + run_command: + - command: [/testbin/puppet, config, print, agent_disabled_lockfile] + environ: *env-def + rc: 0 + out: blah, anything + err: '' + - command: + - /testbin/timeout + - -s + - '9' + - 30m + - /testbin/puppet + - agent + - --onetime + - --no-daemonize + - --no-usecacheonfailure + - --no-splay + - --detailed-exitcodes + - --verbose + - --color + - '0' + - --no-noop + environ: *env-def + rc: 0 + out: '' + err: '' + - id: puppet_agent_noop_true + input: + noop: true + output: + changed: false + mocks: + run_command: + - command: [/testbin/puppet, config, print, agent_disabled_lockfile] + environ: *env-def + rc: 0 + out: blah, anything + err: '' + - command: + - /testbin/timeout + - -s + - '9' + - 30m + - /testbin/puppet + - agent + - --onetime + - --no-daemonize + - --no-usecacheonfailure + - --no-splay + - --detailed-exitcodes + - --verbose + - --color + - '0' + - --noop + environ: *env-def + rc: 0 + out: '' + err: '' + - id: puppet_agent_waitforlock + input: + waitforlock: 30 + output: + changed: false + mocks: + run_command: + - command: [/testbin/puppet, config, print, agent_disabled_lockfile] + environ: *env-def + rc: 0 + out: blah, anything + err: '' + - command: + - /testbin/timeout + - -s + - '9' + - 30m + - /testbin/puppet + - agent + - --onetime + - --no-daemonize + - --no-usecacheonfailure + - --no-splay + - --detailed-exitcodes + - --verbose + - --color + - '0' + - --waitforlock + - '30' + environ: *env-def + rc: 0 + out: '' + err: '' diff --git a/tests/unit/plugins/modules/test_snap.py b/tests/unit/plugins/modules/test_snap.py index 97e3e8700e..e1897be5f2 100644 --- a/tests/unit/plugins/modules/test_snap.py +++ b/tests/unit/plugins/modules/test_snap.py @@ -9,7 +9,7 @@ __metaclass__ = type import sys from ansible_collections.community.general.plugins.modules import snap -from .helper import Helper, RunCommandMock +from .uthelper import UTHelper, RunCommandMock issue_6803_status_out = """Name Version Rev Tracking Publisher Notes @@ -386,117 +386,119 @@ ubuntu 24.04 kernel 6.8.0-49-generic """ -TEST_CASES = [ - dict( - id="simple case", - input={"name": ["hello-world"]}, - output=dict(changed=True, snaps_installed=["hello-world"]), - flags={}, - mocks=dict( - run_command=[ - dict( - command=['/testbin/snap', 'version'], - environ=default_env, - rc=0, - out=default_version_out, - err="", - ), - dict( - command=['/testbin/snap', 'info', 'hello-world'], - environ=default_env, - rc=0, - out='name: hello-world\n', - err="", - ), - dict( - command=['/testbin/snap', 'list'], - environ=default_env, - rc=0, - out="", - err="", - ), - dict( - command=['/testbin/snap', 'install', 'hello-world'], - environ=default_env, - rc=0, - out="hello-world (12345/stable) v12345 from Canonical** installed\n", - err="", - ), - dict( - command=['/testbin/snap', 'list'], - environ=default_env, - rc=0, - out=( - "Name Version Rev Tracking Publisher Notes" - "core20 20220826 1623 latest/stable canonical** base" - "lxd 5.6-794016a 23680 latest/stable/… canonical** -" - "hello-world 5.6-794016a 23680 latest/stable/… canonical** -" - "snapd 2.57.4 17336 latest/stable canonical** snapd" - ""), - err="", - ), - ], +TEST_SPEC = dict( + test_cases=[ + dict( + id="simple case", + input={"name": ["hello-world"]}, + output=dict(changed=True, snaps_installed=["hello-world"]), + flags={}, + mocks=dict( + run_command=[ + dict( + command=['/testbin/snap', 'version'], + environ=default_env, + rc=0, + out=default_version_out, + err="", + ), + dict( + command=['/testbin/snap', 'info', 'hello-world'], + environ=default_env, + rc=0, + out='name: hello-world\n', + err="", + ), + dict( + command=['/testbin/snap', 'list'], + environ=default_env, + rc=0, + out="", + err="", + ), + dict( + command=['/testbin/snap', 'install', 'hello-world'], + environ=default_env, + rc=0, + out="hello-world (12345/stable) v12345 from Canonical** installed\n", + err="", + ), + dict( + command=['/testbin/snap', 'list'], + environ=default_env, + rc=0, + out=( + "Name Version Rev Tracking Publisher Notes" + "core20 20220826 1623 latest/stable canonical** base" + "lxd 5.6-794016a 23680 latest/stable/… canonical** -" + "hello-world 5.6-794016a 23680 latest/stable/… canonical** -" + "snapd 2.57.4 17336 latest/stable canonical** snapd" + ""), + err="", + ), + ], + ), ), - ), - dict( - id="issue_6803", - input={"name": ["microk8s", "kubectl"], "classic": True}, - output=dict(changed=True, snaps_installed=["microk8s", "kubectl"]), - flags={}, - mocks=dict( - run_command=[ - dict( - command=['/testbin/snap', 'version'], - environ=default_env, - rc=0, - out=default_version_out, - err="", - ), - dict( - command=['/testbin/snap', 'info', 'microk8s', 'kubectl'], - environ=default_env, - rc=0, - out='name: microk8s\n---\nname: kubectl\n', - err="", - ), - dict( - command=['/testbin/snap', 'list'], - environ=default_env, - rc=0, - out=issue_6803_status_out, - err="", - ), - dict( - command=['/testbin/snap', 'install', '--classic', 'microk8s'], - environ=default_env, - rc=0, - out=issue_6803_microk8s_out, - err="", - ), - dict( - command=['/testbin/snap', 'install', '--classic', 'kubectl'], - environ=default_env, - rc=0, - out=issue_6803_kubectl_out, - err="", - ), - dict( - command=['/testbin/snap', 'list'], - environ=default_env, - rc=0, - out=( - "Name Version Rev Tracking Publisher Notes" - "core20 20220826 1623 latest/stable canonical** base" - "lxd 5.6-794016a 23680 latest/stable/… canonical** -" - "microk8s 5.6-794016a 23680 latest/stable/… canonical** -" - "kubectl 5.6-794016a 23680 latest/stable/… canonical** -" - "snapd 2.57.4 17336 latest/stable canonical** snapd" - ""), - err="", - ), - ], + dict( + id="issue_6803", + input={"name": ["microk8s", "kubectl"], "classic": True}, + output=dict(changed=True, snaps_installed=["microk8s", "kubectl"]), + flags={}, + mocks=dict( + run_command=[ + dict( + command=['/testbin/snap', 'version'], + environ=default_env, + rc=0, + out=default_version_out, + err="", + ), + dict( + command=['/testbin/snap', 'info', 'microk8s', 'kubectl'], + environ=default_env, + rc=0, + out='name: microk8s\n---\nname: kubectl\n', + err="", + ), + dict( + command=['/testbin/snap', 'list'], + environ=default_env, + rc=0, + out=issue_6803_status_out, + err="", + ), + dict( + command=['/testbin/snap', 'install', '--classic', 'microk8s'], + environ=default_env, + rc=0, + out=issue_6803_microk8s_out, + err="", + ), + dict( + command=['/testbin/snap', 'install', '--classic', 'kubectl'], + environ=default_env, + rc=0, + out=issue_6803_kubectl_out, + err="", + ), + dict( + command=['/testbin/snap', 'list'], + environ=default_env, + rc=0, + out=( + "Name Version Rev Tracking Publisher Notes" + "core20 20220826 1623 latest/stable canonical** base" + "lxd 5.6-794016a 23680 latest/stable/… canonical** -" + "microk8s 5.6-794016a 23680 latest/stable/… canonical** -" + "kubectl 5.6-794016a 23680 latest/stable/… canonical** -" + "snapd 2.57.4 17336 latest/stable canonical** snapd" + ""), + err="", + ), + ], + ), ), - ), -] + ] +) -Helper.from_spec(sys.modules[__name__], snap, TEST_CASES, mocks=[RunCommandMock]) +UTHelper.from_spec(snap, sys.modules[__name__], TEST_SPEC, mocks=[RunCommandMock]) diff --git a/tests/unit/plugins/modules/test_xfconf.py b/tests/unit/plugins/modules/test_xfconf.py index 550345b112..ea89fb93fe 100644 --- a/tests/unit/plugins/modules/test_xfconf.py +++ b/tests/unit/plugins/modules/test_xfconf.py @@ -14,7 +14,7 @@ __metaclass__ = type from ansible_collections.community.general.plugins.modules import xfconf -from .helper import Helper, RunCommandMock +from .uthelper import UTHelper, RunCommandMock -Helper.from_module(xfconf, __name__, mocks=[RunCommandMock]) +UTHelper.from_module(xfconf, __name__, mocks=[RunCommandMock]) diff --git a/tests/unit/plugins/modules/test_xfconf.yaml b/tests/unit/plugins/modules/test_xfconf.yaml index f306bfdfa0..2ba274fdfb 100644 --- a/tests/unit/plugins/modules/test_xfconf.yaml +++ b/tests/unit/plugins/modules/test_xfconf.yaml @@ -14,224 +14,224 @@ anchors: Please report bugs to . test_cases: -- id: test_missing_input - input: {} - output: - failed: true - msg: "missing required arguments: channel, property" -- id: test_property_set_property - input: - channel: xfwm4 - property: /general/inactive_opacity - state: present - value_type: int - value: 90 - output: - changed: true - previous_value: '100' - type: int - value: '90' - version: "4.18.1" - mocks: - run_command: - - command: [/testbin/xfconf-query, --version] - environ: *env-def - rc: 0 - out: *version-output - err: "" - - command: [/testbin/xfconf-query, --channel, xfwm4, --property, /general/inactive_opacity] - environ: *env-def - rc: 0 - out: "100\n" - err: "" - - command: [/testbin/xfconf-query, --channel, xfwm4, --property, /general/inactive_opacity, --create, --type, int, --set, '90'] - environ: *env-def - rc: 0 - out: "" - err: "" -- id: test_property_set_property_same_value - input: - channel: xfwm4 - property: /general/inactive_opacity - state: present - value_type: int - value: 90 - output: - changed: false - previous_value: '90' - type: int - value: '90' - version: "4.18.1" - mocks: - run_command: - - command: [/testbin/xfconf-query, --version] - environ: *env-def - rc: 0 - out: *version-output - err: "" - - command: [/testbin/xfconf-query, --channel, xfwm4, --property, /general/inactive_opacity] - environ: *env-def - rc: 0 - out: "90\n" - err: "" - - command: [/testbin/xfconf-query, --channel, xfwm4, --property, /general/inactive_opacity, --create, --type, int, --set, '90'] - environ: *env-def - rc: 0 - out: "" - err: "" -- id: test_property_set_property_bool_false - input: - channel: xfce4-session - property: /general/SaveOnExit - state: present - value_type: bool - value: false - output: - changed: true - previous_value: 'true' - type: bool - value: 'False' - version: "4.18.1" - mocks: - run_command: - - command: [/testbin/xfconf-query, --version] - environ: *env-def - rc: 0 - out: *version-output - err: "" - - command: [/testbin/xfconf-query, --channel, xfce4-session, --property, /general/SaveOnExit] - environ: *env-def - rc: 0 - out: "true\n" - err: "" - - command: [/testbin/xfconf-query, --channel, xfce4-session, --property, /general/SaveOnExit, --create, --type, bool, --set, 'false'] - environ: *env-def - rc: 0 - out: "false\n" - err: "" -- id: test_property_set_array - input: - channel: xfwm4 - property: /general/workspace_names - state: present - value_type: string - value: [A, B, C] - output: - changed: true - previous_value: [Main, Work, Tmp] - type: [string, string, string] - value: [A, B, C] - version: "4.18.1" - mocks: - run_command: - - command: [/testbin/xfconf-query, --version] - environ: *env-def - rc: 0 - out: *version-output - err: "" - - command: [/testbin/xfconf-query, --channel, xfwm4, --property, /general/workspace_names] - environ: *env-def - rc: 0 - out: "Value is an array with 3 items:\n\nMain\nWork\nTmp\n" - err: "" - - command: - - /testbin/xfconf-query - - --channel - - xfwm4 - - --property - - /general/workspace_names - - --create - - --force-array - - --type - - string - - --set - - A - - --type - - string - - --set - - B - - --type - - string - - --set - - C - environ: *env-def - rc: 0 - out: "" - err: "" -- id: test_property_set_array_to_same_value - input: - channel: xfwm4 - property: /general/workspace_names - state: present - value_type: string - value: [A, B, C] - output: - changed: false - previous_value: [A, B, C] - type: [string, string, string] - value: [A, B, C] - version: "4.18.1" - mocks: - run_command: - - command: [/testbin/xfconf-query, --version] - environ: *env-def - rc: 0 - out: *version-output - err: "" - - command: [/testbin/xfconf-query, --channel, xfwm4, --property, /general/workspace_names] - environ: *env-def - rc: 0 - out: "Value is an array with 3 items:\n\nA\nB\nC\n" - err: "" - - command: - - /testbin/xfconf-query - - --channel - - xfwm4 - - --property - - /general/workspace_names - - --create - - --force-array - - --type - - string - - --set - - A - - --type - - string - - --set - - B - - --type - - string - - --set - - C - environ: *env-def - rc: 0 - out: "" - err: "" -- id: test_property_reset_value - input: - channel: xfwm4 - property: /general/workspace_names - state: absent - output: - changed: true - previous_value: [A, B, C] - type: - value: - version: "4.18.1" - mocks: - run_command: - - command: [/testbin/xfconf-query, --version] - environ: *env-def - rc: 0 - out: *version-output - err: "" - - command: [/testbin/xfconf-query, --channel, xfwm4, --property, /general/workspace_names] - environ: *env-def - rc: 0 - out: "Value is an array with 3 items:\n\nA\nB\nC\n" - err: "" - - command: [/testbin/xfconf-query, --channel, xfwm4, --property, /general/workspace_names, --reset] - environ: *env-def - rc: 0 - out: "" - err: "" + - id: test_missing_input + input: {} + output: + failed: true + msg: 'missing required arguments: channel, property' + - id: test_property_set_property + input: + channel: xfwm4 + property: /general/inactive_opacity + state: present + value_type: int + value: 90 + output: + changed: true + previous_value: '100' + type: int + value: '90' + version: 4.18.1 + mocks: + run_command: + - command: [/testbin/xfconf-query, --version] + environ: *env-def + rc: 0 + out: *version-output + err: '' + - command: [/testbin/xfconf-query, --channel, xfwm4, --property, /general/inactive_opacity] + environ: *env-def + rc: 0 + out: "100\n" + err: '' + - command: [/testbin/xfconf-query, --channel, xfwm4, --property, /general/inactive_opacity, --create, --type, int, --set, '90'] + environ: *env-def + rc: 0 + out: '' + err: '' + - id: test_property_set_property_same_value + input: + channel: xfwm4 + property: /general/inactive_opacity + state: present + value_type: int + value: 90 + output: + changed: false + previous_value: '90' + type: int + value: '90' + version: 4.18.1 + mocks: + run_command: + - command: [/testbin/xfconf-query, --version] + environ: *env-def + rc: 0 + out: *version-output + err: '' + - command: [/testbin/xfconf-query, --channel, xfwm4, --property, /general/inactive_opacity] + environ: *env-def + rc: 0 + out: "90\n" + err: '' + - command: [/testbin/xfconf-query, --channel, xfwm4, --property, /general/inactive_opacity, --create, --type, int, --set, '90'] + environ: *env-def + rc: 0 + out: '' + err: '' + - id: test_property_set_property_bool_false + input: + channel: xfce4-session + property: /general/SaveOnExit + state: present + value_type: bool + value: false + output: + changed: true + previous_value: 'true' + type: bool + value: 'False' + version: 4.18.1 + mocks: + run_command: + - command: [/testbin/xfconf-query, --version] + environ: *env-def + rc: 0 + out: *version-output + err: '' + - command: [/testbin/xfconf-query, --channel, xfce4-session, --property, /general/SaveOnExit] + environ: *env-def + rc: 0 + out: "true\n" + err: '' + - command: [/testbin/xfconf-query, --channel, xfce4-session, --property, /general/SaveOnExit, --create, --type, bool, --set, 'false'] + environ: *env-def + rc: 0 + out: "false\n" + err: '' + - id: test_property_set_array + input: + channel: xfwm4 + property: /general/workspace_names + state: present + value_type: string + value: [A, B, C] + output: + changed: true + previous_value: [Main, Work, Tmp] + type: [string, string, string] + value: [A, B, C] + version: 4.18.1 + mocks: + run_command: + - command: [/testbin/xfconf-query, --version] + environ: *env-def + rc: 0 + out: *version-output + err: '' + - command: [/testbin/xfconf-query, --channel, xfwm4, --property, /general/workspace_names] + environ: *env-def + rc: 0 + out: "Value is an array with 3 items:\n\nMain\nWork\nTmp\n" + err: '' + - command: + - /testbin/xfconf-query + - --channel + - xfwm4 + - --property + - /general/workspace_names + - --create + - --force-array + - --type + - string + - --set + - A + - --type + - string + - --set + - B + - --type + - string + - --set + - C + environ: *env-def + rc: 0 + out: '' + err: '' + - id: test_property_set_array_to_same_value + input: + channel: xfwm4 + property: /general/workspace_names + state: present + value_type: string + value: [A, B, C] + output: + changed: false + previous_value: [A, B, C] + type: [string, string, string] + value: [A, B, C] + version: 4.18.1 + mocks: + run_command: + - command: [/testbin/xfconf-query, --version] + environ: *env-def + rc: 0 + out: *version-output + err: '' + - command: [/testbin/xfconf-query, --channel, xfwm4, --property, /general/workspace_names] + environ: *env-def + rc: 0 + out: "Value is an array with 3 items:\n\nA\nB\nC\n" + err: '' + - command: + - /testbin/xfconf-query + - --channel + - xfwm4 + - --property + - /general/workspace_names + - --create + - --force-array + - --type + - string + - --set + - A + - --type + - string + - --set + - B + - --type + - string + - --set + - C + environ: *env-def + rc: 0 + out: '' + err: '' + - id: test_property_reset_value + input: + channel: xfwm4 + property: /general/workspace_names + state: absent + output: + changed: true + previous_value: [A, B, C] + type: + value: + version: 4.18.1 + mocks: + run_command: + - command: [/testbin/xfconf-query, --version] + environ: *env-def + rc: 0 + out: *version-output + err: '' + - command: [/testbin/xfconf-query, --channel, xfwm4, --property, /general/workspace_names] + environ: *env-def + rc: 0 + out: "Value is an array with 3 items:\n\nA\nB\nC\n" + err: '' + - command: [/testbin/xfconf-query, --channel, xfwm4, --property, /general/workspace_names, --reset] + environ: *env-def + rc: 0 + out: '' + err: '' diff --git a/tests/unit/plugins/modules/test_xfconf_info.py b/tests/unit/plugins/modules/test_xfconf_info.py index 4cdb92b305..d65e7035cf 100644 --- a/tests/unit/plugins/modules/test_xfconf_info.py +++ b/tests/unit/plugins/modules/test_xfconf_info.py @@ -7,7 +7,7 @@ __metaclass__ = type from ansible_collections.community.general.plugins.modules import xfconf_info -from .helper import Helper, RunCommandMock +from .uthelper import UTHelper, RunCommandMock -Helper.from_module(xfconf_info, __name__, mocks=[RunCommandMock]) +UTHelper.from_module(xfconf_info, __name__, mocks=[RunCommandMock]) diff --git a/tests/unit/plugins/modules/test_xfconf_info.yaml b/tests/unit/plugins/modules/test_xfconf_info.yaml index 8e7ae667c4..d4d0deb39f 100644 --- a/tests/unit/plugins/modules/test_xfconf_info.yaml +++ b/tests/unit/plugins/modules/test_xfconf_info.yaml @@ -14,114 +14,114 @@ anchors: Please report bugs to . test_cases: -- id: test_simple_property_get - input: - channel: xfwm4 - property: /general/inactive_opacity - output: - value: '100' - is_array: false - version: "4.18.1" - mocks: - run_command: - - command: [/testbin/xfconf-query, --version] - environ: *env-def - rc: 0 - out: *version-output - err: "" - - command: [/testbin/xfconf-query, --channel, xfwm4, --property, /general/inactive_opacity] - environ: *env-def - rc: 0 - out: "100\n" - err: "" -- id: test_simple_property_get_nonexistent - input: - channel: xfwm4 - property: /general/i_dont_exist - output: - version: "4.18.1" - mocks: - run_command: - - command: [/testbin/xfconf-query, --version] - environ: *env-def - rc: 0 - out: *version-output - err: "" - - command: [/testbin/xfconf-query, --channel, xfwm4, --property, /general/i_dont_exist] - environ: *env-def - rc: 1 - out: "" - err: 'Property "/general/i_dont_exist" does not exist on channel "xfwm4".\n' -- id: test_property_no_channel - input: - property: /general/i_dont_exist - output: - failed: true - msg: "missing parameter(s) required by 'property': channel" -- id: test_property_get_array - input: - channel: xfwm4 - property: /general/workspace_names - output: - is_array: true - value_array: [Main, Work, Tmp] - version: "4.18.1" - mocks: - run_command: - - command: [/testbin/xfconf-query, --version] - environ: *env-def - rc: 0 - out: *version-output - err: "" - - command: [/testbin/xfconf-query, --channel, xfwm4, --property, /general/workspace_names] - environ: *env-def - rc: 0 - out: "Value is an array with 3 items:\n\nMain\nWork\nTmp\n" - err: "" -- id: get_channels - input: {} - output: - channels: [a, b, c] - version: "4.18.1" - mocks: - run_command: - - command: [/testbin/xfconf-query, --version] - environ: *env-def - rc: 0 - out: *version-output - err: "" - - command: [/testbin/xfconf-query, --list] - environ: *env-def - rc: 0 - out: "Channels:\n a\n b\n c\n" - err: "" -- id: get_properties - input: - channel: xfwm4 - output: - properties: - - /general/wrap_cycle - - /general/wrap_layout - - /general/wrap_resistance - - /general/wrap_windows - - /general/wrap_workspaces - - /general/zoom_desktop - version: "4.18.1" - mocks: - run_command: - - command: [/testbin/xfconf-query, --version] - environ: *env-def - rc: 0 - out: *version-output - err: "" - - command: [/testbin/xfconf-query, --list, --channel, xfwm4] - environ: *env-def - rc: 0 - out: | - /general/wrap_cycle - /general/wrap_layout - /general/wrap_resistance - /general/wrap_windows - /general/wrap_workspaces - /general/zoom_desktop - err: "" + - id: test_simple_property_get + input: + channel: xfwm4 + property: /general/inactive_opacity + output: + value: '100' + is_array: false + version: 4.18.1 + mocks: + run_command: + - command: [/testbin/xfconf-query, --version] + environ: *env-def + rc: 0 + out: *version-output + err: '' + - command: [/testbin/xfconf-query, --channel, xfwm4, --property, /general/inactive_opacity] + environ: *env-def + rc: 0 + out: "100\n" + err: '' + - id: test_simple_property_get_nonexistent + input: + channel: xfwm4 + property: /general/i_dont_exist + output: + version: 4.18.1 + mocks: + run_command: + - command: [/testbin/xfconf-query, --version] + environ: *env-def + rc: 0 + out: *version-output + err: '' + - command: [/testbin/xfconf-query, --channel, xfwm4, --property, /general/i_dont_exist] + environ: *env-def + rc: 1 + out: '' + err: Property "/general/i_dont_exist" does not exist on channel "xfwm4".\n + - id: test_property_no_channel + input: + property: /general/i_dont_exist + output: + failed: true + msg: "missing parameter(s) required by 'property': channel" + - id: test_property_get_array + input: + channel: xfwm4 + property: /general/workspace_names + output: + is_array: true + value_array: [Main, Work, Tmp] + version: 4.18.1 + mocks: + run_command: + - command: [/testbin/xfconf-query, --version] + environ: *env-def + rc: 0 + out: *version-output + err: '' + - command: [/testbin/xfconf-query, --channel, xfwm4, --property, /general/workspace_names] + environ: *env-def + rc: 0 + out: "Value is an array with 3 items:\n\nMain\nWork\nTmp\n" + err: '' + - id: get_channels + input: {} + output: + channels: [a, b, c] + version: 4.18.1 + mocks: + run_command: + - command: [/testbin/xfconf-query, --version] + environ: *env-def + rc: 0 + out: *version-output + err: '' + - command: [/testbin/xfconf-query, --list] + environ: *env-def + rc: 0 + out: "Channels:\n a\n b\n c\n" + err: '' + - id: get_properties + input: + channel: xfwm4 + output: + properties: + - /general/wrap_cycle + - /general/wrap_layout + - /general/wrap_resistance + - /general/wrap_windows + - /general/wrap_workspaces + - /general/zoom_desktop + version: 4.18.1 + mocks: + run_command: + - command: [/testbin/xfconf-query, --version] + environ: *env-def + rc: 0 + out: *version-output + err: '' + - command: [/testbin/xfconf-query, --list, --channel, xfwm4] + environ: *env-def + rc: 0 + out: | + /general/wrap_cycle + /general/wrap_layout + /general/wrap_resistance + /general/wrap_windows + /general/wrap_workspaces + /general/zoom_desktop + err: '' diff --git a/tests/unit/plugins/modules/helper.py b/tests/unit/plugins/modules/uthelper.py similarity index 76% rename from tests/unit/plugins/modules/helper.py rename to tests/unit/plugins/modules/uthelper.py index 8071bc2aa9..ceb1d5f620 100644 --- a/tests/unit/plugins/modules/helper.py +++ b/tests/unit/plugins/modules/uthelper.py @@ -6,6 +6,7 @@ from __future__ import (absolute_import, division, print_function) __metaclass__ = type +import os import sys import json @@ -13,49 +14,49 @@ import yaml import pytest -from ansible.module_utils.common._collections_compat import Sequence - - -class Helper(object): +class UTHelper(object): TEST_SPEC_VALID_SECTIONS = ["anchors", "test_cases"] @staticmethod - def from_spec(test_module, ansible_module, test_spec, mocks=None): - helper = Helper(test_module, ansible_module, test_spec=test_spec, mocks=mocks) + def from_spec(ansible_module, test_module, test_spec, mocks=None): + helper = UTHelper(ansible_module, test_module, test_spec=test_spec, mocks=mocks) return helper @staticmethod - def from_file(test_module, ansible_module, filename, mocks=None): - with open(filename, "r") as test_cases: - test_spec = yaml.safe_load(test_cases) - return Helper.from_spec(test_module, ansible_module, test_spec, mocks) + def from_file(ansible_module, test_module, test_spec_filehandle, mocks=None): + test_spec = yaml.safe_load(test_spec_filehandle) + return UTHelper.from_spec(ansible_module, test_module, test_spec, mocks) + # @TODO: calculate the test_module_name automatically, remove one more parameter @staticmethod - def from_module(ansible_module, test_module_name, test_spec=None, mocks=None): + def from_module(ansible_module, test_module_name, mocks=None): test_module = sys.modules[test_module_name] - if test_spec is None: - test_spec = test_module.__file__.replace('.py', '.yaml') - return Helper.from_file(test_module, ansible_module, test_spec) + extensions = ['.yaml', '.yml'] + for ext in extensions: + test_spec_filename = test_module.__file__.replace('.py', ext) + if os.path.exists(test_spec_filename): + with open(test_spec_filename, "r") as test_spec_filehandle: + return UTHelper.from_file(ansible_module, test_module, test_spec_filehandle, mocks=mocks) + + raise Exception("Cannot find test case file for {0} with one of the extensions: {1}".format(test_module.__file__, extensions)) def add_func_to_test_module(self, name, func): setattr(self.test_module, name, func) - def __init__(self, test_module, ansible_module, test_spec, mocks=None): - self.test_module = test_module + def __init__(self, ansible_module, test_module, test_spec, mocks=None): self.ansible_module = ansible_module + self.test_module = test_module self.test_cases = [] self.fixtures = {} - if isinstance(test_spec, Sequence): - test_cases = test_spec - else: # it is a dict - test_cases = test_spec['test_cases'] - spec_diff = set(test_spec.keys()) - set(self.TEST_SPEC_VALID_SECTIONS) - if spec_diff: - raise ValueError("Test specification contain unknown keys: {0}".format(", ".join(spec_diff))) + + spec_diff = set(test_spec.keys()) - set(self.TEST_SPEC_VALID_SECTIONS) + if spec_diff: + raise ValueError("Test specification contain unknown keys: {0}".format(", ".join(spec_diff))) + self.mocks_map = {m.name: m for m in mocks} if mocks else {} - for test_case in test_cases: - tc = ModuleTestCase.make_test_case(test_case, test_module, self.mocks_map) + for spec_test_case in test_spec['test_cases']: + tc = ModuleTestCase.make_test_case(spec_test_case, test_module, self.mocks_map) self.test_cases.append(tc) self.fixtures.update(tc.fixtures) self.set_test_func() @@ -72,7 +73,13 @@ class Helper(object): """ Run unit tests for each test case in self.test_cases """ - patch_ansible_module(test_case.input) + args = {} + args.update(test_case.input) + if test_case.flags.get("check"): + args["_ansible_check_mode"] = test_case.flags.get("check") + if test_case.flags.get("diff"): + args["_ansible_diff"] = test_case.flags.get("diff") + patch_ansible_module(args) self.runner.run(mocker, capfd, test_case) self.add_func_to_test_module("test_module", _test_module) @@ -145,26 +152,19 @@ class ModuleTestCase: mocks=test_case_spec.get("mocks", {}), flags=test_case_spec.get("flags", {}) ) - tc.build_mocks(test_module, mocks_map) + tc.build_mocks(mocks_map) return tc - def build_mocks(self, test_module, mocks_map): + def build_mocks(self, mocks_map): for mock_name, mock_spec in self.mock_specs.items(): - mock_class = mocks_map.get(mock_name, self.get_mock_class(test_module, mock_name)) + try: + mock_class = mocks_map[mock_name] + except KeyError: + raise Exception("Cannot find TestCaseMock class for: {0}".format(mock_name)) self.mocks[mock_name] = mock_class.build_mock(mock_spec) self._fixtures.update(self.mocks[mock_name].fixtures()) - @staticmethod - def get_mock_class(test_module, mock): - try: - class_name = "".join(x.capitalize() for x in mock.split("_")) + "Mock" - plugin_class = getattr(test_module, class_name) - assert issubclass(plugin_class, TestCaseMock), "Class {0} is not a subclass of TestCaseMock".format(class_name) - return plugin_class - except AttributeError: - raise ValueError("Cannot find class {0} for mock {1}".format(class_name, mock)) - @property def fixtures(self): return dict(self._fixtures) @@ -200,10 +200,6 @@ class ModuleTestCase: class TestCaseMock: - @property - def name(self): - raise NotImplementedError() - @classmethod def build_mock(cls, mock_specs): return cls(mock_specs) @@ -222,9 +218,7 @@ class TestCaseMock: class RunCommandMock(TestCaseMock): - @property - def name(self): - return "run_command" + name = "run_command" def __str__(self): return "".format(specs=self.mock_specs)