summaryrefslogtreecommitdiffstats
path: root/test/integration/targets/handlers
diff options
context:
space:
mode:
Diffstat (limited to 'test/integration/targets/handlers')
-rw-r--r--test/integration/targets/handlers/46447.yml16
-rw-r--r--test/integration/targets/handlers/52561.yml20
-rw-r--r--test/integration/targets/handlers/54991.yml11
-rw-r--r--test/integration/targets/handlers/58841.yml9
-rw-r--r--test/integration/targets/handlers/79776-handlers.yml2
-rw-r--r--test/integration/targets/handlers/79776.yml10
-rw-r--r--test/integration/targets/handlers/aliases2
-rw-r--r--test/integration/targets/handlers/from_handlers.yml39
-rw-r--r--test/integration/targets/handlers/handlers.yml2
-rw-r--r--test/integration/targets/handlers/include_handlers_fail_force-handlers.yml2
-rw-r--r--test/integration/targets/handlers/include_handlers_fail_force.yml11
-rw-r--r--test/integration/targets/handlers/inventory.handlers10
-rw-r--r--test/integration/targets/handlers/order.yml34
-rw-r--r--test/integration/targets/handlers/roles/import_template_handler_names/tasks/main.yml11
-rw-r--r--test/integration/targets/handlers/roles/template_handler_names/handlers/main.yml5
-rw-r--r--test/integration/targets/handlers/roles/template_handler_names/tasks/evaluation_time.yml5
-rw-r--r--test/integration/targets/handlers/roles/template_handler_names/tasks/lazy_evaluation.yml5
-rw-r--r--test/integration/targets/handlers/roles/test_force_handlers/handlers/main.yml2
-rw-r--r--test/integration/targets/handlers/roles/test_force_handlers/tasks/main.yml26
-rw-r--r--test/integration/targets/handlers/roles/test_handlers/handlers/main.yml5
-rw-r--r--test/integration/targets/handlers/roles/test_handlers/meta/main.yml1
-rw-r--r--test/integration/targets/handlers/roles/test_handlers/tasks/main.yml52
-rw-r--r--test/integration/targets/handlers/roles/test_handlers_include/handlers/main.yml1
-rw-r--r--test/integration/targets/handlers/roles/test_handlers_include/tasks/main.yml4
-rw-r--r--test/integration/targets/handlers/roles/test_handlers_include_role/handlers/main.yml5
-rw-r--r--test/integration/targets/handlers/roles/test_handlers_include_role/meta/main.yml1
-rw-r--r--test/integration/targets/handlers/roles/test_handlers_include_role/tasks/main.yml47
-rw-r--r--test/integration/targets/handlers/roles/test_handlers_listen/handlers/main.yml10
-rw-r--r--test/integration/targets/handlers/roles/test_handlers_listen/tasks/main.yml6
-rw-r--r--test/integration/targets/handlers/roles/test_handlers_meta/handlers/alternate.yml12
-rw-r--r--test/integration/targets/handlers/roles/test_handlers_meta/handlers/main.yml10
-rw-r--r--test/integration/targets/handlers/roles/test_handlers_meta/tasks/main.yml75
-rw-r--r--test/integration/targets/handlers/roles/test_role_handlers_include_tasks/handlers/A.yml1
-rw-r--r--test/integration/targets/handlers/roles/test_role_handlers_include_tasks/handlers/main.yml5
-rw-r--r--test/integration/targets/handlers/roles/test_role_handlers_include_tasks/tasks/B.yml1
-rw-r--r--test/integration/targets/handlers/roles/test_templating_in_handlers/handlers/main.yml21
-rw-r--r--test/integration/targets/handlers/roles/test_templating_in_handlers/tasks/main.yml26
-rwxr-xr-xtest/integration/targets/handlers/runme.sh183
-rw-r--r--test/integration/targets/handlers/test_block_as_handler-import.yml7
-rw-r--r--test/integration/targets/handlers/test_block_as_handler-include.yml8
-rw-r--r--test/integration/targets/handlers/test_block_as_handler-include_import-handlers.yml8
-rw-r--r--test/integration/targets/handlers/test_block_as_handler.yml13
-rw-r--r--test/integration/targets/handlers/test_flush_handlers_as_handler.yml9
-rw-r--r--test/integration/targets/handlers/test_flush_handlers_rescue_always.yml22
-rw-r--r--test/integration/targets/handlers/test_flush_in_rescue_always.yml35
-rw-r--r--test/integration/targets/handlers/test_force_handlers.yml27
-rw-r--r--test/integration/targets/handlers/test_fqcn_meta_flush_handlers.yml14
-rw-r--r--test/integration/targets/handlers/test_handlers.yml47
-rw-r--r--test/integration/targets/handlers/test_handlers_any_errors_fatal.yml24
-rw-r--r--test/integration/targets/handlers/test_handlers_include.yml14
-rw-r--r--test/integration/targets/handlers/test_handlers_include_role.yml8
-rw-r--r--test/integration/targets/handlers/test_handlers_including_task.yml16
-rw-r--r--test/integration/targets/handlers/test_handlers_inexistent_notify.yml10
-rw-r--r--test/integration/targets/handlers/test_handlers_infinite_loop.yml25
-rw-r--r--test/integration/targets/handlers/test_handlers_listen.yml128
-rw-r--r--test/integration/targets/handlers/test_handlers_meta.yml9
-rw-r--r--test/integration/targets/handlers/test_handlers_template_run_once.yml12
-rw-r--r--test/integration/targets/handlers/test_listening_handlers.yml39
-rw-r--r--test/integration/targets/handlers/test_notify_included-handlers.yml3
-rw-r--r--test/integration/targets/handlers/test_notify_included.yml16
-rw-r--r--test/integration/targets/handlers/test_role_as_handler.yml11
-rw-r--r--test/integration/targets/handlers/test_role_handlers_including_tasks.yml18
-rw-r--r--test/integration/targets/handlers/test_skip_flush.yml13
-rw-r--r--test/integration/targets/handlers/test_templating_in_handlers.yml62
64 files changed, 1286 insertions, 0 deletions
diff --git a/test/integration/targets/handlers/46447.yml b/test/integration/targets/handlers/46447.yml
new file mode 100644
index 0000000..d2812b5
--- /dev/null
+++ b/test/integration/targets/handlers/46447.yml
@@ -0,0 +1,16 @@
+- hosts: A,B
+ gather_facts: no
+ any_errors_fatal: True
+ tasks:
+ - command: /bin/true
+ notify: test_handler
+
+ - meta: flush_handlers
+
+ - name: Should not get here
+ debug:
+ msg: "SHOULD NOT GET HERE"
+
+ handlers:
+ - name: test_handler
+ command: /usr/bin/{{ (inventory_hostname == 'A') | ternary('true', 'false') }}
diff --git a/test/integration/targets/handlers/52561.yml b/test/integration/targets/handlers/52561.yml
new file mode 100644
index 0000000..f2e2b58
--- /dev/null
+++ b/test/integration/targets/handlers/52561.yml
@@ -0,0 +1,20 @@
+- hosts: A,B
+ gather_facts: false
+ tasks:
+ - block:
+ - debug:
+ changed_when: true
+ notify:
+ - handler1
+ - name: EXPECTED FAILURE
+ fail:
+ when: inventory_hostname == 'B'
+ always:
+ - debug:
+ msg: 'always'
+ - debug:
+ msg: 'after always'
+ handlers:
+ - name: handler1
+ debug:
+ msg: 'handler1 ran'
diff --git a/test/integration/targets/handlers/54991.yml b/test/integration/targets/handlers/54991.yml
new file mode 100644
index 0000000..c7424ed
--- /dev/null
+++ b/test/integration/targets/handlers/54991.yml
@@ -0,0 +1,11 @@
+- hosts: A,B,C,D
+ gather_facts: false
+ serial: 2
+ tasks:
+ - command: echo
+ notify: handler
+ handlers:
+ - name: handler
+ debug:
+ msg: 'handler ran'
+ failed_when: inventory_hostname == 'A'
diff --git a/test/integration/targets/handlers/58841.yml b/test/integration/targets/handlers/58841.yml
new file mode 100644
index 0000000..eea5c2f
--- /dev/null
+++ b/test/integration/targets/handlers/58841.yml
@@ -0,0 +1,9 @@
+---
+- hosts: localhost
+ gather_facts: no
+ tasks:
+ - include_role:
+ name: import_template_handler_names
+ tags:
+ - lazy_evaluation
+ - evaluation_time
diff --git a/test/integration/targets/handlers/79776-handlers.yml b/test/integration/targets/handlers/79776-handlers.yml
new file mode 100644
index 0000000..639c9ca
--- /dev/null
+++ b/test/integration/targets/handlers/79776-handlers.yml
@@ -0,0 +1,2 @@
+- debug:
+ msg: "Handler for {{ inventory_hostname }}"
diff --git a/test/integration/targets/handlers/79776.yml b/test/integration/targets/handlers/79776.yml
new file mode 100644
index 0000000..08d2227
--- /dev/null
+++ b/test/integration/targets/handlers/79776.yml
@@ -0,0 +1,10 @@
+- hosts: A,B
+ gather_facts: false
+ force_handlers: true
+ tasks:
+ - command: echo
+ notify: handler1
+ when: inventory_hostname == "A"
+ handlers:
+ - name: handler1
+ include_tasks: 79776-handlers.yml
diff --git a/test/integration/targets/handlers/aliases b/test/integration/targets/handlers/aliases
new file mode 100644
index 0000000..498fedd
--- /dev/null
+++ b/test/integration/targets/handlers/aliases
@@ -0,0 +1,2 @@
+shippable/posix/group4
+context/controller
diff --git a/test/integration/targets/handlers/from_handlers.yml b/test/integration/targets/handlers/from_handlers.yml
new file mode 100644
index 0000000..7b2dea2
--- /dev/null
+++ b/test/integration/targets/handlers/from_handlers.yml
@@ -0,0 +1,39 @@
+- name: verify handlers_from on include_role
+ hosts: A
+ gather_facts: False
+ tags: ['scenario1']
+ tasks:
+ - name: test include_role
+ include_role: name=test_handlers_meta handlers_from=alternate.yml
+
+ - name: force handler run
+ meta: flush_handlers
+
+ - name: verify handlers ran
+ assert:
+ that:
+ - "'handler1_alt_called' in hostvars[inventory_hostname]"
+ - "'handler2_alt_called' in hostvars[inventory_hostname]"
+ tags: ['scenario1']
+
+
+- name: verify handlers_from on import_role
+ hosts: A
+ gather_facts: False
+ tasks:
+ - name: set facts to false
+ set_fact:
+ handler1_alt_called: False
+ handler2_alt_called: False
+
+ - import_role: name=test_handlers_meta handlers_from=alternate.yml
+
+ - name: force handler run
+ meta: flush_handlers
+
+ - name: verify handlers ran
+ assert:
+ that:
+ - handler1_alt_called|bool
+ - handler2_alt_called|bool
+ tags: ['scenario1']
diff --git a/test/integration/targets/handlers/handlers.yml b/test/integration/targets/handlers/handlers.yml
new file mode 100644
index 0000000..aed75bd
--- /dev/null
+++ b/test/integration/targets/handlers/handlers.yml
@@ -0,0 +1,2 @@
+- name: test handler
+ debug: msg="handler called"
diff --git a/test/integration/targets/handlers/include_handlers_fail_force-handlers.yml b/test/integration/targets/handlers/include_handlers_fail_force-handlers.yml
new file mode 100644
index 0000000..8867b06
--- /dev/null
+++ b/test/integration/targets/handlers/include_handlers_fail_force-handlers.yml
@@ -0,0 +1,2 @@
+- debug:
+ msg: included handler ran
diff --git a/test/integration/targets/handlers/include_handlers_fail_force.yml b/test/integration/targets/handlers/include_handlers_fail_force.yml
new file mode 100644
index 0000000..f2289ba
--- /dev/null
+++ b/test/integration/targets/handlers/include_handlers_fail_force.yml
@@ -0,0 +1,11 @@
+- hosts: A
+ gather_facts: false
+ tasks:
+ - command: echo
+ notify:
+ - handler
+ - name: EXPECTED FAILURE
+ fail:
+ handlers:
+ - name: handler
+ include_tasks: include_handlers_fail_force-handlers.yml
diff --git a/test/integration/targets/handlers/inventory.handlers b/test/integration/targets/handlers/inventory.handlers
new file mode 100644
index 0000000..268cf65
--- /dev/null
+++ b/test/integration/targets/handlers/inventory.handlers
@@ -0,0 +1,10 @@
+[testgroup]
+A
+B
+C
+D
+E
+
+[testgroup:vars]
+ansible_connection=local
+ansible_python_interpreter="{{ ansible_playbook_python }}"
diff --git a/test/integration/targets/handlers/order.yml b/test/integration/targets/handlers/order.yml
new file mode 100644
index 0000000..8143ef7
--- /dev/null
+++ b/test/integration/targets/handlers/order.yml
@@ -0,0 +1,34 @@
+- name: Test handlers are executed in the order they are defined, not notified
+ hosts: localhost
+ gather_facts: false
+ tasks:
+ - set_fact:
+ foo: ''
+ changed_when: true
+ notify:
+ - handler4
+ - handler3
+ - handler1
+ - handler2
+ - handler5
+ - name: EXPECTED FAILURE
+ fail:
+ when: test_force_handlers | default(false) | bool
+ handlers:
+ - name: handler1
+ set_fact:
+ foo: "{{ foo ~ 1 }}"
+ - name: handler2
+ set_fact:
+ foo: "{{ foo ~ 2 }}"
+ - name: handler3
+ set_fact:
+ foo: "{{ foo ~ 3 }}"
+ - name: handler4
+ set_fact:
+ foo: "{{ foo ~ 4 }}"
+ - name: handler5
+ assert:
+ that:
+ - foo == '1234'
+ fail_msg: "{{ foo }}"
diff --git a/test/integration/targets/handlers/roles/import_template_handler_names/tasks/main.yml b/test/integration/targets/handlers/roles/import_template_handler_names/tasks/main.yml
new file mode 100644
index 0000000..3bc285e
--- /dev/null
+++ b/test/integration/targets/handlers/roles/import_template_handler_names/tasks/main.yml
@@ -0,0 +1,11 @@
+- import_role:
+ name: template_handler_names
+ tasks_from: lazy_evaluation
+ tags:
+ - lazy_evaluation
+
+- import_role:
+ name: template_handler_names
+ tasks_from: evaluation_time
+ tags:
+ - evaluation_time
diff --git a/test/integration/targets/handlers/roles/template_handler_names/handlers/main.yml b/test/integration/targets/handlers/roles/template_handler_names/handlers/main.yml
new file mode 100644
index 0000000..bf8ca85
--- /dev/null
+++ b/test/integration/targets/handlers/roles/template_handler_names/handlers/main.yml
@@ -0,0 +1,5 @@
+- name: handler name with {{ test_var }}
+ debug: msg='handler with var ran'
+
+- name: handler name
+ debug: msg='handler ran'
diff --git a/test/integration/targets/handlers/roles/template_handler_names/tasks/evaluation_time.yml b/test/integration/targets/handlers/roles/template_handler_names/tasks/evaluation_time.yml
new file mode 100644
index 0000000..c0706fc
--- /dev/null
+++ b/test/integration/targets/handlers/roles/template_handler_names/tasks/evaluation_time.yml
@@ -0,0 +1,5 @@
+- debug: msg='notify handler with variable in name'
+ notify: handler name with myvar
+ changed_when: True
+ tags:
+ - evaluation_time
diff --git a/test/integration/targets/handlers/roles/template_handler_names/tasks/lazy_evaluation.yml b/test/integration/targets/handlers/roles/template_handler_names/tasks/lazy_evaluation.yml
new file mode 100644
index 0000000..e82dca0
--- /dev/null
+++ b/test/integration/targets/handlers/roles/template_handler_names/tasks/lazy_evaluation.yml
@@ -0,0 +1,5 @@
+- debug: msg='notify handler'
+ notify: handler name
+ changed_when: True
+ tags:
+ - lazy_evaluation
diff --git a/test/integration/targets/handlers/roles/test_force_handlers/handlers/main.yml b/test/integration/targets/handlers/roles/test_force_handlers/handlers/main.yml
new file mode 100644
index 0000000..962d756
--- /dev/null
+++ b/test/integration/targets/handlers/roles/test_force_handlers/handlers/main.yml
@@ -0,0 +1,2 @@
+- name: echoing handler
+ command: echo CALLED_HANDLER_{{ inventory_hostname }}
diff --git a/test/integration/targets/handlers/roles/test_force_handlers/tasks/main.yml b/test/integration/targets/handlers/roles/test_force_handlers/tasks/main.yml
new file mode 100644
index 0000000..f5d78c7
--- /dev/null
+++ b/test/integration/targets/handlers/roles/test_force_handlers/tasks/main.yml
@@ -0,0 +1,26 @@
+---
+
+# We notify for A and B, and hosts B and C fail.
+# When forcing, we expect A and B to run handlers
+# When not forcing, we expect only B to run handlers
+
+- name: notify the handler for host A and B
+ shell: echo
+ notify:
+ - echoing handler
+ when: inventory_hostname == 'A' or inventory_hostname == 'B'
+
+- name: EXPECTED FAILURE fail task for all
+ fail: msg="Fail All"
+ when: fail_all is defined and fail_all
+
+- name: EXPECTED FAILURE fail task for A
+ fail: msg="Fail A"
+ when: inventory_hostname == 'A'
+
+- name: EXPECTED FAILURE fail task for C
+ fail: msg="Fail C"
+ when: inventory_hostname == 'C'
+
+- name: echo after A and C have failed
+ command: echo CALLED_TASK_{{ inventory_hostname }}
diff --git a/test/integration/targets/handlers/roles/test_handlers/handlers/main.yml b/test/integration/targets/handlers/roles/test_handlers/handlers/main.yml
new file mode 100644
index 0000000..0261f93
--- /dev/null
+++ b/test/integration/targets/handlers/roles/test_handlers/handlers/main.yml
@@ -0,0 +1,5 @@
+- name: set handler fact
+ set_fact:
+ handler_called: True
+- name: test handler
+ debug: msg="handler called"
diff --git a/test/integration/targets/handlers/roles/test_handlers/meta/main.yml b/test/integration/targets/handlers/roles/test_handlers/meta/main.yml
new file mode 100644
index 0000000..32cf5dd
--- /dev/null
+++ b/test/integration/targets/handlers/roles/test_handlers/meta/main.yml
@@ -0,0 +1 @@
+dependencies: []
diff --git a/test/integration/targets/handlers/roles/test_handlers/tasks/main.yml b/test/integration/targets/handlers/roles/test_handlers/tasks/main.yml
new file mode 100644
index 0000000..a857dac
--- /dev/null
+++ b/test/integration/targets/handlers/roles/test_handlers/tasks/main.yml
@@ -0,0 +1,52 @@
+# test code for the async keyword
+# (c) 2014, James Tanner <tanner.jc@gmail.com>
+
+# This file is part of Ansible
+#
+# Ansible is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Ansible is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
+
+
+- name: reset handler_called variable to false for all hosts
+ set_fact:
+ handler_called: False
+ tags: scenario1
+
+- name: notify the handler for host A only
+ shell: echo
+ notify:
+ - set handler fact
+ when: inventory_hostname == 'A'
+ tags: scenario1
+
+- name: force handler execution now
+ meta: "flush_handlers"
+ tags: scenario1
+
+- debug: var=handler_called
+ tags: scenario1
+
+- name: validate the handler only ran on one host
+ assert:
+ that:
+ - "inventory_hostname == 'A' and handler_called == True or handler_called == False"
+ tags: scenario1
+
+- name: 'test notify with loop'
+ debug: msg='a task'
+ changed_when: item == 1
+ notify: test handler
+ with_items:
+ - 1
+ - 2
+ tags: scenario2
diff --git a/test/integration/targets/handlers/roles/test_handlers_include/handlers/main.yml b/test/integration/targets/handlers/roles/test_handlers_include/handlers/main.yml
new file mode 100644
index 0000000..6c3b73c
--- /dev/null
+++ b/test/integration/targets/handlers/roles/test_handlers_include/handlers/main.yml
@@ -0,0 +1 @@
+- import_tasks: handlers.yml
diff --git a/test/integration/targets/handlers/roles/test_handlers_include/tasks/main.yml b/test/integration/targets/handlers/roles/test_handlers_include/tasks/main.yml
new file mode 100644
index 0000000..84f0a58
--- /dev/null
+++ b/test/integration/targets/handlers/roles/test_handlers_include/tasks/main.yml
@@ -0,0 +1,4 @@
+- name: 'main task'
+ debug: msg='main task'
+ changed_when: True
+ notify: test handler
diff --git a/test/integration/targets/handlers/roles/test_handlers_include_role/handlers/main.yml b/test/integration/targets/handlers/roles/test_handlers_include_role/handlers/main.yml
new file mode 100644
index 0000000..0261f93
--- /dev/null
+++ b/test/integration/targets/handlers/roles/test_handlers_include_role/handlers/main.yml
@@ -0,0 +1,5 @@
+- name: set handler fact
+ set_fact:
+ handler_called: True
+- name: test handler
+ debug: msg="handler called"
diff --git a/test/integration/targets/handlers/roles/test_handlers_include_role/meta/main.yml b/test/integration/targets/handlers/roles/test_handlers_include_role/meta/main.yml
new file mode 100644
index 0000000..32cf5dd
--- /dev/null
+++ b/test/integration/targets/handlers/roles/test_handlers_include_role/meta/main.yml
@@ -0,0 +1 @@
+dependencies: []
diff --git a/test/integration/targets/handlers/roles/test_handlers_include_role/tasks/main.yml b/test/integration/targets/handlers/roles/test_handlers_include_role/tasks/main.yml
new file mode 100644
index 0000000..fbc3d1c
--- /dev/null
+++ b/test/integration/targets/handlers/roles/test_handlers_include_role/tasks/main.yml
@@ -0,0 +1,47 @@
+# This file is part of Ansible
+#
+# Ansible is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Ansible is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
+
+
+- name: reset handler_called variable to false for all hosts
+ set_fact:
+ handler_called: False
+ tags: scenario1
+
+- name: notify the handler for host A only
+ shell: echo
+ notify:
+ - set handler fact
+ when: inventory_hostname == 'A'
+ tags: scenario1
+
+- name: force handler execution now
+ meta: "flush_handlers"
+ tags: scenario1
+
+- debug: var=handler_called
+ tags: scenario1
+
+- name: validate the handler only ran on one host
+ assert:
+ that:
+ - "inventory_hostname == 'A' and handler_called == True or handler_called == False"
+ tags: scenario1
+
+# item below is passed in by the playbook that calls this
+- name: 'test notify with loop'
+ debug: msg='a task'
+ changed_when: item == 1
+ notify: test handler
+ tags: scenario2
diff --git a/test/integration/targets/handlers/roles/test_handlers_listen/handlers/main.yml b/test/integration/targets/handlers/roles/test_handlers_listen/handlers/main.yml
new file mode 100644
index 0000000..3bfd82a
--- /dev/null
+++ b/test/integration/targets/handlers/roles/test_handlers_listen/handlers/main.yml
@@ -0,0 +1,10 @@
+---
+- name: notify_listen_ran_4_3
+ set_fact:
+ notify_listen_ran_4_3: True
+ listen: notify_listen
+
+- name: notify_listen_in_role_4
+ set_fact:
+ notify_listen_in_role_4: True
+ listen: notify_listen_in_role
diff --git a/test/integration/targets/handlers/roles/test_handlers_listen/tasks/main.yml b/test/integration/targets/handlers/roles/test_handlers_listen/tasks/main.yml
new file mode 100644
index 0000000..bac9b71
--- /dev/null
+++ b/test/integration/targets/handlers/roles/test_handlers_listen/tasks/main.yml
@@ -0,0 +1,6 @@
+---
+- name: notify some handlers from a role
+ command: uptime
+ notify:
+ - notify_listen_from_role
+ - notify_listen_in_role
diff --git a/test/integration/targets/handlers/roles/test_handlers_meta/handlers/alternate.yml b/test/integration/targets/handlers/roles/test_handlers_meta/handlers/alternate.yml
new file mode 100644
index 0000000..9268ce5
--- /dev/null
+++ b/test/integration/targets/handlers/roles/test_handlers_meta/handlers/alternate.yml
@@ -0,0 +1,12 @@
+- name: set_handler_fact_1
+ set_fact:
+ handler1_called: True
+ handler1_alt_called: True
+
+- name: set_handler_fact_2
+ set_fact:
+ handler2_called: True
+ handler2_alt_called: True
+
+- name: count_handler
+ shell: echo . >> {{ handler_countpath }}
diff --git a/test/integration/targets/handlers/roles/test_handlers_meta/handlers/main.yml b/test/integration/targets/handlers/roles/test_handlers_meta/handlers/main.yml
new file mode 100644
index 0000000..0dd408b
--- /dev/null
+++ b/test/integration/targets/handlers/roles/test_handlers_meta/handlers/main.yml
@@ -0,0 +1,10 @@
+- name: set_handler_fact_1
+ set_fact:
+ handler1_called: True
+
+- name: set_handler_fact_2
+ set_fact:
+ handler2_called: True
+
+- name: count_handler
+ shell: echo . >> {{ handler_countpath }}
diff --git a/test/integration/targets/handlers/roles/test_handlers_meta/tasks/main.yml b/test/integration/targets/handlers/roles/test_handlers_meta/tasks/main.yml
new file mode 100644
index 0000000..d9f5c57
--- /dev/null
+++ b/test/integration/targets/handlers/roles/test_handlers_meta/tasks/main.yml
@@ -0,0 +1,75 @@
+# test code for the async keyword
+# (c) 2014, James Tanner <tanner.jc@gmail.com>
+
+# This file is part of Ansible
+#
+# Ansible is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Ansible is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
+
+- name: notify the first handler
+ shell: echo
+ notify:
+ - set_handler_fact_1
+
+- name: force handler execution now
+ meta: "flush_handlers"
+
+- name: assert handler1 ran and not handler2
+ assert:
+ that:
+ - "handler1_called is defined"
+ - "handler2_called is not defined"
+
+- name: make a tempfile for counting
+ shell: mktemp
+ register: mktemp_out
+
+- name: register tempfile path
+ set_fact:
+ handler_countpath: "{{ mktemp_out.stdout }}"
+
+- name: notify the counting handler
+ shell: echo
+ notify:
+ - count_handler
+
+- name: notify the counting handler again
+ shell: echo
+ notify:
+ - count_handler
+
+- name: force handler execution now
+ meta: flush_handlers
+
+- name: get handler execution count
+ shell: cat {{ handler_countpath }} | grep -o . | wc -l
+ register: exec_count_out
+
+- debug: var=exec_count_out.stdout
+
+- name: ensure single execution
+ assert:
+ that:
+ - exec_count_out.stdout | int == 1
+
+- name: cleanup tempfile
+ file: path={{ handler_countpath }} state=absent
+
+- name: reset handler1_called
+ set_fact:
+ handler1_called: False
+
+- name: notify the second handler
+ shell: echo
+ notify:
+ - set_handler_fact_2
diff --git a/test/integration/targets/handlers/roles/test_role_handlers_include_tasks/handlers/A.yml b/test/integration/targets/handlers/roles/test_role_handlers_include_tasks/handlers/A.yml
new file mode 100644
index 0000000..b7520c7
--- /dev/null
+++ b/test/integration/targets/handlers/roles/test_role_handlers_include_tasks/handlers/A.yml
@@ -0,0 +1 @@
+- debug: msg="handler with tasks from A.yml called"
diff --git a/test/integration/targets/handlers/roles/test_role_handlers_include_tasks/handlers/main.yml b/test/integration/targets/handlers/roles/test_role_handlers_include_tasks/handlers/main.yml
new file mode 100644
index 0000000..ba2e8f6
--- /dev/null
+++ b/test/integration/targets/handlers/roles/test_role_handlers_include_tasks/handlers/main.yml
@@ -0,0 +1,5 @@
+- name: role-based handler from handler subdir
+ include_tasks: A.yml
+
+- name: role-based handler from tasks subdir
+ include_tasks: B.yml
diff --git a/test/integration/targets/handlers/roles/test_role_handlers_include_tasks/tasks/B.yml b/test/integration/targets/handlers/roles/test_role_handlers_include_tasks/tasks/B.yml
new file mode 100644
index 0000000..956c975
--- /dev/null
+++ b/test/integration/targets/handlers/roles/test_role_handlers_include_tasks/tasks/B.yml
@@ -0,0 +1 @@
+- debug: msg="handler with tasks from B.yml called"
diff --git a/test/integration/targets/handlers/roles/test_templating_in_handlers/handlers/main.yml b/test/integration/targets/handlers/roles/test_templating_in_handlers/handlers/main.yml
new file mode 100644
index 0000000..7dbf334
--- /dev/null
+++ b/test/integration/targets/handlers/roles/test_templating_in_handlers/handlers/main.yml
@@ -0,0 +1,21 @@
+---
+- name: name1
+ set_fact:
+ role_non_templated_name: True
+- name: "{{ handler2 }}"
+ set_fact:
+ role_templated_name: True
+- name: testlistener1
+ set_fact:
+ role_non_templated_listener: True
+ listen: name3
+- name: testlistener2
+ set_fact:
+ role_templated_listener: True
+ listen: "{{ handler4 }}"
+- name: name5
+ set_fact:
+ role_handler5: True
+- set_fact:
+ role_handler6: True
+ listen: name6
diff --git a/test/integration/targets/handlers/roles/test_templating_in_handlers/tasks/main.yml b/test/integration/targets/handlers/roles/test_templating_in_handlers/tasks/main.yml
new file mode 100644
index 0000000..5417417
--- /dev/null
+++ b/test/integration/targets/handlers/roles/test_templating_in_handlers/tasks/main.yml
@@ -0,0 +1,26 @@
+---
+- command: echo Hello World
+ notify:
+ - "{{ handler1 }}"
+ - "{{ handler2 }}"
+ - "{{ handler3 }}"
+ - "{{ handler4 }}"
+
+- meta: flush_handlers
+
+- assert:
+ that:
+ - role_non_templated_name is defined
+ - role_templated_name is defined
+ - role_non_templated_listener is defined
+ - role_templated_listener is undefined
+
+- command: echo
+ notify: "{{ handler_list }}"
+
+- meta: flush_handlers
+
+- assert:
+ that:
+ - role_handler5 is defined
+ - role_handler6 is defined
diff --git a/test/integration/targets/handlers/runme.sh b/test/integration/targets/handlers/runme.sh
new file mode 100755
index 0000000..76fc99d
--- /dev/null
+++ b/test/integration/targets/handlers/runme.sh
@@ -0,0 +1,183 @@
+#!/usr/bin/env bash
+
+set -eux
+
+export ANSIBLE_FORCE_HANDLERS
+
+ANSIBLE_FORCE_HANDLERS=false
+
+# simple handler test
+ansible-playbook test_handlers.yml -i inventory.handlers -v "$@" --tags scenario1
+
+# simple from_handlers test
+ansible-playbook from_handlers.yml -i inventory.handlers -v "$@" --tags scenario1
+
+ansible-playbook test_listening_handlers.yml -i inventory.handlers -v "$@"
+
+[ "$(ansible-playbook test_handlers.yml -i inventory.handlers -v "$@" --tags scenario2 -l A \
+| grep -E -o 'RUNNING HANDLER \[test_handlers : .*]')" = "RUNNING HANDLER [test_handlers : test handler]" ]
+
+# Test forcing handlers using the linear and free strategy
+for strategy in linear free; do
+
+ export ANSIBLE_STRATEGY=$strategy
+
+ # Not forcing, should only run on successful host
+ [ "$(ansible-playbook test_force_handlers.yml -i inventory.handlers -v "$@" --tags normal \
+ | grep -E -o CALLED_HANDLER_. | sort | uniq | xargs)" = "CALLED_HANDLER_B" ]
+
+ # Forcing from command line
+ [ "$(ansible-playbook test_force_handlers.yml -i inventory.handlers -v "$@" --tags normal --force-handlers \
+ | grep -E -o CALLED_HANDLER_. | sort | uniq | xargs)" = "CALLED_HANDLER_A CALLED_HANDLER_B" ]
+
+ # Forcing from command line, should only run later tasks on unfailed hosts
+ [ "$(ansible-playbook test_force_handlers.yml -i inventory.handlers -v "$@" --tags normal --force-handlers \
+ | grep -E -o CALLED_TASK_. | sort | uniq | xargs)" = "CALLED_TASK_B CALLED_TASK_D CALLED_TASK_E" ]
+
+ # Forcing from command line, should call handlers even if all hosts fail
+ [ "$(ansible-playbook test_force_handlers.yml -i inventory.handlers -v "$@" --tags normal --force-handlers -e fail_all=yes \
+ | grep -E -o CALLED_HANDLER_. | sort | uniq | xargs)" = "CALLED_HANDLER_A CALLED_HANDLER_B" ]
+
+ # Forcing from ansible.cfg
+ [ "$(ANSIBLE_FORCE_HANDLERS=true ansible-playbook test_force_handlers.yml -i inventory.handlers -v "$@" --tags normal \
+ | grep -E -o CALLED_HANDLER_. | sort | uniq | xargs)" = "CALLED_HANDLER_A CALLED_HANDLER_B" ]
+
+ # Forcing true in play
+ [ "$(ansible-playbook test_force_handlers.yml -i inventory.handlers -v "$@" --tags force_true_in_play \
+ | grep -E -o CALLED_HANDLER_. | sort | uniq | xargs)" = "CALLED_HANDLER_A CALLED_HANDLER_B" ]
+
+ # Forcing false in play, which overrides command line
+ [ "$(ansible-playbook test_force_handlers.yml -i inventory.handlers -v "$@" --tags force_false_in_play --force-handlers \
+ | grep -E -o CALLED_HANDLER_. | sort | uniq | xargs)" = "CALLED_HANDLER_B" ]
+
+ unset ANSIBLE_STRATEGY
+
+done
+
+[ "$(ansible-playbook test_handlers_include.yml -i ../../inventory -v "$@" --tags playbook_include_handlers \
+| grep -E -o 'RUNNING HANDLER \[.*]')" = "RUNNING HANDLER [test handler]" ]
+
+[ "$(ansible-playbook test_handlers_include.yml -i ../../inventory -v "$@" --tags role_include_handlers \
+| grep -E -o 'RUNNING HANDLER \[test_handlers_include : .*]')" = "RUNNING HANDLER [test_handlers_include : test handler]" ]
+
+[ "$(ansible-playbook test_handlers_include_role.yml -i ../../inventory -v "$@" \
+| grep -E -o 'RUNNING HANDLER \[test_handlers_include_role : .*]')" = "RUNNING HANDLER [test_handlers_include_role : test handler]" ]
+
+# Notify handler listen
+ansible-playbook test_handlers_listen.yml -i inventory.handlers -v "$@"
+
+# Notify inexistent handlers results in error
+set +e
+result="$(ansible-playbook test_handlers_inexistent_notify.yml -i inventory.handlers "$@" 2>&1)"
+set -e
+grep -q "ERROR! The requested handler 'notify_inexistent_handler' was not found in either the main handlers list nor in the listening handlers list" <<< "$result"
+
+# Notify inexistent handlers without errors when ANSIBLE_ERROR_ON_MISSING_HANDLER=false
+ANSIBLE_ERROR_ON_MISSING_HANDLER=false ansible-playbook test_handlers_inexistent_notify.yml -i inventory.handlers -v "$@"
+
+ANSIBLE_ERROR_ON_MISSING_HANDLER=false ansible-playbook test_templating_in_handlers.yml -v "$@"
+
+# https://github.com/ansible/ansible/issues/36649
+output_dir=/tmp
+set +e
+result="$(ansible-playbook test_handlers_any_errors_fatal.yml -e output_dir=$output_dir -i inventory.handlers -v "$@" 2>&1)"
+set -e
+[ ! -f $output_dir/should_not_exist_B ] || (rm -f $output_dir/should_not_exist_B && exit 1)
+
+# https://github.com/ansible/ansible/issues/47287
+[ "$(ansible-playbook test_handlers_including_task.yml -i ../../inventory -v "$@" | grep -E -o 'failed=[0-9]+')" = "failed=0" ]
+
+# https://github.com/ansible/ansible/issues/71222
+ansible-playbook test_role_handlers_including_tasks.yml -i ../../inventory -v "$@"
+
+# https://github.com/ansible/ansible/issues/27237
+set +e
+result="$(ansible-playbook test_handlers_template_run_once.yml -i inventory.handlers "$@" 2>&1)"
+set -e
+grep -q "handler A" <<< "$result"
+grep -q "handler B" <<< "$result"
+
+# Test an undefined variable in another handler name isn't a failure
+ansible-playbook 58841.yml "$@" --tags lazy_evaluation 2>&1 | tee out.txt ; cat out.txt
+grep out.txt -e "\[WARNING\]: Handler 'handler name with {{ test_var }}' is unusable"
+[ "$(grep out.txt -ce 'handler ran')" = "1" ]
+[ "$(grep out.txt -ce 'handler with var ran')" = "0" ]
+
+# Test templating a handler name with a defined variable
+ansible-playbook 58841.yml "$@" --tags evaluation_time -e test_var=myvar | tee out.txt ; cat out.txt
+[ "$(grep out.txt -ce 'handler ran')" = "0" ]
+[ "$(grep out.txt -ce 'handler with var ran')" = "1" ]
+
+# Test the handler is not found when the variable is undefined
+ansible-playbook 58841.yml "$@" --tags evaluation_time 2>&1 | tee out.txt ; cat out.txt
+grep out.txt -e "ERROR! The requested handler 'handler name with myvar' was not found"
+grep out.txt -e "\[WARNING\]: Handler 'handler name with {{ test_var }}' is unusable"
+[ "$(grep out.txt -ce 'handler ran')" = "0" ]
+[ "$(grep out.txt -ce 'handler with var ran')" = "0" ]
+
+# Test include_role and import_role cannot be used as handlers
+ansible-playbook test_role_as_handler.yml "$@" 2>&1 | tee out.txt
+grep out.txt -e "ERROR! Using 'include_role' as a handler is not supported."
+
+# Test notifying a handler from within include_tasks does not work anymore
+ansible-playbook test_notify_included.yml "$@" 2>&1 | tee out.txt
+[ "$(grep out.txt -ce 'I was included')" = "1" ]
+grep out.txt -e "ERROR! The requested handler 'handler_from_include' was not found in either the main handlers list nor in the listening handlers list"
+
+ansible-playbook test_handlers_meta.yml -i inventory.handlers -vv "$@" | tee out.txt
+[ "$(grep out.txt -ce 'RUNNING HANDLER \[noop_handler\]')" = "1" ]
+[ "$(grep out.txt -ce 'META: noop')" = "1" ]
+
+# https://github.com/ansible/ansible/issues/46447
+set +e
+test "$(ansible-playbook 46447.yml -i inventory.handlers -vv "$@" 2>&1 | grep -c 'SHOULD NOT GET HERE')"
+set -e
+
+# https://github.com/ansible/ansible/issues/52561
+ansible-playbook 52561.yml -i inventory.handlers "$@" 2>&1 | tee out.txt
+[ "$(grep out.txt -ce 'handler1 ran')" = "1" ]
+
+# Test flush_handlers meta task does not imply any_errors_fatal
+ansible-playbook 54991.yml -i inventory.handlers "$@" 2>&1 | tee out.txt
+[ "$(grep out.txt -ce 'handler ran')" = "4" ]
+
+ansible-playbook order.yml -i inventory.handlers "$@" 2>&1
+set +e
+ansible-playbook order.yml --force-handlers -e test_force_handlers=true -i inventory.handlers "$@" 2>&1
+set -e
+
+ansible-playbook include_handlers_fail_force.yml --force-handlers -i inventory.handlers "$@" 2>&1 | tee out.txt
+[ "$(grep out.txt -ce 'included handler ran')" = "1" ]
+
+ansible-playbook test_flush_handlers_as_handler.yml -i inventory.handlers "$@" 2>&1 | tee out.txt
+grep out.txt -e "ERROR! flush_handlers cannot be used as a handler"
+
+ansible-playbook test_skip_flush.yml -i inventory.handlers "$@" 2>&1 | tee out.txt
+[ "$(grep out.txt -ce 'handler ran')" = "0" ]
+
+ansible-playbook test_flush_in_rescue_always.yml -i inventory.handlers "$@" 2>&1 | tee out.txt
+[ "$(grep out.txt -ce 'handler ran in rescue')" = "1" ]
+[ "$(grep out.txt -ce 'handler ran in always')" = "2" ]
+[ "$(grep out.txt -ce 'lockstep works')" = "2" ]
+
+ansible-playbook test_handlers_infinite_loop.yml -i inventory.handlers "$@" 2>&1
+
+ansible-playbook test_flush_handlers_rescue_always.yml -i inventory.handlers "$@" 2>&1 | tee out.txt
+[ "$(grep out.txt -ce 'rescue ran')" = "1" ]
+[ "$(grep out.txt -ce 'always ran')" = "2" ]
+[ "$(grep out.txt -ce 'should run for both hosts')" = "2" ]
+
+ansible-playbook test_fqcn_meta_flush_handlers.yml -i inventory.handlers "$@" 2>&1 | tee out.txt
+grep out.txt -e "handler ran"
+grep out.txt -e "after flush"
+
+ansible-playbook 79776.yml -i inventory.handlers "$@"
+
+ansible-playbook test_block_as_handler.yml "$@" 2>&1 | tee out.txt
+grep out.txt -e "ERROR! Using a block as a handler is not supported."
+
+ansible-playbook test_block_as_handler-include.yml "$@" 2>&1 | tee out.txt
+grep out.txt -e "ERROR! Using a block as a handler is not supported."
+
+ansible-playbook test_block_as_handler-import.yml "$@" 2>&1 | tee out.txt
+grep out.txt -e "ERROR! Using a block as a handler is not supported."
diff --git a/test/integration/targets/handlers/test_block_as_handler-import.yml b/test/integration/targets/handlers/test_block_as_handler-import.yml
new file mode 100644
index 0000000..ad6bb0d
--- /dev/null
+++ b/test/integration/targets/handlers/test_block_as_handler-import.yml
@@ -0,0 +1,7 @@
+- hosts: localhost
+ gather_facts: false
+ tasks:
+ - debug:
+ handlers:
+ - name: handler
+ import_tasks: test_block_as_handler-include_import-handlers.yml
diff --git a/test/integration/targets/handlers/test_block_as_handler-include.yml b/test/integration/targets/handlers/test_block_as_handler-include.yml
new file mode 100644
index 0000000..5b03b0a
--- /dev/null
+++ b/test/integration/targets/handlers/test_block_as_handler-include.yml
@@ -0,0 +1,8 @@
+- hosts: localhost
+ gather_facts: false
+ tasks:
+ - command: echo
+ notify: handler
+ handlers:
+ - name: handler
+ include_tasks: test_block_as_handler-include_import-handlers.yml
diff --git a/test/integration/targets/handlers/test_block_as_handler-include_import-handlers.yml b/test/integration/targets/handlers/test_block_as_handler-include_import-handlers.yml
new file mode 100644
index 0000000..61c058b
--- /dev/null
+++ b/test/integration/targets/handlers/test_block_as_handler-include_import-handlers.yml
@@ -0,0 +1,8 @@
+- name: handler
+ block:
+ - name: due to how handlers are implemented, this is correct as it is equivalent to an implicit block
+ debug:
+ - name: this is a parser error, blocks as handlers are not supported
+ block:
+ - name: handler in a nested block
+ debug:
diff --git a/test/integration/targets/handlers/test_block_as_handler.yml b/test/integration/targets/handlers/test_block_as_handler.yml
new file mode 100644
index 0000000..bd4f5b9
--- /dev/null
+++ b/test/integration/targets/handlers/test_block_as_handler.yml
@@ -0,0 +1,13 @@
+- hosts: localhost
+ gather_facts: false
+ tasks:
+ - debug:
+ handlers:
+ - name: handler
+ block:
+ - name: due to how handlers are implemented, this is correct as it is equivalent to an implicit block
+ debug:
+ - name: this is a parser error, blocks as handlers are not supported
+ block:
+ - name: handler in a nested block
+ debug:
diff --git a/test/integration/targets/handlers/test_flush_handlers_as_handler.yml b/test/integration/targets/handlers/test_flush_handlers_as_handler.yml
new file mode 100644
index 0000000..6d19408
--- /dev/null
+++ b/test/integration/targets/handlers/test_flush_handlers_as_handler.yml
@@ -0,0 +1,9 @@
+- hosts: A
+ gather_facts: false
+ tasks:
+ - command: echo
+ notify:
+ - handler
+ handlers:
+ - name: handler
+ meta: flush_handlers
diff --git a/test/integration/targets/handlers/test_flush_handlers_rescue_always.yml b/test/integration/targets/handlers/test_flush_handlers_rescue_always.yml
new file mode 100644
index 0000000..4a1f741
--- /dev/null
+++ b/test/integration/targets/handlers/test_flush_handlers_rescue_always.yml
@@ -0,0 +1,22 @@
+- hosts: A,B
+ gather_facts: false
+ tasks:
+ - block:
+ - command: echo
+ notify: sometimes_fail
+
+ - meta: flush_handlers
+ rescue:
+ - debug:
+ msg: 'rescue ran'
+ always:
+ - debug:
+ msg: 'always ran'
+
+ - debug:
+ msg: 'should run for both hosts'
+
+ handlers:
+ - name: sometimes_fail
+ fail:
+ when: inventory_hostname == 'A'
diff --git a/test/integration/targets/handlers/test_flush_in_rescue_always.yml b/test/integration/targets/handlers/test_flush_in_rescue_always.yml
new file mode 100644
index 0000000..7257a42
--- /dev/null
+++ b/test/integration/targets/handlers/test_flush_in_rescue_always.yml
@@ -0,0 +1,35 @@
+- hosts: A,B
+ gather_facts: false
+ tasks:
+ - block:
+ - name: EXPECTED_FAILURE
+ fail:
+ when: inventory_hostname == 'A'
+ rescue:
+ - command: echo
+ notify: handler_rescue
+
+ - meta: flush_handlers
+
+ - set_fact:
+ was_in_rescue: true
+
+ - name: EXPECTED_FAILURE
+ fail:
+ always:
+ - assert:
+ that:
+ - hostvars['A']['was_in_rescue']|default(false)
+ success_msg: lockstep works
+
+ - command: echo
+ notify: handler_always
+
+ - meta: flush_handlers
+ handlers:
+ - name: handler_rescue
+ debug:
+ msg: handler ran in rescue
+ - name: handler_always
+ debug:
+ msg: handler ran in always
diff --git a/test/integration/targets/handlers/test_force_handlers.yml b/test/integration/targets/handlers/test_force_handlers.yml
new file mode 100644
index 0000000..9cff772
--- /dev/null
+++ b/test/integration/targets/handlers/test_force_handlers.yml
@@ -0,0 +1,27 @@
+---
+
+- name: test force handlers (default)
+ tags: normal
+ hosts: testgroup
+ gather_facts: False
+ roles:
+ - { role: test_force_handlers }
+ tasks:
+ - debug: msg="you should see this with --tags=normal"
+
+- name: test force handlers (set to true)
+ tags: force_true_in_play
+ hosts: testgroup
+ gather_facts: False
+ force_handlers: True
+ roles:
+ - { role: test_force_handlers, tags: force_true_in_play }
+
+
+- name: test force handlers (set to false)
+ tags: force_false_in_play
+ hosts: testgroup
+ gather_facts: False
+ force_handlers: False
+ roles:
+ - { role: test_force_handlers, tags: force_false_in_play }
diff --git a/test/integration/targets/handlers/test_fqcn_meta_flush_handlers.yml b/test/integration/targets/handlers/test_fqcn_meta_flush_handlers.yml
new file mode 100644
index 0000000..f9c67cf
--- /dev/null
+++ b/test/integration/targets/handlers/test_fqcn_meta_flush_handlers.yml
@@ -0,0 +1,14 @@
+- hosts: A
+ gather_facts: false
+ tasks:
+ - command: echo
+ notify: handler
+
+ - ansible.builtin.meta: flush_handlers
+
+ - debug:
+ msg: after flush
+ handlers:
+ - name: handler
+ debug:
+ msg: handler ran
diff --git a/test/integration/targets/handlers/test_handlers.yml b/test/integration/targets/handlers/test_handlers.yml
new file mode 100644
index 0000000..ae9847b
--- /dev/null
+++ b/test/integration/targets/handlers/test_handlers.yml
@@ -0,0 +1,47 @@
+---
+- name: run handlers
+ hosts: A
+ gather_facts: False
+ roles:
+ - { role: test_handlers_meta, tags: ['scenario1'] }
+
+- name: verify final handler was run
+ hosts: A
+ gather_facts: False
+ tasks:
+ - name: verify handler2 ran
+ assert:
+ that:
+ - "not hostvars[inventory_hostname]['handler1_called']"
+ - "'handler2_called' in hostvars[inventory_hostname]"
+ tags: ['scenario1']
+
+- name: verify listening handlers
+ hosts: A
+ gather_facts: False
+ tasks:
+ - name: notify some handlers
+ command: echo foo
+ notify:
+ - notify_listen
+ post_tasks:
+ - name: assert all defined handlers ran without error
+ assert:
+ that:
+ - "notify_listen_ran_1 is defined"
+ - "notify_listen_ran_2 is defined"
+ handlers:
+ - name: first listening handler has a name
+ set_fact:
+ notify_listen_ran_1: True
+ listen: notify_listen
+ # second listening handler does not
+ - set_fact:
+ notify_listen_ran_2: True
+ listen: notify_listen
+
+- name: test handlers
+ hosts: testgroup
+ gather_facts: False
+ roles:
+ - { role: test_handlers }
diff --git a/test/integration/targets/handlers/test_handlers_any_errors_fatal.yml b/test/integration/targets/handlers/test_handlers_any_errors_fatal.yml
new file mode 100644
index 0000000..6b791a3
--- /dev/null
+++ b/test/integration/targets/handlers/test_handlers_any_errors_fatal.yml
@@ -0,0 +1,24 @@
+- hosts:
+ - A
+ - B
+ gather_facts: no
+ any_errors_fatal: yes
+ vars:
+ output_dir: /tmp
+ tasks:
+ - name: Task one
+ debug:
+ msg: 'task 1'
+ changed_when: yes
+ notify: EXPECTED FAILURE failed_handler
+
+ - meta: flush_handlers
+
+ - name: This task should never happen
+ file:
+ path: "{{ output_dir }}/should_not_exist_{{ inventory_hostname }}"
+ state: touch
+ handlers:
+ - name: EXPECTED FAILURE failed_handler
+ fail:
+ when: 'inventory_hostname == "A"'
diff --git a/test/integration/targets/handlers/test_handlers_include.yml b/test/integration/targets/handlers/test_handlers_include.yml
new file mode 100644
index 0000000..158266d
--- /dev/null
+++ b/test/integration/targets/handlers/test_handlers_include.yml
@@ -0,0 +1,14 @@
+- name: verify that play can include handler
+ hosts: testhost
+ tasks:
+ - debug: msg="main task"
+ changed_when: True
+ notify: test handler
+ tags: ['playbook_include_handlers']
+ handlers:
+ - import_tasks: handlers.yml
+
+- name: verify that role can include handler
+ hosts: testhost
+ roles:
+ - { role: test_handlers_include, tags: ['role_include_handlers'] }
diff --git a/test/integration/targets/handlers/test_handlers_include_role.yml b/test/integration/targets/handlers/test_handlers_include_role.yml
new file mode 100644
index 0000000..77e6b53
--- /dev/null
+++ b/test/integration/targets/handlers/test_handlers_include_role.yml
@@ -0,0 +1,8 @@
+- name: verify that play can include handler
+ hosts: testhost
+ tasks:
+ - include_role:
+ name: test_handlers_include_role
+ with_items:
+ - 1
+ - 2
diff --git a/test/integration/targets/handlers/test_handlers_including_task.yml b/test/integration/targets/handlers/test_handlers_including_task.yml
new file mode 100644
index 0000000..8f7933a
--- /dev/null
+++ b/test/integration/targets/handlers/test_handlers_including_task.yml
@@ -0,0 +1,16 @@
+---
+- name: Verify handler can include other tasks (#47287)
+ hosts: testhost
+ tasks:
+ - name: include a task from the tasks section
+ include_tasks: handlers.yml
+
+ - name: notify a handler
+ debug:
+ msg: notifying handler
+ changed_when: yes
+ notify: include a task from the handlers section
+
+ handlers:
+ - name: include a task from the handlers section
+ include_tasks: handlers.yml
diff --git a/test/integration/targets/handlers/test_handlers_inexistent_notify.yml b/test/integration/targets/handlers/test_handlers_inexistent_notify.yml
new file mode 100644
index 0000000..15de38a
--- /dev/null
+++ b/test/integration/targets/handlers/test_handlers_inexistent_notify.yml
@@ -0,0 +1,10 @@
+---
+- name: notify inexistent handler
+ hosts: localhost
+ gather_facts: false
+ tasks:
+ - name: test notify an inexistent handler
+ command: uptime
+ notify:
+ - notify_inexistent_handler
+ register: result
diff --git a/test/integration/targets/handlers/test_handlers_infinite_loop.yml b/test/integration/targets/handlers/test_handlers_infinite_loop.yml
new file mode 100644
index 0000000..413b492
--- /dev/null
+++ b/test/integration/targets/handlers/test_handlers_infinite_loop.yml
@@ -0,0 +1,25 @@
+- hosts: A
+ gather_facts: false
+ tasks:
+ - command: echo
+ notify:
+ - handler1
+ - self_notify
+ handlers:
+ - name: handler1
+ debug:
+ msg: handler1 ran
+ changed_when: true
+ notify: handler2
+
+ - name: handler2
+ debug:
+ msg: handler2 ran
+ changed_when: true
+ notify: handler1
+
+ - name: self_notify
+ debug:
+ msg: self_notify ran
+ changed_when: true
+ notify: self_notify
diff --git a/test/integration/targets/handlers/test_handlers_listen.yml b/test/integration/targets/handlers/test_handlers_listen.yml
new file mode 100644
index 0000000..dd2cd87
--- /dev/null
+++ b/test/integration/targets/handlers/test_handlers_listen.yml
@@ -0,0 +1,128 @@
+---
+- name: test listen with named handlers
+ hosts: localhost
+ gather_facts: false
+ tasks:
+ - name: test notify handlers listen
+ command: uptime
+ notify:
+ - notify_listen
+ - meta: flush_handlers
+ - name: verify test notify handlers listen
+ assert:
+ that:
+ - "notify_listen_ran_1_1 is defined"
+ - "notify_listen_ran_1_2 is defined"
+ - "notify_listen_ran_1_3 is undefined"
+ handlers:
+ - name: notify_handler_ran_1_1
+ set_fact:
+ notify_listen_ran_1_1: True
+ listen: notify_listen
+ - name: notify_handler_ran_1_2
+ set_fact:
+ notify_listen_ran_1_2: True
+ listen: notify_listen
+ - name: notify_handler_ran_1_3
+ set_fact:
+ notify_handler_ran_1_3: True
+ listen: notify_listen2
+
+- name: test listen unnamed handlers
+ hosts: localhost
+ gather_facts: false
+ pre_tasks:
+ - name: notify some handlers
+ command: echo foo
+ notify:
+ - notify_listen
+ tasks:
+ - meta: flush_handlers
+ - name: assert all defined handlers ran without error
+ assert:
+ that:
+ - "notify_listen_ran_1 is defined"
+ - "notify_listen_ran_2 is defined"
+ - "notify_listen_ran_3 is undefined"
+ handlers:
+ - set_fact:
+ notify_listen_ran_1: True
+ listen: notify_listen
+ - set_fact:
+ notify_listen_ran_2: True
+ listen: notify_listen
+ - set_fact:
+ notify_handler_ran_3: True
+ listen: notify_listen2
+
+- name: test with mixed notify by name and listen
+ hosts: localhost
+ gather_facts: false
+ tasks:
+ - name: test notify handlers names and identical listen
+ command: uptime
+ notify:
+ - notify_listen
+ - meta: flush_handlers
+ - name: verify test notify handlers names and identical listen
+ assert:
+ that:
+ - "notify_handler_name_ran_3 is defined"
+ - "notify_handler_name_ran_3_1 is not defined"
+ - "notify_listen_ran_3_2 is defined"
+ - "notify_listen_ran_3_3 is defined"
+ - "not_notify_listen_3_4 is not defined"
+ handlers:
+ - name: notify_listen
+ set_fact:
+ notify_handler_name_ran_3: True
+ # this will not run as we have a handler with a identical name notified first
+ - name: notify_listen
+ set_fact:
+ notify_handler_name_ran_3_1: True
+ - name: notify_handler_ran_3_2
+ set_fact:
+ notify_listen_ran_3_2: True
+ listen: notify_listen
+ - name: notify_handler_ran_3_3
+ set_fact:
+ notify_listen_ran_3_3: True
+ listen: notify_listen
+ # this one is not notified
+ - name: not_notify_listen_3_4
+ set_fact:
+ not_notify_listen_3_4: True
+ listen: not_notified
+
+- name: test listen in roles
+ hosts: localhost
+ gather_facts: false
+ roles:
+ - role: test_handlers_listen
+ tasks:
+ - name: test notify handlers listen in roles
+ command: uptime
+ notify:
+ - notify_listen
+ - meta: flush_handlers
+ - name: verify test notify handlers listen in roles
+ assert:
+ that:
+ - "notify_listen_ran_4_1 is defined"
+ - "notify_listen_ran_4_2 is defined"
+ - "notify_listen_ran_4_3 is defined"
+ - "notify_listen_in_role_4 is defined"
+ - "notify_listen_from_role_4 is defined"
+ handlers:
+ - name: notify_listen_ran_4_1
+ set_fact:
+ notify_listen_ran_4_1: True
+ listen: notify_listen
+ - name: notify_listen_ran_4_2
+ set_fact:
+ notify_listen_ran_4_2: True
+ listen: notify_listen
+ - name: notify_listen_from_role_4
+ set_fact:
+ notify_listen_from_role_4: True
+ listen: notify_listen_from_role
diff --git a/test/integration/targets/handlers/test_handlers_meta.yml b/test/integration/targets/handlers/test_handlers_meta.yml
new file mode 100644
index 0000000..636513a
--- /dev/null
+++ b/test/integration/targets/handlers/test_handlers_meta.yml
@@ -0,0 +1,9 @@
+- hosts: A
+ gather_facts: false
+ tasks:
+ - command: echo
+ notify:
+ - noop_handler
+ handlers:
+ - name: noop_handler
+ meta: noop
diff --git a/test/integration/targets/handlers/test_handlers_template_run_once.yml b/test/integration/targets/handlers/test_handlers_template_run_once.yml
new file mode 100644
index 0000000..6edc32e
--- /dev/null
+++ b/test/integration/targets/handlers/test_handlers_template_run_once.yml
@@ -0,0 +1,12 @@
+- hosts: A,B
+ gather_facts: no
+ tasks:
+ - debug:
+ changed_when: true
+ notify:
+ - handler
+ handlers:
+ - name: handler
+ debug:
+ msg: "handler {{ inventory_hostname }}"
+ run_once: "{{ testvar | default(False) }}"
diff --git a/test/integration/targets/handlers/test_listening_handlers.yml b/test/integration/targets/handlers/test_listening_handlers.yml
new file mode 100644
index 0000000..f4c3cae
--- /dev/null
+++ b/test/integration/targets/handlers/test_listening_handlers.yml
@@ -0,0 +1,39 @@
+---
+- name: verify listening handlers
+ hosts: A
+ gather_facts: False
+ tasks:
+ - name: notify some handlers
+ command: echo foo
+ notify:
+ - notify_listen
+
+ - name: notify another handler
+ debug:
+ changed_when: true
+ notify: another_listen
+
+ - name: nofity another handler 2
+ debug:
+ changed_when: true
+ notify: another_listen
+ post_tasks:
+ - name: assert all defined handlers ran without error
+ assert:
+ that:
+ - "notify_listen_ran_1 is defined"
+ - "notify_listen_ran_2 is defined"
+ - "another_listen_ran is true"
+ handlers:
+ - name: first listening handler has a name
+ set_fact:
+ notify_listen_ran_1: True
+ listen: notify_listen
+ # second listening handler does not
+ - set_fact:
+ notify_listen_ran_2: True
+ listen: notify_listen
+
+ - set_fact:
+ another_listen_ran: '{{ False if another_listen_ran is defined else True }}'
+ listen: another_listen
diff --git a/test/integration/targets/handlers/test_notify_included-handlers.yml b/test/integration/targets/handlers/test_notify_included-handlers.yml
new file mode 100644
index 0000000..61fce70
--- /dev/null
+++ b/test/integration/targets/handlers/test_notify_included-handlers.yml
@@ -0,0 +1,3 @@
+- name: handler_from_include
+ debug:
+ msg: I was included
diff --git a/test/integration/targets/handlers/test_notify_included.yml b/test/integration/targets/handlers/test_notify_included.yml
new file mode 100644
index 0000000..e612507
--- /dev/null
+++ b/test/integration/targets/handlers/test_notify_included.yml
@@ -0,0 +1,16 @@
+- name: This worked unintentionally, make sure it does not anymore
+ hosts: localhost
+ gather_facts: false
+ tasks:
+ - command: echo
+ notify:
+ - include_handler
+
+ - meta: flush_handlers
+
+ - command: echo
+ notify:
+ - handler_from_include
+ handlers:
+ - name: include_handler
+ include_tasks: test_notify_included-handlers.yml
diff --git a/test/integration/targets/handlers/test_role_as_handler.yml b/test/integration/targets/handlers/test_role_as_handler.yml
new file mode 100644
index 0000000..ae67427
--- /dev/null
+++ b/test/integration/targets/handlers/test_role_as_handler.yml
@@ -0,0 +1,11 @@
+- name: test include_role and import_role cannot be used as handlers
+ hosts: localhost
+ gather_facts: false
+ tasks:
+ - command: "echo"
+ notify:
+ - role_handler
+ handlers:
+ - name: role_handler
+ include_role:
+ name: doesnotmatter_fails_at_parse_time
diff --git a/test/integration/targets/handlers/test_role_handlers_including_tasks.yml b/test/integration/targets/handlers/test_role_handlers_including_tasks.yml
new file mode 100644
index 0000000..47d8f00
--- /dev/null
+++ b/test/integration/targets/handlers/test_role_handlers_including_tasks.yml
@@ -0,0 +1,18 @@
+---
+- name: Verify a role handler can include other tasks from handlers and tasks subdirs
+ hosts: testhost
+ roles:
+ - test_role_handlers_include_tasks
+
+ tasks:
+ - name: notify a role-based handler (include tasks from handler subdir)
+ debug:
+ msg: notifying role handler
+ changed_when: yes
+ notify: role-based handler from handler subdir
+
+ - name: notify a role-based handler (include tasks from tasks subdir)
+ debug:
+ msg: notifying another role handler
+ changed_when: yes
+ notify: role-based handler from tasks subdir
diff --git a/test/integration/targets/handlers/test_skip_flush.yml b/test/integration/targets/handlers/test_skip_flush.yml
new file mode 100644
index 0000000..5c1e82b
--- /dev/null
+++ b/test/integration/targets/handlers/test_skip_flush.yml
@@ -0,0 +1,13 @@
+- hosts: A
+ gather_facts: false
+ tasks:
+ - command: echo
+ notify:
+ - handler
+ - meta: flush_handlers
+ when: false
+ - fail:
+ handlers:
+ - name: handler
+ debug:
+ msg: handler ran
diff --git a/test/integration/targets/handlers/test_templating_in_handlers.yml b/test/integration/targets/handlers/test_templating_in_handlers.yml
new file mode 100644
index 0000000..662b8c1
--- /dev/null
+++ b/test/integration/targets/handlers/test_templating_in_handlers.yml
@@ -0,0 +1,62 @@
+- name: test templated values in handlers
+ hosts: localhost
+ gather_facts: no
+ vars:
+ handler1: name1
+ handler2: name2
+ handler3: name3
+ handler4: name4
+ handler_list:
+ - name5
+ - name6
+
+ handlers:
+ - name: name1
+ set_fact:
+ non_templated_name: True
+ - name: "{{ handler2 }}"
+ set_fact:
+ templated_name: True
+ - name: testlistener1
+ set_fact:
+ non_templated_listener: True
+ listen: name3
+ - name: testlistener2
+ set_fact:
+ templated_listener: True
+ listen: "{{ handler4 }}"
+ - name: name5
+ set_fact:
+ handler5: True
+ - set_fact:
+ handler6: True
+ listen: name6
+
+ tasks:
+ - command: echo Hello World
+ notify:
+ - "{{ handler1 }}"
+ - "{{ handler2 }}"
+ - "{{ handler3 }}"
+ - "{{ handler4 }}"
+
+ - meta: flush_handlers
+
+ - assert:
+ that:
+ - non_templated_name is defined
+ - templated_name is defined
+ - non_templated_listener is defined
+ - templated_listener is undefined
+
+ - command: echo
+ notify: "{{ handler_list }}"
+
+ - meta: flush_handlers
+
+ - assert:
+ that:
+ - handler5 is defined
+ - handler6 is defined
+
+ - include_role: name=test_templating_in_handlers