diff options
Diffstat (limited to 'test/integration/targets/pause')
-rw-r--r-- | test/integration/targets/pause/aliases | 3 | ||||
-rw-r--r-- | test/integration/targets/pause/pause-1.yml | 11 | ||||
-rw-r--r-- | test/integration/targets/pause/pause-2.yml | 12 | ||||
-rw-r--r-- | test/integration/targets/pause/pause-3.yml | 12 | ||||
-rw-r--r-- | test/integration/targets/pause/pause-4.yml | 13 | ||||
-rw-r--r-- | test/integration/targets/pause/pause-5.yml | 35 | ||||
-rwxr-xr-x | test/integration/targets/pause/runme.sh | 43 | ||||
-rw-r--r-- | test/integration/targets/pause/setup.yml | 4 | ||||
-rw-r--r-- | test/integration/targets/pause/test-pause-background.yml | 10 | ||||
-rw-r--r-- | test/integration/targets/pause/test-pause-no-tty.yml | 7 | ||||
-rwxr-xr-x | test/integration/targets/pause/test-pause.py | 292 | ||||
-rw-r--r-- | test/integration/targets/pause/test-pause.yml | 72 |
12 files changed, 514 insertions, 0 deletions
diff --git a/test/integration/targets/pause/aliases b/test/integration/targets/pause/aliases new file mode 100644 index 0000000..8597f01 --- /dev/null +++ b/test/integration/targets/pause/aliases @@ -0,0 +1,3 @@ +needs/target/setup_pexpect +shippable/posix/group3 +context/controller # this is a controller-only action, the module is just for documentation diff --git a/test/integration/targets/pause/pause-1.yml b/test/integration/targets/pause/pause-1.yml new file mode 100644 index 0000000..44c9960 --- /dev/null +++ b/test/integration/targets/pause/pause-1.yml @@ -0,0 +1,11 @@ +- name: Test pause module in default state + hosts: localhost + become: no + gather_facts: no + + tasks: + - name: EXPECTED FAILURE + pause: + + - debug: + msg: Task after pause diff --git a/test/integration/targets/pause/pause-2.yml b/test/integration/targets/pause/pause-2.yml new file mode 100644 index 0000000..81a7fda --- /dev/null +++ b/test/integration/targets/pause/pause-2.yml @@ -0,0 +1,12 @@ +- name: Test pause module with custom prompt + hosts: localhost + become: no + gather_facts: no + + tasks: + - name: EXPECTED FAILURE + pause: + prompt: Custom prompt + + - debug: + msg: Task after pause diff --git a/test/integration/targets/pause/pause-3.yml b/test/integration/targets/pause/pause-3.yml new file mode 100644 index 0000000..8f8c72e --- /dev/null +++ b/test/integration/targets/pause/pause-3.yml @@ -0,0 +1,12 @@ +- name: Test pause module with pause + hosts: localhost + become: no + gather_facts: no + + tasks: + - name: EXPECTED FAILURE + pause: + seconds: 2 + + - debug: + msg: Task after pause diff --git a/test/integration/targets/pause/pause-4.yml b/test/integration/targets/pause/pause-4.yml new file mode 100644 index 0000000..f16c7d6 --- /dev/null +++ b/test/integration/targets/pause/pause-4.yml @@ -0,0 +1,13 @@ +- name: Test pause module with pause and custom prompt + hosts: localhost + become: no + gather_facts: no + + tasks: + - name: EXPECTED FAILURE + pause: + seconds: 2 + prompt: Waiting for two seconds + + - debug: + msg: Task after pause diff --git a/test/integration/targets/pause/pause-5.yml b/test/integration/targets/pause/pause-5.yml new file mode 100644 index 0000000..22955cd --- /dev/null +++ b/test/integration/targets/pause/pause-5.yml @@ -0,0 +1,35 @@ +- name: Test pause module echo output + hosts: localhost + become: no + gather_facts: no + + tasks: + - pause: + echo: yes + prompt: Enter some text + register: results + + - name: Ensure that input was captured + assert: + that: + - results.user_input == 'hello there' + + - pause: + echo: yes + prompt: Enter some text to edit + register: result + + - name: Ensure edited input was captured + assert: + that: + - result.user_input == 'hello tommy boy' + + - pause: + echo: no + prompt: Enter some text + register: result + + - name: Ensure secret input was caputered + assert: + that: + - result.user_input == 'supersecretpancakes' diff --git a/test/integration/targets/pause/runme.sh b/test/integration/targets/pause/runme.sh new file mode 100755 index 0000000..eb2c6f7 --- /dev/null +++ b/test/integration/targets/pause/runme.sh @@ -0,0 +1,43 @@ +#!/usr/bin/env bash + +set -eux + +ANSIBLE_ROLES_PATH=../ ansible-playbook setup.yml + +# Test pause module when no tty and non-interactive with no seconds parameter. +# This is to prevent playbooks from hanging in cron and Tower jobs. +/usr/bin/env bash << EOF +ansible-playbook test-pause-no-tty.yml 2>&1 | \ + grep '\[WARNING\]: Not waiting for response to prompt as stdin is not interactive' && { + echo 'Successfully skipped pause in no TTY mode' >&2 + exit 0 + } || { + echo 'Failed to skip pause module' >&2 + exit 1 + } +EOF + +# Do not issue a warning when run in the background if a timeout is given +# https://github.com/ansible/ansible/issues/73042 +if sleep 0 | ansible localhost -m pause -a 'seconds=1' 2>&1 | grep '\[WARNING\]: Not waiting for response'; then + echo "Incorrectly issued warning when run in the background" + exit 1 +else + echo "Succesfully ran in the background with no warning" +fi + +# Test redirecting stdout +# https://github.com/ansible/ansible/issues/41717 +if ansible-playbook pause-3.yml > /dev/null ; then + echo "Successfully redirected stdout" +else + echo "Failure when attempting to redirect stdout" + exit 1 +fi + + +# Test pause with seconds and minutes specified +ansible-playbook test-pause.yml "$@" + +# Interactively test pause +python test-pause.py "$@" diff --git a/test/integration/targets/pause/setup.yml b/test/integration/targets/pause/setup.yml new file mode 100644 index 0000000..9f6ab11 --- /dev/null +++ b/test/integration/targets/pause/setup.yml @@ -0,0 +1,4 @@ +- hosts: localhost + gather_facts: no + roles: + - setup_pexpect diff --git a/test/integration/targets/pause/test-pause-background.yml b/test/integration/targets/pause/test-pause-background.yml new file mode 100644 index 0000000..e480a77 --- /dev/null +++ b/test/integration/targets/pause/test-pause-background.yml @@ -0,0 +1,10 @@ +- name: Test pause in a background task + hosts: localhost + gather_facts: no + become: no + + tasks: + - pause: + + - pause: + seconds: 1 diff --git a/test/integration/targets/pause/test-pause-no-tty.yml b/test/integration/targets/pause/test-pause-no-tty.yml new file mode 100644 index 0000000..6e0e402 --- /dev/null +++ b/test/integration/targets/pause/test-pause-no-tty.yml @@ -0,0 +1,7 @@ +- name: Test pause + hosts: localhost + gather_facts: no + become: no + + tasks: + - pause: diff --git a/test/integration/targets/pause/test-pause.py b/test/integration/targets/pause/test-pause.py new file mode 100755 index 0000000..3703470 --- /dev/null +++ b/test/integration/targets/pause/test-pause.py @@ -0,0 +1,292 @@ +#!/usr/bin/env python + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +import os +import pexpect +import sys +import termios + +from ansible.module_utils.six import PY2 + +args = sys.argv[1:] + +env_vars = { + 'ANSIBLE_ROLES_PATH': './roles', + 'ANSIBLE_NOCOLOR': 'True', + 'ANSIBLE_RETRY_FILES_ENABLED': 'False' +} + +try: + backspace = termios.tcgetattr(sys.stdin.fileno())[6][termios.VERASE] +except Exception: + backspace = b'\x7f' + +if PY2: + log_buffer = sys.stdout +else: + log_buffer = sys.stdout.buffer + +os.environ.update(env_vars) + +# -- Plain pause -- # +playbook = 'pause-1.yml' + +# Case 1 - Contiune with enter +pause_test = pexpect.spawn( + 'ansible-playbook', + args=[playbook] + args, + timeout=10, + env=os.environ +) + +pause_test.logfile = log_buffer +pause_test.expect(r'Press enter to continue, Ctrl\+C to interrupt:') +pause_test.send('\r') +pause_test.expect('Task after pause') +pause_test.expect(pexpect.EOF) +pause_test.close() + + +# Case 2 - Continue with C +pause_test = pexpect.spawn( + 'ansible-playbook', + args=[playbook] + args, + timeout=10, + env=os.environ +) + +pause_test.logfile = log_buffer +pause_test.expect(r'Press enter to continue, Ctrl\+C to interrupt:') +pause_test.send('\x03') +pause_test.expect("Press 'C' to continue the play or 'A' to abort") +pause_test.send('C') +pause_test.expect('Task after pause') +pause_test.expect(pexpect.EOF) +pause_test.close() + + +# Case 3 - Abort with A +pause_test = pexpect.spawn( + 'ansible-playbook', + args=[playbook] + args, + timeout=10, + env=os.environ +) + +pause_test.logfile = log_buffer +pause_test.expect(r'Press enter to continue, Ctrl\+C to interrupt:') +pause_test.send('\x03') +pause_test.expect("Press 'C' to continue the play or 'A' to abort") +pause_test.send('A') +pause_test.expect('user requested abort!') +pause_test.expect(pexpect.EOF) +pause_test.close() + +# -- Custom Prompt -- # +playbook = 'pause-2.yml' + +# Case 1 - Contiune with enter +pause_test = pexpect.spawn( + 'ansible-playbook', + args=[playbook] + args, + timeout=10, + env=os.environ +) + +pause_test.logfile = log_buffer +pause_test.expect(r'Custom prompt:') +pause_test.send('\r') +pause_test.expect('Task after pause') +pause_test.expect(pexpect.EOF) +pause_test.close() + + +# Case 2 - Contiune with C +pause_test = pexpect.spawn( + 'ansible-playbook', + args=[playbook] + args, + timeout=10, + env=os.environ +) + +pause_test.logfile = log_buffer +pause_test.expect(r'Custom prompt:') +pause_test.send('\x03') +pause_test.expect("Press 'C' to continue the play or 'A' to abort") +pause_test.send('C') +pause_test.expect('Task after pause') +pause_test.expect(pexpect.EOF) +pause_test.close() + + +# Case 3 - Abort with A +pause_test = pexpect.spawn( + 'ansible-playbook', + args=[playbook] + args, + timeout=10, + env=os.environ +) + +pause_test.logfile = log_buffer +pause_test.expect(r'Custom prompt:') +pause_test.send('\x03') +pause_test.expect("Press 'C' to continue the play or 'A' to abort") +pause_test.send('A') +pause_test.expect('user requested abort!') +pause_test.expect(pexpect.EOF) +pause_test.close() + +# -- Pause for N seconds -- # + +playbook = 'pause-3.yml' + +# Case 1 - Wait for task to continue after timeout +pause_test = pexpect.spawn( + 'ansible-playbook', + args=[playbook] + args, + timeout=10, + env=os.environ +) + +pause_test.logfile = log_buffer +pause_test.expect(r'Pausing for \d+ seconds') +pause_test.expect(r"\(ctrl\+C then 'C' = continue early, ctrl\+C then 'A' = abort\)") +pause_test.expect('Task after pause') +pause_test.expect(pexpect.EOF) +pause_test.close() + +# Case 2 - Contiune with Ctrl + C, C +pause_test = pexpect.spawn( + 'ansible-playbook', + args=[playbook] + args, + timeout=10, + env=os.environ +) + +pause_test.logfile = log_buffer +pause_test.expect(r'Pausing for \d+ seconds') +pause_test.expect(r"\(ctrl\+C then 'C' = continue early, ctrl\+C then 'A' = abort\)") +pause_test.send('\x03') +pause_test.send('C') +pause_test.expect('Task after pause') +pause_test.expect(pexpect.EOF) +pause_test.close() + + +# Case 3 - Abort with Ctrl + C, A +pause_test = pexpect.spawn( + 'ansible-playbook', + args=[playbook] + args, + timeout=10, + env=os.environ +) + +pause_test.logfile = log_buffer +pause_test.expect(r'Pausing for \d+ seconds') +pause_test.expect(r"\(ctrl\+C then 'C' = continue early, ctrl\+C then 'A' = abort\)") +pause_test.send('\x03') +pause_test.send('A') +pause_test.expect('user requested abort!') +pause_test.expect(pexpect.EOF) +pause_test.close() + +# -- Pause for N seconds with custom prompt -- # + +playbook = 'pause-4.yml' + +# Case 1 - Wait for task to continue after timeout +pause_test = pexpect.spawn( + 'ansible-playbook', + args=[playbook] + args, + timeout=10, + env=os.environ +) + +pause_test.logfile = log_buffer +pause_test.expect(r'Pausing for \d+ seconds') +pause_test.expect(r"\(ctrl\+C then 'C' = continue early, ctrl\+C then 'A' = abort\)") +pause_test.expect(r"Waiting for two seconds:") +pause_test.expect('Task after pause') +pause_test.expect(pexpect.EOF) +pause_test.close() + +# Case 2 - Contiune with Ctrl + C, C +pause_test = pexpect.spawn( + 'ansible-playbook', + args=[playbook] + args, + timeout=10, + env=os.environ +) + +pause_test.logfile = log_buffer +pause_test.expect(r'Pausing for \d+ seconds') +pause_test.expect(r"\(ctrl\+C then 'C' = continue early, ctrl\+C then 'A' = abort\)") +pause_test.expect(r"Waiting for two seconds:") +pause_test.send('\x03') +pause_test.send('C') +pause_test.expect('Task after pause') +pause_test.expect(pexpect.EOF) +pause_test.close() + + +# Case 3 - Abort with Ctrl + C, A +pause_test = pexpect.spawn( + 'ansible-playbook', + args=[playbook] + args, + timeout=10, + env=os.environ +) + +pause_test.logfile = log_buffer +pause_test.expect(r'Pausing for \d+ seconds') +pause_test.expect(r"\(ctrl\+C then 'C' = continue early, ctrl\+C then 'A' = abort\)") +pause_test.expect(r"Waiting for two seconds:") +pause_test.send('\x03') +pause_test.send('A') +pause_test.expect('user requested abort!') +pause_test.expect(pexpect.EOF) +pause_test.close() + +# -- Enter input and ensure it's captured, echoed, and can be edited -- # + +playbook = 'pause-5.yml' + +pause_test = pexpect.spawn( + 'ansible-playbook', + args=[playbook] + args, + timeout=10, + env=os.environ +) + +pause_test.logfile = log_buffer +pause_test.expect(r'Enter some text:') +pause_test.send('hello there') +pause_test.send('\r') +pause_test.expect(r'Enter some text to edit:') +pause_test.send('hello there') +pause_test.send(backspace * 4) +pause_test.send('ommy boy') +pause_test.send('\r') +pause_test.expect(r'Enter some text \(output is hidden\):') +pause_test.send('supersecretpancakes') +pause_test.send('\r') +pause_test.expect(pexpect.EOF) +pause_test.close() + + +# Test that enter presses may not continue the play when a timeout is set. + +pause_test = pexpect.spawn( + 'ansible-playbook', + args=["pause-3.yml"] + args, + timeout=10, + env=os.environ +) + +pause_test.logfile = log_buffer +pause_test.expect(r"\(ctrl\+C then 'C' = continue early, ctrl\+C then 'A' = abort\)") +pause_test.send('\r') +pause_test.expect(pexpect.EOF) +pause_test.close() diff --git a/test/integration/targets/pause/test-pause.yml b/test/integration/targets/pause/test-pause.yml new file mode 100644 index 0000000..1c8045b --- /dev/null +++ b/test/integration/targets/pause/test-pause.yml @@ -0,0 +1,72 @@ +- name: Test pause + hosts: localhost + gather_facts: no + become: no + + tasks: + - name: non-integer for duraction (EXPECTED FAILURE) + pause: + seconds: hello + register: result + ignore_errors: yes + + - assert: + that: + - result is failed + - "'unable to convert to int' in result.msg" + + - name: non-boolean for echo (EXPECTED FAILURE) + pause: + echo: hello + register: result + ignore_errors: yes + + - assert: + that: + - result is failed + - "'not a valid boolean' in result.msg" + + - name: Less than 1 + pause: + seconds: 0.1 + register: results + + - assert: + that: + - results.stdout is search('Paused for \d+\.\d+ seconds') + + - name: 1 second + pause: + seconds: 1 + register: results + + - assert: + that: + - results.stdout is search('Paused for \d+\.\d+ seconds') + + - name: 1 minute + pause: + minutes: 1 + register: results + + - assert: + that: + - results.stdout is search('Paused for \d+\.\d+ minutes') + + - name: minutes and seconds + pause: + minutes: 1 + seconds: 1 + register: exclusive + ignore_errors: yes + + - name: invalid arg + pause: + foo: bar + register: invalid + ignore_errors: yes + + - assert: + that: + - '"parameters are mutually exclusive: minutes|seconds" in exclusive.msg' + - '"Unsupported parameters for (pause) module: foo." in invalid.msg' |