summaryrefslogtreecommitdiff
path: root/test/integration
diff options
context:
space:
mode:
authorMatt Davis <nitzmahone@users.noreply.github.com>2016-09-06 17:38:12 -0700
committerGitHub <noreply@github.com>2016-09-06 17:38:12 -0700
commitf239e1e61f71e23300ce64e320c7962a1ba2ad8b (patch)
treeb5971a1da2773f6f0afb37a671e3207c50625258 /test/integration
parent056a7cb957ab649e5facb9a3047727d04595de3b (diff)
downloadansible-f239e1e61f71e23300ce64e320c7962a1ba2ad8b.tar.gz
windows async changes and tests (#17400)
Diffstat (limited to 'test/integration')
-rw-r--r--test/integration/roles/test_win_async_wrapper/library/async_test.ps157
-rw-r--r--test/integration/roles/test_win_async_wrapper/tasks/main.yml187
-rw-r--r--test/integration/test_win_group3.yml1
3 files changed, 245 insertions, 0 deletions
diff --git a/test/integration/roles/test_win_async_wrapper/library/async_test.ps1 b/test/integration/roles/test_win_async_wrapper/library/async_test.ps1
new file mode 100644
index 0000000000..3b891b9fac
--- /dev/null
+++ b/test/integration/roles/test_win_async_wrapper/library/async_test.ps1
@@ -0,0 +1,57 @@
+#!powershell
+# 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/>.
+
+# WANT_JSON
+# POWERSHELL_COMMON
+
+$parsed_args = Parse-Args $args
+
+$sleep_delay_sec = Get-AnsibleParam $parsed_args "sleep_delay_sec" -default 0
+$fail_mode = Get-AnsibleParam $parsed_args "fail_mode" -default "success" -validateset "success","graceful","exception"
+
+If($fail_mode -isnot [array]) {
+ $fail_mode = @($fail_mode)
+}
+
+$result = @{changed=$true; module_pid=$pid; module_tempdir=$PSScriptRoot}
+
+If($sleep_delay_sec -gt 0) {
+ Sleep -Seconds $sleep_delay_sec
+ $result["slept_sec"] = $sleep_delay_sec
+}
+
+If($fail_mode -contains "leading_junk") {
+ Write-Output "leading junk before module output"
+}
+
+Try {
+
+ If($fail_mode -contains "graceful") {
+ Fail-Json $result "failed gracefully"
+ }
+
+ If($fail_mode -eq "exception") {
+ Throw "failing via exception"
+ }
+
+ Exit-Json $result
+}
+Finally
+{
+ If($fail_mode -contains "trailing_junk") {
+ Write-Output "trailing junk after module output"
+ }
+}
diff --git a/test/integration/roles/test_win_async_wrapper/tasks/main.yml b/test/integration/roles/test_win_async_wrapper/tasks/main.yml
new file mode 100644
index 0000000000..d3d24bb753
--- /dev/null
+++ b/test/integration/roles/test_win_async_wrapper/tasks/main.yml
@@ -0,0 +1,187 @@
+- name: async fire and forget
+ async_test:
+ sleep_delay_sec: 5
+ async: 20
+ poll: 0
+ register: asyncresult
+
+- name: validate response
+ assert:
+ that:
+ - asyncresult.ansible_job_id is match('\d+\.\d+')
+ - asyncresult.started == 1
+ - asyncresult.finished == 0
+ - asyncresult.results_file is search('\.ansible_async.+\d+\.\d+')
+ - asyncresult._suppress_tmpdir_delete == true
+
+- name: async poll immediate success
+ async_test:
+ sleep_delay_sec: 0
+ async: 10
+ poll: 1
+ register: asyncresult
+
+- name: validate response
+ assert:
+ that:
+ - asyncresult.ansible_job_id is match('\d+\.\d+')
+ - asyncresult.finished == 1
+ - asyncresult.changed == true
+ - asyncresult.ansible_async_watchdog_pid is number
+ - asyncresult.module_tempdir is search('ansible-tmp-')
+ - asyncresult.module_pid is number
+
+# this part of the test is flaky- Windows PIDs are reused aggressively, so this occasionally fails due to a new process with the same ID
+# FUTURE: consider having the test module hook to a kernel object we can poke at that gets signaled/released on exit
+#- name: ensure that watchdog and module procs have exited
+# raw: Get-Process | Where { $_.Id -in ({{ asyncresult.ansible_async_watchdog_pid }}, {{ asyncresult.module_pid }}) }
+# register: proclist
+#
+#- name: validate no running watchdog/module processes were returned
+# assert:
+# that:
+# - proclist.stdout.strip() == ''
+
+- name: ensure that module_tempdir was deleted
+ raw: Test-Path {{ asyncresult.module_tempdir }}
+ register: tempdircheck
+
+- name: validate tempdir response
+ assert:
+ that:
+ - tempdircheck.stdout | search('False')
+
+- name: async poll retry
+ async_test:
+ sleep_delay_sec: 5
+ async: 10
+ poll: 1
+ register: asyncresult
+
+- name: validate response
+ assert:
+ that:
+ - asyncresult.ansible_job_id is match('\d+\.\d+')
+ - asyncresult.finished == 1
+ - asyncresult.changed == true
+ - asyncresult.module_tempdir is search('ansible-tmp-')
+ - asyncresult.module_pid is number
+
+# this part of the test is flaky- Windows PIDs are reused aggressively, so this occasionally fails due to a new process with the same ID
+# FUTURE: consider having the test module hook to a kernel object we can poke at that gets signaled/released on exit
+#- name: ensure that watchdog and module procs have exited
+# raw: Get-Process | Where { $_.Id -in ({{ asyncresult.ansible_async_watchdog_pid }}, {{ asyncresult.module_pid }}) }
+# register: proclist
+#
+#- name: validate no running watchdog/module processes were returned
+# assert:
+# that:
+# - proclist.stdout.strip() == ''
+
+- name: ensure that module_tempdir was deleted
+ raw: Test-Path {{ asyncresult.module_tempdir }}
+ register: tempdircheck
+
+- name: validate tempdir response
+ assert:
+ that:
+ - tempdircheck.stdout | search('False')
+
+- name: async poll timeout
+ async_test:
+ sleep_delay_sec: 5
+ async: 3
+ poll: 1
+ register: asyncresult
+ ignore_errors: true
+
+- name: validate response
+ assert:
+ that:
+ - asyncresult.ansible_job_id is match('\d+\.\d+')
+ - asyncresult.finished == 1
+ - asyncresult.changed == false
+ - asyncresult | failed == true
+ - asyncresult.msg is search('timed out')
+
+- name: async poll graceful module failure
+ async_test:
+ fail_mode: graceful
+ async: 5
+ poll: 1
+ register: asyncresult
+ ignore_errors: true
+
+- name: validate response
+ assert:
+ that:
+ - asyncresult.ansible_job_id is match('\d+\.\d+')
+ - asyncresult.finished == 1
+ - asyncresult.changed == false
+ - asyncresult | failed == true
+ - asyncresult.msg == 'failed gracefully'
+
+- name: async poll exception module failure
+ async_test:
+ fail_mode: exception
+ async: 5
+ poll: 1
+ register: asyncresult
+ ignore_errors: true
+
+- name: validate response
+ assert:
+ that:
+ - asyncresult.ansible_job_id is match('\d+\.\d+')
+ - asyncresult.finished == 1
+ - asyncresult.changed == false
+ - asyncresult | failed == true
+ - asyncresult.msg is search('failing via exception')
+
+- name: loop async success
+ async_test:
+ sleep_delay_sec: 3
+ async: 10
+ poll: 0
+ with_sequence: start=1 end=4
+ register: async_many
+
+- name: wait for completion
+ async_status:
+ jid: "{{ item }}"
+ register: asyncout
+ until: asyncout.finished == 1
+ retries: 10
+ delay: 1
+ with_items: "{{ async_many.results | map(attribute='ansible_job_id') | list }}"
+
+- name: validate results
+ assert:
+ that:
+ - item.finished == 1
+ - item.slept_sec == 3
+ - item.changed == true
+ - item.ansible_job_id is match('\d+\.\d+')
+ with_items: "{{ asyncout.results }}"
+
+# this part of the test is flaky- Windows PIDs are reused aggressively, so this occasionally fails due to a new process with the same ID
+# FUTURE: consider having the test module hook to a kernel object we can poke at that gets signaled/released on exit
+#- name: ensure that all watchdog and module procs have exited
+# raw: Get-Process | Where { $_.Id -in ({{ asyncout.results | join(',', attribute='ansible_async_watchdog_pid') }}, {{ asyncout.results | join(',', attribute='module_pid') }}) }
+# register: proclist
+#
+#- name: validate no processes were returned
+# assert:
+# that:
+# - proclist.stdout.strip() == ""
+
+# FUTURE: test junk before/after JSON
+# FUTURE: verify tempdir stays through module exec
+# FUTURE: verify tempdir is deleted after module exec
+# FUTURE: verify tempdir is permanent with ANSIBLE_KEEP_REMOTE_FILES=1 (how?)
+# FUTURE: verify binary modules work
+
+# FUTURE: test status/return
+# FUTURE: test status/cleanup
+# FUTURE: test reboot/connection failure
+# FUTURE: figure out how to ensure that processes and tempdirs are cleaned up in all exceptional cases
diff --git a/test/integration/test_win_group3.yml b/test/integration/test_win_group3.yml
index f8bcdcd780..7ade0cb122 100644
--- a/test/integration/test_win_group3.yml
+++ b/test/integration/test_win_group3.yml
@@ -4,3 +4,4 @@
- { role: test_win_service, tags: test_win_service }
- { role: test_win_feature, tags: test_win_feature }
- { role: test_win_user, tags: test_win_user }
+ - { role: test_win_async_wrapper, tags: test_win_async_wrapper }