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
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
|
- name: Failure
set_fact:
hello: world
failed_when: true
ignore_errors: yes
register: intentional_failure
- name: Success
set_fact:
hello: world
register: intentional_success
- name: Try failure test on non-dictionary
set_fact:
hello: "{{ 'nope' is failure }}"
ignore_errors: yes
register: misuse_of_failure
- name: Assert failure tests work
assert:
that:
- intentional_failure is failed # old name
- intentional_failure is failure
- intentional_success is not failure
- misuse_of_failure is failed
- name: Assert successful tests work
assert:
that:
- intentional_success is succeeded # old name
- intentional_success is success # old name
- intentional_success is successful
- intentional_failure is not successful
- name: Try reachable host
command: id
register: reachable_host
- name: Try unreachable host
command: id
delegate_to: unreachable
ignore_unreachable: yes
ignore_errors: yes
register: unreachable_host
- name: Try reachable test on non-dictionary
set_fact:
hello: "{{ 'nope' is reachable }}"
ignore_errors: yes
register: misuse_of_reachable
- name: Assert reachable tests work
assert:
that:
- misuse_of_reachable is failed
- reachable_host is reachable
- unreachable_host is not reachable
- name: Try unreachable test on non-dictionary
set_fact:
hello: "{{ 'nope' is unreachable }}"
ignore_errors: yes
register: misuse_of_unreachable
- name: Assert unreachable tests work
assert:
that:
- misuse_of_unreachable is failed
- reachable_host is not unreachable
- unreachable_host is unreachable
- name: Make changes
file:
path: dir_for_changed
state: directory
register: directory_created
- name: Make no changes
file:
path: dir_for_changed
state: directory
register: directory_unchanged
- name: Try changed test on non-dictionary
set_fact:
hello: "{{ 'nope' is changed }}"
ignore_errors: yes
register: misuse_of_changed
# providing artificial task results since there are no modules in ansible-core that provide a 'results' list instead of 'changed'
- name: Prepare artificial task results
set_fact:
results_all_changed:
results:
- changed: true
- changed: true
results_some_changed:
results:
- changed: true
- changed: false
results_none_changed:
results:
- changed: false
- changed: false
results_missing_changed: {}
- name: Assert changed tests work
assert:
that:
- directory_created is changed
- directory_unchanged is not changed
- misuse_of_changed is failed
- results_all_changed is changed
- results_some_changed is changed
- results_none_changed is not changed
- results_missing_changed is not changed
- name: Skip me
set_fact:
hello: world
when: false
register: skipped_task
- name: Don't skip me
set_fact:
hello: world
register: executed_task
- name: Try skipped test on non-dictionary
set_fact:
hello: "{{ 'nope' is skipped }}"
ignore_errors: yes
register: misuse_of_skipped
- name: Assert skipped tests work
assert:
that:
- skipped_task is skipped
- executed_task is not skipped
- misuse_of_skipped is failure
- name: Not an async task
set_fact:
hello: world
register: non_async_task
- name: Complete an async task
command: id
async: 10
poll: 1
register: async_completed
- name: Start an async task without waiting for completion
shell: sleep 3
async: 10
poll: 0
register: async_incomplete
- name: Try finished test on non-dictionary
set_fact:
hello: "{{ 'nope' is finished }}"
ignore_errors: yes
register: misuse_of_finished
- name: Assert finished tests work (warning expected)
assert:
that:
- non_async_task is finished
- misuse_of_finished is failed
- async_completed is finished
- async_incomplete is not finished
- name: Try started test on non-dictionary
set_fact:
hello: "{{ 'nope' is started }}"
ignore_errors: yes
register: misuse_of_started
- name: Assert started tests work (warning expected)
assert:
that:
- non_async_task is started
- misuse_of_started is failed
- async_completed is started
- async_incomplete is started
- name: Assert match tests work
assert:
that:
- "'hello' is match('h.ll.')"
- "'hello' is not match('.ll.')"
- name: Assert search tests work
assert:
that:
- "'hello' is search('.l')"
- "'hello' is not search('nope')"
- name: Assert regex tests work
assert:
that:
- "'hello' is regex('.l')"
- "'hello' is regex('.L', ignorecase=true)"
- "'hello\nAnsible' is regex('^Ansible', multiline=true)"
- "'hello' is not regex('.L')"
- "'hello\nAnsible' is not regex('^Ansible')"
- name: Try version tests with bad operator
set_fact:
result: "{{ '1.0' is version('1.0', 'equals') }}"
ignore_errors: yes
register: version_bad_operator
- name: Try version tests with bad value
set_fact:
result: "{{ '1.0' is version('nope', '==', true) }}"
ignore_errors: yes
register: version_bad_value
- name: Try version with both strict and version_type
debug:
msg: "{{ '1.0' is version('1.0', strict=False, version_type='loose') }}"
ignore_errors: yes
register: version_strict_version_type
- name: Try version with bad version_type
debug:
msg: "{{ '1.0' is version('1.0', version_type='boom') }}"
ignore_errors: yes
register: version_bad_version_type
- name: Try version with bad semver
debug:
msg: "{{ 'nope' is version('nopenope', version_type='semver') }}"
ignore_errors: yes
register: version_bad_semver
- name: Try version with empty input value
debug:
msg: "{{ '' is version('1.0', '>') }}"
ignore_errors: yes
register: version_empty_input
- name: Try version with empty comparison value
debug:
msg: "{{ '1.0' is version('', '>') }}"
ignore_errors: yes
register: version_empty_comparison
- name: Try version with empty input and comparison values
debug:
msg: "{{ '' is version('', '>') }}"
ignore_errors: yes
register: version_empty_both
- name: Assert version tests work
assert:
that:
- "'1.0' is version_compare('1.0', '==')" # old name
- "'1.0' is version('1.0', '==')"
- "'1.0' is version('2.0', '!=')"
- "'1.0' is version('2.0', '<')"
- "'2.0' is version('1.0', '>')"
- "'1.0' is version('1.0', '<=')"
- "'1.0' is version('1.0', '>=')"
- "'1.0' is version_compare('1.0', '==', true)" # old name
- "'1.0' is version('1.0', '==', true)"
- "'1.0' is version('2.0', '!=', true)"
- "'1.0' is version('2.0', '<', true)"
- "'2.0' is version('1.0', '>', true)"
- "'1.0' is version('1.0', '<=', true)"
- "'1.0' is version('1.0', '>=', true)"
- "'1.2.3' is version('2.0.0', 'lt', version_type='semver')"
- "'2.14.0rc1' is version('2.14.0', 'lt', version_type='pep440')"
- version_bad_operator is failed
- version_bad_value is failed
- version_strict_version_type is failed
- version_bad_version_type is failed
- version_bad_semver is failed
- version_empty_input is failed
- version_empty_input is search('version value cannot be empty')
- version_empty_comparison is failed
- version_empty_comparison is search('to compare against cannot be empty')
- version_empty_both is failed
- version_empty_both is search('version value cannot be empty')
- name: Assert any tests work
assert:
that:
- "[true, false] is any"
- "[false] is not any"
- name: Assert all tests work
assert:
that:
- "[true] is all"
- "[true, false] is not all"
- name: Assert truthy tests work
assert:
that:
- '"string" is truthy'
- '"" is not truthy'
- True is truthy
- False is not truthy
- true is truthy
- false is not truthy
- 1 is truthy
- 0 is not truthy
- '[""] is truthy'
- '[] is not truthy'
- '"on" is truthy(convert_bool=True)'
- '"off" is not truthy(convert_bool=True)'
- '"fred" is truthy(convert_bool=True)'
- '{} is not truthy'
- '{"key": "value"} is truthy'
- name: Assert falsy tests work
assert:
that:
- '"string" is not falsy'
- '"" is falsy'
- True is not falsy
- False is falsy
- true is not falsy
- false is falsy
- 1 is not falsy
- 0 is falsy
- '[""] is not falsy'
- '[] is falsy'
- '"on" is not falsy(convert_bool=True)'
- '"off" is falsy(convert_bool=True)'
- '{} is falsy'
- '{"key": "value"} is not falsy'
- name: Create vaulted variable for vault_encrypted test
set_fact:
vaulted_value: !vault |
$ANSIBLE_VAULT;1.1;AES256
35323961353038346165643738646465376139363061353835303739663538343266303232326635
3365353662646236356665323135633630656238316530640a663362363763633436373439663031
33663433383037396438656464636433653837376361313638366362333037323961316364363363
3835616438623261650a636164376534376661393134326662326362323131373964313961623365
3833
- name: Assert vault_encrypted tests work
assert:
that:
- vaulted_value is vault_encrypted
- inventory_hostname is not vault_encrypted
|