From c5f37f6bd63072a672616d680845e2f77aa00066 Mon Sep 17 00:00:00 2001 From: Pilou Date: Wed, 8 Aug 2018 06:48:03 +0200 Subject: [PATCH] improve 'service' integration tests (#43655) * service tests: check that daemon is really running (spoiler: it isn't) * service tests: add PIDFile directive in systemd unit * service tests: check 'changed' too * service tests: fix indentation & use changed test * service tests: #16694 has been fixed a long time ago * service tests: refactor - always execute cleaning tasks - move tests tasks in a dedicated file * service tests: add test for #42786 * service tests: display value of ansible_service_mgr * service tests: allow to run tests twice in a row stop & disable ansible test service * service tests: 'pattern' value must be a substring 'pattern' parameter is poorly named * service tests: check ansible_test service status * service tests: test daemon must handle SIGHUP because 'initctl reload' sends SIGHUP, otherwise test daemon stops when receiving the signal * service tests: remove upstart override file too and check that files were removed using raw module and stat command --- .../targets/service/files/ansible.systemd | 1 + .../service/files/ansible_test_service | 3 + .../targets/service/tasks/main.yml | 196 ++++-------------- .../targets/service/tasks/systemd_setup.yml | 2 +- .../targets/service/tasks/tests.yml | 164 +++++++++++++++ .../targets/service/tasks/upstart_cleanup.yml | 30 +-- 6 files changed, 231 insertions(+), 165 deletions(-) create mode 100644 test/integration/targets/service/tasks/tests.yml diff --git a/test/integration/targets/service/files/ansible.systemd b/test/integration/targets/service/files/ansible.systemd index c1a710a1b3e..3466f25a08f 100644 --- a/test/integration/targets/service/files/ansible.systemd +++ b/test/integration/targets/service/files/ansible.systemd @@ -5,6 +5,7 @@ Description=Ansible Test Service ExecStart=/usr/sbin/ansible_test_service "Test\nthat newlines in scripts\nwork" ExecReload=/bin/true Type=forking +PIDFile=/var/run/ansible_test_service.pid [Install] WantedBy=multi-user.target diff --git a/test/integration/targets/service/files/ansible_test_service b/test/integration/targets/service/files/ansible_test_service index 682edebb85b..598bc1a4c93 100755 --- a/test/integration/targets/service/files/ansible_test_service +++ b/test/integration/targets/service/files/ansible_test_service @@ -5,6 +5,7 @@ import os import resource +import signal import sys import time @@ -60,6 +61,8 @@ def createDaemon(): if __name__ == "__main__": + signal.signal(signal.SIGHUP, signal.SIG_IGN) + retCode = createDaemon() while True: diff --git a/test/integration/targets/service/tasks/main.yml b/test/integration/targets/service/tasks/main.yml index 5d327043eb6..a131bf9a979 100644 --- a/test/integration/targets/service/tasks/main.yml +++ b/test/integration/targets/service/tasks/main.yml @@ -2,153 +2,49 @@ copy: src=ansible_test_service dest=/usr/sbin/ansible_test_service mode=755 register: install_result -- name: assert that the daemon script was installed - assert: - that: - - "install_result.dest == '/usr/sbin/ansible_test_service'" - - "install_result.state == 'file'" - - "install_result.mode == '0755'" - -# determine init system is in use -- name: detect sysv init system - set_fact: service_type=sysv - when: ansible_distribution in ['RedHat', 'CentOS', 'ScientificLinux'] and ( ansible_distribution_version is version('6', '>=') and ansible_distribution_version is version('7', '<')) -- name: detect systemd init system - set_fact: service_type=systemd - when: (ansible_distribution in ['RedHat', 'CentOS', 'ScientificLinux'] and ( ansible_distribution_version is version('7', '>=') and ansible_distribution_version is version('8', '<'))) or ansible_distribution == 'Fedora' or (ansible_distribution == 'Ubuntu' and ansible_distribution_version is version('15.04', '>=')) or (ansible_distribution == 'Debian' and ansible_distribution_version is version('8', '>=')) or ansible_os_family == 'Suse' -- name: detect upstart init system - set_fact: service_type=upstart - when: ansible_distribution == 'Ubuntu' and ansible_distribution_version is version('15.04', '<') - -# setup test service script -- include: 'sysv_setup.yml' - when: service_type == "sysv" -- include: 'systemd_setup.yml' - when: service_type == "systemd" -- include: 'upstart_setup.yml' - when: service_type == "upstart" - -- name: disable the ansible test service - service: name=ansible_test enabled=no - -- name: (check mode run) enable the ansible test service - service: name=ansible_test enabled=yes - register: enable_in_check_mode_result - check_mode: yes - -- name: assert that changes reported for check mode run - assert: - that: - - "enable_in_check_mode_result.changed == true" - -- name: enable the ansible test service - service: name=ansible_test enabled=yes - register: enable_result - -- name: assert that the service was enabled and changes reported - assert: - that: - - "enable_result.enabled == true" - - "enable_result.changed == true" - -- name: start the ansible test service - service: name=ansible_test state=started - register: start_result - -- name: assert that the service was started - assert: - that: - - "start_result.state == 'started'" - -- name: find the service with a pattern - service: name=ansible_test pattern="ansible_test_ser*" state=started - register: start2_result - # don't enable this check yet on systems with systemd because of https://github.com/ansible/ansible/issues/16694 - when: service_type != "systemd" - -- name: assert that the service was started via the pattern - assert: - that: - - "start2_result.name == 'ansible_test'" - - "start2_result.state == 'started'" - when: service_type != "systemd" - -- name: restart the ansible test service - service: name=ansible_test state=restarted - register: restart_result - -- name: assert that the service was restarted - assert: - that: - - "restart_result.state == 'started'" - -- name: restart the ansible test service with a sleep - service: name=ansible_test state=restarted sleep=2 - register: restart_sleep_result - # don't enable this check yet on systems with systemd because of https://github.com/ansible/ansible/issues/16694 - when: service_type != "systemd" - -- name: assert that the service was restarted with a sleep - assert: - that: - - "restart_sleep_result.state == 'started'" - when: service_type != "systemd" - -- name: reload the ansible test service - service: name=ansible_test state=reloaded - register: reload_result - # don't do this on systems with systemd because it triggers error: - # Unable to reload service ansible_test: ansible_test.service is not active, cannot reload. - when: service_type != "systemd" - -- name: assert that the service was reloaded - assert: - that: - - "reload_result.state == 'started'" - when: service_type != "systemd" - -- name: stop the ansible test service - service: name=ansible_test state=stopped - register: stop_result - -- name: assert that the service was stopped - assert: - that: - - "stop_result.state == 'stopped'" - -- name: disable the ansible test service - service: name=ansible_test enabled=no - register: disable_result - -- name: assert that the service was disabled - assert: - that: - - "disable_result.enabled == false" - -- name: try to enable a broken service - service: name=ansible_broken_test enabled=yes - register: broken_enable_result - ignore_errors: True - -- name: assert that the broken test failed - assert: - that: - - "broken_enable_result is failed" - -- name: remove the test daemon script - file: path=/usr/sbin/ansible_test_service state=absent - register: remove_result - -- name: assert that the test daemon script was removed - assert: - that: - - "remove_result.path == '/usr/sbin/ansible_test_service'" - - "remove_result.state == 'absent'" - -# cleaning up changes made by this playbook -- include: 'sysv_cleanup.yml' - when: service_type == "sysv" -- include: 'systemd_cleanup.yml' - when: service_type == "systemd" -- include: 'upstart_cleanup.yml' - when: service_type == "upstart" +- block: + - name: assert that the daemon script was installed + assert: + that: + - "install_result.dest == '/usr/sbin/ansible_test_service'" + - "install_result.state == 'file'" + - "install_result.mode == '0755'" + + # determine init system is in use + - name: detect sysv init system + set_fact: + service_type: sysv + when: + - ansible_distribution in ['RedHat', 'CentOS', 'ScientificLinux'] + - ansible_distribution_version is version('6', '>=') + - ansible_distribution_version is version('7', '<') + - name: detect systemd init system + set_fact: + service_type: systemd + when: (ansible_distribution in ['RedHat', 'CentOS', 'ScientificLinux'] and ( ansible_distribution_version is version('7', '>=') and ansible_distribution_version is version('8', '<'))) or ansible_distribution == 'Fedora' or (ansible_distribution == 'Ubuntu' and ansible_distribution_version is version('15.04', '>=')) or (ansible_distribution == 'Debian' and ansible_distribution_version is version('8', '>=')) or ansible_os_family == 'Suse' + - name: detect upstart init system + set_fact: + service_type: upstart + when: + - ansible_distribution == 'Ubuntu' + - ansible_distribution_version is version('15.04', '<') + + - name: display value of ansible_service_mgr + debug: + msg: 'ansible_service_mgr: {{ ansible_service_mgr }}' + + - name: setup test service script + include_tasks: '{{ service_type }}_setup.yml' + + - name: execute tests + import_tasks: tests.yml + + always: + - name: disable and stop ansible test service + service: + name: ansible_test + state: stopped + enabled: false + + # cleaning up changes made by this playbook + - include_tasks: '{{ service_type }}_cleanup.yml' diff --git a/test/integration/targets/service/tasks/systemd_setup.yml b/test/integration/targets/service/tasks/systemd_setup.yml index bee5ce1f28a..eb944e6f601 100644 --- a/test/integration/targets/service/tasks/systemd_setup.yml +++ b/test/integration/targets/service/tasks/systemd_setup.yml @@ -12,6 +12,6 @@ - "install_systemd_result.dest == '/etc/systemd/system/ansible_test.service'" - "install_systemd_result.state == 'file'" - "install_systemd_result.mode == '0644'" - - "install_systemd_result.checksum == '6b5f2b9318524a387c77c550cef4dd411a471acf'" + - "install_systemd_result.checksum == '9e6320795a5c79c01230a6de1c343ea32097af52'" - "install_broken_systemd_result.dest == '/etc/systemd/system/ansible_test_broken.service'" - "install_broken_systemd_result.state == 'link'" diff --git a/test/integration/targets/service/tasks/tests.yml b/test/integration/targets/service/tasks/tests.yml new file mode 100644 index 00000000000..d7e4d7f655a --- /dev/null +++ b/test/integration/targets/service/tasks/tests.yml @@ -0,0 +1,164 @@ +- name: disable the ansible test service + service: name=ansible_test enabled=no + +- name: (check mode run) enable the ansible test service + service: name=ansible_test enabled=yes + register: enable_in_check_mode_result + check_mode: yes + +- name: assert that changes reported for check mode run + assert: + that: + - "enable_in_check_mode_result is changed" + +- name: enable the ansible test service + service: name=ansible_test enabled=yes + register: enable_result + +- name: assert that the service was enabled and changes reported + assert: + that: + - "enable_result.enabled == true" + - "enable_result is changed" + +- name: start the ansible test service + service: name=ansible_test state=started + register: start_result + +- name: assert that the service was started + assert: + that: + - "start_result.state == 'started'" + - "start_result is changed" + +- name: check that the service was started + shell: 'cat /proc/$(cat /var/run/ansible_test_service.pid)/cmdline' + register: cmdline + failed_when: cmdline is failed or not cmdline.stdout.startswith('python\0/usr/sbin/ansible_test_service\0') + +- name: find the service with a pattern + service: name=ansible_test pattern="ansible_test_ser" state=started + register: start2_result + +- name: assert that the service was started via the pattern + assert: + that: + - "start2_result.name == 'ansible_test'" + - "start2_result.state == 'started'" + - "start2_result is not changed" + +- name: fetch PID for ansible_test service (before restart) + command: 'cat /var/run/ansible_test_service.pid' + register: pid_before_restart + +- name: restart the ansible test service + service: name=ansible_test state=restarted + register: restart_result + +- name: assert that the service was restarted + assert: + that: + - "restart_result.state == 'started'" + - "restart_result is changed" + +- name: fetch PID for ansible_test service (after restart) + command: 'cat /var/run/ansible_test_service.pid' + register: pid_after_restart + +- name: "check that PIDs aren't the same" + fail: + when: pid_before_restart.stdout == pid_after_restart.stdout + +- name: check that service is started + command: 'cat /proc/{{ pid_after_restart.stdout }}/cmdline' + register: cmdline + failed_when: cmdline is failed or not cmdline.stdout.startswith('python\0/usr/sbin/ansible_test_service\0') + +- name: restart the ansible test service with a sleep + service: name=ansible_test state=restarted sleep=2 + register: restart_sleep_result + +- name: assert that the service was restarted with a sleep + assert: + that: + - "restart_sleep_result.state == 'started'" + - "restart_sleep_result is changed" + +- name: reload the ansible test service + service: name=ansible_test state=reloaded + register: reload_result + # don't do this on systems with systemd because it triggers error: + # Unable to reload service ansible_test: ansible_test.service is not active, cannot reload. + when: service_type != "systemd" + +- name: assert that the service was reloaded + assert: + that: + - "reload_result.state == 'started'" + - "reload_result is changed" + when: service_type != "systemd" + +- name: "test for #42786 (sysvinit)" + when: service_type == "sysv" + block: + - name: "sysvinit (#42786): check state, 'enable' parameter isn't set" + service: use=sysvinit name=ansible_test state=started + + - name: "sysvinit (#42786): check that service is still enabled" + service: use=sysvinit name=ansible_test enabled=yes + register: result_enabled + failed_when: result_enabled is changed + +- name: fetch PID for ansible_test service + command: 'cat /var/run/ansible_test_service.pid' + register: ansible_test_pid + +- name: check that service is started + command: 'cat /proc/{{ ansible_test_pid.stdout }}/cmdline' + register: cmdline + failed_when: cmdline is failed or not cmdline.stdout.startswith('python\0/usr/sbin/ansible_test_service\0') + +- name: stop the ansible test service + service: name=ansible_test state=stopped + register: stop_result + +- name: check that the service is stopped + command: 'cat /proc/{{ ansible_test_pid.stdout }}/cmdline' + register: cmdline + failed_when: cmdline is not failed or cmdline.stdout.startswith('python\0/usr/sbin/ansible_test_service\0') + +- name: assert that the service was stopped + assert: + that: + - "stop_result.state == 'stopped'" + - "stop_result is changed" + +- name: disable the ansible test service + service: name=ansible_test enabled=no + register: disable_result + +- name: assert that the service was disabled + assert: + that: + - "disable_result.enabled == false" + - "disable_result is changed" + +- name: try to enable a broken service + service: name=ansible_broken_test enabled=yes + register: broken_enable_result + ignore_errors: True + +- name: assert that the broken test failed + assert: + that: + - "broken_enable_result is failed" + +- name: remove the test daemon script + file: path=/usr/sbin/ansible_test_service state=absent + register: remove_result + +- name: assert that the test daemon script was removed + assert: + that: + - "remove_result.path == '/usr/sbin/ansible_test_service'" + - "remove_result.state == 'absent'" diff --git a/test/integration/targets/service/tasks/upstart_cleanup.yml b/test/integration/targets/service/tasks/upstart_cleanup.yml index a589d5a986e..683fb104aba 100644 --- a/test/integration/targets/service/tasks/upstart_cleanup.yml +++ b/test/integration/targets/service/tasks/upstart_cleanup.yml @@ -1,15 +1,17 @@ -- name: remove the upstart init file - file: path=/etc/init/ansible_test.conf state=absent - register: remove_upstart_result +- vars: + upstart_files: + - /etc/init/ansible_test.conf + - /etc/init/ansible_test.override + - /etc/init/ansible_test_broken.conf + block: + - name: remove upstart init files + file: + path: '{{ item }}' + state: absent + loop: '{{ upstart_files }}' -- name: remove the upstart init file - file: path=/etc/init/ansible_test_broken.conf state=absent - register: remove_upstart_broken_result - -- name: assert that the upstart init file was removed - assert: - that: - - "remove_upstart_result.path == '/etc/init/ansible_test.conf'" - - "remove_upstart_result.state == 'absent'" - - "remove_upstart_broken_result.path == '/etc/init/ansible_test_broken.conf'" - - "remove_upstart_broken_result.state == 'absent'" + - name: assert that upstart init files were removed + raw: 'test -e {{ item }}' + loop: '{{ upstart_files }}' + register: file_exists + failed_when: file_exists is not failed