xml module: Better change detection, improved tests (#28460)

This PR includes:

- Improvements to change-detection by comparing 2 objectified XML trees
- Implement better integration tests by comparing 2 files using copy
pull/27817/head
Dag Wieers 7 years ago committed by GitHub
parent 3302248616
commit 2634ef955a

@ -21,7 +21,8 @@ module: xml
short_description: Manage bits and pieces of XML files or strings short_description: Manage bits and pieces of XML files or strings
description: description:
- A CRUD-like interface to managing bits of XML files. - A CRUD-like interface to managing bits of XML files.
- You might also be interested in a brief tutorial from U(http://www.w3schools.com/xpath/). - You might also be interested in a brief tutorial from U(http://www.w3schools.com/xpath/)
and U(https://developer.mozilla.org/en-US/docs/Web/XPath).
version_added: '2.4' version_added: '2.4'
options: options:
path: path:
@ -101,6 +102,7 @@ requirements:
- lxml >= 2.3.0 - lxml >= 2.3.0
notes: notes:
- Use the C(--check) and C(--diff) options when testing your expressions. - Use the C(--check) and C(--diff) options when testing your expressions.
- The diff output is automatically pretty-printed, so may not reflect the actual file content, only the file structure.
- This module does not handle complicated xpath expressions, so limit xpath selectors to simple expressions. - This module does not handle complicated xpath expressions, so limit xpath selectors to simple expressions.
- Beware that in case your XML elements are namespaced, you need to use the C(namespaces) parameter. - Beware that in case your XML elements are namespaced, you need to use the C(namespaces) parameter.
- Namespaces prefix should be used for all children of an element where namespace is defined, unless another namespace is defined for them. - Namespaces prefix should be used for all children of an element where namespace is defined, unless another namespace is defined for them.
@ -233,7 +235,7 @@ from distutils.version import LooseVersion
from io import BytesIO from io import BytesIO
try: try:
from lxml import etree from lxml import etree, objectify
HAS_LXML = True HAS_LXML = True
except ImportError: except ImportError:
HAS_LXML = False HAS_LXML = False
@ -256,6 +258,12 @@ _RE_SPLITSUBLAST = re.compile("^(.*)/(" + _NSIDENT + ")\\[(.*)\\]$")
_RE_SPLITONLYEQVALUE = re.compile("^(.*)/text\\(\\)=" + _XPSTR + "$") _RE_SPLITONLYEQVALUE = re.compile("^(.*)/text\\(\\)=" + _XPSTR + "$")
def has_changed(doc):
orig_obj = etree.tostring(objectify.fromstring(etree.tostring(orig_doc)))
obj = etree.tostring(objectify.fromstring(etree.tostring(doc)))
return (orig_obj != obj)
def do_print_match(module, tree, xpath, namespaces): def do_print_match(module, tree, xpath, namespaces):
match = tree.xpath(xpath, namespaces=namespaces) match = tree.xpath(xpath, namespaces=namespaces)
match_xpaths = [] match_xpaths = []
@ -535,34 +543,6 @@ def set_target(module, tree, xpath, namespaces, attribute, value):
finish(module, tree, xpath, namespaces, changed) finish(module, tree, xpath, namespaces, changed)
def pretty(module, tree):
xml_string = etree.tostring(tree, xml_declaration=True, encoding='UTF-8', pretty_print=module.params['pretty_print'])
result = dict(
changed=False,
)
if module.params['path']:
xml_file = module.params['path']
xml_content = open(xml_file)
try:
if xml_string != xml_content.read():
result['changed'] = True
if not module.check_mode:
if module.params['backup']:
result['backup_file'] = module.backup_local(module.params['path'])
tree.write(xml_file, xml_declaration=True, encoding='UTF-8', pretty_print=module.params['pretty_print'])
finally:
xml_content.close()
elif module.params['xmlstring']:
result['xmlstring'] = xml_string
if xml_string != module.params['xmlstring']:
result['changed'] = True
module.exit_json(**result)
def get_element_text(module, tree, xpath, namespaces): def get_element_text(module, tree, xpath, namespaces):
if not is_node(tree, xpath, namespaces): if not is_node(tree, xpath, namespaces):
module.fail_json(msg="Xpath %s does not reference a node!" % xpath) module.fail_json(msg="Xpath %s does not reference a node!" % xpath)
@ -633,27 +613,56 @@ def children_to_nodes(module=None, children=[], type='yaml'):
return [child_to_element(module, child, type) for child in children] return [child_to_element(module, child, type) for child in children]
def pretty(module, tree):
xml_string = etree.tostring(tree, xml_declaration=True, encoding='UTF-8', pretty_print=module.params['pretty_print'])
result = dict(
changed=False,
)
if module.params['path']:
xml_file = module.params['path']
xml_content = open(xml_file)
try:
if xml_string != xml_content.read():
result['changed'] = True
if not module.check_mode:
if module.params['backup']:
result['backup_file'] = module.backup_local(module.params['path'])
tree.write(xml_file, xml_declaration=True, encoding='UTF-8', pretty_print=module.params['pretty_print'])
finally:
xml_content.close()
elif module.params['xmlstring']:
result['xmlstring'] = xml_string
# NOTE: Modifying a string is not considered a change !
if xml_string != module.params['xmlstring']:
result['changed'] = True
module.exit_json(**result)
def finish(module, tree, xpath, namespaces, changed=False, msg="", hitcount=0, matches=tuple()): def finish(module, tree, xpath, namespaces, changed=False, msg="", hitcount=0, matches=tuple()):
result = dict( result = dict(
actions=dict(xpath=xpath, namespaces=namespaces, state=module.params['state']), actions=dict(xpath=xpath, namespaces=namespaces, state=module.params['state']),
changed=changed, changed=has_changed(tree),
count=hitcount, count=hitcount,
matches=matches, matches=matches,
msg=msg, msg=msg,
) )
if changed and module._diff: if result['changed']:
result['diff'] = dict( if module._diff:
before=etree.tostring(orig_doc, xml_declaration=True, encoding='UTF-8', pretty_print=module.params['pretty_print']), result['diff'] = dict(
after=etree.tostring(tree, xml_declaration=True, encoding='UTF-8', pretty_print=module.params['pretty_print']), before=etree.tostring(orig_doc, xml_declaration=True, encoding='UTF-8', pretty_print=True),
) after=etree.tostring(tree, xml_declaration=True, encoding='UTF-8', pretty_print=True),
)
if module.params['path'] and not module.check_mode:
if module.params['backup']:
result['backup_file'] = module.backup_local(module.params['path'])
tree.write(module.params['path'], xml_declaration=True, encoding='UTF-8', pretty_print=module.params['pretty_print']) if module.params['path'] and not module.check_mode:
if module.params['backup']:
result['backup_file'] = module.backup_local(module.params['path'])
tree.write(module.params['path'], xml_declaration=True, encoding='UTF-8', pretty_print=module.params['pretty_print'])
if module.params['xmlstring']: if module.params['xmlstring']:
result['xmlstring'] = etree.tostring(tree, xml_declaration=True, encoding='UTF-8', pretty_print=module.params['pretty_print']) result['xmlstring'] = etree.tostring(tree, xml_declaration=True, encoding='UTF-8', pretty_print=module.params['pretty_print'])
@ -741,9 +750,8 @@ def main():
module.fail_json(msg="Error while parsing document: %s (%s)" % (xml_file or 'xml_string', e)) module.fail_json(msg="Error while parsing document: %s (%s)" % (xml_file or 'xml_string', e))
# Ensure we have the original copy to compare # Ensure we have the original copy to compare
if module._diff: global orig_doc
global orig_doc orig_doc = copy.deepcopy(doc)
orig_doc = copy.deepcopy(doc)
if print_match: if print_match:
do_print_match(module, doc, xpath, namespaces) do_print_match(module, doc, xpath, namespaces)

@ -35,34 +35,35 @@
when: lxml_xpath_attribute_result_attrname when: lxml_xpath_attribute_result_attrname
block: block:
- include: test-add-children-elements.yml - include_tasks: test-add-children-elements.yml
- include: test-add-children-from-groupvars.yml - include_tasks: test-add-children-from-groupvars.yml
- include: test-add-children-with-attributes.yml - include_tasks: test-add-children-with-attributes.yml
- include: test-add-element-implicitly.yml - include_tasks: test-add-element-implicitly.yml
- include: test-count.yml - include_tasks: test-count.yml
- include: test-mutually-exclusive-attributes.yml - include_tasks: test-mutually-exclusive-attributes.yml
- include: test-remove-attribute.yml - include_tasks: test-remove-attribute.yml
- include: test-remove-element.yml - include_tasks: test-remove-element.yml
- include: test-set-attribute-value.yml - include_tasks: test-set-attribute-value.yml
- include: test-set-children-elements.yml - include_tasks: test-set-children-elements.yml
- include: test-set-children-elements-level.yml - include_tasks: test-set-children-elements-level.yml
- include: test-set-element-value.yml - include_tasks: test-set-element-value.yml
- include: test-set-element-value-empty.yml - include_tasks: test-set-element-value-empty.yml
- include: test-pretty-print.yml - include_tasks: test-pretty-print.yml
- include: test-pretty-print-only.yml - include_tasks: test-pretty-print-only.yml
- include: test-add-namespaced-children-elements.yml - include_tasks: test-add-namespaced-children-elements.yml
- include: test-remove-namespaced-attribute.yml - include_tasks: test-remove-namespaced-attribute.yml
- include: test-set-namespaced-attribute-value.yml - include_tasks: test-set-namespaced-attribute-value.yml
- include: test-set-namespaced-element-value.yml - include_tasks: test-set-namespaced-element-value.yml
- include: test-get-element-content.yml - include_tasks: test-set-namespaced-children-elements.yml
- include: test-xmlstring.yml - include_tasks: test-get-element-content.yml
- include: test-children-elements-xml.yml - include_tasks: test-xmlstring.yml
- include_tasks: test-children-elements-xml.yml
# Unicode tests # Unicode tests
- include: test-add-children-elements-unicode.yml - include_tasks: test-add-children-elements-unicode.yml
- include: test-add-children-with-attributes-unicode.yml - include_tasks: test-add-children-with-attributes-unicode.yml
- include: test-set-attribute-value-unicode.yml - include_tasks: test-set-attribute-value-unicode.yml
- include: test-count-unicode.yml - include_tasks: test-count-unicode.yml
- include: test-get-element-content.yml - include_tasks: test-get-element-content.yml
- include: test-set-children-elements-unicode.yml - include_tasks: test-set-children-elements-unicode.yml
- include: test-set-element-value-unicode.yml - include_tasks: test-set-element-value-unicode.yml

@ -1,15 +1,29 @@
--- ---
- name: Setup test fixture - name: Setup test fixture
copy: copy:
src: '{{ role_path }}/fixtures/ansible-xml-beers.xml' src: fixtures/ansible-xml-beers.xml
dest: /tmp/ansible-xml-beers.xml dest: /tmp/ansible-xml-beers.xml
- name: Add child element - name: Add child element
xml: xml:
path: /tmp/ansible-xml-beers.xml path: /tmp/ansible-xml-beers.xml
xpath: /business/beers xpath: /business/beers
add_children: add_children:
- beer: "Окское" - beer: Окское
register: add_children_elements_unicode
- name: Compare to expected result
copy:
src: results/test-add-children-elements-unicode.xml
dest: /tmp/ansible-xml-beers.xml
check_mode: yes
diff: yes
register: comparison
- name: Test expected result - name: Test expected result
command: diff -u {{ role_path }}/results/test-add-children-elements-unicode.xml /tmp/ansible-xml-beers.xml assert:
that:
- add_children_elements_unicode.changed == true
- comparison.changed == false # identical
#command: diff -u {{ role_path }}/results/test-add-children-elements-unicode.xml /tmp/ansible-xml-beers.xml

@ -1,15 +1,29 @@
--- ---
- name: Setup test fixture - name: Setup test fixture
copy: copy:
src: '{{ role_path }}/fixtures/ansible-xml-beers.xml' src: fixtures/ansible-xml-beers.xml
dest: /tmp/ansible-xml-beers.xml dest: /tmp/ansible-xml-beers.xml
- name: Add child element - name: Add child element
xml: xml:
path: /tmp/ansible-xml-beers.xml path: /tmp/ansible-xml-beers.xml
xpath: /business/beers xpath: /business/beers
add_children: add_children:
- beer: "Old Rasputin" - beer: Old Rasputin
register: add_children_elements
- name: Compare to expected result
copy:
src: results/test-add-children-elements.xml
dest: /tmp/ansible-xml-beers.xml
check_mode: yes
diff: yes
register: comparison
- name: Test expected result - name: Test expected result
command: diff -u {{ role_path }}/results/test-add-children-elements.xml /tmp/ansible-xml-beers.xml assert:
that:
- add_children_elements.changed == true
- comparison.changed == false # identical
#command: diff -u {{ role_path }}/results/test-add-children-elements.xml /tmp/ansible-xml-beers.xml

@ -1,14 +1,28 @@
--- ---
- name: Setup test fixture - name: Setup test fixture
copy: copy:
src: '{{ role_path }}/fixtures/ansible-xml-beers.xml' src: fixtures/ansible-xml-beers.xml
dest: /tmp/ansible-xml-beers.xml dest: /tmp/ansible-xml-beers.xml
- name: Add child element - name: Add child element
xml: xml:
path: /tmp/ansible-xml-beers.xml path: /tmp/ansible-xml-beers.xml
xpath: /business/beers xpath: /business/beers
add_children: "{{ bad_beers }}" add_children: '{{ bad_beers }}'
register: add_children_from_groupvars
- name: Compare to expected result
copy:
src: results/test-add-children-from-groupvars.xml
dest: /tmp/ansible-xml-beers.xml
check_mode: yes
diff: yes
register: comparison
- name: Test expected result - name: Test expected result
command: diff -u {{ role_path }}/results/test-add-children-from-groupvars.xml /tmp/ansible-xml-beers.xml assert:
that:
- add_children_from_groupvars.changed == true
- comparison.changed == false # identical
#command: diff -u {{ role_path }}/results/test-add-children-from-groupvars.xml /tmp/ansible-xml-beers.xml

@ -1,17 +1,31 @@
--- ---
- name: Setup test fixture - name: Setup test fixture
copy: copy:
src: '{{ role_path }}/fixtures/ansible-xml-beers.xml' src: fixtures/ansible-xml-beers.xml
dest: /tmp/ansible-xml-beers.xml dest: /tmp/ansible-xml-beers.xml
- name: Add child element - name: Add child element
xml: xml:
path: /tmp/ansible-xml-beers.xml path: /tmp/ansible-xml-beers.xml
xpath: /business/beers xpath: /business/beers
add_children: add_children:
- beer: - beer:
name: Окское name: Окское
type: экстра type: экстра
register: add_children_with_attributes_unicode
- name: Compare to expected result
copy:
src: results/test-add-children-with-attributes-unicode.xml
dest: /tmp/ansible-xml-beers.xml
check_mode: yes
diff: yes
register: comparison
- name: Test expected result - name: Test expected result
command: diff -u {{ role_path }}/results/test-add-children-with-attributes-unicode.xml /tmp/ansible-xml-beers.xml assert:
that:
- add_children_with_attributes_unicode.changed == true
- comparison.changed == false # identical
#command: diff -u {{ role_path }}/results/test-add-children-with-attributes-unicode.xml /tmp/ansible-xml-beers.xml

@ -1,22 +1,35 @@
--- ---
- name: Setup test fixture - name: Setup test fixture
copy: copy:
src: '{{ role_path }}/fixtures/ansible-xml-beers.xml' src: fixtures/ansible-xml-beers.xml
dest: /tmp/ansible-xml-beers.xml dest: /tmp/ansible-xml-beers.xml
- name: Add child element - name: Add child element
xml: xml:
path: /tmp/ansible-xml-beers.xml path: /tmp/ansible-xml-beers.xml
xpath: /business/beers xpath: /business/beers
add_children: add_children:
- beer: - beer:
name: Ansible Brew name: Ansible Brew
type: light type: light
register: add_children_with_attributes
- name: Compare to expected result
copy:
src: results/test-add-children-with-attributes.xml
dest: /tmp/ansible-xml-beers.xml
check_mode: yes
diff: yes
register: comparison
# NOTE: This test may fail if lxml does not support predictable element attribute order # NOTE: This test may fail if lxml does not support predictable element attribute order
# So we filter the failure out for these platforms (e.g. CentOS 6) # So we filter the failure out for these platforms (e.g. CentOS 6)
# The module still works fine, we simply are not comparing as smart as we should. # The module still works fine, we simply are not comparing as smart as we should.
- name: Test expected result - name: Test expected result
command: diff -u {{ role_path }}/results/test-add-children-with-attributes.xml /tmp/ansible-xml-beers.xml assert:
register: diff that:
failed_when: diff.rc != 0 and lxml_predictable_attribute_order - add_children_with_attributes.changed == true
- comparison.changed == false # identical
when: lxml_predictable_attribute_order
#command: diff -u {{ role_path }}/results/test-add-children-with-attributes.xml /tmp/ansible-xml-beers.xml

@ -1,62 +1,118 @@
--- ---
- name: Setup test fixture - name: Setup test fixture
copy: src={{ role_path }}/fixtures/ansible-xml-beers.xml dest=/tmp/ansible-xml-beers-implicit.xml copy:
src: fixtures/ansible-xml-beers.xml
dest: /tmp/ansible-xml-beers-implicit.xml
- name: Add a phonenumber element to the business element. Implicit mkdir -p behavior where applicable - name: Add a phonenumber element to the business element. Implicit mkdir -p behavior where applicable
xml: file=/tmp/ansible-xml-beers-implicit.xml xpath=/business/phonenumber value=555-555-1234 xml:
file: /tmp/ansible-xml-beers-implicit.xml
xpath: /business/phonenumber
value: 555-555-1234
- name: Add a owner element to the business element, testing implicit mkdir -p behavior 1/2 - name: Add a owner element to the business element, testing implicit mkdir -p behavior 1/2
xml: file=/tmp/ansible-xml-beers-implicit.xml xpath=/business/owner/name/last value=Smith xml:
file: /tmp/ansible-xml-beers-implicit.xml
xpath: /business/owner/name/last
value: Smith
- name: Add a owner element to the business element, testing implicit mkdir -p behavior 2/2 - name: Add a owner element to the business element, testing implicit mkdir -p behavior 2/2
xml: file=/tmp/ansible-xml-beers-implicit.xml xpath=/business/owner/name/first value=John xml:
file: /tmp/ansible-xml-beers-implicit.xml
xpath: /business/owner/name/first
value: John
- name: Add a validxhtml element to the website element. Note that ensure is present by default and while value defaults to null for elements, if one doesn't specify it we don't know what to do. - name: Add a validxhtml element to the website element. Note that ensure is present by default and while value defaults to null for elements, if one doesn't specify it we don't know what to do.
xml: file=/tmp/ansible-xml-beers-implicit.xml xpath=/business/website/validxhtml xml:
file: /tmp/ansible-xml-beers-implicit.xml
xpath: /business/website/validxhtml
- name: Add an empty validateon attribute to the validxhtml element. This actually makes the previous example redundant because of the implicit parent-node creation behavior. - name: Add an empty validateon attribute to the validxhtml element. This actually makes the previous example redundant because of the implicit parent-node creation behavior.
xml: file=/tmp/ansible-xml-beers-implicit.xml xpath=/business/website/validxhtml/@validateon xml:
file: /tmp/ansible-xml-beers-implicit.xml
xpath: /business/website/validxhtml/@validateon
- name: Add an empty validateon attribute to the validxhtml element. Actually verifies the implicit parent-node creation behavior. - name: Add an empty validateon attribute to the validxhtml element. Actually verifies the implicit parent-node creation behavior.
xml: file=/tmp/ansible-xml-beers-implicit.xml xpath=/business/website_bis/validxhtml/@validateon xml:
file: /tmp/ansible-xml-beers-implicit.xml
xpath: /business/website_bis/validxhtml/@validateon
- name: Add an attribute with a value - name: Add an attribute with a value
xml: file=/tmp/ansible-xml-beers-implicit.xml xpath=/business/owner/@dob='1976-04-12' xml:
file: /tmp/ansible-xml-beers-implicit.xml
xpath: /business/owner/@dob='1976-04-12'
- name: Add an element with a value, alternate syntax - name: Add an element with a value, alternate syntax
xml: file=/tmp/ansible-xml-beers-implicit.xml xpath="/business/beers/beer/text()=\"George Killian's Irish Red\"" # note the quote within an XPath string thing xml:
file: /tmp/ansible-xml-beers-implicit.xml
xpath: /business/beers/beer/text()="George Killian's Irish Red" # note the quote within an XPath string thing
- name: Add an element without special characters - name: Add an element without special characters
xml: file=/tmp/ansible-xml-beers-implicit.xml xpath=/business/testnormalelement value="xml tag with no special characters" pretty_print=true xml:
file: /tmp/ansible-xml-beers-implicit.xml
xpath: /business/testnormalelement
value: xml tag with no special characters
pretty_print: yes
- name: Add an element with dash - name: Add an element with dash
xml: file=/tmp/ansible-xml-beers-implicit.xml xpath=/business/test-with-dash value="xml tag with dashes" pretty_print=true xml:
file: /tmp/ansible-xml-beers-implicit.xml
xpath: /business/test-with-dash
value: xml tag with dashes
pretty_print: yes
- name: Add an element with dot - name: Add an element with dot
xml: file=/tmp/ansible-xml-beers-implicit.xml xpath=/business/test-with-dash.and.dot value="xml tag with dashes and dots" pretty_print=true xml:
file: /tmp/ansible-xml-beers-implicit.xml
xpath: /business/test-with-dash.and.dot
value: xml tag with dashes and dots
pretty_print: yes
- name: Add an element with underscore - name: Add an element with underscore
xml: file=/tmp/ansible-xml-beers-implicit.xml xpath=/business/test-with.dash_and.dot_and-underscores value="xml tag with dashes, dots and underscores" pretty_print=true xml:
file: /tmp/ansible-xml-beers-implicit.xml
xpath: /business/test-with.dash_and.dot_and-underscores
value: xml tag with dashes, dots and underscores
pretty_print: yes
- name: Add an attribute on a conditional element - name: Add an attribute on a conditional element
xml: file=/tmp/ansible-xml-beers-implicit.xml xpath="/business/beers/beer[text()=\"George Killian's Irish Red\"]/@color='red'" xml:
file: /tmp/ansible-xml-beers-implicit.xml
xpath: /business/beers/beer[text()="George Killian's Irish Red"]/@color='red'
- name: Add two attributes on a conditional element - name: Add two attributes on a conditional element
xml: file=/tmp/ansible-xml-beers-implicit.xml xpath="/business/beers/beer[text()=\"Pilsner Urquell\" and @origin='CZ']/@color='blonde'" xml:
file: /tmp/ansible-xml-beers-implicit.xml
xpath: /business/beers/beer[text()="Pilsner Urquell" and @origin='CZ']/@color='blonde'
- name: Add a owner element to the business element, testing implicit mkdir -p behavior 3/2 -- complex lookup - name: Add a owner element to the business element, testing implicit mkdir -p behavior 3/2 -- complex lookup
xml: file=/tmp/ansible-xml-beers-implicit.xml xpath=/business/owner/name[first/text()='John']/middle value=Q xml:
file: /tmp/ansible-xml-beers-implicit.xml
xpath: /business/owner/name[first/text()='John']/middle
value: Q
- name: Pretty Print this! - name: Pretty Print this!
xml: file=/tmp/ansible-xml-beers-implicit.xml pretty_print=True xml:
file: /tmp/ansible-xml-beers-implicit.xml
pretty_print: yes
- name: Compare to expected result
copy:
src: results/test-add-element-implicitly.yml
dest: /tmp/ansible-xml-beers-implicit.xml
check_mode: yes
diff: yes
register: comparison
- name: Test expected result - name: Test expected result
command: diff -u {{ role_path }}/results/test-add-element-implicitly.yml /tmp/ansible-xml-beers-implicit.xml assert:
that:
- comparison.changed == false # identical
#command: diff -u {{ role_path }}/results/test-add-element-implicitly.yml /tmp/ansible-xml-beers-implicit.xml
#
# Now we repeat the same, just to ensure proper use of namespaces
#
# Now we repeat the same, just to ensure proper use of namespaces
- name: Add a phonenumber element to the business element. Implicit mkdir -p behavior where applicable - name: Add a phonenumber element to the business element. Implicit mkdir -p behavior where applicable
xml: xml:
file: /tmp/ansible-xml-beers-implicit.xml file: /tmp/ansible-xml-beers-implicit.xml
@ -112,21 +168,21 @@
- name: Add an element with a value, alternate syntax - name: Add an element with a value, alternate syntax
xml: xml:
file: /tmp/ansible-xml-beers-implicit.xml file: /tmp/ansible-xml-beers-implicit.xml
xpath: "/business/a:beers/a:beer/text()=\"George Killian's Irish Red\"" # note the quote within an XPath string thing xpath: /business/a:beers/a:beer/text()="George Killian's Irish Red" # note the quote within an XPath string thing
namespaces: namespaces:
a: http://example.com/some/namespace a: http://example.com/some/namespace
- name: Add an attribute on a conditional element - name: Add an attribute on a conditional element
xml: xml:
file: /tmp/ansible-xml-beers-implicit.xml file: /tmp/ansible-xml-beers-implicit.xml
xpath: "/business/a:beers/a:beer[text()=\"George Killian's Irish Red\"]/@a:color='red'" xpath: /business/a:beers/a:beer[text()="George Killian's Irish Red"]/@a:color='red'
namespaces: namespaces:
a: http://example.com/some/namespace a: http://example.com/some/namespace
- name: Add two attributes on a conditional element - name: Add two attributes on a conditional element
xml: xml:
file: /tmp/ansible-xml-beers-implicit.xml file: /tmp/ansible-xml-beers-implicit.xml
xpath: "/business/a:beers/a:beer[text()=\"Pilsner Urquell\" and @a:origin='CZ']/@a:color='blonde'" xpath: /business/a:beers/a:beer[text()="Pilsner Urquell" and @a:origin='CZ']/@a:color='blonde'
namespaces: namespaces:
a: http://example.com/some/namespace a: http://example.com/some/namespace
@ -142,8 +198,8 @@
xml: xml:
file: /tmp/ansible-xml-beers-implicit.xml file: /tmp/ansible-xml-beers-implicit.xml
xpath: /business/testnormalelement xpath: /business/testnormalelement
value: "xml tag with no special characters" value: xml tag with no special characters
pretty_print: true pretty_print: yes
namespaces: namespaces:
a: http://example.com/some/namespace a: http://example.com/some/namespace
@ -152,8 +208,8 @@
xml: xml:
file: /tmp/ansible-xml-beers-implicit.xml file: /tmp/ansible-xml-beers-implicit.xml
xpath: /business/test-with-dash xpath: /business/test-with-dash
value: "xml tag with dashes" value: xml tag with dashes
pretty_print: true pretty_print: yes
namespaces: namespaces:
a: http://example.com/some/namespace a: http://example.com/some/namespace
@ -161,8 +217,8 @@
xml: xml:
file: /tmp/ansible-xml-beers-implicit.xml file: /tmp/ansible-xml-beers-implicit.xml
xpath: /business/test-with-dash.and.dot xpath: /business/test-with-dash.and.dot
value: "xml tag with dashes and dots" value: xml tag with dashes and dots
pretty_print: true pretty_print: yes
namespaces: namespaces:
a: http://example.com/some/namespace a: http://example.com/some/namespace
@ -170,10 +226,12 @@
xml: xml:
file: /tmp/ansible-xml-beers-implicit.xml file: /tmp/ansible-xml-beers-implicit.xml
xpath: /business/test-with.dash_and.dot_and-underscores xpath: /business/test-with.dash_and.dot_and-underscores
value: "xml tag with dashes, dots and underscores" value: xml tag with dashes, dots and underscores
pretty_print: true pretty_print: yes
namespaces: namespaces:
a: http://example.com/some/namespace a: http://example.com/some/namespace
- name: Pretty Print this! - name: Pretty Print this!
xml: file=/tmp/ansible-xml-beers-implicit.xml pretty_print=True xml:
file: /tmp/ansible-xml-beers-implicit.xml
pretty_print: yes

@ -1,9 +1,10 @@
--- ---
- name: Setup test fixture - name: Setup test fixture
copy: copy:
src: '{{ role_path }}/fixtures/ansible-xml-namespaced-beers.xml' src: fixtures/ansible-xml-namespaced-beers.xml
dest: /tmp/ansible-xml-namespaced-beers.xml dest: /tmp/ansible-xml-namespaced-beers.xml
- name: Add namespaced child element - name: Add namespaced child element
xml: xml:
path: /tmp/ansible-xml-namespaced-beers.xml path: /tmp/ansible-xml-namespaced-beers.xml
@ -12,7 +13,20 @@
bus: http://test.business bus: http://test.business
ber: http://test.beers ber: http://test.beers
add_children: add_children:
- beer: "Old Rasputin" - beer: Old Rasputin
register: add_namespaced_children_elements
- name: Compare to expected result
copy:
src: results/test-add-namespaced-children-elements.xml
dest: /tmp/ansible-xml-namespaced-beers.xml
check_mode: yes
diff: yes
register: comparison
- name: Test expected result - name: Test expected result
command: diff -u {{ role_path }}/results/test-add-namespaced-children-elements.xml /tmp/ansible-xml-namespaced-beers.xml assert:
that:
- add_namespaced_children_elements.changed == true
- comparison.changed == false # identical
#command: diff -u {{ role_path }}/results/test-add-namespaced-children-elements.xml /tmp/ansible-xml-namespaced-beers.xml

@ -1,16 +1,30 @@
--- ---
- name: Setup test fixture - name: Setup test fixture
copy: copy:
src: '{{ role_path }}/fixtures/ansible-xml-beers.xml' src: fixtures/ansible-xml-beers.xml
dest: /tmp/ansible-xml-beers.xml dest: /tmp/ansible-xml-beers.xml
- name: Add child element with xml format - name: Add child element with xml format
xml: xml:
path: /tmp/ansible-xml-beers.xml path: /tmp/ansible-xml-beers.xml
xpath: /business/beers xpath: /business/beers
input_type: xml input_type: xml
add_children: add_children:
- "<beer>Old Rasputin</beer>" - '<beer>Old Rasputin</beer>'
register: children_elements
- name: Compare to expected result
copy:
src: results/test-add-children-elements.xml
dest: /tmp/ansible-xml-beers.xml
check_mode: yes
diff: yes·
register: comparison
- name: Test expected result - name: Test expected result
command: diff -u {{ role_path }}/results/test-add-children-elements.xml /tmp/ansible-xml-beers.xml assert:
that:
- children_elements.changed == true
- comparison.changed == false # identical
#command: diff -u {{ role_path }}/results/test-add-children-elements.xml /tmp/ansible-xml-beers.xml

@ -1,13 +1,19 @@
--- ---
- name: Setup test fixture - name: Setup test fixture
copy: copy:
src: '{{ role_path }}/fixtures/ansible-xml-beers-unicode.xml' src: fixtures/ansible-xml-beers-unicode.xml
dest: /tmp/ansible-xml-beers-unicode.xml dest: /tmp/ansible-xml-beers-unicode.xml
- name: Count child element - name: Count child element
xml: xml:
path: /tmp/ansible-xml-beers-unicode.xml path: /tmp/ansible-xml-beers-unicode.xml
xpath: /business/beers/beer xpath: /business/beers/beer
count: true count: yes
register: beers register: beers
failed_when: beers.count != 2
- name: Test expected result
assert:
that:
- beers.changed == false
- beers.count == 2

@ -1,13 +1,19 @@
--- ---
- name: Setup test fixture - name: Setup test fixture
copy: copy:
src: '{{ role_path }}/fixtures/ansible-xml-beers.xml' src: fixtures/ansible-xml-beers.xml
dest: /tmp/ansible-xml-beers.xml dest: /tmp/ansible-xml-beers.xml
- name: Add child element - name: Add child element
xml: xml:
path: /tmp/ansible-xml-beers.xml path: /tmp/ansible-xml-beers.xml
xpath: /business/beers/beer xpath: /business/beers/beer
count: true count: yes
register: beers register: beers
failed_when: beers.count != 3
- name: Test expected result
assert:
that:
- beers.changed == false
- beers.count == 3

@ -1,21 +1,32 @@
--- ---
- name: Setup test fixture - name: Setup test fixture
copy: copy:
src: '{{ role_path }}/fixtures/ansible-xml-beers-unicode.xml' src: fixtures/ansible-xml-beers-unicode.xml
dest: /tmp/ansible-xml-beers-unicode.xml dest: /tmp/ansible-xml-beers-unicode.xml
- name: Get element attributes - name: Get element attributes
xml: xml:
path: /tmp/ansible-xml-beers-unicode.xml path: /tmp/ansible-xml-beers-unicode.xml
xpath: /business/rating xpath: /business/rating
content: 'attribute' content: attribute
register: get_element_attribute register: get_element_attribute
failed_when: get_element_attribute.matches[0]['rating'] is not defined or get_element_attribute.matches[0]['rating']['subjective'] != 'да'
- name: Test expected result
assert:
that:
- get_element_attribute.changed == false
- get_element_attribute.matches[0]['rating'] is defined and get_element_attribute.matches[0]['rating']['subjective'] == 'да'
- name: Get element text - name: Get element text
xml: xml:
path: /tmp/ansible-xml-beers-unicode.xml path: /tmp/ansible-xml-beers-unicode.xml
xpath: /business/rating xpath: /business/rating
content: 'text' content: text
register: get_element_text register: get_element_text
failed_when: get_element_text.matches[0]['rating'] != 'десять'
- name: Test expected result
assert:
that:
- get_element_text.changed == false
- get_element_text.matches[0]['rating'] == 'десять'

@ -1,21 +1,32 @@
--- ---
- name: Setup test fixture - name: Setup test fixture
copy: copy:
src: '{{ role_path }}/fixtures/ansible-xml-beers.xml' src: fixtures/ansible-xml-beers.xml
dest: /tmp/ansible-xml-beers.xml dest: /tmp/ansible-xml-beers.xml
- name: Get element attributes - name: Get element attributes
xml: xml:
path: /tmp/ansible-xml-beers.xml path: /tmp/ansible-xml-beers.xml
xpath: /business/rating xpath: /business/rating
content: 'attribute' content: attribute
register: get_element_attribute register: get_element_attribute
failed_when: get_element_attribute.matches[0]['rating'] is not defined or get_element_attribute.matches[0]['rating']['subjective'] != 'true'
- name: Test expected result
assert:
that:
- get_element_attribute.changed == false
- get_element_attribute.matches[0]['rating'] is defined and get_element_attribute.matches[0]['rating']['subjective'] == 'true'
- name: Get element text - name: Get element text
xml: xml:
path: /tmp/ansible-xml-beers.xml path: /tmp/ansible-xml-beers.xml
xpath: /business/rating xpath: /business/rating
content: 'text' content: text
register: get_element_text register: get_element_text
failed_when: get_element_text.matches[0]['rating'] != '10'
- name: Test expected result
assert:
that:
- get_element_text.changed == false
- get_element_text.matches[0]['rating'] == '10'

@ -1,15 +1,22 @@
--- ---
- name: Setup test fixture - name: Setup test fixture
copy: copy:
src: '{{ role_path }}/fixtures/ansible-xml-beers.xml' src: fixtures/ansible-xml-beers.xml
dest: /tmp/ansible-xml-beers.xml dest: /tmp/ansible-xml-beers.xml
- name: Specify both children to add and a value - name: Specify both children to add and a value
xml: xml:
path: /tmp/ansible-xml-beers.xml path: /tmp/ansible-xml-beers.xml
add_children: add_children:
- child01 - child01
- child02 - child02
value: conflict! value: conflict!
register: module_output register: module_output
failed_when: "module_output.failed == 'false'" ignore_errors: yes
- name: Test expected result
assert:
that:
- module_output.changed == false
- module_output.failed == true

@ -2,10 +2,24 @@
- name: Setup test fixture - name: Setup test fixture
shell: cat {{ role_path }}/fixtures/ansible-xml-beers.xml | sed 's/^[ ]*//g' > /tmp/ansible-xml-beers.xml shell: cat {{ role_path }}/fixtures/ansible-xml-beers.xml | sed 's/^[ ]*//g' > /tmp/ansible-xml-beers.xml
- name: Pretty print without modification - name: Pretty print without modification
xml: xml:
path: /tmp/ansible-xml-beers.xml path: /tmp/ansible-xml-beers.xml
pretty_print: True pretty_print: yes
register: pretty_print_only
- name: Compare to expected result
copy:
src: results/test-pretty-print-only.xml
dest: /tmp/ansible-xml-beers.xml
check_mode: yes
diff: yes
register: comparison
- name: Test expected result - name: Test expected result
command: diff -u {{ role_path }}/results/test-pretty-print-only.xml /tmp/ansible-xml-beers.xml assert:
that:
- pretty_print_only.changed == true
- comparison.changed == false # identical
#command: diff -u {{ role_path }}/results/test-pretty-print-only.xml /tmp/ansible-xml-beers.xml

@ -1,16 +1,30 @@
--- ---
- name: Setup test fixture - name: Setup test fixture
copy: copy:
src: '{{ role_path }}/fixtures/ansible-xml-beers.xml' src: fixtures/ansible-xml-beers.xml
dest: /tmp/ansible-xml-beers.xml dest: /tmp/ansible-xml-beers.xml
- name: Pretty print - name: Pretty print
xml: xml:
path: /tmp/ansible-xml-beers.xml path: /tmp/ansible-xml-beers.xml
xpath: /business/beers xpath: /business/beers
pretty_print: True pretty_print: yes
add_children: add_children:
- beer: "Old Rasputin" - beer: Old Rasputin
register: pretty_print
- name: Compare to expected result
copy:
src: results/test-pretty-print.xml
dest: /tmp/ansible-xml-beers.xml
check_mode: yes
diff: yes
register: comparison
- name: Test expected result - name: Test expected result
command: diff -u {{ role_path }}/results/test-pretty-print.xml /tmp/ansible-xml-beers.xml assert:
that:
- pretty_print.changed == true
- comparison.changed == false # identical
#command: diff -u {{ role_path }}/results/test-pretty-print.xml /tmp/ansible-xml-beers.xml

@ -1,14 +1,28 @@
--- ---
- name: Setup test fixture - name: Setup test fixture
copy: copy:
src: '{{ role_path }}/fixtures/ansible-xml-beers.xml' src: fixtures/ansible-xml-beers.xml
dest: /tmp/ansible-xml-beers.xml dest: /tmp/ansible-xml-beers.xml
- name: Remove '/business/rating/@subjective' - name: Remove '/business/rating/@subjective'
xml: xml:
path: /tmp/ansible-xml-beers.xml path: /tmp/ansible-xml-beers.xml
xpath: /business/rating/@subjective xpath: /business/rating/@subjective
ensure: absent state: absent
register: remove_attribute
- name: Compare to expected result
copy:
src: results/test-remove-attribute.xml
dest: /tmp/ansible-xml-beers.xml
check_mode: yes
diff: yes
register: comparison
- name: Test expected result - name: Test expected result
command: diff -u {{ role_path }}/results/test-remove-attribute.xml /tmp/ansible-xml-beers.xml assert:
that:
- remove_attribute.changed == true
- comparison.changed == false # identical
#command: diff -u {{ role_path }}/results/test-remove-attribute.xml /tmp/ansible-xml-beers.xml

@ -1,14 +1,28 @@
--- ---
- name: Setup test fixture - name: Setup test fixture
copy: copy:
src: '{{ role_path }}/fixtures/ansible-xml-beers.xml' src: fixtures/ansible-xml-beers.xml
dest: /tmp/ansible-xml-beers.xml dest: /tmp/ansible-xml-beers.xml
- name: Remove '/business/rating' - name: Remove '/business/rating'
xml: xml:
path: /tmp/ansible-xml-beers.xml path: /tmp/ansible-xml-beers.xml
xpath: /business/rating xpath: /business/rating
ensure: absent state: absent
register: remove_element
- name: Compare to expected result
copy:
src: results/test-remove-element.xml
dest: /tmp/ansible-xml-beers.xml
check_mode: yes
diff: yes
register: comparison
- name: Test expected result - name: Test expected result
command: diff -u {{ role_path }}/results/test-remove-element.xml /tmp/ansible-xml-beers.xml assert:
that:
- remove_element.changed == true
- comparison.changed == false # identical
#command: diff -u {{ role_path }}/results/test-remove-element.xml /tmp/ansible-xml-beers.xml

@ -1,9 +1,10 @@
--- ---
- name: Setup test fixture - name: Setup test fixture
copy: copy:
src: '{{ role_path }}/fixtures/ansible-xml-namespaced-beers.xml' src: fixtures/ansible-xml-namespaced-beers.xml
dest: /tmp/ansible-xml-namespaced-beers.xml dest: /tmp/ansible-xml-namespaced-beers.xml
- name: Remove namespaced '/bus:business/rat:rating/@attr:subjective' - name: Remove namespaced '/bus:business/rat:rating/@attr:subjective'
xml: xml:
path: /tmp/ansible-xml-namespaced-beers.xml path: /tmp/ansible-xml-namespaced-beers.xml
@ -13,7 +14,20 @@
ber: http://test.beers ber: http://test.beers
rat: http://test.rating rat: http://test.rating
attr: http://test.attribute attr: http://test.attribute
ensure: absent state: absent
register: remove_namespaced_attribute
- name: Compare to expected result
copy:
src: results/test-remove-namespaced-attribute.xml
dest: /tmp/ansible-xml-namespaced-beers.xml
check_mode: yes
diff: yes
register: comparison
- name: Test expected result - name: Test expected result
command: diff -u {{ role_path }}/results/test-remove-namespaced-attribute.xml /tmp/ansible-xml-namespaced-beers.xml assert:
that:
- remove_element.changed == true
- comparison.changed == false # identical
#command: diff -u {{ role_path }}/results/test-remove-namespaced-attribute.xml /tmp/ansible-xml-namespaced-beers.xml

@ -1,9 +1,10 @@
--- ---
- name: Setup test fixture - name: Setup test fixture
copy: copy:
src: '{{ role_path }}/fixtures/ansible-xml-namespaced-beers.xml' src: fixtures/ansible-xml-namespaced-beers.xml
dest: /tmp/ansible-xml-namespaced-beers.xml dest: /tmp/ansible-xml-namespaced-beers.xml
- name: Remove namespaced '/bus:business/rat:rating' - name: Remove namespaced '/bus:business/rat:rating'
xml: xml:
path: /tmp/ansible-xml-namespaced-beers.xml path: /tmp/ansible-xml-namespaced-beers.xml
@ -13,7 +14,20 @@
ber: http://test.beers ber: http://test.beers
rat: http://test.rating rat: http://test.rating
attr: http://test.attribute attr: http://test.attribute
ensure: absent state: absent
register: remove_namespaced_element
- name: Compare to expected result
copy:
src: results/test-remove-element.xml
dest: /tmp/ansible-xml-namespaced-beers.xml
check_mode: yes
diff: yes
register: comparison
- name: Test expected result - name: Test expected result
command: diff -u {{ role_path }}/results/test-remove-element.xml /tmp/ansible-xml-namespaced-beers.xml assert:
that:
- remove_namespaced_element.changed == true
- comparison.changed == false # identical
#command: diff -u {{ role_path }}/results/test-remove-element.xml /tmp/ansible-xml-namespaced-beers.xml

@ -1,16 +1,29 @@
--- ---
- name: Setup test fixture - name: Setup test fixture
copy: copy:
src: '{{ role_path }}/fixtures/ansible-xml-beers.xml' src: fixtures/ansible-xml-beers.xml
dest: /tmp/ansible-xml-beers.xml dest: /tmp/ansible-xml-beers.xml
- name: Set '/business/rating/@subjective' to 'нет' - name: Set '/business/rating/@subjective' to 'нет'
xml: xml:
path: /tmp/ansible-xml-beers.xml path: /tmp/ansible-xml-beers.xml
xpath: /business/rating xpath: /business/rating
attribute: subjective attribute: subjective
value: "нет" value: нет
register: set_attribute_value_unicode
- name: Compare to expected result
copy:
src: results/test-set-attribute-value-unicode.xml
dest: /tmp/ansible-xml-beers.xml
check_mode: yes
diff: yes
register: comparison
- name: Test expected result - name: Test expected result
command: diff -u {{ role_path }}/results/test-set-attribute-value-unicode.xml /tmp/ansible-xml-beers.xml assert:
changed_when: False that:
- set_attribute_value_unicode.changed == true
- comparison.changed == false # identical
#command: diff -u {{ role_path }}/results/test-set-attribute-value-unicode.xml /tmp/ansible-xml-beers.xml

@ -1,16 +1,29 @@
--- ---
- name: Setup test fixture - name: Setup test fixture
copy: copy:
src: '{{ role_path }}/fixtures/ansible-xml-beers.xml' src: fixtures/ansible-xml-beers.xml
dest: /tmp/ansible-xml-beers.xml dest: /tmp/ansible-xml-beers.xml
- name: Set '/business/rating/@subjective' to 'false' - name: Set '/business/rating/@subjective' to 'false'
xml: xml:
path: /tmp/ansible-xml-beers.xml path: /tmp/ansible-xml-beers.xml
xpath: /business/rating xpath: /business/rating
attribute: subjective attribute: subjective
value: "false" value: 'false'
register: set_attribute_value
- name: Compare to expected result
copy:
src: results/test-set-attribute-value.xml
dest: /tmp/ansible-xml-beers.xml
check_mode: yes
diff: yes
register: comparison
- name: Test expected result - name: Test expected result
command: diff -u {{ role_path }}/results/test-set-attribute-value.xml /tmp/ansible-xml-beers.xml assert:
changed_when: False that:
- set_attribute_value.changed == true
- comparison.changed == false # identical
#command: diff -u {{ role_path }}/results/test-set-attribute-value.xml /tmp/ansible-xml-beers.xml

@ -1,14 +1,17 @@
--- ---
- name: Setup test fixture - name: Setup test fixture
command: cp {{ role_path }}/fixtures/ansible-xml-beers.xml /tmp/ansible-xml-beers.xml copy:
src: fixtures/ansible-xml-beers.xml
dest: /tmp/ansible-xml-beers.xml
- name: Set child elements - name: Set child elements
xml: xml:
path: /tmp/ansible-xml-beers.xml path: /tmp/ansible-xml-beers.xml
xpath: /business/beers xpath: /business/beers
set_children: set_children: &children
- beer: - beer:
name: "90 Minute IPA" name: 90 Minute IPA
alcohol: "0.5" alcohol: "0.5"
_: _:
- Water: - Water:
@ -21,7 +24,7 @@
- Yeast: - Yeast:
quantity: 20g quantity: 20g
- beer: - beer:
name: "Harvest Pumpkin Ale" name: Harvest Pumpkin Ale
alcohol: "0.3" alcohol: "0.3"
_: _:
- Water: - Water:
@ -31,41 +34,41 @@
quantity: 25g quantity: 25g
- Yeast: - Yeast:
quantity: 20g quantity: 20g
register: set_children_elements_level
- name: Compare to expected result
copy:
src: results/test-set-children-elements-level.xml
dest: /tmp/ansible-xml-beers.xml
check_mode: yes
diff: yes
register: comparison
- name: Test expected result - name: Test expected result
command: diff -u {{ role_path }}/results/test-set-children-elements-level.xml /tmp/ansible-xml-beers.xml assert:
that:
- set_children_elements_level.changed == true
- comparison.changed == false # identical
#command: diff -u {{ role_path }}/results/test-set-children-elements-level.xml /tmp/ansible-xml-beers.xml
- name: Set child elements
- name: Set child elements (again)
xml: xml:
path: /tmp/ansible-xml-beers.xml path: /tmp/ansible-xml-beers.xml
xpath: /business/beers xpath: /business/beers
set_children: set_children: *children
- beer:
name: "90 Minute IPA"
alcohol: "0.5"
_:
- Water:
quantity: 200g
liter: "0.2"
- Starch:
quantity: 10g
- Hops:
quantity: 50g
- Yeast:
quantity: 20g
- beer:
name: "Harvest Pumpkin Ale"
alcohol: "0.3"
_:
- Water:
quantity: 200g
liter: "0.2"
- Hops:
quantity: 25g
- Yeast:
quantity: 20g
register: set_children_again register: set_children_again
- fail: - name: Compare to expected result
msg: "Setting children is not idempotent!" copy:
when: set_children_again.changed src: results/test-set-children-elements-level.xml
dest: /tmp/ansible-xml-beers.xml
check_mode: yes
diff: yes
register: comparison
- name: Test expected result
assert:
that:
- set_children_again.changed == false
- comparison.changed == false # identical

@ -1,27 +1,46 @@
--- ---
- name: Setup test fixture - name: Setup test fixture
command: cp {{ role_path }}/fixtures/ansible-xml-beers.xml /tmp/ansible-xml-beers.xml copy:
src: fixtures/ansible-xml-beers.xml
dest: /tmp/ansible-xml-beers.xml
- name: Set child elements - name: Set child elements
xml: xml:
path: /tmp/ansible-xml-beers.xml path: /tmp/ansible-xml-beers.xml
xpath: /business/beers xpath: /business/beers
set_children: set_children: &children
- beer: "Окское" - beer: Окское
- beer: "Невское" - beer: Невское
register: set_children_elements_unicode
- name: Compare to expected result
copy:
src: results/test-set-children-elements-unicode.xml
dest: /tmp/ansible-xml-beers.xml
check_mode: yes
diff: yes
register: comparison
- name: Test expected result - name: Test expected result
command: diff -u {{ role_path }}/results/test-set-children-elements-unicode.xml /tmp/ansible-xml-beers.xml assert:
that:
- set_children_elements_unicode.changed == true
- comparison.changed == false # identical
#command: diff -u {{ role_path }}/results/test-set-children-elements-unicode.xml /tmp/ansible-xml-beers.xml
- name: Set child elements
xml:
path: /tmp/ansible-xml-beers.xml
xpath: /business/beers
set_children:
- beer: "Окское"
- beer: "Невское"
register: set_children_again
- fail: - name: Compare to expected result
msg: "Setting children is not idempotent!" copy:
when: set_children_again.changed src: results/test-set-children-elements-unicode.xml
dest: /tmp/ansible-xml-beers.xml
check_mode: yes
diff: yes
register: comparison
- name: Test expected result
assert:
that:
- set_children_again.changed == false
- comparison.changed == false # identical
#command: diff -u {{ role_path }}/results/test-set-children-elements-unicode.xml /tmp/ansible-xml-beers.xml

@ -1,27 +1,53 @@
--- ---
- name: Setup test fixture - name: Setup test fixture
command: cp {{ role_path }}/fixtures/ansible-xml-beers.xml /tmp/ansible-xml-beers.xml copy:
src: fixtures/ansible-xml-beers.xml
dest: /tmp/ansible-xml-beers.xml
- name: Set child elements - name: Set child elements
xml: xml:
path: /tmp/ansible-xml-beers.xml path: /tmp/ansible-xml-beers.xml
xpath: /business/beers xpath: /business/beers
set_children: set_children: &children
- beer: "90 Minute IPA" - beer: 90 Minute IPA
- beer: "Harvest Pumpkin Ale" - beer: Harvest Pumpkin Ale
register: set_children_elements
- name: Compare to expected result
copy:
src: results/test-set-children-elements.xml
dest: /tmp/ansible-xml-beers.xml
check_mode: yes
diff: yes
register: comparison
- name: Test expected result - name: Test expected result
command: diff -u {{ role_path }}/results/test-set-children-elements.xml /tmp/ansible-xml-beers.xml assert:
that:
- set_children_elements.changed == true
- comparison.changed == false # identical
#command: diff -u {{ role_path }}/results/test-set-children-elements.xml /tmp/ansible-xml-beers.xml
- name: Set child elements
- name: Set child elements (again)
xml: xml:
path: /tmp/ansible-xml-beers.xml path: /tmp/ansible-xml-beers.xml
xpath: /business/beers xpath: /business/beers
set_children: set_children: *children
- beer: "90 Minute IPA"
- beer: "Harvest Pumpkin Ale"
register: set_children_again register: set_children_again
- fail: - name: Compare to expected result
msg: "Setting children is not idempotent!" copy:
when: set_children_again.changed src: results/test-set-children-elements.xml
dest: /tmp/ansible-xml-beers.xml
check_mode: yes
diff: yes
register: comparison
- name: Test expected result
assert:
that:
- set_children_again.changed == false
- comparison.changed == false # identical
#command: diff -u {{ role_path }}/results/test-set-children-elements.xml /tmp/ansible-xml-beers.xml

@ -1,14 +1,28 @@
--- ---
- name: Setup test fixture - name: Setup test fixture
copy: copy:
src: '{{ role_path }}/fixtures/ansible-xml-beers.xml' src: fixtures/ansible-xml-beers.xml
dest: /tmp/ansible-xml-beers.xml dest: /tmp/ansible-xml-beers.xml
- name: Set /business/website/address to empty string.
- name: Set '/business/website/address' to empty string.
xml: xml:
path: /tmp/ansible-xml-beers.xml path: /tmp/ansible-xml-beers.xml
xpath: /business/website/address xpath: /business/website/address
value: '' value: ''
register: set_element_value_empty
- name: Compare to expected result
copy:
src: results/test-set-element-value-empty.xml
dest: /tmp/ansible-xml-beers.xml
check_mode: yes
diff: yes
register: comparison
- name: Test expected result - name: Test expected result
command: diff -u {{ role_path }}/results/test-set-element-value-empty.xml /tmp/ansible-xml-beers.xml assert:
that:
- set_element_value_empty.changed == true
- comparison.changed == false # identical
#command: diff -u {{ role_path }}/results/test-set-element-value-empty.xml /tmp/ansible-xml-beers.xml

@ -1,37 +1,43 @@
--- ---
- name: Setup test fixture - name: Setup test fixture
copy: copy:
src: '{{ role_path }}/fixtures/ansible-xml-beers.xml' src: fixtures/ansible-xml-beers.xml
dest: /tmp/ansible-xml-beers.xml dest: /tmp/ansible-xml-beers.xml
- name: Add 2nd '/business/rating' with value 'пять' - name: Add 2nd '/business/rating' with value 'пять'
xml: xml:
path: /tmp/ansible-xml-beers.xml path: /tmp/ansible-xml-beers.xml
xpath: /business xpath: /business
add_children: add_children:
- rating: "пять" - rating: пять
- name: Set '/business/rating' to 'пять' - name: Set '/business/rating' to 'пять'
xml: xml:
path: /tmp/ansible-xml-beers.xml path: /tmp/ansible-xml-beers.xml
xpath: /business/rating xpath: /business/rating
value: "пять" value: пять
register: set_element_first_run register: set_element_first_run
- name: Set '/business/rating' to 'false'... again - name: Set '/business/rating' to 'false'... again
xml: xml:
path: /tmp/ansible-xml-beers.xml path: /tmp/ansible-xml-beers.xml
xpath: /business/rating xpath: /business/rating
value: "пять" value: пять
register: set_element_second_run register: set_element_second_run
- name: Test expected result - name: Compare to expected result
command: diff -u {{ role_path }}/results/test-set-element-value-unicode.xml /tmp/ansible-xml-beers.xml copy:
changed_when: no src: results/test-set-element-value-unicode.xml
dest: /tmp/ansible-xml-beers.xml
check_mode: yes
diff: yes
register: comparison
- name: Test registered 'changed' on run 1 and unchanged on run 2 - name: Test expected result
assert: assert:
that: that:
- set_element_first_run.changed - set_element_first_run.changed == true
- not set_element_second_run.changed - set_element_second_run.changed == false
... - comparison.changed == false # identical
#command: diff -u {{ role_path }}/results/test-set-element-value-unicode.xml /tmp/ansible-xml-beers.xml

@ -1,37 +1,43 @@
--- ---
- name: Setup test fixture - name: Setup test fixture
copy: copy:
src: '{{ role_path }}/fixtures/ansible-xml-beers.xml' src: fixtures/ansible-xml-beers.xml
dest: /tmp/ansible-xml-beers.xml dest: /tmp/ansible-xml-beers.xml
- name: Add 2nd '/business/rating' with value '5' - name: Add 2nd '/business/rating' with value '5'
xml: xml:
path: /tmp/ansible-xml-beers.xml path: /tmp/ansible-xml-beers.xml
xpath: /business xpath: /business
add_children: add_children:
- rating: "5" - rating: '5'
- name: Set '/business/rating' to '5' - name: Set '/business/rating' to '5'
xml: xml:
path: /tmp/ansible-xml-beers.xml path: /tmp/ansible-xml-beers.xml
xpath: /business/rating xpath: /business/rating
value: "5" value: '5'
register: set_element_first_run register: set_element_first_run
- name: Set '/business/rating' to 'false'... again - name: Set '/business/rating' to '5'... again
xml: xml:
path: /tmp/ansible-xml-beers.xml path: /tmp/ansible-xml-beers.xml
xpath: /business/rating xpath: /business/rating
value: "5" value: '5'
register: set_element_second_run register: set_element_second_run
- name: Test expected result - name: Compare to expected result
command: diff -u {{ role_path }}/results/test-set-element-value.xml /tmp/ansible-xml-beers.xml copy:
changed_when: no src: results/test-set-element-value.xml
dest: /tmp/ansible-xml-beers.xml
check_mode: yes
diff: yes
register: comparison
- name: Test registered 'changed' on run 1 and unchanged on run 2 - name: Test expected result
assert: assert:
that: that:
- set_element_first_run.changed - set_element_first_run.changed == true
- not set_element_second_run.changed - set_element_second_run.changed == false
... - comparison.changed == false # identical
#command: diff -u {{ role_path }}/results/test-set-element-value.xml /tmp/ansible-xml-beers.xml

@ -1,9 +1,10 @@
--- ---
- name: Setup test fixture - name: Setup test fixture
copy: copy:
src: '{{ role_path }}/fixtures/ansible-xml-namespaced-beers.xml' src: fixtures/ansible-xml-namespaced-beers.xml
dest: /tmp/ansible-xml-namespaced-beers.xml dest: /tmp/ansible-xml-namespaced-beers.xml
- name: Set namespaced '/bus:business/rat:rating/@attr:subjective' to 'false' - name: Set namespaced '/bus:business/rat:rating/@attr:subjective' to 'false'
xml: xml:
path: /tmp/ansible-xml-namespaced-beers.xml path: /tmp/ansible-xml-namespaced-beers.xml
@ -14,8 +15,20 @@
rat: http://test.rating rat: http://test.rating
attr: http://test.attribute attr: http://test.attribute
attribute: attr:subjective attribute: attr:subjective
value: "false" value: 'false'
register: set_namespaced_attribute_value
- name: Compare to expected result
copy:
src: results/test-set-namespaced-attribute-value.xml
dest: /tmp/ansible-xml-namespaced-beers.xml
check_mode: yes
diff: yes
register: comparison
- name: Test expected result - name: Test expected result
command: diff -u {{ role_path }}/results/test-set-namespaced-attribute-value.xml /tmp/ansible-xml-namespaced-beers.xml assert:
changed_when: no that:
- set_namespaced_attribute_value.changed == true
- comparison.changed == false # identical
#command: diff -u {{ role_path }}/results/test-set-namespaced-attribute-value.xml /tmp/ansible-xml-namespaced-beers.xml

@ -0,0 +1,54 @@
---
- name: Setup test fixture
copy:
src: fixtures/ansible-xml-namespaced-beers.xml
dest: /tmp/ansible-xml-namespaced-beers-xml.xml
- name: Set child elements
xml:
path: /tmp/ansible-xml-namespaced-beers-xml.xml
xpath: /bus:business/ber:beers
namespaces:
bus: http://test.business
ber: http://test.beers
set_children:
- beer: 90 Minute IPA
- beer: Harvest Pumpkin Ale
- name: Copy state after first set_children
copy:
src: /tmp/ansible-xml-namespaced-beers.xml
dest: /tmp/ansible-xml-namespaced-beers-1.xml
- name: Set child elements again
xml:
path: /tmp/ansible-xml-namespaced-beers-xml.xml
xpath: /bus:business/ber:beers
namespaces:
bus: http://test.business
ber: http://test.beers
set_children:
- beer: 90 Minute IPA
- beer: Harvest Pumpkin Ale
register: set_children_again
- name: Copy state after second set_children
copy:
src: /tmp/ansible-xml-namespaced-beers.xml
dest: /tmp/ansible-xml-namespaced-beers-2.xml
- name: Compare to expected result
copy:
src: /tmp/ansible-xml-namespaced-beers-1.xml
dest: /tmp/ansible-xml-namespaced-beers-2.xml
check_mode: yes
diff: yes
register: comparison
#command: diff /tmp/ansible-xml-namespaced-beers-1.xml /tmp/ansible-xml-namespaced-beers-2.xml
- name: Test expected result
assert:
that:
- set_children_again.changed == false # idempotency
- set_namespaced_attribute_value.changed == true
- comparison.changed == false # identical

@ -1,9 +1,10 @@
--- ---
- name: Setup test fixture - name: Setup test fixture
copy: copy:
src: '{{ role_path }}/fixtures/ansible-xml-namespaced-beers.xml' src: fixtures/ansible-xml-namespaced-beers.xml
dest: /tmp/ansible-xml-namespaced-beers.xml dest: /tmp/ansible-xml-namespaced-beers.xml
- name: Set namespaced '/bus:business/rat:rating' to '11' - name: Set namespaced '/bus:business/rat:rating' to '11'
xml: xml:
path: /tmp/ansible-xml-namespaced-beers.xml path: /tmp/ansible-xml-namespaced-beers.xml
@ -13,7 +14,7 @@
rat: http://test.rating rat: http://test.rating
attr: http://test.attribute attr: http://test.attribute
xpath: /bus:business/rat:rating xpath: /bus:business/rat:rating
value: "11" value: '11'
register: set_element_first_run register: set_element_first_run
- name: Set namespaced '/bus:business/rat:rating' to '11' again - name: Set namespaced '/bus:business/rat:rating' to '11' again
@ -25,15 +26,21 @@
rat: http://test.rating rat: http://test.rating
attr: http://test.attribute attr: http://test.attribute
xpath: /bus:business/rat:rating xpath: /bus:business/rat:rating
value: "11" value: '11'
register: set_element_second_run register: set_element_second_run
- name: Test expected result - name: Compare to expected result
command: diff -u {{ role_path }}/results/test-set-namespaced-element-value.xml /tmp/ansible-xml-namespaced-beers.xml copy:
changed_when: no src: results/test-set-namespaced-element-value.xml
dest: /tmp/ansible-xml-namespaced-beers.xml
check_mode: yes
diff: yes
register: comparison
#command: diff -u {{ role_path }}/results/test-set-namespaced-element-value.xml /tmp/ansible-xml-namespaced-beers.xml
- name: Test registered 'changed' on run 1 and unchanged on run 2 - name: Test expected result
assert: assert:
that: that:
- set_element_first_run.changed - set_element_first_run.changed == true
- not set_element_second_run.changed - set_element_second_run.changed == false
- comparison.changed == false # identical

@ -1,31 +1,74 @@
--- ---
- name: Read from xmlstring # NOTE: Jinja2 templating eats trailing newlines
- name: Read from xmlstring (not using pretty_print)
xml:
xmlstring: "{{ lookup('file', '{{ role_path }}/fixtures/ansible-xml-beers.xml') }}"
xpath: .
register: xmlresponse
- name: Compare to expected result
copy:
content: "{{ xmlresponse.xmlstring }}\n"
dest: '{{ role_path }}/results/test-pretty-print-only.xml'
check_mode: yes
diff: yes
register: comparison
- name: Test expected result
assert:
that:
- xmlresponse.changed == false
- comparison.changed == false # identical
#command: diff -u {{ role_path }}/results/test-pretty-print-only.xml /tmp/ansible-xml-beers.xml
# NOTE: Jinja2 templating eats trailing newlines
- name: Read from xmlstring (using pretty_print)
xml: xml:
xmlstring: "{{ lookup('file', '{{ role_path }}/fixtures/ansible-xml-beers.xml') }}" xmlstring: "{{ lookup('file', '{{ role_path }}/fixtures/ansible-xml-beers.xml') }}"
pretty_print: True pretty_print: yes
register: xmlresponse register: xmlresponse
- name: Write result to file - name: Compare to expected result
copy: copy:
dest: /tmp/ansible-xml-beers.xml content: '{{ xmlresponse.xmlstring }}'
content: "{{ xmlresponse.xmlstring }}" dest: '{{ role_path }}/results/test-pretty-print-only.xml'
check_mode: yes
diff: yes
register: comparison
# FIXME: This change is related to the newline added by pretty_print
- name: Test expected result - name: Test expected result
command: diff -u {{ role_path }}/results/test-pretty-print-only.xml /tmp/ansible-xml-beers.xml assert:
that:
- xmlresponse.changed == true
- comparison.changed == false # identical
#command: diff -u {{ role_path }}/results/test-pretty-print-only.xml /tmp/ansible-xml-beers.xml
# NOTE: Jinja2 templating eats trailing newlines
- name: Read from xmlstring - name: Read from xmlstring
xml: xml:
xmlstring: "{{ lookup('file', '{{ role_path }}/fixtures/ansible-xml-beers.xml') }}" xmlstring: "{{ lookup('file', '{{ role_path }}/fixtures/ansible-xml-beers.xml') }}"
xpath: /business/beers xpath: /business/beers
pretty_print: True pretty_print: yes
add_children: add_children:
- beer: "Old Rasputin" - beer: Old Rasputin
register: xmlresponse_modification register: xmlresponse_modification
- name: Write result to file - name: Compare to expected result
copy: copy:
dest: /tmp/ansible-xml-beers.xml content: '{{ xmlresponse_modification.xmlstring }}'
content: "{{ xmlresponse_modification.xmlstring }}" dest: '{{ role_path }}/results/test-pretty-print.xml'
check_mode: yes
diff: yes
register: comparison
# FIXME: This change is related to the newline added by pretty_print
- name: Test expected result - name: Test expected result
command: diff -u {{ role_path }}/results/test-pretty-print.xml /tmp/ansible-xml-beers.xml assert:
that:
- xmlresponse_modification.changed == true
- comparison.changed == false # identical
#command: diff -u {{ role_path }}/results/test-pretty-print.xml /tmp/ansible-xml-beers.xml

Loading…
Cancel
Save