alternatives: handle absent link, add integration tests (#27967)

* alternatives: add integration tests

* alternatives: handle absent link (fix AttributeError)

Error occurred at least on Debian Stretch and OpenSuse 42.2:
Traceback (most recent call last):
  File "/tmp/ansible_RY6X41/ansible_module_alternatives.py", line 161, in <module>
    main()
  File "/tmp/ansible_RY6X41/ansible_module_alternatives.py", line 113, in main
    current_path = current_path_regex.search(display_output).group(1)
AttributeError: 'NoneType' object has no attribute 'group'

update-alternatives stdout sample:
dummy - manual mode
  link best version is /usr/bin/dummy1
  link currently absent
  link dummy is /usr/bin/dummy

* alternatives: PEP 8 fixes

* alternatives: fix copyright in integration tests

* alternatives: nested loops handle more than 2 items

Thanks to Michael Scherer (@mscherer) for pointing that.

* alternatives: enable integration tests
pull/28283/head
Pilou 7 years ago committed by Brian Coca
parent 6886153b54
commit 016cd0691c

@ -77,12 +77,12 @@ from ansible.module_utils.basic import AnsibleModule
def main():
module = AnsibleModule(
argument_spec = dict(
name = dict(required=True),
path = dict(required=True, type='path'),
link = dict(required=False, type='path'),
priority = dict(required=False, type='int',
default=50),
argument_spec=dict(
name=dict(required=True),
path=dict(required=True, type='path'),
link=dict(required=False, type='path'),
priority=dict(required=False, type='int',
default=50),
),
supports_check_mode=True,
)
@ -93,7 +93,7 @@ def main():
link = params['link']
priority = params['priority']
UPDATE_ALTERNATIVES = module.get_bin_path('update-alternatives',True)
UPDATE_ALTERNATIVES = module.get_bin_path('update-alternatives', True)
current_path = None
all_alternatives = []
@ -111,7 +111,9 @@ def main():
re.MULTILINE)
alternative_regex = re.compile(r'^(\/.*)\s-\spriority', re.MULTILINE)
current_path = current_path_regex.search(display_output).group(1)
match = current_path_regex.search(display_output)
if match:
current_path = match.group(1)
all_alternatives = alternative_regex.findall(display_output)
if not link:

@ -0,0 +1,5 @@
posix/ci/group3
destructive
needs/root
skip/freebsd
skip/osx

@ -0,0 +1,62 @@
# Copyright (c) 2017 Pierre-Louis Bonicoli <pierre-louis.bonicoli@libregerbil.fr>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
- name: 'setup: create a dummy alternative'
block:
- import_tasks: setup.yml
##############
# Test parameters:
# link parameter present / absent ('with_link' variable)
# with / without alternatives defined in alternatives file ('with_alternatives' variable)
# auto / manual ('mode' variable)
- include_tasks: tests.yml
with_nested:
- [ True, False ] # with_link
- [ True, False ] # with_alternatives
- [ 'auto', 'manual' ] # mode
loop_control:
loop_var: test_conf
##########
# Priority
- block:
- include_tasks: remove_links.yml
- include_tasks: setup_test.yml
# at least two iterations again
- include_tasks: tests_set_priority.yml
with_sequence: start=3 end=4
vars:
with_alternatives: True
mode: auto
- block:
- include_tasks: remove_links.yml
- include_tasks: setup_test.yml
# at least two iterations again
- include_tasks: tests_set_priority.yml
with_sequence: start=3 end=4
vars:
with_alternatives: False
mode: auto
always:
- include_tasks: remove_links.yml
- file:
path: '{{ item }}'
state: absent
with_items:
- '{{ alternatives_dir }}/dummy'
- file:
path: '/usr/bin/dummy{{ item }}'
state: absent
with_sequence: start=1 end=4
# *Disable tests on Fedora 24*
# Shippable Fedora 24 image provides chkconfig-1.7-2.fc24.x86_64 but not the
# latest available version (chkconfig-1.8-1.fc24.x86_64). update-alternatives
# in chkconfig-1.7-2 fails when /etc/alternatives/dummy link is missing,
# error is: 'failed to read link /usr/bin/dummy: No such file or directory'.
# Moreover Fedora 24 is no longer maintained.
when: ansible_distribution != 'Fedora' or ansible_distribution_major_version|int > 24

@ -0,0 +1,7 @@
- name: remove links
file:
path: '{{ item }}'
state: absent
with_items:
- /etc/alternatives/dummy
- /usr/bin/dummy

@ -0,0 +1,14 @@
- include_vars: '{{ item }}'
with_first_found:
- files:
- '{{ ansible_os_family }}.yml'
- 'default.yml'
paths: '../vars'
- template:
src: dummy_command
dest: '/usr/bin/dummy{{ item }}'
owner: root
group: root
mode: 0755
with_sequence: start=1 end=4

@ -0,0 +1,22 @@
- template:
src: dummy_alternative
dest: '{{ alternatives_dir }}/dummy'
owner: root
group: root
mode: 0644
when: with_alternatives or ansible_os_family != 'RedHat'
# update-alternatives included in Fedora 26 (1.10) & Red Hat 7.4 (1.8) segfaults
# when <admindir>/dummy file contains only mode and link. Hence the file is
# deleted instead of containing only mode and link. The file below works fine with
# newer version of update-alternatives:
# """
# auto
# /usr/bin/dummy
#
#
# """
- file:
path: '{{ alternatives_dir }}/dummy'
state: absent
when: not with_alternatives and ansible_os_family == 'RedHat'

@ -0,0 +1,53 @@
- debug:
msg: ' with_alternatives: {{ with_alternatives }}, mode: {{ mode }}'
- block:
- name: set alternative (using link parameter)
alternatives:
name: dummy
path: '/usr/bin/dummy{{ item }}'
link: '/usr/bin/dummy'
register: alternative
- name: check expected command was executed
assert:
that:
- 'alternative|success'
- 'alternative|changed'
when: with_link
- block:
- name: set alternative (without link parameter)
alternatives:
name: dummy
path: '/usr/bin/dummy{{ item }}'
register: alternative
- name: check expected command was executed
assert:
that:
- 'alternative|success'
- 'alternative|changed'
when: not with_link
- name: execute dummy command
shell: dummy
register: cmd
- name: check expected command was executed
assert:
that:
- 'cmd.stdout == "dummy" ~ item'
- name: 'check mode (manual: alternatives file existed, it has been updated)'
shell: 'head -n1 {{ alternatives_dir }}/dummy | grep "^manual$"'
when: ansible_os_family != 'RedHat' or with_alternatives or item != 1
- name: 'check mode (auto: alternatives file didn''t exist, it has been created)'
shell: 'head -n1 {{ alternatives_dir }}/dummy | grep "^auto$"'
when: ansible_os_family == 'RedHat' and not with_alternatives and item == 1
- name: check that alternative has been updated
command: "grep -Pzq '/bin/dummy{{ item }}\\n' '{{ alternatives_dir }}/dummy'"
# priority doesn't seem updated
#command: "grep -Pzq '/bin/dummy{{ item }}\\n50' '{{ alternatives_dir }}/dummy'"

@ -0,0 +1,15 @@
- block:
- include_tasks: remove_links.yml
- include_tasks: setup_test.yml
# at least two iterations:
# - first will use 'link currently absent',
# - second will receive 'link currently points to'
- include_tasks: test.yml
with_sequence: start=1 end=2
vars:
with_link: '{{ test_conf[0] }}'
with_alternatives: '{{ test_conf[1] }}'
mode: '{{ test_conf[2] }}'
# update-alternatives included in Fedora 26 (1.10) & Red Hat 7.4 (1.8) doesn't provide
# '--query' switch, 'link' is mandatory for these distributions.
when: ansible_os_family != 'RedHat' or test_conf[0]

@ -0,0 +1,23 @@
- name: update dummy alternative
alternatives:
name: dummy
path: '/usr/bin/dummy{{ item }}'
link: /usr/bin/dummy
priority: '{{ 60 + item|int }}'
register: alternative
- name: execute dummy command
shell: dummy
register: cmd
- name: check if link group is in manual mode
shell: 'head -n1 {{ alternatives_dir }}/dummy | grep "^manual$"'
- name: check expected command was executed
assert:
that:
- 'alternative|changed'
- 'cmd.stdout == "dummy{{ item }}"'
- name: check that alternative has been updated
command: "grep -Pzq '/bin/dummy{{ item }}\\n{{ 60 + item|int }}' '{{ alternatives_dir }}/dummy'"

@ -0,0 +1,12 @@
{{ mode }}
/usr/bin/dummy
{% if with_alternatives %}
/usr/bin/dummy1
40
/usr/bin/dummy2
30
{% else %}
{% endif %}

@ -0,0 +1,2 @@
---
alternatives_dir: /var/lib/dpkg/alternatives/

@ -0,0 +1,2 @@
---
alternatives_dir: /var/lib/rpm/alternatives/

@ -0,0 +1,2 @@
---
alternatives_dir: /var/lib/alternatives/

@ -431,7 +431,6 @@ lib/ansible/modules/storage/netapp/sf_volume_access_group_manager.py
lib/ansible/modules/storage/netapp/sf_volume_manager.py
lib/ansible/modules/storage/zfs/zfs.py
lib/ansible/modules/system/aix_inittab.py
lib/ansible/modules/system/alternatives.py
lib/ansible/modules/system/at.py
lib/ansible/modules/system/capabilities.py
lib/ansible/modules/system/cron.py

Loading…
Cancel
Save