I'm trying to write a fairly simply unittest for an ansible task. Here is the basic task:
---
- name: Test task
host: localhost
task:
- name: My test task
ansible.builtin.blockinfile:
dest: /my_output.yaml
block: |
thing 1
thing 2
thing 3
register: output
- name: Test output
ansible.builtin.assert:
that:
- output.changed == true
- output.block: | <-- Problem line
# BEGIN ANSIBLE MANAGED BLOCK
thing 1
thing 2
thing 3
# END ANSIBLE MANAGED BLOCK
I can confirm that the output to the my_output.yaml
does in fact match the block text per the assert, including the spacing on thing 2
and thing 3
. However this assertion does not actually run during the test. Obviously, the test isn't currently setup to actually test for ==
.
If I use - output.block == |
the formatted block text doesn't work. I can also use spacing and \n
to represent the formatted text and that does work using - output.block == "# BEGIN AN...MANAGED BLOCK"
but it is very difficult to read.
Is there a way to use block in this context?
NOTE... I know that I can use something like this as a separate assert, but it is multiple files and more difficult to 'read'.
- name: Compare output
ansible.builtin.assert:
that:
- lookup('file', '/my_output.yaml') == lookup('file', '/my_output_verified.yaml')
There's a bit of confusion in the above. The pipe sign (|
) is a yaml construct for yaml multiline strings. But you are using it inside an assert
expression which is by definition a raw Jinja2 expression without double curly braces (see assert
documentation and basic conditional when:
. Moreover, your second condition is actually not using any test.
So to achieve your above test with the ease of use of a yaml scalar block, you need to assign the value to a variable and use that variable in your test. Something like the following should do (untested as I don't have an example file nor an output of your registered variable)
- name: Test output
vars:
compare: |
# BEGIN ANSIBLE MANAGED BLOCK
thing 1
thing 2
thing 3
# END ANSIBLE MANAGED BLOCK
ansible.builtin.assert:
that:
- output.changed | bool
- output.block == compare
This should put you on track for your direct problem.
Now to go further, the real question is: why are you doing this at all? The blockinfile
module is (as the vast majority of Ansible modules) fully idempotent and will report changed
if it modified something or ok
if the content is already aligned. So the blockinfile
task is already your test as in any case the content will be the one you passed for the block content.