1
0
Fork 0
mirror of https://github.com/ansible-collections/community.general.git synced 2026-06-08 09:14:13 +00:00
community.general/tests/integration/targets/xml/tasks/test-set-element-value-predicate.yml
Alexei Znamensky 15616be827
xml: fix predicated xpath no-match incorrectly creating nodes (#12031)
* fix(xml): no-op when predicated xpath finds no match instead of creating nodes

When using xpath like element[text()='old'] with value=new, a no-match due
to the predicate not being satisfied incorrectly triggered node creation,
corrupting the XML. Now treats predicate misses as a no-op.

Fixes #8730

* changelog(xml): add fragment for PR #12031

* fix(xml): remove spurious test-unset-element-value include from main.yml

That file belongs to a different branch and was accidentally dragged in
during a stash conflict resolution.

* feat(xml): add create_if_missing option to control node creation on value no-match

Instead of implicitly creating nodes when value is set and xpath finds no match,
expose create_if_missing (default true, preserving old behavior) so callers
can opt into a silent no-op with create_if_missing=false.

Fixes #8730
2026-05-17 10:48:56 +02:00

96 lines
2.9 KiB
YAML

---
# Copyright (c) Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
# Tests for https://github.com/ansible-collections/community.general/issues/8730
# --- create_if_missing=false: predicate no-match must be a silent no-op ---
- name: Setup test fixture
copy:
src: fixtures/ansible-xml-items.xml
dest: /tmp/ansible-xml-items.xml
- name: Update items via predicate (create_if_missing=false, first run - matches)
xml:
path: /tmp/ansible-xml-items.xml
xpath: /business/items/item[text()='value_a']
value: value_c
create_if_missing: false
register: set_predicate_first_run
- name: Update items via predicate (create_if_missing=false, second run - predicate no longer matches)
xml:
path: /tmp/ansible-xml-items.xml
xpath: /business/items/item[text()='value_a']
value: value_c
create_if_missing: false
register: set_predicate_second_run
- name: Add trailing newline
shell: echo "" >> /tmp/ansible-xml-items.xml
- name: Compare to expected result
copy:
src: results/test-set-element-value-predicate.xml
dest: /tmp/ansible-xml-items.xml
check_mode: true
diff: true
register: comparison
- name: Assert create_if_missing=false with predicate no-match is a no-op
assert:
that:
- set_predicate_first_run is changed
- set_predicate_second_run is not changed
- comparison is not changed # no spurious elements created
# --- create_if_missing=false: non-existent simple path must also be a no-op ---
- name: Setup test fixture
copy:
src: fixtures/ansible-xml-items.xml
dest: /tmp/ansible-xml-items.xml
- name: Set value on non-existent element (create_if_missing=false)
xml:
path: /tmp/ansible-xml-items.xml
xpath: /business/items/nonexistent
value: something
create_if_missing: false
register: set_nonexistent
- name: Assert create_if_missing=false with missing simple path is a no-op
assert:
that:
- set_nonexistent is not changed
# --- create_if_missing=true (default): no-match must create the node ---
- name: Setup test fixture
copy:
src: fixtures/ansible-xml-items.xml
dest: /tmp/ansible-xml-items.xml
- name: Set value on non-existent element (create_if_missing=true, should create)
xml:
path: /tmp/ansible-xml-items.xml
xpath: /business/items/item[text()='value_z']
value: value_z
create_if_missing: true
register: set_predicate_create
- name: Set same value again (create_if_missing=true, should be idempotent)
xml:
path: /tmp/ansible-xml-items.xml
xpath: /business/items/item[text()='value_z']
value: value_z
create_if_missing: true
register: set_predicate_create_again
- name: Assert create_if_missing=true creates the node and is then idempotent
assert:
that:
- set_predicate_create is changed
- set_predicate_create_again is not changed