mirror of
https://github.com/ansible-collections/community.general.git
synced 2026-04-30 02:16:50 +00:00
Compare commits
46 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1357e47f92 | ||
|
|
cc6d4209d4 | ||
|
|
01134d4625 | ||
|
|
16089ab2de | ||
|
|
0da4607c7f | ||
|
|
46cbf60c2d | ||
|
|
e7d86f5add | ||
|
|
ee4c76fa43 | ||
|
|
095d09ec12 | ||
|
|
d9ed00fb12 | ||
|
|
94bb204e29 | ||
|
|
9b1f450102 | ||
|
|
dd3bc067f5 | ||
|
|
15916cd61f | ||
|
|
02a257569a | ||
|
|
c486e42faa | ||
|
|
7f7e622262 | ||
|
|
e1551b3d34 | ||
|
|
a3bc0535a5 | ||
|
|
9e59665bee | ||
|
|
30b29d24ab | ||
|
|
d5efc3f13a | ||
|
|
d237faa447 | ||
|
|
65ce979d4a | ||
|
|
938367b67a | ||
|
|
578df1b054 | ||
|
|
0b494a5d2d | ||
|
|
f92043c7f5 | ||
|
|
839336c21d | ||
|
|
2a5e4b8a46 | ||
|
|
fae1dbc198 | ||
|
|
dc7aba3bca | ||
|
|
03c66d0db4 | ||
|
|
5707fc1b33 | ||
|
|
830e3988aa | ||
|
|
f4ccef462e | ||
|
|
cd26dd6b0a | ||
|
|
009bfd786d | ||
|
|
9f08cc11a8 | ||
|
|
cae4bc80af | ||
|
|
058462973e | ||
|
|
23dc90812f | ||
|
|
97e17fcee2 | ||
|
|
d75d5f67f7 | ||
|
|
c597a75372 | ||
|
|
031a3b56bf |
@@ -29,14 +29,14 @@ schedules:
|
||||
always: true
|
||||
branches:
|
||||
include:
|
||||
- stable-8
|
||||
- stable-7
|
||||
- stable-6
|
||||
- cron: 0 11 * * 0
|
||||
displayName: Weekly (old stable branches)
|
||||
always: true
|
||||
branches:
|
||||
include:
|
||||
- stable-5
|
||||
- stable-6
|
||||
|
||||
variables:
|
||||
- name: checkoutPath
|
||||
@@ -59,14 +59,14 @@ pool: Standard
|
||||
|
||||
stages:
|
||||
### Sanity
|
||||
- stage: Sanity_devel
|
||||
displayName: Sanity devel
|
||||
- stage: Sanity_2_16
|
||||
displayName: Sanity 2.16
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/matrix.yml
|
||||
parameters:
|
||||
nameFormat: Test {0}
|
||||
testFormat: devel/sanity/{0}
|
||||
testFormat: 2.16/sanity/{0}
|
||||
targets:
|
||||
- test: 1
|
||||
- test: 2
|
||||
@@ -99,28 +99,15 @@ stages:
|
||||
- test: 2
|
||||
- test: 3
|
||||
- test: 4
|
||||
- stage: Sanity_2_13
|
||||
displayName: Sanity 2.13
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/matrix.yml
|
||||
parameters:
|
||||
nameFormat: Test {0}
|
||||
testFormat: 2.13/sanity/{0}
|
||||
targets:
|
||||
- test: 1
|
||||
- test: 2
|
||||
- test: 3
|
||||
- test: 4
|
||||
### Units
|
||||
- stage: Units_devel
|
||||
displayName: Units devel
|
||||
- stage: Units_2_16
|
||||
displayName: Units 2.16
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/matrix.yml
|
||||
parameters:
|
||||
nameFormat: Python {0}
|
||||
testFormat: devel/units/{0}/1
|
||||
testFormat: 2.16/units/{0}/1
|
||||
targets:
|
||||
- test: 2.7
|
||||
- test: 3.6
|
||||
@@ -150,26 +137,15 @@ stages:
|
||||
testFormat: 2.14/units/{0}/1
|
||||
targets:
|
||||
- test: 3.9
|
||||
- stage: Units_2_13
|
||||
displayName: Units 2.13
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/matrix.yml
|
||||
parameters:
|
||||
nameFormat: Python {0}
|
||||
testFormat: 2.13/units/{0}/1
|
||||
targets:
|
||||
- test: 2.7
|
||||
- test: 3.8
|
||||
|
||||
## Remote
|
||||
- stage: Remote_devel_extra_vms
|
||||
displayName: Remote devel extra VMs
|
||||
- stage: Remote_2_16_extra_vms
|
||||
displayName: Remote 2.16 extra VMs
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/matrix.yml
|
||||
parameters:
|
||||
testFormat: devel/{0}
|
||||
testFormat: 2.16/{0}
|
||||
targets:
|
||||
- name: Alpine 3.18
|
||||
test: alpine/3.18
|
||||
@@ -179,13 +155,13 @@ stages:
|
||||
test: ubuntu/22.04
|
||||
groups:
|
||||
- vm
|
||||
- stage: Remote_devel
|
||||
displayName: Remote devel
|
||||
- stage: Remote_2_16
|
||||
displayName: Remote 2.16
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/matrix.yml
|
||||
parameters:
|
||||
testFormat: devel/{0}
|
||||
testFormat: 2.16/{0}
|
||||
targets:
|
||||
- name: macOS 13.2
|
||||
test: macos/13.2
|
||||
@@ -231,39 +207,21 @@ stages:
|
||||
targets:
|
||||
- name: RHEL 9.0
|
||||
test: rhel/9.0
|
||||
- name: FreeBSD 12.3
|
||||
test: freebsd/12.3
|
||||
groups:
|
||||
- 1
|
||||
- 2
|
||||
- 3
|
||||
- stage: Remote_2_13
|
||||
displayName: Remote 2.13
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/matrix.yml
|
||||
parameters:
|
||||
testFormat: 2.13/{0}
|
||||
targets:
|
||||
- name: macOS 12.0
|
||||
test: macos/12.0
|
||||
- name: RHEL 8.5
|
||||
test: rhel/8.5
|
||||
- name: FreeBSD 13.0
|
||||
test: freebsd/13.0
|
||||
#- name: FreeBSD 12.4
|
||||
# test: freebsd/12.4
|
||||
groups:
|
||||
- 1
|
||||
- 2
|
||||
- 3
|
||||
|
||||
### Docker
|
||||
- stage: Docker_devel
|
||||
displayName: Docker devel
|
||||
- stage: Docker_2_16
|
||||
displayName: Docker 2.16
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/matrix.yml
|
||||
parameters:
|
||||
testFormat: devel/linux/{0}
|
||||
testFormat: 2.16/linux/{0}
|
||||
targets:
|
||||
- name: Fedora 38
|
||||
test: fedora38
|
||||
@@ -309,33 +267,15 @@ stages:
|
||||
- 1
|
||||
- 2
|
||||
- 3
|
||||
- stage: Docker_2_13
|
||||
displayName: Docker 2.13
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/matrix.yml
|
||||
parameters:
|
||||
testFormat: 2.13/linux/{0}
|
||||
targets:
|
||||
- name: Fedora 35
|
||||
test: fedora35
|
||||
- name: openSUSE 15 py2
|
||||
test: opensuse15py2
|
||||
- name: Alpine 3
|
||||
test: alpine3
|
||||
groups:
|
||||
- 1
|
||||
- 2
|
||||
- 3
|
||||
|
||||
### Community Docker
|
||||
- stage: Docker_community_devel
|
||||
displayName: Docker (community images) devel
|
||||
- stage: Docker_community_2_16
|
||||
displayName: Docker (community images) 2.16
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/matrix.yml
|
||||
parameters:
|
||||
testFormat: devel/linux-community/{0}
|
||||
testFormat: 2.16/linux-community/{0}
|
||||
targets:
|
||||
- name: Debian Bullseye
|
||||
test: debian-bullseye/3.9
|
||||
@@ -349,14 +289,14 @@ stages:
|
||||
- 3
|
||||
|
||||
### Generic
|
||||
- stage: Generic_devel
|
||||
displayName: Generic devel
|
||||
- stage: Generic_2_16
|
||||
displayName: Generic 2.16
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/matrix.yml
|
||||
parameters:
|
||||
nameFormat: Python {0}
|
||||
testFormat: devel/generic/{0}/1
|
||||
testFormat: 2.16/generic/{0}/1
|
||||
targets:
|
||||
- test: 2.7
|
||||
- test: '3.11'
|
||||
@@ -380,42 +320,27 @@ stages:
|
||||
testFormat: 2.14/generic/{0}/1
|
||||
targets:
|
||||
- test: '3.10'
|
||||
- stage: Generic_2_13
|
||||
displayName: Generic 2.13
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/matrix.yml
|
||||
parameters:
|
||||
nameFormat: Python {0}
|
||||
testFormat: 2.13/generic/{0}/1
|
||||
targets:
|
||||
- test: 3.9
|
||||
|
||||
- stage: Summary
|
||||
condition: succeededOrFailed()
|
||||
dependsOn:
|
||||
- Sanity_devel
|
||||
- Sanity_2_13
|
||||
- Sanity_2_14
|
||||
- Sanity_2_15
|
||||
- Units_devel
|
||||
- Units_2_13
|
||||
- Sanity_2_16
|
||||
- Units_2_14
|
||||
- Units_2_15
|
||||
- Remote_devel_extra_vms
|
||||
- Remote_devel
|
||||
- Remote_2_13
|
||||
- Units_2_16
|
||||
- Remote_2_14
|
||||
- Remote_2_15
|
||||
- Docker_devel
|
||||
- Docker_2_13
|
||||
- Remote_2_16
|
||||
- Remote_2_16_extra_vms
|
||||
- Docker_2_14
|
||||
- Docker_2_15
|
||||
- Docker_community_devel
|
||||
- Docker_2_16
|
||||
- Docker_community_2_16
|
||||
# Right now all generic tests are disabled. Uncomment when at least one of them is re-enabled.
|
||||
# - Generic_devel
|
||||
# - Generic_2_13
|
||||
# - Generic_2_14
|
||||
# - Generic_2_15
|
||||
# - Generic_2_16
|
||||
jobs:
|
||||
- template: templates/coverage.yml
|
||||
|
||||
6
.github/BOTMETA.yml
vendored
6
.github/BOTMETA.yml
vendored
@@ -247,9 +247,11 @@ files:
|
||||
labels: onepassword
|
||||
maintainers: samdoran
|
||||
$lookups/onepassword.py:
|
||||
maintainers: azenk scottsb
|
||||
ignore: scottsb
|
||||
maintainers: azenk
|
||||
$lookups/onepassword_raw.py:
|
||||
maintainers: azenk scottsb
|
||||
ignore: scottsb
|
||||
maintainers: azenk
|
||||
$lookups/passwordstore.py: {}
|
||||
$lookups/random_pet.py:
|
||||
maintainers: Akasurde
|
||||
|
||||
47
.github/workflows/ansible-test.yml
vendored
47
.github/workflows/ansible-test.yml
vendored
@@ -31,6 +31,7 @@ jobs:
|
||||
ansible:
|
||||
- '2.11'
|
||||
- '2.12'
|
||||
- '2.13'
|
||||
# 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
|
||||
@@ -80,6 +81,10 @@ jobs:
|
||||
python: '2.6'
|
||||
- ansible: '2.12'
|
||||
python: '3.8'
|
||||
- ansible: '2.13'
|
||||
python: '2.7'
|
||||
- ansible: '2.13'
|
||||
python: '3.8'
|
||||
|
||||
steps:
|
||||
- name: >-
|
||||
@@ -211,6 +216,48 @@ jobs:
|
||||
# docker: default
|
||||
# python: '3.8'
|
||||
# target: azp/generic/1/
|
||||
# 2.13
|
||||
- ansible: '2.13'
|
||||
docker: fedora35
|
||||
python: ''
|
||||
target: azp/posix/1/
|
||||
- ansible: '2.13'
|
||||
docker: fedora35
|
||||
python: ''
|
||||
target: azp/posix/2/
|
||||
- ansible: '2.13'
|
||||
docker: fedora35
|
||||
python: ''
|
||||
target: azp/posix/3/
|
||||
- ansible: '2.13'
|
||||
docker: opensuse15py2
|
||||
python: ''
|
||||
target: azp/posix/1/
|
||||
- ansible: '2.13'
|
||||
docker: opensuse15py2
|
||||
python: ''
|
||||
target: azp/posix/2/
|
||||
- ansible: '2.13'
|
||||
docker: opensuse15py2
|
||||
python: ''
|
||||
target: azp/posix/3/
|
||||
- ansible: '2.13'
|
||||
docker: alpine3
|
||||
python: ''
|
||||
target: azp/posix/1/
|
||||
- ansible: '2.13'
|
||||
docker: alpine3
|
||||
python: ''
|
||||
target: azp/posix/2/
|
||||
- ansible: '2.13'
|
||||
docker: alpine3
|
||||
python: ''
|
||||
target: azp/posix/3/
|
||||
# Right now all generic tests are disabled. Uncomment when at least one of them is re-enabled.
|
||||
# - ansible: '2.13'
|
||||
# docker: default
|
||||
# python: '3.9'
|
||||
# target: azp/generic/1/
|
||||
|
||||
steps:
|
||||
- name: >-
|
||||
|
||||
@@ -6,6 +6,72 @@ Community General Release Notes
|
||||
|
||||
This changelog describes changes after version 5.0.0.
|
||||
|
||||
v6.6.7
|
||||
======
|
||||
|
||||
Release Summary
|
||||
---------------
|
||||
|
||||
Bugfix release.
|
||||
|
||||
From now on, community.general 6.x.y will only receive major bugfixes and security fixes anymore.
|
||||
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- composer - fix impossible to run ``working_dir`` dependent commands. The module was throwing an error when trying to run a ``working_dir`` dependent command, because it tried to get the command help without passing the ``working_dir`` (https://github.com/ansible-collections/community.general/issues/3787).
|
||||
- github_deploy_key - fix pagination behaviour causing a crash when only a single page of deploy keys exist (https://github.com/ansible-collections/community.general/pull/7375).
|
||||
- gitlab_group_members - fix gitlab constants call in ``gitlab_group_members`` module (https://github.com/ansible-collections/community.general/issues/7467).
|
||||
- gitlab_project_members - fix gitlab constants call in ``gitlab_project_members`` module (https://github.com/ansible-collections/community.general/issues/7467).
|
||||
- gitlab_protected_branches - fix gitlab constants call in ``gitlab_protected_branches`` module (https://github.com/ansible-collections/community.general/issues/7467).
|
||||
- gitlab_user - fix gitlab constants call in ``gitlab_user`` module (https://github.com/ansible-collections/community.general/issues/7467).
|
||||
- lxc connection plugin - properly evaluate options (https://github.com/ansible-collections/community.general/pull/7369).
|
||||
- memset module utils - make compatible with ansible-core 2.17 (https://github.com/ansible-collections/community.general/pull/7379).
|
||||
- redhat_subscription - use the right D-Bus options for the consumer type when
|
||||
registering a RHEL system older than 9 or a RHEL 9 system older than 9.2
|
||||
and using ``consumer_type``
|
||||
(https://github.com/ansible-collections/community.general/pull/7378).
|
||||
- selective callback plugin - fix length of task name lines in output always being 3 characters longer than desired (https://github.com/ansible-collections/community.general/pull/7374).
|
||||
|
||||
v6.6.6
|
||||
======
|
||||
|
||||
Release Summary
|
||||
---------------
|
||||
|
||||
Regular bugfix release.
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- mail - skip headers containing equals characters due to missing ``maxsplit`` on header key/value parsing (https://github.com/ansible-collections/community.general/pull/7303).
|
||||
- onepassword - fix KeyError exception when trying to access value of a field that is not filled out in OnePassword item (https://github.com/ansible-collections/community.general/pull/7241).
|
||||
- terraform - prevents ``-backend-config`` option double encapsulating with ``shlex_quote`` function. (https://github.com/ansible-collections/community.general/pull/7301).
|
||||
|
||||
v6.6.5
|
||||
======
|
||||
|
||||
Release Summary
|
||||
---------------
|
||||
|
||||
Regular bugfix release.
|
||||
|
||||
Minor Changes
|
||||
-------------
|
||||
|
||||
- make - allows ``params`` to be used without value (https://github.com/ansible-collections/community.general/pull/7180).
|
||||
- pritunl module utils - ensure ``validate_certs`` parameter is honoured in all methods (https://github.com/ansible-collections/community.general/pull/7156).
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- CmdRunner module utils - does not attempt to resolve path if executable is a relative or absolute path (https://github.com/ansible-collections/community.general/pull/7200).
|
||||
- lxc connection plugin - now handles ``remote_addr`` defaulting to ``inventory_hostname`` correctly (https://github.com/ansible-collections/community.general/pull/7104).
|
||||
- nsupdate - fix a possible ``list index out of range`` exception (https://github.com/ansible-collections/community.general/issues/836).
|
||||
- oci_utils module util - fix inappropriate logical comparison expressions and makes them simpler. The previous checks had logical short circuits (https://github.com/ansible-collections/community.general/pull/7125).
|
||||
- pritunl module utils - fix incorrect URL parameter for orgnization add method (https://github.com/ansible-collections/community.general/pull/7161).
|
||||
|
||||
v6.6.4
|
||||
======
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ If you encounter abusive behavior violating the [Ansible Code of Conduct](https:
|
||||
|
||||
## Tested with Ansible
|
||||
|
||||
Tested with the current ansible-core 2.11, ansible-core 2.12, ansible-core 2.13, ansible-core 2.14, ansible-core 2.15 releases and the current development version of ansible-core. Ansible-core versions before 2.11.0 are not supported. This includes all ansible-base 2.10 and Ansible 2.9 releases.
|
||||
Tested with the current ansible-core 2.11, ansible-core 2.12, ansible-core 2.13, ansible-core 2.14, ansible-core 2.15, and ansible-core 2.16 releases. Ansible-core versions before 2.11.0 are not supported. This includes all ansible-base 2.10 and Ansible 2.9 releases.
|
||||
|
||||
Parts of this collection will not work with ansible-core 2.11 on Python 3.12+.
|
||||
|
||||
@@ -34,13 +34,13 @@ Some modules and plugins require external libraries. Please check the requiremen
|
||||
|
||||
## Included content
|
||||
|
||||
Please check the included content on the [Ansible Galaxy page for this collection](https://galaxy.ansible.com/community/general) or the [documentation on the Ansible docs site](https://docs.ansible.com/ansible/latest/collections/community/general/).
|
||||
Please check the included content on the [Ansible Galaxy page for this collection](https://galaxy.ansible.com/ui/repo/published/community/general/) or the [documentation on the Ansible docs site](https://docs.ansible.com/ansible/latest/collections/community/general/).
|
||||
|
||||
## Using this collection
|
||||
|
||||
This collection is shipped with the Ansible package. So if you have it installed, no more action is required.
|
||||
|
||||
If you have a minimal installation (only Ansible Core installed) or you want to use the latest version of the collection along with the whole Ansible package, you need to install the collection from [Ansible Galaxy](https://galaxy.ansible.com/community/general) manually with the `ansible-galaxy` command-line tool:
|
||||
If you have a minimal installation (only Ansible Core installed) or you want to use the latest version of the collection along with the whole Ansible package, you need to install the collection from [Ansible Galaxy](https://galaxy.ansible.com/ui/repo/published/community/general/) manually with the `ansible-galaxy` command-line tool:
|
||||
|
||||
ansible-galaxy collection install community.general
|
||||
|
||||
@@ -57,7 +57,7 @@ Note that if you install the collection manually, it will not be upgraded automa
|
||||
ansible-galaxy collection install community.general --upgrade
|
||||
```
|
||||
|
||||
You can also install a specific version of the collection, for example, if you need to downgrade when something is broken in the latest version (please report an issue in this repository). Use the following syntax where `X.Y.Z` can be any [available version](https://galaxy.ansible.com/community/general):
|
||||
You can also install a specific version of the collection, for example, if you need to downgrade when something is broken in the latest version (please report an issue in this repository). Use the following syntax where `X.Y.Z` can be any [available version](https://galaxy.ansible.com/ui/repo/published/community/general/):
|
||||
|
||||
```bash
|
||||
ansible-galaxy collection install community.general:==X.Y.Z
|
||||
|
||||
@@ -1530,3 +1530,92 @@ releases:
|
||||
- 7081-redfish-utils-fix-for-storagecontrollers-deprecated-key.yaml
|
||||
- 7085-sanity.yml
|
||||
release_date: '2023-08-13'
|
||||
6.6.5:
|
||||
changes:
|
||||
bugfixes:
|
||||
- CmdRunner module utils - does not attempt to resolve path if executable is
|
||||
a relative or absolute path (https://github.com/ansible-collections/community.general/pull/7200).
|
||||
- lxc connection plugin - now handles ``remote_addr`` defaulting to ``inventory_hostname``
|
||||
correctly (https://github.com/ansible-collections/community.general/pull/7104).
|
||||
- nsupdate - fix a possible ``list index out of range`` exception (https://github.com/ansible-collections/community.general/issues/836).
|
||||
- oci_utils module util - fix inappropriate logical comparison expressions and
|
||||
makes them simpler. The previous checks had logical short circuits (https://github.com/ansible-collections/community.general/pull/7125).
|
||||
- pritunl module utils - fix incorrect URL parameter for orgnization add method
|
||||
(https://github.com/ansible-collections/community.general/pull/7161).
|
||||
minor_changes:
|
||||
- make - allows ``params`` to be used without value (https://github.com/ansible-collections/community.general/pull/7180).
|
||||
- pritunl module utils - ensure ``validate_certs`` parameter is honoured in
|
||||
all methods (https://github.com/ansible-collections/community.general/pull/7156).
|
||||
release_summary: Regular bugfix release.
|
||||
fragments:
|
||||
- 6.6.5.yml
|
||||
- 7104_fix_lxc_remoteaddr_default.yml
|
||||
- 7125-fix-inappropriate-comparison.yml
|
||||
- 7156-ensure-validate-certs-parameter-is-honoured.yml
|
||||
- 7161-fix-incorrect-post-parameter.yml
|
||||
- 7180-make_params_without_value.yml
|
||||
- 7200-cmd-runner-abs-path.yml
|
||||
- 7219-fix-nsupdate-cname.yaml
|
||||
release_date: '2023-09-11'
|
||||
6.6.6:
|
||||
changes:
|
||||
bugfixes:
|
||||
- mail - skip headers containing equals characters due to missing ``maxsplit``
|
||||
on header key/value parsing (https://github.com/ansible-collections/community.general/pull/7303).
|
||||
- onepassword - fix KeyError exception when trying to access value of a field
|
||||
that is not filled out in OnePassword item (https://github.com/ansible-collections/community.general/pull/7241).
|
||||
- terraform - prevents ``-backend-config`` option double encapsulating with
|
||||
``shlex_quote`` function. (https://github.com/ansible-collections/community.general/pull/7301).
|
||||
release_summary: Regular bugfix release.
|
||||
fragments:
|
||||
- 6.6.6.yml
|
||||
- 7241-prevent-key-error-when-value-does-not-exist.yml
|
||||
- 7301-fix-backend-config-string-encapsulation.yml
|
||||
- 7303-mail-incorrect-header-parsing.yml
|
||||
release_date: '2023-10-08'
|
||||
6.6.7:
|
||||
changes:
|
||||
bugfixes:
|
||||
- composer - fix impossible to run ``working_dir`` dependent commands. The module
|
||||
was throwing an error when trying to run a ``working_dir`` dependent command,
|
||||
because it tried to get the command help without passing the ``working_dir``
|
||||
(https://github.com/ansible-collections/community.general/issues/3787).
|
||||
- github_deploy_key - fix pagination behaviour causing a crash when only a single
|
||||
page of deploy keys exist (https://github.com/ansible-collections/community.general/pull/7375).
|
||||
- gitlab_group_members - fix gitlab constants call in ``gitlab_group_members``
|
||||
module (https://github.com/ansible-collections/community.general/issues/7467).
|
||||
- gitlab_project_members - fix gitlab constants call in ``gitlab_project_members``
|
||||
module (https://github.com/ansible-collections/community.general/issues/7467).
|
||||
- gitlab_protected_branches - fix gitlab constants call in ``gitlab_protected_branches``
|
||||
module (https://github.com/ansible-collections/community.general/issues/7467).
|
||||
- gitlab_user - fix gitlab constants call in ``gitlab_user`` module (https://github.com/ansible-collections/community.general/issues/7467).
|
||||
- lxc connection plugin - properly evaluate options (https://github.com/ansible-collections/community.general/pull/7369).
|
||||
- memset module utils - make compatible with ansible-core 2.17 (https://github.com/ansible-collections/community.general/pull/7379).
|
||||
- 'redhat_subscription - use the right D-Bus options for the consumer type when
|
||||
|
||||
registering a RHEL system older than 9 or a RHEL 9 system older than 9.2
|
||||
|
||||
and using ``consumer_type``
|
||||
|
||||
(https://github.com/ansible-collections/community.general/pull/7378).
|
||||
|
||||
'
|
||||
- selective callback plugin - fix length of task name lines in output always
|
||||
being 3 characters longer than desired (https://github.com/ansible-collections/community.general/pull/7374).
|
||||
release_summary: 'Bugfix release.
|
||||
|
||||
|
||||
From now on, community.general 6.x.y will only receive major bugfixes and
|
||||
security fixes anymore.
|
||||
|
||||
'
|
||||
fragments:
|
||||
- 3787-pass-composer-working-dir.yml
|
||||
- 6.6.7.yml
|
||||
- 7369-fix-lxc-options.yml
|
||||
- 7374-fix-selective-callback-taskname-length.yml
|
||||
- 7375-fix-github-deploy-key-pagination.yml
|
||||
- 7378-redhat_subscription-dbus-consumer-type.yaml
|
||||
- 7379-url.yml
|
||||
- 7467-fix-gitlab-constants-calls.yml
|
||||
release_date: '2023-11-04'
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
namespace: community
|
||||
name: general
|
||||
version: 6.6.4
|
||||
version: 6.6.7
|
||||
readme: README.md
|
||||
authors:
|
||||
- Ansible (https://github.com/ansible)
|
||||
|
||||
@@ -115,8 +115,8 @@ class CallbackModule(CallbackBase):
|
||||
line_length = 120
|
||||
if self.last_skipped:
|
||||
print()
|
||||
msg = colorize("# {0} {1}".format(task_name,
|
||||
'*' * (line_length - len(task_name))), 'bold')
|
||||
line = "# {0} ".format(task_name)
|
||||
msg = colorize("{0}{1}".format(line, '*' * (line_length - len(line))), 'bold')
|
||||
print(msg)
|
||||
|
||||
def _indent_text(self, text, indent_level):
|
||||
|
||||
@@ -19,6 +19,7 @@ DOCUMENTATION = '''
|
||||
- Container identifier
|
||||
default: inventory_hostname
|
||||
vars:
|
||||
- name: inventory_hostname
|
||||
- name: ansible_host
|
||||
- name: ansible_lxc_host
|
||||
executable:
|
||||
@@ -59,7 +60,7 @@ class Connection(ConnectionBase):
|
||||
def __init__(self, play_context, new_stdin, *args, **kwargs):
|
||||
super(Connection, self).__init__(play_context, new_stdin, *args, **kwargs)
|
||||
|
||||
self.container_name = self._play_context.remote_addr
|
||||
self.container_name = None
|
||||
self.container = None
|
||||
|
||||
def _connect(self):
|
||||
@@ -67,12 +68,14 @@ class Connection(ConnectionBase):
|
||||
super(Connection, self)._connect()
|
||||
|
||||
if not HAS_LIBLXC:
|
||||
msg = "lxc bindings for python2 are not installed"
|
||||
msg = "lxc python bindings are not installed"
|
||||
raise errors.AnsibleError(msg)
|
||||
|
||||
if self.container:
|
||||
return
|
||||
|
||||
self.container_name = self.get_option('remote_addr')
|
||||
|
||||
self._display.vvv("THIS IS A LOCAL LXC DIR", host=self.container_name)
|
||||
self.container = _lxc.Container(self.container_name)
|
||||
if self.container.state == "STOPPED":
|
||||
@@ -117,7 +120,7 @@ class Connection(ConnectionBase):
|
||||
super(Connection, self).exec_command(cmd, in_data=in_data, sudoable=sudoable)
|
||||
|
||||
# python2-lxc needs bytes. python3-lxc needs text.
|
||||
executable = to_native(self._play_context.executable, errors='surrogate_or_strict')
|
||||
executable = to_native(self.get_option('executable'), errors='surrogate_or_strict')
|
||||
local_cmd = [executable, '-c', to_native(cmd, errors='surrogate_or_strict')]
|
||||
|
||||
read_stdout, write_stdout = None, None
|
||||
|
||||
@@ -56,7 +56,7 @@ EXAMPLES = '''
|
||||
- name: Parse a CSV file's contents
|
||||
ansible.builtin.debug:
|
||||
msg: >-
|
||||
{{ csv_data | community.genera.from_csv(dialect='unix') }}
|
||||
{{ csv_data | community.general.from_csv(dialect='unix') }}
|
||||
vars:
|
||||
csv_data: |
|
||||
Column 1,Value
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2018, Scott Buchanan <sbuchanan@ri.pn>
|
||||
# Copyright (c) 2018, Scott Buchanan <scott@buchanan.works>
|
||||
# Copyright (c) 2016, Andrew Zenk <azenk@umn.edu> (lastpass.py used as starting point)
|
||||
# Copyright (c) 2018, 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)
|
||||
@@ -451,10 +451,10 @@ class OnePassCLIv2(OnePassCLIBase):
|
||||
# If the field name doesn't exist in the section, match on the value of "label"
|
||||
# then "id" and return "value"
|
||||
if field.get("label") == field_name:
|
||||
return field["value"]
|
||||
return field.get("value", "")
|
||||
|
||||
if field.get("id") == field_name:
|
||||
return field["value"]
|
||||
return field.get("value", "")
|
||||
|
||||
# Look at the section data and get an indentifier. The value of 'id' is either a unique ID
|
||||
# or a human-readable string. If a 'label' field exists, prefer that since
|
||||
@@ -464,10 +464,10 @@ class OnePassCLIv2(OnePassCLIBase):
|
||||
if section_title == current_section_title:
|
||||
# In the correct section. Check "label" then "id" for the desired field_name
|
||||
if field.get("label") == field_name:
|
||||
return field["value"]
|
||||
return field.get("value", "")
|
||||
|
||||
if field.get("id") == field_name:
|
||||
return field["value"]
|
||||
return field.get("value", "")
|
||||
|
||||
return ""
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
from __future__ import absolute_import, division, print_function
|
||||
__metaclass__ = type
|
||||
|
||||
import os
|
||||
from functools import wraps
|
||||
|
||||
from ansible.module_utils.common.collections import is_sequence
|
||||
@@ -199,12 +200,17 @@ class CmdRunner(object):
|
||||
environ_update = {}
|
||||
self.environ_update = environ_update
|
||||
|
||||
self.command[0] = module.get_bin_path(self.command[0], opt_dirs=path_prefix, required=True)
|
||||
_cmd = self.command[0]
|
||||
self.command[0] = _cmd if (os.path.isabs(_cmd) or '/' in _cmd) else module.get_bin_path(_cmd, opt_dirs=path_prefix, required=True)
|
||||
|
||||
for mod_param_name, spec in iteritems(module.argument_spec):
|
||||
if mod_param_name not in self.arg_formats:
|
||||
self.arg_formats[mod_param_name] = _Format.as_default_type(spec.get('type', 'str'), mod_param_name)
|
||||
|
||||
@property
|
||||
def binary(self):
|
||||
return self.command[0]
|
||||
|
||||
def __call__(self, args_order=None, output_process=None, ignore_value_none=True, check_mode_skip=False, check_mode_return=None, **kwargs):
|
||||
if output_process is None:
|
||||
output_process = _process_as_is
|
||||
|
||||
@@ -14,8 +14,9 @@ from __future__ import (absolute_import, division, print_function)
|
||||
__metaclass__ = type
|
||||
|
||||
from ansible.module_utils.six.moves.urllib.parse import urlencode
|
||||
from ansible.module_utils.urls import open_url, urllib_error
|
||||
from ansible.module_utils.urls import open_url
|
||||
from ansible.module_utils.basic import json
|
||||
import ansible.module_utils.six.moves.urllib.error as urllib_error
|
||||
|
||||
|
||||
class Response(object):
|
||||
|
||||
@@ -79,7 +79,7 @@ def _post_pritunl_organization(
|
||||
api_secret=api_secret,
|
||||
base_url=base_url,
|
||||
method="POST",
|
||||
path="/organization/%s",
|
||||
path="/organization",
|
||||
headers={"Content-Type": "application/json"},
|
||||
data=json.dumps(organization_data),
|
||||
validate_certs=validate_certs,
|
||||
@@ -220,7 +220,7 @@ def post_pritunl_organization(
|
||||
api_secret=api_secret,
|
||||
base_url=base_url,
|
||||
organization_data={"name": organization_name},
|
||||
validate_certs=True,
|
||||
validate_certs=validate_certs,
|
||||
)
|
||||
|
||||
if response.getcode() != 200:
|
||||
@@ -248,7 +248,7 @@ def post_pritunl_user(
|
||||
base_url=base_url,
|
||||
organization_id=organization_id,
|
||||
user_data=user_data,
|
||||
validate_certs=True,
|
||||
validate_certs=validate_certs,
|
||||
)
|
||||
|
||||
if response.getcode() != 200:
|
||||
@@ -267,7 +267,7 @@ def post_pritunl_user(
|
||||
organization_id=organization_id,
|
||||
user_data=user_data,
|
||||
user_id=user_id,
|
||||
validate_certs=True,
|
||||
validate_certs=validate_certs,
|
||||
)
|
||||
|
||||
if response.getcode() != 200:
|
||||
@@ -287,7 +287,7 @@ def delete_pritunl_organization(
|
||||
api_secret=api_secret,
|
||||
base_url=base_url,
|
||||
organization_id=organization_id,
|
||||
validate_certs=True,
|
||||
validate_certs=validate_certs,
|
||||
)
|
||||
|
||||
if response.getcode() != 200:
|
||||
@@ -307,7 +307,7 @@ def delete_pritunl_user(
|
||||
base_url=base_url,
|
||||
organization_id=organization_id,
|
||||
user_id=user_id,
|
||||
validate_certs=True,
|
||||
validate_certs=validate_certs,
|
||||
)
|
||||
|
||||
if response.getcode() != 200:
|
||||
|
||||
@@ -561,7 +561,7 @@ def are_lists_equal(s, t):
|
||||
if s is None and t is None:
|
||||
return True
|
||||
|
||||
if (s is None and len(t) >= 0) or (t is None and len(s) >= 0) or (len(s) != len(t)):
|
||||
if s is None or t is None or (len(s) != len(t)):
|
||||
return False
|
||||
|
||||
if len(s) == 0:
|
||||
@@ -1026,10 +1026,7 @@ def check_if_user_value_matches_resources_attr(
|
||||
return
|
||||
|
||||
if (
|
||||
resources_value_for_attr is None
|
||||
and len(user_provided_value_for_attr) >= 0
|
||||
or user_provided_value_for_attr is None
|
||||
and len(resources_value_for_attr) >= 0
|
||||
resources_value_for_attr is None or user_provided_value_for_attr is None
|
||||
):
|
||||
res[0] = False
|
||||
return
|
||||
|
||||
@@ -154,7 +154,7 @@ def _get_ctl_binary(module):
|
||||
if ctl_binary is not None:
|
||||
return ctl_binary
|
||||
|
||||
module.fail_json(msg="Neither of apache2ctl nor apachctl found. At least one apache control binary is necessary.")
|
||||
module.fail_json(msg="Neither of apache2ctl nor apachectl found. At least one apache control binary is necessary.")
|
||||
|
||||
|
||||
def _module_is_enabled(module):
|
||||
|
||||
@@ -170,10 +170,15 @@ def get_available_options(module, command='install'):
|
||||
return command_help_json['definition']['options']
|
||||
|
||||
|
||||
def composer_command(module, command, arguments="", options=None, global_command=False):
|
||||
def composer_command(module, command, arguments="", options=None):
|
||||
if options is None:
|
||||
options = []
|
||||
|
||||
global_command = module.params['global_command']
|
||||
|
||||
if not global_command:
|
||||
options.extend(['--working-dir', "'%s'" % module.params['working_dir']])
|
||||
|
||||
if module.params['executable'] is None:
|
||||
php_path = module.get_bin_path("php", True, ["/usr/local/bin"])
|
||||
else:
|
||||
@@ -217,7 +222,6 @@ def main():
|
||||
module.fail_json(msg="Use the 'arguments' param for passing arguments with the 'command'")
|
||||
|
||||
arguments = module.params['arguments']
|
||||
global_command = module.params['global_command']
|
||||
available_options = get_available_options(module=module, command=command)
|
||||
|
||||
options = []
|
||||
@@ -234,9 +238,6 @@ def main():
|
||||
option = "--%s" % option
|
||||
options.append(option)
|
||||
|
||||
if not global_command:
|
||||
options.extend(['--working-dir', "'%s'" % module.params['working_dir']])
|
||||
|
||||
option_params = {
|
||||
'prefer_source': 'prefer-source',
|
||||
'prefer_dist': 'prefer-dist',
|
||||
@@ -260,7 +261,7 @@ def main():
|
||||
else:
|
||||
module.exit_json(skipped=True, msg="command '%s' does not support check mode, skipping" % command)
|
||||
|
||||
rc, out, err = composer_command(module, command, arguments, options, global_command)
|
||||
rc, out, err = composer_command(module, command, arguments, options)
|
||||
|
||||
if rc != 0:
|
||||
output = parse_out(err)
|
||||
|
||||
@@ -227,7 +227,7 @@ class GithubDeployKey(object):
|
||||
yield self.module.from_json(resp.read())
|
||||
|
||||
links = {}
|
||||
for x, y in findall(r'<([^>]+)>;\s*rel="(\w+)"', info["link"]):
|
||||
for x, y in findall(r'<([^>]+)>;\s*rel="(\w+)"', info.get("link", '')):
|
||||
links[y] = x
|
||||
|
||||
url = links.get('next')
|
||||
|
||||
@@ -276,11 +276,11 @@ def main():
|
||||
ensure_gitlab_package(module)
|
||||
|
||||
access_level_int = {
|
||||
'guest': gitlab.GUEST_ACCESS,
|
||||
'reporter': gitlab.REPORTER_ACCESS,
|
||||
'developer': gitlab.DEVELOPER_ACCESS,
|
||||
'maintainer': gitlab.MAINTAINER_ACCESS,
|
||||
'owner': gitlab.OWNER_ACCESS,
|
||||
'guest': gitlab.const.GUEST_ACCESS,
|
||||
'reporter': gitlab.const.REPORTER_ACCESS,
|
||||
'developer': gitlab.const.DEVELOPER_ACCESS,
|
||||
'maintainer': gitlab.const.MAINTAINER_ACCESS,
|
||||
'owner': gitlab.const.OWNER_ACCESS,
|
||||
}
|
||||
|
||||
gitlab_group = module.params['gitlab_group']
|
||||
|
||||
@@ -282,10 +282,10 @@ def main():
|
||||
ensure_gitlab_package(module)
|
||||
|
||||
access_level_int = {
|
||||
'guest': gitlab.GUEST_ACCESS,
|
||||
'reporter': gitlab.REPORTER_ACCESS,
|
||||
'developer': gitlab.DEVELOPER_ACCESS,
|
||||
'maintainer': gitlab.MAINTAINER_ACCESS,
|
||||
'guest': gitlab.const.GUEST_ACCESS,
|
||||
'reporter': gitlab.const.REPORTER_ACCESS,
|
||||
'developer': gitlab.const.DEVELOPER_ACCESS,
|
||||
'maintainer': gitlab.const.MAINTAINER_ACCESS,
|
||||
}
|
||||
|
||||
gitlab_project = module.params['project']
|
||||
|
||||
@@ -94,9 +94,9 @@ class GitlabProtectedBranch(object):
|
||||
self._module = module
|
||||
self.project = self.get_project(project)
|
||||
self.ACCESS_LEVEL = {
|
||||
'nobody': gitlab.NO_ACCESS,
|
||||
'developer': gitlab.DEVELOPER_ACCESS,
|
||||
'maintainer': gitlab.MAINTAINER_ACCESS
|
||||
'nobody': gitlab.const.NO_ACCESS,
|
||||
'developer': gitlab.const.DEVELOPER_ACCESS,
|
||||
'maintainer': gitlab.const.MAINTAINER_ACCESS
|
||||
}
|
||||
|
||||
def get_project(self, project_name):
|
||||
|
||||
@@ -244,12 +244,12 @@ class GitLabUser(object):
|
||||
self._gitlab = gitlab_instance
|
||||
self.user_object = None
|
||||
self.ACCESS_LEVEL = {
|
||||
'guest': gitlab.GUEST_ACCESS,
|
||||
'reporter': gitlab.REPORTER_ACCESS,
|
||||
'developer': gitlab.DEVELOPER_ACCESS,
|
||||
'master': gitlab.MAINTAINER_ACCESS,
|
||||
'maintainer': gitlab.MAINTAINER_ACCESS,
|
||||
'owner': gitlab.OWNER_ACCESS,
|
||||
'guest': gitlab.const.GUEST_ACCESS,
|
||||
'reporter': gitlab.const.REPORTER_ACCESS,
|
||||
'developer': gitlab.const.DEVELOPER_ACCESS,
|
||||
'master': gitlab.const.MAINTAINER_ACCESS,
|
||||
'maintainer': gitlab.const.MAINTAINER_ACCESS,
|
||||
'owner': gitlab.const.OWNER_ACCESS,
|
||||
}
|
||||
|
||||
'''
|
||||
|
||||
@@ -30,7 +30,9 @@ options:
|
||||
default: 'always'
|
||||
choices: [ always, on_create ]
|
||||
givenname:
|
||||
description: First name.
|
||||
description:
|
||||
- First name.
|
||||
- If user does not exist and I(state=present), the usage of I(givenname) is required.
|
||||
type: str
|
||||
krbpasswordexpiration:
|
||||
description:
|
||||
@@ -54,7 +56,9 @@ options:
|
||||
- Will not be set for an existing user unless I(update_password=always), which is the default.
|
||||
type: str
|
||||
sn:
|
||||
description: Surname.
|
||||
description:
|
||||
- Surname.
|
||||
- If user does not exist and I(state=present), the usage of I(sn) is required.
|
||||
type: str
|
||||
sshpubkey:
|
||||
description:
|
||||
|
||||
@@ -67,7 +67,7 @@ author:
|
||||
|
||||
EXAMPLES = '''
|
||||
- name: Set default client scopes on realm level
|
||||
community.general.keycloak_clientsecret_info:
|
||||
community.general.keycloak_clientscope_type:
|
||||
auth_client_id: admin-cli
|
||||
auth_keycloak_url: https://auth.example.com/auth
|
||||
auth_realm: master
|
||||
@@ -79,7 +79,7 @@ EXAMPLES = '''
|
||||
|
||||
|
||||
- name: Set default and optional client scopes on client level with token auth
|
||||
community.general.keycloak_clientsecret_info:
|
||||
community.general.keycloak_clientscope_type:
|
||||
auth_client_id: admin-cli
|
||||
auth_keycloak_url: https://auth.example.com/auth
|
||||
token: TOKEN
|
||||
|
||||
@@ -354,7 +354,7 @@ def main():
|
||||
# NOTE: Backward compatible with old syntax using '|' as delimiter
|
||||
for hdr in [x.strip() for x in header.split('|')]:
|
||||
try:
|
||||
h_key, h_val = hdr.split('=')
|
||||
h_key, h_val = hdr.split('=', 1)
|
||||
h_val = to_native(Header(h_val, charset))
|
||||
msg.add_header(h_key, h_val)
|
||||
except Exception:
|
||||
|
||||
@@ -49,6 +49,7 @@ options:
|
||||
params:
|
||||
description:
|
||||
- Any extra parameters to pass to make.
|
||||
- If the value is empty, only the key will be used. For example, C(FOO:) will produce C(FOO), not C(FOO=).
|
||||
type: dict
|
||||
target:
|
||||
description:
|
||||
@@ -81,6 +82,18 @@ EXAMPLES = r'''
|
||||
chdir: /home/ubuntu/cool-project
|
||||
target: all
|
||||
file: /some-project/Makefile
|
||||
|
||||
- name: build arm64 kernel on FreeBSD, with 16 parallel jobs
|
||||
community.general.make:
|
||||
chdir: /usr/src
|
||||
jobs: 16
|
||||
target: buildkernel
|
||||
params:
|
||||
# This adds -DWITH_FDT to the command line:
|
||||
-DWITH_FDT:
|
||||
# The following adds TARGET=arm64 TARGET_ARCH=aarch64 to the command line:
|
||||
TARGET: arm64
|
||||
TARGET_ARCH: aarch64
|
||||
'''
|
||||
|
||||
RETURN = r'''
|
||||
@@ -174,7 +187,7 @@ def main():
|
||||
make_path = module.get_bin_path('make', required=True)
|
||||
make_target = module.params['target']
|
||||
if module.params['params'] is not None:
|
||||
make_parameters = [k + '=' + str(v) for k, v in iteritems(module.params['params'])]
|
||||
make_parameters = [k + (('=' + str(v)) if v is not None else '') for k, v in iteritems(module.params['params'])]
|
||||
else:
|
||||
make_parameters = []
|
||||
|
||||
|
||||
@@ -467,10 +467,8 @@ class RecordManager(object):
|
||||
if lookup.rcode() != dns.rcode.NOERROR:
|
||||
self.module.fail_json(msg='Failed to lookup TTL of existing matching record.')
|
||||
|
||||
if self.module.params['type'] == 'NS':
|
||||
current_ttl = lookup.answer[0].ttl if lookup.answer else lookup.authority[0].ttl
|
||||
else:
|
||||
current_ttl = lookup.answer[0].ttl
|
||||
current_ttl = lookup.answer[0].ttl if lookup.answer else lookup.authority[0].ttl
|
||||
|
||||
return current_ttl != self.module.params['ttl']
|
||||
|
||||
|
||||
|
||||
@@ -408,6 +408,14 @@ options:
|
||||
smbios:
|
||||
description:
|
||||
- Specifies SMBIOS type 1 fields.
|
||||
- "Comma separated, Base64 encoded (optional) SMBIOS properties:"
|
||||
- C([base64=<1|0>] [,family=<Base64 encoded string>])
|
||||
- C([,manufacturer=<Base64 encoded string>])
|
||||
- C([,product=<Base64 encoded string>])
|
||||
- C([,serial=<Base64 encoded string>])
|
||||
- C([,sku=<Base64 encoded string>])
|
||||
- C([,uuid=<UUID>])
|
||||
- C([,version=<Base64 encoded string>])
|
||||
type: str
|
||||
snapname:
|
||||
description:
|
||||
|
||||
@@ -588,7 +588,34 @@ class Rhsm(RegistrationBase):
|
||||
|
||||
register_opts = {}
|
||||
if consumer_type:
|
||||
register_opts['consumer_type'] = consumer_type
|
||||
# The option for the consumer type used to be 'type' in versions
|
||||
# of RHEL before 9 & in RHEL 9 before 9.2, and then it changed to
|
||||
# 'consumer_type'; since the Register*() D-Bus functions reject
|
||||
# unknown options, we have to pass the right option depending on
|
||||
# the version -- funky.
|
||||
def supports_option_consumer_type():
|
||||
# subscription-manager in any supported Fedora version
|
||||
# has the new option.
|
||||
if distro_id == 'fedora':
|
||||
return True
|
||||
# Check for RHEL 9 >= 9.2, or RHEL >= 10.
|
||||
if distro_id == 'rhel' and \
|
||||
((distro_version[0] == 9 and distro_version[1] >= 2) or
|
||||
distro_version[0] >= 10):
|
||||
return True
|
||||
# CentOS: since the change was only done in EL 9, then there is
|
||||
# only CentOS Stream for 9, and thus we can assume it has the
|
||||
# latest version of subscription-manager.
|
||||
if distro_id == 'centos' and distro_version[0] >= 9:
|
||||
return True
|
||||
# Unknown or old distro: assume it does not support
|
||||
# the new option.
|
||||
return False
|
||||
|
||||
consumer_type_key = 'type'
|
||||
if supports_option_consumer_type():
|
||||
consumer_type_key = 'consumer_type'
|
||||
register_opts[consumer_type_key] = consumer_type
|
||||
if consumer_name:
|
||||
register_opts['name'] = consumer_name
|
||||
if consumer_id:
|
||||
|
||||
@@ -325,7 +325,7 @@ def init_plugins(bin_path, project_path, backend_config, backend_config_files, i
|
||||
for key, val in backend_config.items():
|
||||
command.extend([
|
||||
'-backend-config',
|
||||
shlex_quote('{0}={1}'.format(key, val))
|
||||
'{0}={1}'.format(key, val)
|
||||
])
|
||||
if backend_config_files:
|
||||
for f in backend_config_files:
|
||||
|
||||
@@ -21,6 +21,8 @@ from ansible_collections.community.general.plugins.module_utils.cmd_runner impor
|
||||
def main():
|
||||
module = AnsibleModule(
|
||||
argument_spec=dict(
|
||||
cmd=dict(type="str", default="echo"),
|
||||
path_prefix=dict(type="str"),
|
||||
arg_formats=dict(type="dict", default={}),
|
||||
arg_order=dict(type="raw", required=True),
|
||||
arg_values=dict(type="dict", default={}),
|
||||
@@ -41,7 +43,7 @@ def main():
|
||||
|
||||
arg_formats[arg] = func(*args)
|
||||
|
||||
runner = CmdRunner(module, ['echo', '--'], arg_formats=arg_formats)
|
||||
runner = CmdRunner(module, [module.params["cmd"], '--'], arg_formats=arg_formats, path_prefix=module.params["path_prefix"])
|
||||
|
||||
with runner.context(p['arg_order'], check_mode_skip=p['check_mode_skip']) as ctx:
|
||||
result = ctx.run(**p['arg_values'])
|
||||
|
||||
7
tests/integration/targets/cmd_runner/meta/main.yml
Normal file
7
tests/integration/targets/cmd_runner/meta/main.yml
Normal file
@@ -0,0 +1,7 @@
|
||||
---
|
||||
# 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
|
||||
|
||||
dependencies:
|
||||
- setup_remote_tmp_dir
|
||||
@@ -6,3 +6,4 @@
|
||||
ansible.builtin.include_tasks:
|
||||
file: test_cmd_echo.yml
|
||||
loop: "{{ cmd_echo_tests }}"
|
||||
when: item.condition | default(true) | bool
|
||||
|
||||
@@ -3,17 +3,26 @@
|
||||
# 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
|
||||
|
||||
- name: test cmd_echo [{{ item.name }}]
|
||||
cmd_echo:
|
||||
arg_formats: "{{ item.arg_formats|default(omit) }}"
|
||||
arg_order: "{{ item.arg_order }}"
|
||||
arg_values: "{{ item.arg_values|default(omit) }}"
|
||||
check_mode_skip: "{{ item.check_mode_skip|default(omit) }}"
|
||||
aa: "{{ item.aa|default(omit) }}"
|
||||
register: test_result
|
||||
check_mode: "{{ item.check_mode|default(omit) }}"
|
||||
ignore_errors: "{{ item.expect_error|default(omit) }}"
|
||||
- name: create copy of /bin/echo ({{ item.name }})
|
||||
ansible.builtin.copy:
|
||||
src: /bin/echo
|
||||
dest: "{{ item.copy_to }}/echo"
|
||||
mode: "755"
|
||||
when: item.copy_to is defined
|
||||
|
||||
- name: check results [{{ item.name }}]
|
||||
- name: test cmd_echo module ({{ item.name }})
|
||||
cmd_echo:
|
||||
cmd: "{{ item.cmd | default(omit) }}"
|
||||
path_prefix: "{{ item.path_prefix | default(omit) }}"
|
||||
arg_formats: "{{ item.arg_formats | default(omit) }}"
|
||||
arg_order: "{{ item.arg_order }}"
|
||||
arg_values: "{{ item.arg_values | default(omit) }}"
|
||||
check_mode_skip: "{{ item.check_mode_skip | default(omit) }}"
|
||||
aa: "{{ item.aa | default(omit) }}"
|
||||
register: test_result
|
||||
check_mode: "{{ item.check_mode | default(omit) }}"
|
||||
ignore_errors: "{{ item.expect_error | default(omit) }}"
|
||||
|
||||
- name: check results ({{ item.name }})
|
||||
assert:
|
||||
that: "{{ item.assertions }}"
|
||||
|
||||
@@ -138,3 +138,125 @@ cmd_echo_tests:
|
||||
- test_result.rc == 0
|
||||
- test_result.out == "-- --answer=11 --tt-arg potatoes\n"
|
||||
- test_result.err == ""
|
||||
|
||||
- name: use cmd echo
|
||||
cmd: echo
|
||||
arg_formats:
|
||||
aa:
|
||||
func: as_opt_eq_val
|
||||
args: [--answer]
|
||||
tt:
|
||||
func: as_opt_val
|
||||
args: [--tt-arg]
|
||||
arg_order: 'aa tt'
|
||||
arg_values:
|
||||
tt: potatoes
|
||||
aa: 11
|
||||
assertions:
|
||||
- test_result.rc == 0
|
||||
- test_result.out == "-- --answer=11 --tt-arg potatoes\n"
|
||||
- test_result.err == ""
|
||||
|
||||
- name: use cmd /bin/echo
|
||||
cmd: /bin/echo
|
||||
arg_formats:
|
||||
aa:
|
||||
func: as_opt_eq_val
|
||||
args: [--answer]
|
||||
tt:
|
||||
func: as_opt_val
|
||||
args: [--tt-arg]
|
||||
arg_order: 'aa tt'
|
||||
arg_values:
|
||||
tt: potatoes
|
||||
aa: 11
|
||||
assertions:
|
||||
- test_result.rc == 0
|
||||
- test_result.out == "-- --answer=11 --tt-arg potatoes\n"
|
||||
- test_result.err == ""
|
||||
|
||||
# this will not be in the regular set of paths get_bin_path() searches
|
||||
- name: use cmd {{ remote_tmp_dir }}/echo
|
||||
condition: >
|
||||
{{
|
||||
ansible_distribution != "MacOSX" and
|
||||
not (ansible_distribution == "CentOS" and ansible_distribution_major_version is version('7.0', '<'))
|
||||
}}
|
||||
copy_to: "{{ remote_tmp_dir }}"
|
||||
cmd: "{{ remote_tmp_dir }}/echo"
|
||||
arg_formats:
|
||||
aa:
|
||||
func: as_opt_eq_val
|
||||
args: [--answer]
|
||||
tt:
|
||||
func: as_opt_val
|
||||
args: [--tt-arg]
|
||||
arg_order: 'aa tt'
|
||||
arg_values:
|
||||
tt: potatoes
|
||||
aa: 11
|
||||
assertions:
|
||||
- test_result.rc == 0
|
||||
- test_result.out == "-- --answer=11 --tt-arg potatoes\n"
|
||||
- test_result.err == ""
|
||||
|
||||
- name: use cmd echo with path_prefix {{ remote_tmp_dir }}
|
||||
cmd: echo
|
||||
condition: >
|
||||
{{
|
||||
ansible_distribution != "MacOSX" and
|
||||
not (ansible_distribution == "CentOS" and ansible_distribution_major_version is version('7.0', '<'))
|
||||
}}
|
||||
copy_to: "{{ remote_tmp_dir }}"
|
||||
path_prefix: "{{ remote_tmp_dir }}"
|
||||
arg_formats:
|
||||
aa:
|
||||
func: as_opt_eq_val
|
||||
args: [--answer]
|
||||
tt:
|
||||
func: as_opt_val
|
||||
args: [--tt-arg]
|
||||
arg_order: 'aa tt'
|
||||
arg_values:
|
||||
tt: potatoes
|
||||
aa: 11
|
||||
assertions:
|
||||
- test_result.rc == 0
|
||||
- test_result.out == "-- --answer=11 --tt-arg potatoes\n"
|
||||
- test_result.err == ""
|
||||
|
||||
- name: use cmd never-existed
|
||||
cmd: never-existed
|
||||
arg_formats:
|
||||
aa:
|
||||
func: as_opt_eq_val
|
||||
args: [--answer]
|
||||
tt:
|
||||
func: as_opt_val
|
||||
args: [--tt-arg]
|
||||
arg_order: 'aa tt'
|
||||
arg_values:
|
||||
tt: potatoes
|
||||
aa: 11
|
||||
expect_error: true
|
||||
assertions:
|
||||
- >
|
||||
"Failed to find required executable" in test_result.msg
|
||||
|
||||
- name: use cmd /usr/bin/never-existed
|
||||
cmd: /usr/bin/never-existed
|
||||
arg_formats:
|
||||
aa:
|
||||
func: as_opt_eq_val
|
||||
args: [--answer]
|
||||
tt:
|
||||
func: as_opt_val
|
||||
args: [--tt-arg]
|
||||
arg_order: 'aa tt'
|
||||
arg_values:
|
||||
tt: potatoes
|
||||
aa: 11
|
||||
expect_error: true
|
||||
assertions:
|
||||
- >
|
||||
"No such file or directory" in test_result.msg
|
||||
|
||||
@@ -11,3 +11,4 @@ skip/rhel9.0
|
||||
skip/rhel9.1
|
||||
skip/rhel9.2
|
||||
skip/freebsd
|
||||
skip/python2.6
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
- when:
|
||||
- ansible_os_family != 'Archlinux' # TODO install driver from AUR: https://aur.archlinux.org/packages/psqlodbc
|
||||
- ansible_os_family != 'RedHat' or ansible_distribution_major_version != '7' # CentOS 7 stopped working
|
||||
block:
|
||||
|
||||
#
|
||||
|
||||
@@ -4,13 +4,14 @@
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
- vars:
|
||||
package_name: xinetd
|
||||
config_file: /etc/xinetd.conf
|
||||
package_name: mdadm
|
||||
config_file: /etc/mdadm.conf
|
||||
block:
|
||||
- name: Make sure that {{ package_name }} is not installed
|
||||
pacman:
|
||||
name: '{{ package_name }}'
|
||||
state: absent
|
||||
|
||||
- name: Make sure {{config_file}}.pacsave file doesn't exist
|
||||
file:
|
||||
path: '{{config_file}}.pacsave'
|
||||
@@ -32,6 +33,7 @@
|
||||
pacman:
|
||||
name: '{{ package_name }}'
|
||||
state: absent
|
||||
|
||||
- name: Make sure {{config_file}}.pacsave exists
|
||||
stat:
|
||||
path: '{{config_file}}.pacsave'
|
||||
|
||||
@@ -21,3 +21,8 @@
|
||||
update_cache: true
|
||||
upgrade: true
|
||||
when: archlinux_upgrade_tag is changed
|
||||
|
||||
- name: Remove EXTERNALLY-MANAGED file
|
||||
file:
|
||||
path: /usr/lib/python{{ ansible_python.version.major }}.{{ ansible_python.version.minor }}/EXTERNALLY-MANAGED
|
||||
state: absent
|
||||
|
||||
@@ -6,20 +6,81 @@
|
||||
from __future__ import (absolute_import, division, print_function)
|
||||
__metaclass__ = type
|
||||
|
||||
import pytest
|
||||
import sys
|
||||
|
||||
from io import StringIO
|
||||
|
||||
from ansible_collections.community.general.tests.unit.compat import unittest
|
||||
from ansible_collections.community.general.plugins.connection import lxc
|
||||
from ansible.errors import AnsibleError
|
||||
from ansible.playbook.play_context import PlayContext
|
||||
from ansible.plugins.loader import connection_loader
|
||||
from ansible_collections.community.general.tests.unit.compat import mock
|
||||
|
||||
|
||||
class TestLXCConnectionClass(unittest.TestCase):
|
||||
@pytest.fixture(autouse=True)
|
||||
def lxc(request):
|
||||
"""Fixture to import/load the lxc plugin module.
|
||||
|
||||
def test_lxc_connection_module(self):
|
||||
The fixture parameter is used to determine the presence of liblxc.
|
||||
When true (default), a mocked liblxc module is injected. If False,
|
||||
no liblxc will be present.
|
||||
"""
|
||||
liblxc_present = getattr(request, 'param', True)
|
||||
|
||||
class ContainerMock(mock.MagicMock):
|
||||
def __init__(self, name):
|
||||
super(ContainerMock, self).__init__()
|
||||
self.name = name
|
||||
self.state = 'STARTED'
|
||||
|
||||
liblxc_module_mock = mock.MagicMock()
|
||||
liblxc_module_mock.Container = ContainerMock
|
||||
|
||||
with mock.patch.dict('sys.modules'):
|
||||
if liblxc_present:
|
||||
sys.modules['lxc'] = liblxc_module_mock
|
||||
elif 'lxc' in sys.modules:
|
||||
del sys.modules['lxc']
|
||||
|
||||
from ansible_collections.community.general.plugins.connection import lxc as lxc_plugin_module
|
||||
|
||||
assert lxc_plugin_module.HAS_LIBLXC == liblxc_present
|
||||
assert bool(getattr(lxc_plugin_module, '_lxc', None)) == liblxc_present
|
||||
|
||||
yield lxc_plugin_module
|
||||
|
||||
|
||||
class TestLXCConnectionClass():
|
||||
|
||||
@pytest.mark.parametrize('lxc', [True, False], indirect=True)
|
||||
def test_lxc_connection_module(self, lxc):
|
||||
"""Test that a connection can be created with the plugin."""
|
||||
play_context = PlayContext()
|
||||
play_context.prompt = (
|
||||
'[sudo via ansible, key=ouzmdnewuhucvuaabtjmweasarviygqq] password: '
|
||||
)
|
||||
in_stream = StringIO()
|
||||
|
||||
self.assertIsInstance(lxc.Connection(play_context, in_stream), lxc.Connection)
|
||||
conn = connection_loader.get('lxc', play_context, in_stream)
|
||||
assert conn
|
||||
assert isinstance(conn, lxc.Connection)
|
||||
|
||||
@pytest.mark.parametrize('lxc', [False], indirect=True)
|
||||
def test_lxc_connection_liblxc_error(self, lxc):
|
||||
"""Test that on connect an error is thrown if liblxc is not present."""
|
||||
play_context = PlayContext()
|
||||
in_stream = StringIO()
|
||||
conn = connection_loader.get('lxc', play_context, in_stream)
|
||||
|
||||
with pytest.raises(AnsibleError, match='lxc python bindings are not installed'):
|
||||
conn._connect()
|
||||
|
||||
def test_remote_addr_option(self):
|
||||
"""Test that the remote_addr option is used"""
|
||||
play_context = PlayContext()
|
||||
in_stream = StringIO()
|
||||
conn = connection_loader.get('lxc', play_context, in_stream)
|
||||
|
||||
container_name = 'my-container'
|
||||
conn.set_option('remote_addr', container_name)
|
||||
assert conn.get_option('remote_addr') == container_name
|
||||
|
||||
conn._connect()
|
||||
assert conn.container_name == container_name
|
||||
|
||||
@@ -81,5 +81,47 @@ MOCK_ENTRIES = {
|
||||
"expected": ["first value"],
|
||||
"output": load_file("v2_out_03.json")
|
||||
},
|
||||
{
|
||||
# Request data from an omitted value (label lookup, no section)
|
||||
"vault_name": "Test Vault",
|
||||
"queries": ["Omitted values"],
|
||||
"kwargs": {
|
||||
"field": "label-without-value",
|
||||
},
|
||||
"expected": [""],
|
||||
"output": load_file("v2_out_04.json")
|
||||
},
|
||||
{
|
||||
# Request data from an omitted value (id lookup, no section)
|
||||
"vault_name": "Test Vault",
|
||||
"queries": ["Omitted values"],
|
||||
"kwargs": {
|
||||
"field": "67890q7mspf4x6zrlw3qejn7m",
|
||||
},
|
||||
"expected": [""],
|
||||
"output": load_file("v2_out_04.json")
|
||||
},
|
||||
{
|
||||
# Request data from an omitted value (label lookup, with section)
|
||||
"vault_name": "Test Vault",
|
||||
"queries": ["Omitted values"],
|
||||
"kwargs": {
|
||||
"field": "section-label-without-value",
|
||||
"section": "section-without-values"
|
||||
},
|
||||
"expected": [""],
|
||||
"output": load_file("v2_out_04.json")
|
||||
},
|
||||
{
|
||||
# Request data from an omitted value (id lookup, with section)
|
||||
"vault_name": "Test Vault",
|
||||
"queries": ["Omitted values"],
|
||||
"kwargs": {
|
||||
"field": "123345q7mspf4x6zrlw3qejn7m",
|
||||
"section": "section-without-values",
|
||||
},
|
||||
"expected": [""],
|
||||
"output": load_file("v2_out_04.json")
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
{
|
||||
"id": "bgqegp3xcxnpfkb45olwigpkpi",
|
||||
"title": "OmittedValues",
|
||||
"version": 1,
|
||||
"vault": {
|
||||
"id": "stpebbaccrq72xulgouxsk4p7y",
|
||||
"name": "Private"
|
||||
},
|
||||
"category": "LOGIN",
|
||||
"last_edited_by": "WOUTERRUYBH7BFPHMZ2KKGL6AU",
|
||||
"created_at": "2023-09-12T08:30:07Z",
|
||||
"updated_at": "2023-09-12T08:30:07Z",
|
||||
"additional_information": "fluxility",
|
||||
"sections": [
|
||||
{
|
||||
"id": "7osqcvd43i75teocdzbb6d7mie",
|
||||
"label": "section-without-values"
|
||||
}
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"id": "username",
|
||||
"type": "STRING",
|
||||
"purpose": "USERNAME",
|
||||
"label": "username",
|
||||
"value": "fluxility",
|
||||
"reference": "op://Testcase/OmittedValues/username"
|
||||
},
|
||||
{
|
||||
"id": "password",
|
||||
"type": "CONCEALED",
|
||||
"purpose": "PASSWORD",
|
||||
"label": "password",
|
||||
"value": "j89Dyb7psat*hkbkyLUQyq@GR.a-g2pQH_V_xtMhrn37rQ_2uRYoRiozj6TjWVLy2pbfEvjnse",
|
||||
"entropy": 427.01202392578125,
|
||||
"reference": "op://Testcase/OmittedValues/password",
|
||||
"password_details": {
|
||||
"entropy": 427,
|
||||
"generated": true,
|
||||
"strength": "FANTASTIC"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "notesPlain",
|
||||
"type": "STRING",
|
||||
"purpose": "NOTES",
|
||||
"label": "notesPlain",
|
||||
"reference": "op://Testcase/OmittedValues/notesPlain"
|
||||
},
|
||||
{
|
||||
"id": "67890q7mspf4x6zrlw3qejn7m",
|
||||
"type": "URL",
|
||||
"label": "label-without-value",
|
||||
"reference": "op://01202392578125/OmittedValues/section-without-values/section-without-value"
|
||||
},
|
||||
{
|
||||
"id": "123345q7mspf4x6zrlw3qejn7m",
|
||||
"section": {
|
||||
"id": "6hbtca5yrlmoptgy3nw74222",
|
||||
"label": "section-without-values"
|
||||
},
|
||||
"type": "URL",
|
||||
"label": "section-label-without-value",
|
||||
"reference": "op://01202392578125/OmittedValues/section-without-values/section-without-value"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
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
|
||||
SPDX-FileCopyrightText: 2022, Ansible Project
|
||||
102
tests/unit/plugins/modules/cmd_runner_test_utils.py
Normal file
102
tests/unit/plugins/modules/cmd_runner_test_utils.py
Normal file
@@ -0,0 +1,102 @@
|
||||
# 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
|
||||
|
||||
|
||||
from __future__ import (absolute_import, division, print_function)
|
||||
__metaclass__ = type
|
||||
|
||||
from collections import namedtuple
|
||||
from itertools import chain, repeat
|
||||
|
||||
import pytest
|
||||
import yaml
|
||||
|
||||
|
||||
ModuleTestCase = namedtuple("ModuleTestCase", ["id", "input", "output", "run_command_calls"])
|
||||
RunCmdCall = namedtuple("RunCmdCall", ["command", "environ", "rc", "out", "err"])
|
||||
|
||||
|
||||
class CmdRunnerTestHelper(object):
|
||||
def __init__(self, test_cases):
|
||||
self._test_cases = test_cases
|
||||
if isinstance(test_cases, (list, tuple)):
|
||||
self.testcases = test_cases
|
||||
else:
|
||||
self.testcases = self._make_test_cases()
|
||||
|
||||
@property
|
||||
def cmd_fixture(self):
|
||||
@pytest.fixture
|
||||
def patch_bin(mocker):
|
||||
def mockie(self, path, *args, **kwargs):
|
||||
return "/testbin/{0}".format(path)
|
||||
mocker.patch('ansible.module_utils.basic.AnsibleModule.get_bin_path', mockie)
|
||||
|
||||
return patch_bin
|
||||
|
||||
def _make_test_cases(self):
|
||||
test_cases = yaml.safe_load(self._test_cases)
|
||||
|
||||
results = []
|
||||
for tc in test_cases:
|
||||
tc["run_command_calls"] = [RunCmdCall(**r) for r in tc["run_command_calls"]] if tc.get("run_command_calls") else []
|
||||
|
||||
results.append(ModuleTestCase(**tc))
|
||||
|
||||
return results
|
||||
|
||||
@property
|
||||
def testcases_params(self):
|
||||
return [[x.input, x] for x in self.testcases]
|
||||
|
||||
@property
|
||||
def testcases_ids(self):
|
||||
return [item.id for item in self.testcases]
|
||||
|
||||
def __call__(self, testcase, mocker):
|
||||
return _Context(self, testcase, mocker)
|
||||
|
||||
|
||||
class _Context(object):
|
||||
def __init__(self, helper, testcase, mocker):
|
||||
self.helper = helper
|
||||
self.testcase = testcase
|
||||
self.mocker = mocker
|
||||
|
||||
self.run_cmd_calls = self.testcase.run_command_calls
|
||||
self.mock_run_cmd = self._make_mock_run_cmd()
|
||||
|
||||
def _make_mock_run_cmd(self):
|
||||
call_results = [(x.rc, x.out, x.err) for x in self.run_cmd_calls]
|
||||
error_call_results = (123,
|
||||
"OUT: testcase has not enough run_command calls",
|
||||
"ERR: testcase has not enough run_command calls")
|
||||
mock_run_command = self.mocker.patch('ansible.module_utils.basic.AnsibleModule.run_command',
|
||||
side_effect=chain(call_results, repeat(error_call_results)))
|
||||
return mock_run_command
|
||||
|
||||
def __enter__(self):
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type, exc_val, exc_tb):
|
||||
return False
|
||||
|
||||
def check_results(self, results):
|
||||
print("testcase =\n%s" % str(self.testcase))
|
||||
print("results =\n%s" % results)
|
||||
if 'exception' in results:
|
||||
print("exception = \n%s" % results["exception"])
|
||||
|
||||
for test_result in self.testcase.output:
|
||||
assert results[test_result] == self.testcase.output[test_result], \
|
||||
"'{0}': '{1}' != '{2}'".format(test_result, results[test_result], self.testcase.output[test_result])
|
||||
|
||||
call_args_list = [(item[0][0], item[1]) for item in self.mock_run_cmd.call_args_list]
|
||||
expected_call_args_list = [(item.command, item.environ) for item in self.run_cmd_calls]
|
||||
print("call args list =\n%s" % call_args_list)
|
||||
print("expected args list =\n%s" % expected_call_args_list)
|
||||
|
||||
assert self.mock_run_cmd.call_count == len(self.run_cmd_calls)
|
||||
if self.mock_run_cmd.call_count:
|
||||
assert call_args_list == expected_call_args_list
|
||||
@@ -7,235 +7,34 @@ from __future__ import (absolute_import, division, print_function)
|
||||
__metaclass__ = type
|
||||
|
||||
import json
|
||||
|
||||
from collections import namedtuple
|
||||
from ansible_collections.community.general.plugins.modules import opkg
|
||||
from ansible_collections.community.general.plugins.modules import opkg as module
|
||||
|
||||
import pytest
|
||||
|
||||
TESTED_MODULE = opkg.__name__
|
||||
from .cmd_runner_test_utils import CmdRunnerTestHelper
|
||||
|
||||
|
||||
ModuleTestCase = namedtuple("ModuleTestCase", ["id", "input", "output", "run_command_calls"])
|
||||
RunCmdCall = namedtuple("RunCmdCall", ["command", "environ", "rc", "out", "err"])
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def patch_opkg(mocker):
|
||||
mocker.patch('ansible.module_utils.basic.AnsibleModule.get_bin_path', return_value='/testbin/opkg')
|
||||
|
||||
|
||||
TEST_CASES = [
|
||||
ModuleTestCase(
|
||||
id="install_zlibdev",
|
||||
input={"name": "zlib-dev", "state": "present"},
|
||||
output={
|
||||
"msg": "installed 1 package(s)"
|
||||
},
|
||||
run_command_calls=[
|
||||
RunCmdCall(
|
||||
command=["/testbin/opkg", "list-installed", "zlib-dev"],
|
||||
environ={'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': False},
|
||||
rc=0,
|
||||
out="",
|
||||
err="",
|
||||
),
|
||||
RunCmdCall(
|
||||
command=["/testbin/opkg", "install", "zlib-dev"],
|
||||
environ={'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': False},
|
||||
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="",
|
||||
),
|
||||
RunCmdCall(
|
||||
command=["/testbin/opkg", "list-installed", "zlib-dev"],
|
||||
environ={'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': False},
|
||||
rc=0,
|
||||
out="zlib-dev - 1.2.11-6\n",
|
||||
err="",
|
||||
),
|
||||
],
|
||||
),
|
||||
ModuleTestCase(
|
||||
id="install_zlibdev_present",
|
||||
input={"name": "zlib-dev", "state": "present"},
|
||||
output={
|
||||
"msg": "package(s) already present"
|
||||
},
|
||||
run_command_calls=[
|
||||
RunCmdCall(
|
||||
command=["/testbin/opkg", "list-installed", "zlib-dev"],
|
||||
environ={'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': False},
|
||||
rc=0,
|
||||
out="zlib-dev - 1.2.11-6\n",
|
||||
err="",
|
||||
),
|
||||
],
|
||||
),
|
||||
ModuleTestCase(
|
||||
id="install_zlibdev_force_reinstall",
|
||||
input={"name": "zlib-dev", "state": "present", "force": "reinstall"},
|
||||
output={
|
||||
"msg": "installed 1 package(s)"
|
||||
},
|
||||
run_command_calls=[
|
||||
RunCmdCall(
|
||||
command=["/testbin/opkg", "list-installed", "zlib-dev"],
|
||||
environ={'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': False},
|
||||
rc=0,
|
||||
out="zlib-dev - 1.2.11-6\n",
|
||||
err="",
|
||||
),
|
||||
RunCmdCall(
|
||||
command=["/testbin/opkg", "install", "--force-reinstall", "zlib-dev"],
|
||||
environ={'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': False},
|
||||
rc=0,
|
||||
out=(
|
||||
"Installing zlib-dev (1.2.11-6) to root...\n"
|
||||
"Downloading https://downloads.openwrt.org/releases/22.03.0/packages/mips_24kc/base/zlib-dev_1.2.11-6_mips_24kc.ipk\n"
|
||||
"Configuring zlib-dev.\n"
|
||||
),
|
||||
err="",
|
||||
),
|
||||
RunCmdCall(
|
||||
command=["/testbin/opkg", "list-installed", "zlib-dev"],
|
||||
environ={'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': False},
|
||||
rc=0,
|
||||
out="zlib-dev - 1.2.11-6\n",
|
||||
err="",
|
||||
),
|
||||
],
|
||||
),
|
||||
ModuleTestCase(
|
||||
id="install_zlibdev_with_version",
|
||||
input={"name": "zlib-dev=1.2.11-6", "state": "present"},
|
||||
output={
|
||||
"msg": "installed 1 package(s)"
|
||||
},
|
||||
run_command_calls=[
|
||||
RunCmdCall(
|
||||
command=["/testbin/opkg", "list-installed", "zlib-dev"],
|
||||
environ={'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': False},
|
||||
rc=0,
|
||||
out="",
|
||||
err="",
|
||||
),
|
||||
RunCmdCall(
|
||||
command=["/testbin/opkg", "install", "zlib-dev=1.2.11-6"],
|
||||
environ={'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': False},
|
||||
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="",
|
||||
),
|
||||
RunCmdCall(
|
||||
command=["/testbin/opkg", "list-installed", "zlib-dev"],
|
||||
environ={'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': False},
|
||||
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="",
|
||||
),
|
||||
],
|
||||
),
|
||||
ModuleTestCase(
|
||||
id="install_vim_updatecache",
|
||||
input={"name": "vim-fuller", "state": "present", "update_cache": True},
|
||||
output={
|
||||
"msg": "installed 1 package(s)"
|
||||
},
|
||||
run_command_calls=[
|
||||
RunCmdCall(
|
||||
command=["/testbin/opkg", "update"],
|
||||
environ={'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': False},
|
||||
rc=0,
|
||||
out="",
|
||||
err="",
|
||||
),
|
||||
RunCmdCall(
|
||||
command=["/testbin/opkg", "list-installed", "vim-fuller"],
|
||||
environ={'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': False},
|
||||
rc=0,
|
||||
out="",
|
||||
err="",
|
||||
),
|
||||
RunCmdCall(
|
||||
command=["/testbin/opkg", "install", "vim-fuller"],
|
||||
environ={'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': False},
|
||||
rc=0,
|
||||
out=(
|
||||
"Multiple packages (libgcc1 and libgcc1) providing same name marked HOLD or PREFER. Using latest.\n"
|
||||
"Installing vim-fuller (9.0-1) to root...\n"
|
||||
"Downloading https://downloads.openwrt.org/snapshots/packages/x86_64/packages/vim-fuller_9.0-1_x86_64.ipk\n"
|
||||
"Installing terminfo (6.4-2) to root...\n"
|
||||
"Downloading https://downloads.openwrt.org/snapshots/packages/x86_64/base/terminfo_6.4-2_x86_64.ipk\n"
|
||||
"Installing libncurses6 (6.4-2) to root...\n"
|
||||
"Downloading https://downloads.openwrt.org/snapshots/packages/x86_64/base/libncurses6_6.4-2_x86_64.ipk\n"
|
||||
"Configuring terminfo.\n"
|
||||
"Configuring libncurses6.\n"
|
||||
"Configuring vim-fuller.\n"
|
||||
),
|
||||
err="",
|
||||
),
|
||||
RunCmdCall(
|
||||
command=["/testbin/opkg", "list-installed", "vim-fuller"],
|
||||
environ={'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': False},
|
||||
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="",
|
||||
),
|
||||
],
|
||||
),
|
||||
]
|
||||
TEST_CASES_IDS = [item.id for item in TEST_CASES]
|
||||
TESTED_MODULE = module.__name__
|
||||
with open("tests/unit/plugins/modules/test_opkg.yaml", "r") as TEST_CASES:
|
||||
helper = CmdRunnerTestHelper(test_cases=TEST_CASES)
|
||||
patch_bin = helper.cmd_fixture
|
||||
|
||||
|
||||
@pytest.mark.parametrize('patch_ansible_module, testcase',
|
||||
[[x.input, x] for x in TEST_CASES],
|
||||
ids=TEST_CASES_IDS,
|
||||
helper.testcases_params, ids=helper.testcases_ids,
|
||||
indirect=['patch_ansible_module'])
|
||||
@pytest.mark.usefixtures('patch_ansible_module')
|
||||
def test_opkg(mocker, capfd, patch_opkg, testcase):
|
||||
def test_module(mocker, capfd, patch_bin, testcase):
|
||||
"""
|
||||
Run unit tests for test cases listen in TEST_CASES
|
||||
Run unit tests for test cases listed in TEST_CASES
|
||||
"""
|
||||
|
||||
run_cmd_calls = testcase.run_command_calls
|
||||
with helper(testcase, mocker) as ctx:
|
||||
# Try to run test case
|
||||
with pytest.raises(SystemExit):
|
||||
module.main()
|
||||
|
||||
# Mock function used for running commands first
|
||||
call_results = [(x.rc, x.out, x.err) for x in run_cmd_calls]
|
||||
mock_run_command = mocker.patch('ansible.module_utils.basic.AnsibleModule.run_command', side_effect=call_results)
|
||||
out, err = capfd.readouterr()
|
||||
results = json.loads(out)
|
||||
|
||||
# Try to run test case
|
||||
with pytest.raises(SystemExit):
|
||||
opkg.main()
|
||||
|
||||
out, err = capfd.readouterr()
|
||||
results = json.loads(out)
|
||||
print("testcase =\n%s" % str(testcase))
|
||||
print("results =\n%s" % results)
|
||||
|
||||
for test_result in testcase.output:
|
||||
assert results[test_result] == testcase.output[test_result], \
|
||||
"'{0}': '{1}' != '{2}'".format(test_result, results[test_result], testcase.output[test_result])
|
||||
|
||||
call_args_list = [(item[0][0], item[1]) for item in mock_run_command.call_args_list]
|
||||
expected_call_args_list = [(item.command, item.environ) for item in run_cmd_calls]
|
||||
print("call args list =\n%s" % call_args_list)
|
||||
print("expected args list =\n%s" % expected_call_args_list)
|
||||
|
||||
assert mock_run_command.call_count == len(run_cmd_calls)
|
||||
if mock_run_command.call_count:
|
||||
assert call_args_list == expected_call_args_list
|
||||
ctx.check_results(results)
|
||||
|
||||
142
tests/unit/plugins/modules/test_opkg.yaml
Normal file
142
tests/unit/plugins/modules/test_opkg.yaml
Normal file
@@ -0,0 +1,142 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) Alexei Znamensky (russoz@gmail.com)
|
||||
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
---
|
||||
- id: install_zlibdev
|
||||
input:
|
||||
name: zlib-dev
|
||||
state: present
|
||||
output:
|
||||
msg: installed 1 package(s)
|
||||
run_command_calls:
|
||||
- command: [/testbin/opkg, list-installed, zlib-dev]
|
||||
environ: {environ_update: {LANGUAGE: C, LC_ALL: C}, check_rc: false}
|
||||
rc: 0
|
||||
out: ""
|
||||
err: ""
|
||||
- command: [/testbin/opkg, install, zlib-dev]
|
||||
environ: {environ_update: {LANGUAGE: C, LC_ALL: C}, check_rc: false}
|
||||
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: {environ_update: {LANGUAGE: C, LC_ALL: C}, check_rc: false}
|
||||
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
|
||||
run_command_calls:
|
||||
- command: [/testbin/opkg, list-installed, zlib-dev]
|
||||
environ: {environ_update: {LANGUAGE: C, LC_ALL: C}, check_rc: false}
|
||||
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)
|
||||
run_command_calls:
|
||||
- command: [/testbin/opkg, list-installed, zlib-dev]
|
||||
environ: {environ_update: {LANGUAGE: C, LC_ALL: C}, check_rc: false}
|
||||
rc: 0
|
||||
out: |
|
||||
zlib-dev - 1.2.11-6
|
||||
err: ""
|
||||
- command: [/testbin/opkg, install, --force-reinstall, zlib-dev]
|
||||
environ: {environ_update: {LANGUAGE: C, LC_ALL: C}, check_rc: false}
|
||||
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: {environ_update: {LANGUAGE: C, LC_ALL: C}, check_rc: false}
|
||||
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)
|
||||
run_command_calls:
|
||||
- command: [/testbin/opkg, list-installed, zlib-dev]
|
||||
environ: {environ_update: {LANGUAGE: C, LC_ALL: C}, check_rc: false}
|
||||
rc: 0
|
||||
out: ""
|
||||
err: ""
|
||||
- command: [/testbin/opkg, install, zlib-dev=1.2.11-6]
|
||||
environ: {environ_update: {LANGUAGE: C, LC_ALL: C}, check_rc: false}
|
||||
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: {environ_update: {LANGUAGE: C, LC_ALL: C}, check_rc: false}
|
||||
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)
|
||||
run_command_calls:
|
||||
- command: [/testbin/opkg, update]
|
||||
environ: {environ_update: {LANGUAGE: C, LC_ALL: C}, check_rc: false}
|
||||
rc: 0
|
||||
out: ""
|
||||
err: ""
|
||||
- command: [/testbin/opkg, list-installed, vim-fuller]
|
||||
environ: {environ_update: {LANGUAGE: C, LC_ALL: C}, check_rc: false}
|
||||
rc: 0
|
||||
out: ""
|
||||
err: ""
|
||||
- command: [/testbin/opkg, install, vim-fuller]
|
||||
environ: {environ_update: {LANGUAGE: C, LC_ALL: C}, check_rc: false}
|
||||
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: {environ_update: {LANGUAGE: C, LC_ALL: C}, check_rc: false}
|
||||
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: ""
|
||||
@@ -13,300 +13,34 @@ from __future__ import (absolute_import, division, print_function)
|
||||
__metaclass__ = type
|
||||
|
||||
import json
|
||||
|
||||
from ansible_collections.community.general.plugins.modules import xfconf
|
||||
from ansible_collections.community.general.plugins.modules import xfconf as module
|
||||
|
||||
import pytest
|
||||
|
||||
TESTED_MODULE = xfconf.__name__
|
||||
from .cmd_runner_test_utils import CmdRunnerTestHelper
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def patch_xfconf(mocker):
|
||||
"""
|
||||
Function used for mocking some parts of redhat_subscription module
|
||||
"""
|
||||
mocker.patch('ansible_collections.community.general.plugins.module_utils.mh.module_helper.AnsibleModule.get_bin_path',
|
||||
return_value='/testbin/xfconf-query')
|
||||
|
||||
|
||||
@pytest.mark.parametrize('patch_ansible_module', [{}], indirect=['patch_ansible_module'])
|
||||
@pytest.mark.usefixtures('patch_ansible_module')
|
||||
def test_without_required_parameters(capfd, patch_xfconf):
|
||||
"""
|
||||
Failure must occurs when all parameters are missing
|
||||
"""
|
||||
with pytest.raises(SystemExit):
|
||||
xfconf.main()
|
||||
out, err = capfd.readouterr()
|
||||
results = json.loads(out)
|
||||
assert results['failed']
|
||||
assert 'missing required arguments' in results['msg']
|
||||
|
||||
|
||||
TEST_CASES = [
|
||||
[
|
||||
{
|
||||
'channel': 'xfwm4',
|
||||
'property': '/general/inactive_opacity',
|
||||
'state': 'present',
|
||||
'value_type': 'int',
|
||||
'value': 90,
|
||||
},
|
||||
{
|
||||
'id': 'test_property_set_property',
|
||||
'run_command.calls': [
|
||||
(
|
||||
# Calling of following command will be asserted
|
||||
['/testbin/xfconf-query', '--channel', 'xfwm4', '--property', '/general/inactive_opacity'],
|
||||
# Was return code checked?
|
||||
{'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': False},
|
||||
# Mock of returned code, stdout and stderr
|
||||
(0, '100\n', '',),
|
||||
),
|
||||
(
|
||||
# Calling of following command will be asserted
|
||||
['/testbin/xfconf-query', '--channel', 'xfwm4', '--property', '/general/inactive_opacity',
|
||||
'--create', '--type', 'int', '--set', '90'],
|
||||
# Was return code checked?
|
||||
{'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': False},
|
||||
# Mock of returned code, stdout and stderr
|
||||
(0, '', '',),
|
||||
),
|
||||
],
|
||||
'changed': True,
|
||||
'previous_value': '100',
|
||||
'value_type': 'int',
|
||||
'value': '90',
|
||||
},
|
||||
],
|
||||
[
|
||||
{
|
||||
'channel': 'xfwm4',
|
||||
'property': '/general/inactive_opacity',
|
||||
'state': 'present',
|
||||
'value_type': 'int',
|
||||
'value': 90,
|
||||
},
|
||||
{
|
||||
'id': 'test_property_set_property_same_value',
|
||||
'run_command.calls': [
|
||||
(
|
||||
# Calling of following command will be asserted
|
||||
['/testbin/xfconf-query', '--channel', 'xfwm4', '--property', '/general/inactive_opacity'],
|
||||
# Was return code checked?
|
||||
{'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': False},
|
||||
# Mock of returned code, stdout and stderr
|
||||
(0, '90\n', '',),
|
||||
),
|
||||
(
|
||||
# Calling of following command will be asserted
|
||||
['/testbin/xfconf-query', '--channel', 'xfwm4', '--property', '/general/inactive_opacity',
|
||||
'--create', '--type', 'int', '--set', '90'],
|
||||
# Was return code checked?
|
||||
{'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': False},
|
||||
# Mock of returned code, stdout and stderr
|
||||
(0, '', '',),
|
||||
),
|
||||
],
|
||||
'changed': False,
|
||||
'previous_value': '90',
|
||||
'value_type': 'int',
|
||||
'value': '90',
|
||||
},
|
||||
],
|
||||
[
|
||||
{
|
||||
'channel': 'xfce4-session',
|
||||
'property': '/general/SaveOnExit',
|
||||
'state': 'present',
|
||||
'value_type': 'bool',
|
||||
'value': False,
|
||||
},
|
||||
{
|
||||
'id': 'test_property_set_property_bool_false',
|
||||
'run_command.calls': [
|
||||
(
|
||||
# Calling of following command will be asserted
|
||||
['/testbin/xfconf-query', '--channel', 'xfce4-session', '--property', '/general/SaveOnExit'],
|
||||
# Was return code checked?
|
||||
{'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': False},
|
||||
# Mock of returned code, stdout and stderr
|
||||
(0, 'true\n', '',),
|
||||
),
|
||||
(
|
||||
# Calling of following command will be asserted
|
||||
['/testbin/xfconf-query', '--channel', 'xfce4-session', '--property', '/general/SaveOnExit',
|
||||
'--create', '--type', 'bool', '--set', 'false'],
|
||||
# Was return code checked?
|
||||
{'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': False},
|
||||
# Mock of returned code, stdout and stderr
|
||||
(0, 'false\n', '',),
|
||||
),
|
||||
],
|
||||
'changed': True,
|
||||
'previous_value': 'true',
|
||||
'value_type': 'bool',
|
||||
'value': 'False',
|
||||
},
|
||||
],
|
||||
[
|
||||
{
|
||||
'channel': 'xfwm4',
|
||||
'property': '/general/workspace_names',
|
||||
'state': 'present',
|
||||
'value_type': 'string',
|
||||
'value': ['A', 'B', 'C'],
|
||||
},
|
||||
{
|
||||
'id': 'test_property_set_array',
|
||||
'run_command.calls': [
|
||||
(
|
||||
# Calling of following command will be asserted
|
||||
['/testbin/xfconf-query', '--channel', 'xfwm4', '--property', '/general/workspace_names'],
|
||||
# Was return code checked?
|
||||
{'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': False},
|
||||
# Mock of returned code, stdout and stderr
|
||||
(0, 'Value is an array with 3 items:\n\nMain\nWork\nTmp\n', '',),
|
||||
),
|
||||
(
|
||||
# Calling of following command will be asserted
|
||||
['/testbin/xfconf-query', '--channel', 'xfwm4', '--property', '/general/workspace_names',
|
||||
'--create', '--force-array', '--type', 'string', '--set', 'A', '--type', 'string', '--set', 'B',
|
||||
'--type', 'string', '--set', 'C'],
|
||||
# Was return code checked?
|
||||
{'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': False},
|
||||
# Mock of returned code, stdout and stderr
|
||||
(0, '', '',),
|
||||
),
|
||||
],
|
||||
'changed': True,
|
||||
'previous_value': ['Main', 'Work', 'Tmp'],
|
||||
'value_type': ['str', 'str', 'str'],
|
||||
'value': ['A', 'B', 'C'],
|
||||
},
|
||||
],
|
||||
[
|
||||
{
|
||||
'channel': 'xfwm4',
|
||||
'property': '/general/workspace_names',
|
||||
'state': 'present',
|
||||
'value_type': 'string',
|
||||
'value': ['A', 'B', 'C'],
|
||||
},
|
||||
{
|
||||
'id': 'test_property_set_array_to_same_value',
|
||||
'run_command.calls': [
|
||||
(
|
||||
# Calling of following command will be asserted
|
||||
['/testbin/xfconf-query', '--channel', 'xfwm4', '--property', '/general/workspace_names'],
|
||||
# Was return code checked?
|
||||
{'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': False},
|
||||
# Mock of returned code, stdout and stderr
|
||||
(0, 'Value is an array with 3 items:\n\nA\nB\nC\n', '',),
|
||||
),
|
||||
(
|
||||
# Calling of following command will be asserted
|
||||
['/testbin/xfconf-query', '--channel', 'xfwm4', '--property', '/general/workspace_names',
|
||||
'--create', '--force-array', '--type', 'string', '--set', 'A', '--type', 'string', '--set', 'B',
|
||||
'--type', 'string', '--set', 'C'],
|
||||
# Was return code checked?
|
||||
{'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': False},
|
||||
# Mock of returned code, stdout and stderr
|
||||
(0, '', '',),
|
||||
),
|
||||
],
|
||||
'changed': False,
|
||||
'previous_value': ['A', 'B', 'C'],
|
||||
'value_type': ['str', 'str', 'str'],
|
||||
'value': ['A', 'B', 'C'],
|
||||
},
|
||||
],
|
||||
[
|
||||
{
|
||||
'channel': 'xfwm4',
|
||||
'property': '/general/workspace_names',
|
||||
'state': 'absent',
|
||||
},
|
||||
{
|
||||
'id': 'test_property_reset_value',
|
||||
'run_command.calls': [
|
||||
(
|
||||
# Calling of following command will be asserted
|
||||
['/testbin/xfconf-query', '--channel', 'xfwm4', '--property', '/general/workspace_names'],
|
||||
# Was return code checked?
|
||||
{'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': False},
|
||||
# Mock of returned code, stdout and stderr
|
||||
(0, 'Value is an array with 3 items:\n\nA\nB\nC\n', '',),
|
||||
),
|
||||
(
|
||||
# Calling of following command will be asserted
|
||||
['/testbin/xfconf-query', '--channel', 'xfwm4', '--property', '/general/workspace_names',
|
||||
'--reset'],
|
||||
# Was return code checked?
|
||||
{'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': False},
|
||||
# Mock of returned code, stdout and stderr
|
||||
(0, '', '',),
|
||||
),
|
||||
],
|
||||
'changed': True,
|
||||
'previous_value': ['A', 'B', 'C'],
|
||||
'value_type': None,
|
||||
'value': None,
|
||||
},
|
||||
],
|
||||
]
|
||||
TEST_CASES_IDS = [item[1]['id'] for item in TEST_CASES]
|
||||
TESTED_MODULE = module.__name__
|
||||
with open("tests/unit/plugins/modules/test_xfconf.yaml", "r") as TEST_CASES:
|
||||
helper = CmdRunnerTestHelper(test_cases=TEST_CASES)
|
||||
patch_bin = helper.cmd_fixture
|
||||
|
||||
|
||||
@pytest.mark.parametrize('patch_ansible_module, testcase',
|
||||
TEST_CASES,
|
||||
ids=TEST_CASES_IDS,
|
||||
helper.testcases_params, ids=helper.testcases_ids,
|
||||
indirect=['patch_ansible_module'])
|
||||
@pytest.mark.usefixtures('patch_ansible_module')
|
||||
def test_xfconf(mocker, capfd, patch_xfconf, testcase):
|
||||
def test_module(mocker, capfd, patch_bin, testcase):
|
||||
"""
|
||||
Run unit tests for test cases listen in TEST_CASES
|
||||
Run unit tests for test cases listed in TEST_CASES
|
||||
"""
|
||||
|
||||
# Mock function used for running commands first
|
||||
call_results = [item[2] for item in testcase['run_command.calls']]
|
||||
mock_run_command = mocker.patch(
|
||||
'ansible.module_utils.basic.AnsibleModule.run_command',
|
||||
side_effect=call_results)
|
||||
with helper(testcase, mocker) as ctx:
|
||||
# Try to run test case
|
||||
with pytest.raises(SystemExit):
|
||||
module.main()
|
||||
|
||||
# Try to run test case
|
||||
with pytest.raises(SystemExit):
|
||||
xfconf.main()
|
||||
out, err = capfd.readouterr()
|
||||
results = json.loads(out)
|
||||
|
||||
out, err = capfd.readouterr()
|
||||
results = json.loads(out)
|
||||
print("testcase =\n%s" % testcase)
|
||||
print("results =\n%s" % results)
|
||||
|
||||
assert 'changed' in results
|
||||
assert results['changed'] == testcase['changed']
|
||||
|
||||
for test_result in ('channel', 'property'):
|
||||
assert test_result in results, "'{0}' not found in {1}".format(test_result, results)
|
||||
assert results[test_result] == results['invocation']['module_args'][test_result], \
|
||||
"'{0}': '{1}' != '{2}'".format(test_result, results[test_result], results['invocation']['module_args'][test_result])
|
||||
|
||||
assert mock_run_command.call_count == len(testcase['run_command.calls'])
|
||||
if mock_run_command.call_count:
|
||||
call_args_list = [(item[0][0], item[1]) for item in mock_run_command.call_args_list]
|
||||
expected_call_args_list = [(item[0], item[1]) for item in testcase['run_command.calls']]
|
||||
print("call args list =\n%s" % call_args_list)
|
||||
print("expected args list =\n%s" % expected_call_args_list)
|
||||
assert call_args_list == expected_call_args_list
|
||||
|
||||
expected_cmd, dummy, expected_res = testcase['run_command.calls'][-1]
|
||||
assert results['cmd'] == expected_cmd
|
||||
assert results['stdout'] == expected_res[1]
|
||||
assert results['stderr'] == expected_res[2]
|
||||
|
||||
for conditional_test_result in ('msg', 'value', 'previous_value'):
|
||||
if conditional_test_result in testcase:
|
||||
assert conditional_test_result in results, "'{0}' not found in {1}".format(conditional_test_result, results)
|
||||
assert results[conditional_test_result] == testcase[conditional_test_result], \
|
||||
"'{0}': '{1}' != '{2}'".format(conditional_test_result, results[conditional_test_result], testcase[conditional_test_result])
|
||||
ctx.check_results(results)
|
||||
|
||||
185
tests/unit/plugins/modules/test_xfconf.yaml
Normal file
185
tests/unit/plugins/modules/test_xfconf.yaml
Normal file
@@ -0,0 +1,185 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) Alexei Znamensky (russoz@gmail.com)
|
||||
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
---
|
||||
- id: 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'
|
||||
run_command_calls:
|
||||
- command: [/testbin/xfconf-query, --channel, xfwm4, --property, /general/inactive_opacity]
|
||||
environ: {environ_update: {LANGUAGE: C, LC_ALL: C}, check_rc: false}
|
||||
rc: 0
|
||||
out: "100\n"
|
||||
err: ""
|
||||
- command: [/testbin/xfconf-query, --channel, xfwm4, --property, /general/inactive_opacity, --create, --type, int, --set, '90']
|
||||
environ: {environ_update: {LANGUAGE: C, LC_ALL: C}, check_rc: false}
|
||||
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'
|
||||
run_command_calls:
|
||||
- command: [/testbin/xfconf-query, --channel, xfwm4, --property, /general/inactive_opacity]
|
||||
environ: {environ_update: {LANGUAGE: C, LC_ALL: C}, check_rc: false}
|
||||
rc: 0
|
||||
out: "90\n"
|
||||
err: ""
|
||||
- command: [/testbin/xfconf-query, --channel, xfwm4, --property, /general/inactive_opacity, --create, --type, int, --set, '90']
|
||||
environ: {environ_update: {LANGUAGE: C, LC_ALL: C}, check_rc: false}
|
||||
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'
|
||||
run_command_calls:
|
||||
- command: [/testbin/xfconf-query, --channel, xfce4-session, --property, /general/SaveOnExit]
|
||||
environ: {environ_update: {LANGUAGE: C, LC_ALL: C}, check_rc: false}
|
||||
rc: 0
|
||||
out: "true\n"
|
||||
err: ""
|
||||
- command: [/testbin/xfconf-query, --channel, xfce4-session, --property, /general/SaveOnExit, --create, --type, bool, --set, 'false']
|
||||
environ: {environ_update: {LANGUAGE: C, LC_ALL: C}, check_rc: false}
|
||||
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]
|
||||
run_command_calls:
|
||||
- command: [/testbin/xfconf-query, --channel, xfwm4, --property, /general/workspace_names]
|
||||
environ: {environ_update: {LANGUAGE: C, LC_ALL: C}, check_rc: false}
|
||||
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: {environ_update: {LANGUAGE: C, LC_ALL: C}, check_rc: false}
|
||||
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]
|
||||
run_command_calls:
|
||||
- command: [/testbin/xfconf-query, --channel, xfwm4, --property, /general/workspace_names]
|
||||
environ: {environ_update: {LANGUAGE: C, LC_ALL: C}, check_rc: false}
|
||||
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: {environ_update: {LANGUAGE: C, LC_ALL: C}, check_rc: false}
|
||||
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: null
|
||||
value: null
|
||||
run_command_calls:
|
||||
- command: [/testbin/xfconf-query, --channel, xfwm4, --property, /general/workspace_names]
|
||||
environ: {environ_update: {LANGUAGE: C, LC_ALL: C}, check_rc: false}
|
||||
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: {environ_update: {LANGUAGE: C, LC_ALL: C}, check_rc: false}
|
||||
rc: 0
|
||||
out: ""
|
||||
err: ""
|
||||
@@ -6,167 +6,34 @@ from __future__ import (absolute_import, division, print_function)
|
||||
__metaclass__ = type
|
||||
|
||||
import json
|
||||
|
||||
from ansible_collections.community.general.plugins.modules import xfconf_info
|
||||
from ansible_collections.community.general.plugins.modules import xfconf_info as module
|
||||
|
||||
import pytest
|
||||
|
||||
TESTED_MODULE = xfconf_info.__name__
|
||||
from .cmd_runner_test_utils import CmdRunnerTestHelper
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def patch_xfconf_info(mocker):
|
||||
"""
|
||||
Function used for mocking some parts of redhat_subscription module
|
||||
"""
|
||||
mocker.patch('ansible_collections.community.general.plugins.module_utils.mh.module_helper.AnsibleModule.get_bin_path',
|
||||
return_value='/testbin/xfconf-query')
|
||||
|
||||
|
||||
TEST_CASES = [
|
||||
[
|
||||
{'channel': 'xfwm4', 'property': '/general/inactive_opacity'},
|
||||
{
|
||||
'id': 'test_simple_property_get',
|
||||
'run_command.calls': [
|
||||
(
|
||||
# Calling of following command will be asserted
|
||||
['/testbin/xfconf-query', '--channel', 'xfwm4', '--property', '/general/inactive_opacity'],
|
||||
# Was return code checked?
|
||||
{'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': True},
|
||||
# Mock of returned code, stdout and stderr
|
||||
(0, '100\n', '',),
|
||||
),
|
||||
],
|
||||
'is_array': False,
|
||||
'value': '100',
|
||||
}
|
||||
],
|
||||
[
|
||||
{'channel': 'xfwm4', 'property': '/general/i_dont_exist'},
|
||||
{
|
||||
'id': 'test_simple_property_get_nonexistent',
|
||||
'run_command.calls': [
|
||||
(
|
||||
# Calling of following command will be asserted
|
||||
['/testbin/xfconf-query', '--channel', 'xfwm4', '--property', '/general/i_dont_exist'],
|
||||
# Was return code checked?
|
||||
{'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': True},
|
||||
# Mock of returned code, stdout and stderr
|
||||
(1, '', 'Property "/general/i_dont_exist" does not exist on channel "xfwm4".\n',),
|
||||
),
|
||||
],
|
||||
'is_array': False,
|
||||
}
|
||||
],
|
||||
[
|
||||
{'property': '/general/i_dont_exist'},
|
||||
{
|
||||
'id': 'test_property_no_channel',
|
||||
'run_command.calls': [],
|
||||
}
|
||||
],
|
||||
[
|
||||
{'channel': 'xfwm4', 'property': '/general/workspace_names'},
|
||||
{
|
||||
'id': 'test_property_get_array',
|
||||
'run_command.calls': [
|
||||
(
|
||||
# Calling of following command will be asserted
|
||||
['/testbin/xfconf-query', '--channel', 'xfwm4', '--property', '/general/workspace_names'],
|
||||
# Was return code checked?
|
||||
{'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': True},
|
||||
# Mock of returned code, stdout and stderr
|
||||
(0, 'Value is an array with 3 items:\n\nMain\nWork\nTmp\n', '',),
|
||||
),
|
||||
],
|
||||
'is_array': True,
|
||||
'value_array': ['Main', 'Work', 'Tmp'],
|
||||
},
|
||||
],
|
||||
[
|
||||
{},
|
||||
{
|
||||
'id': 'get_channels',
|
||||
'run_command.calls': [
|
||||
(
|
||||
# Calling of following command will be asserted
|
||||
['/testbin/xfconf-query', '--list'],
|
||||
# Was return code checked?
|
||||
{'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': True},
|
||||
# Mock of returned code, stdout and stderr
|
||||
(0, 'Channels:\n a\n b\n c\n', '',),
|
||||
),
|
||||
],
|
||||
'is_array': False,
|
||||
'channels': ['a', 'b', 'c'],
|
||||
},
|
||||
],
|
||||
[
|
||||
{'channel': 'xfwm4'},
|
||||
{
|
||||
'id': 'get_properties',
|
||||
'run_command.calls': [
|
||||
(
|
||||
# Calling of following command will be asserted
|
||||
['/testbin/xfconf-query', '--list', '--channel', 'xfwm4'],
|
||||
# Was return code checked?
|
||||
{'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': True},
|
||||
# Mock of returned code, stdout and stderr
|
||||
(0, '/general/wrap_cycle\n/general/wrap_layout\n/general/wrap_resistance\n/general/wrap_windows\n'
|
||||
'/general/wrap_workspaces\n/general/zoom_desktop\n', '',),
|
||||
),
|
||||
],
|
||||
'is_array': False,
|
||||
'properties': [
|
||||
'/general/wrap_cycle',
|
||||
'/general/wrap_layout',
|
||||
'/general/wrap_resistance',
|
||||
'/general/wrap_windows',
|
||||
'/general/wrap_workspaces',
|
||||
'/general/zoom_desktop',
|
||||
],
|
||||
},
|
||||
],
|
||||
]
|
||||
TEST_CASES_IDS = [item[1]['id'] for item in TEST_CASES]
|
||||
TESTED_MODULE = module.__name__
|
||||
with open("tests/unit/plugins/modules/test_xfconf_info.yaml", "r") as TEST_CASES:
|
||||
helper = CmdRunnerTestHelper(test_cases=TEST_CASES)
|
||||
patch_bin = helper.cmd_fixture
|
||||
|
||||
|
||||
@pytest.mark.parametrize('patch_ansible_module, testcase',
|
||||
TEST_CASES,
|
||||
ids=TEST_CASES_IDS,
|
||||
helper.testcases_params, ids=helper.testcases_ids,
|
||||
indirect=['patch_ansible_module'])
|
||||
@pytest.mark.usefixtures('patch_ansible_module')
|
||||
def test_xfconf_info(mocker, capfd, patch_xfconf_info, testcase):
|
||||
def test_module(mocker, capfd, patch_bin, testcase):
|
||||
"""
|
||||
Run unit tests for test cases listen in TEST_CASES
|
||||
Run unit tests for test cases listed in TEST_CASES
|
||||
"""
|
||||
|
||||
# Mock function used for running commands first
|
||||
call_results = [item[2] for item in testcase['run_command.calls']]
|
||||
mock_run_command = mocker.patch(
|
||||
'ansible_collections.community.general.plugins.module_utils.mh.module_helper.AnsibleModule.run_command',
|
||||
side_effect=call_results)
|
||||
with helper(testcase, mocker) as ctx:
|
||||
# Try to run test case
|
||||
with pytest.raises(SystemExit):
|
||||
module.main()
|
||||
|
||||
# Try to run test case
|
||||
with pytest.raises(SystemExit):
|
||||
xfconf_info.main()
|
||||
out, err = capfd.readouterr()
|
||||
results = json.loads(out)
|
||||
|
||||
out, err = capfd.readouterr()
|
||||
results = json.loads(out)
|
||||
print("testcase =\n%s" % testcase)
|
||||
print("results =\n%s" % results)
|
||||
|
||||
for conditional_test_result in ('value_array', 'value', 'is_array', 'properties', 'channels'):
|
||||
if conditional_test_result in testcase:
|
||||
assert conditional_test_result in results, "'{0}' not found in {1}".format(conditional_test_result, results)
|
||||
assert results[conditional_test_result] == testcase[conditional_test_result], \
|
||||
"'{0}': '{1}' != '{2}'".format(conditional_test_result, results[conditional_test_result], testcase[conditional_test_result])
|
||||
|
||||
assert mock_run_command.call_count == len(testcase['run_command.calls'])
|
||||
if mock_run_command.call_count:
|
||||
call_args_list = [(item[0][0], item[1]) for item in mock_run_command.call_args_list]
|
||||
expected_call_args_list = [(item[0], item[1]) for item in testcase['run_command.calls']]
|
||||
print("call args list =\n%s" % call_args_list)
|
||||
print("expected args list =\n%s" % expected_call_args_list)
|
||||
assert call_args_list == expected_call_args_list
|
||||
ctx.check_results(results)
|
||||
|
||||
83
tests/unit/plugins/modules/test_xfconf_info.yaml
Normal file
83
tests/unit/plugins/modules/test_xfconf_info.yaml
Normal file
@@ -0,0 +1,83 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) Alexei Znamensky (russoz@gmail.com)
|
||||
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
---
|
||||
- id: test_simple_property_get
|
||||
input:
|
||||
channel: xfwm4
|
||||
property: /general/inactive_opacity
|
||||
output:
|
||||
value: '100'
|
||||
is_array: false
|
||||
run_command_calls:
|
||||
- command: [/testbin/xfconf-query, --channel, xfwm4, --property, /general/inactive_opacity]
|
||||
environ: {environ_update: {LANGUAGE: C, LC_ALL: C}, check_rc: true}
|
||||
rc: 0
|
||||
out: "100\n"
|
||||
err: ""
|
||||
- id: test_simple_property_get_nonexistent
|
||||
input:
|
||||
channel: xfwm4
|
||||
property: /general/i_dont_exist
|
||||
output: {}
|
||||
run_command_calls:
|
||||
- command: [/testbin/xfconf-query, --channel, xfwm4, --property, /general/i_dont_exist]
|
||||
environ: {environ_update: {LANGUAGE: C, LC_ALL: C}, check_rc: true}
|
||||
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"
|
||||
run_command_calls: []
|
||||
- id: test_property_get_array
|
||||
input:
|
||||
channel: xfwm4
|
||||
property: /general/workspace_names
|
||||
output:
|
||||
is_array: true
|
||||
value_array: [Main, Work, Tmp]
|
||||
run_command_calls:
|
||||
- command: [/testbin/xfconf-query, --channel, xfwm4, --property, /general/workspace_names]
|
||||
environ: {environ_update: {LANGUAGE: C, LC_ALL: C}, check_rc: true}
|
||||
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]
|
||||
run_command_calls:
|
||||
- command: [/testbin/xfconf-query, --list]
|
||||
environ: {environ_update: {LANGUAGE: C, LC_ALL: C}, check_rc: true}
|
||||
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
|
||||
run_command_calls:
|
||||
- command: [/testbin/xfconf-query, --list, --channel, xfwm4]
|
||||
environ: {environ_update: {LANGUAGE: C, LC_ALL: C}, check_rc: true}
|
||||
rc: 0
|
||||
out: |
|
||||
/general/wrap_cycle
|
||||
/general/wrap_layout
|
||||
/general/wrap_resistance
|
||||
/general/wrap_windows
|
||||
/general/wrap_workspaces
|
||||
/general/zoom_desktop
|
||||
err: ""
|
||||
Reference in New Issue
Block a user