summaryrefslogtreecommitdiffstats
path: root/test/integration/targets/callback_default/runme.sh
blob: 0ee4259dde82ef09bea14df9092d2e0e5bc7e2cb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
#!/usr/bin/env bash

# This test compares "known good" output with various settings against output
# with the current code. It's brittle by nature, but this is probably the
# "best" approach possible.
#
# Notes:
# * options passed to this script (such as -v) are ignored, as they would change
#   the output and break the test
# * the number of asterisks after a "banner" differs depending on the number of
#   columns on the TTY, so we must adjust the columns for the current session
#   for consistency

set -eux

run_test() {
	local testname=$1
	local playbook=$2

	# output was recorded w/o cowsay, ensure we reproduce the same
	export ANSIBLE_NOCOWS=1

	# The shenanigans with redirection and 'tee' are to capture STDOUT and
	# STDERR separately while still displaying both to the console
	{ ansible-playbook -i inventory "$playbook" "${@:3}" \
		> >(set +x; tee "${OUTFILE}.${testname}.stdout"); } \
		2> >(set +x; tee "${OUTFILE}.${testname}.stderr" >&2)
	# Scrub deprication warning that shows up in Python 2.6 on CentOS 6
	sed -i -e '/RandomPool_DeprecationWarning/d' "${OUTFILE}.${testname}.stderr"
	sed -i -e 's/included: .*\/test\/integration/included: ...\/test\/integration/g' "${OUTFILE}.${testname}.stdout"
	sed -i -e 's/@@ -1,1 +1,1 @@/@@ -1 +1 @@/g' "${OUTFILE}.${testname}.stdout"
	sed -i -e 's/: .*\/test_diff\.txt/: ...\/test_diff.txt/g' "${OUTFILE}.${testname}.stdout"
	sed -i -e "s#${ANSIBLE_PLAYBOOK_DIR}#TEST_PATH#g" "${OUTFILE}.${testname}.stdout"
	sed -i -e 's/^Using .*//g' "${OUTFILE}.${testname}.stdout"
	sed -i -e 's/[0-9]:[0-9]\{2\}:[0-9]\{2\}\.[0-9]\{6\}/0:00:00.000000/g' "${OUTFILE}.${testname}.stdout"
	sed -i -e 's/[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\} [0-9]\{2\}:[0-9]\{2\}:[0-9]\{2\}\.[0-9]\{6\}/0000-00-00 00:00:00.000000/g' "${OUTFILE}.${testname}.stdout"
	sed -i -e 's#: .*/source$#: .../source#g' "${OUTFILE}.${testname}.stdout"
	sed -i -e '/secontext:/d' "${OUTFILE}.${testname}.stdout"
	sed -i -e 's/group: wheel/group: root/g' "${OUTFILE}.${testname}.stdout"

	diff -u "${ORIGFILE}.${testname}.stdout" "${OUTFILE}.${testname}.stdout" || diff_failure
	diff -u "${ORIGFILE}.${testname}.stderr" "${OUTFILE}.${testname}.stderr" || diff_failure
}

run_test_dryrun() {
	local testname=$1
	# optional, pass --check to run a dry run
	local chk=${2:-}

	# outout was recorded w/o cowsay, ensure we reproduce the same
	export ANSIBLE_NOCOWS=1

	# This needed to satisfy shellcheck that can not accept unquoted variable
	cmd="ansible-playbook -i inventory ${chk} test_dryrun.yml"

	# The shenanigans with redirection and 'tee' are to capture STDOUT and
	# STDERR separately while still displaying both to the console
	{ $cmd \
		> >(set +x; tee "${OUTFILE}.${testname}.stdout"); } \
		2> >(set +x; tee "${OUTFILE}.${testname}.stderr" >&2)
	# Scrub deprication warning that shows up in Python 2.6 on CentOS 6
	sed -i -e '/RandomPool_DeprecationWarning/d' "${OUTFILE}.${testname}.stderr"

	diff -u "${ORIGFILE}.${testname}.stdout" "${OUTFILE}.${testname}.stdout" || diff_failure
	diff -u "${ORIGFILE}.${testname}.stderr" "${OUTFILE}.${testname}.stderr" || diff_failure
}

diff_failure() {
	if [[ $INIT = 0 ]]; then
		echo "FAILURE...diff mismatch!"
		exit 1
	fi
}

cleanup() {
	if [[ $INIT = 0 ]]; then
		rm -rf "${OUTFILE}.*"
	fi

	if [[ -f "${BASEFILE}.unreachable.stdout" ]]; then
		rm -rf "${BASEFILE}.unreachable.stdout"
	fi

	if [[ -f "${BASEFILE}.unreachable.stderr" ]]; then
		rm -rf "${BASEFILE}.unreachable.stderr"
	fi

	# Restore TTY cols
	if [[ -n ${TTY_COLS:-} ]]; then
		stty cols "${TTY_COLS}"
	fi
}

adjust_tty_cols() {
	if [[ -t 1 ]]; then
		# Preserve existing TTY cols
		TTY_COLS=$( stty -a | grep -Eo '; columns [0-9]+;' | cut -d';' -f2 | cut -d' ' -f3 )
		# Override TTY cols to make comparing ansible-playbook output easier
		# This value matches the default in the code when there is no TTY
		stty cols 79
	fi
}

BASEFILE=callback_default.out

ORIGFILE="${BASEFILE}"
OUTFILE="${BASEFILE}.new"

trap 'cleanup' EXIT

# The --init flag will (re)generate the "good" output files used by the tests
INIT=0
if [[ ${1:-} == "--init" ]]; then
	shift
	OUTFILE=$ORIGFILE
	INIT=1
fi

adjust_tty_cols

# Force the 'default' callback plugin, since that's what we're testing
export ANSIBLE_STDOUT_CALLBACK=default
# Disable color in output for consistency
export ANSIBLE_FORCE_COLOR=0
export ANSIBLE_NOCOLOR=1

# Default settings
export ANSIBLE_DISPLAY_SKIPPED_HOSTS=1
export ANSIBLE_DISPLAY_OK_HOSTS=1
export ANSIBLE_DISPLAY_FAILED_STDERR=0
export ANSIBLE_CHECK_MODE_MARKERS=0

run_test default test.yml

# Check for async output
# NOTE: regex to match 1 or more digits works for both BSD and GNU grep
ansible-playbook -i inventory test_async.yml 2>&1 | tee async_test.out
grep "ASYNC OK .* jid=[0-9]\{1,\}" async_test.out
grep "ASYNC FAILED .* jid=[0-9]\{1,\}" async_test.out
rm -f async_test.out

# Hide skipped
export ANSIBLE_DISPLAY_SKIPPED_HOSTS=0

run_test hide_skipped test.yml

# Hide skipped/ok
export ANSIBLE_DISPLAY_SKIPPED_HOSTS=0
export ANSIBLE_DISPLAY_OK_HOSTS=0

run_test hide_skipped_ok test.yml

# Hide ok
export ANSIBLE_DISPLAY_SKIPPED_HOSTS=1
export ANSIBLE_DISPLAY_OK_HOSTS=0

run_test hide_ok test.yml

# Failed to stderr
export ANSIBLE_DISPLAY_SKIPPED_HOSTS=1
export ANSIBLE_DISPLAY_OK_HOSTS=1
export ANSIBLE_DISPLAY_FAILED_STDERR=1

run_test failed_to_stderr test.yml
export ANSIBLE_DISPLAY_FAILED_STDERR=0


# Test displaying task path on failure
export ANSIBLE_SHOW_TASK_PATH_ON_FAILURE=1
run_test display_path_on_failure test.yml
export ANSIBLE_SHOW_TASK_PATH_ON_FAILURE=0


# Default settings with unreachable tasks
export ANSIBLE_DISPLAY_SKIPPED_HOSTS=1
export ANSIBLE_DISPLAY_OK_HOSTS=1
export ANSIBLE_DISPLAY_FAILED_STDERR=1
export ANSIBLE_TIMEOUT=1

# Check if UNREACHBLE is available in stderr
set +e
ansible-playbook -i inventory test_2.yml > >(set +x; tee "${BASEFILE}.unreachable.stdout";) 2> >(set +x; tee "${BASEFILE}.unreachable.stderr" >&2) || true
set -e
if test "$(grep -c 'UNREACHABLE' "${BASEFILE}.unreachable.stderr")" -ne 1; then
	echo "Test failed"
	exit 1
fi
export ANSIBLE_DISPLAY_FAILED_STDERR=0

export ANSIBLE_CALLBACK_RESULT_FORMAT=yaml
run_test result_format_yaml test.yml
export ANSIBLE_CALLBACK_RESULT_FORMAT=json

export ANSIBLE_CALLBACK_RESULT_FORMAT=yaml
export ANSIBLE_CALLBACK_FORMAT_PRETTY=1
run_test result_format_yaml_lossy_verbose test.yml -v
run_test yaml_result_format_yaml_verbose test_yaml.yml -v
export ANSIBLE_CALLBACK_RESULT_FORMAT=json
unset ANSIBLE_CALLBACK_FORMAT_PRETTY

export ANSIBLE_CALLBACK_RESULT_FORMAT=yaml
export ANSIBLE_CALLBACK_FORMAT_PRETTY=0
run_test result_format_yaml_verbose test.yml -v
export ANSIBLE_CALLBACK_RESULT_FORMAT=json
unset ANSIBLE_CALLBACK_FORMAT_PRETTY


## DRY RUN tests
#
# Default settings with dry run tasks
export ANSIBLE_DISPLAY_SKIPPED_HOSTS=1
export ANSIBLE_DISPLAY_OK_HOSTS=1
export ANSIBLE_DISPLAY_FAILED_STDERR=1
# Enable Check mode markers
export ANSIBLE_CHECK_MODE_MARKERS=1

# Test the wet run with check markers
run_test_dryrun check_markers_wet

# Test the dry run with check markers
run_test_dryrun check_markers_dry --check

# Disable Check mode markers
export ANSIBLE_CHECK_MODE_MARKERS=0

# Test the wet run without check markers
run_test_dryrun check_nomarkers_wet

# Test the dry run without check markers
run_test_dryrun check_nomarkers_dry --check

# Make sure implicit meta tasks are not printed
ansible-playbook -i host1,host2 no_implicit_meta_banners.yml > meta_test.out
cat meta_test.out
[ "$(grep -c 'TASK \[meta\]' meta_test.out)" -eq 0 ]
rm -f meta_test.out

# Ensure free/host_pinned non-lockstep strategies display correctly
diff -u callback_default.out.free.stdout <(ANSIBLE_STRATEGY=free ansible-playbook -i inventory test_non_lockstep.yml 2>/dev/null)
diff -u callback_default.out.fqcn_free.stdout <(ANSIBLE_STRATEGY=ansible.builtin.free ansible-playbook -i inventory test_non_lockstep.yml 2>/dev/null)
diff -u callback_default.out.host_pinned.stdout <(ANSIBLE_STRATEGY=host_pinned ansible-playbook -i inventory test_non_lockstep.yml 2>/dev/null)