Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package ansible-core for openSUSE:Factory checked in at 2025-12-11 18:41:22 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/ansible-core (Old) and /work/SRC/openSUSE:Factory/.ansible-core.new.1939 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "ansible-core" Thu Dec 11 18:41:22 2025 rev:51 rq:1322178 version:2.20.1 Changes: -------- --- /work/SRC/openSUSE:Factory/ansible-core/ansible-core.changes 2025-11-21 16:55:28.879333777 +0100 +++ /work/SRC/openSUSE:Factory/.ansible-core.new.1939/ansible-core.changes 2025-12-11 18:44:52.694389340 +0100 @@ -1,0 +2,24 @@ +Thu Dec 11 08:28:49 UTC 2025 - Johannes Kastl <[email protected]> + +- update to 2.20.1: + https://github.com/ansible/ansible/blob/v2.20.1/changelogs/CHANGELOG-v2.20.rst + * Bugfixes + - Fix AnsibleModule.human_to_bytes(), which was never adjusted + after the standalone human_to_bytes() got a new parameter + default_unit (#85259). + - Variable loading now uses file source instead of variables + when invalidly formmated vars file is loaded. + - ansible-test - The runtime-metadata sanity test now ignores + pre-release and build identifiers in collection versions. + This prevents errors if a tombstone version is X.0.0, while + the collection's version is X.0.0-prerelease (#85193)." + - display - Fix getuser fallback error handling on Python 3.13 + and later. (#86142) + - first_found - Correct the "Include tasks only if one of the + files exists, otherwise skip" example. + - get_url - fix regex for GNU Digest line which is used in + comparing checksums (#86132). + - local connection - Fix getuser fallback error handling on + Python 3.13 and later. + +------------------------------------------------------------------- Old: ---- ansible_core-2.20.0.tar.gz ansible_core-2.20.0.tar.gz.sha256 New: ---- ansible_core-2.20.1.tar.gz ansible_core-2.20.1.tar.gz.sha256 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ ansible-core.spec ++++++ --- /var/tmp/diff_new_pack.ooKAdL/_old 2025-12-11 18:44:53.458421441 +0100 +++ /var/tmp/diff_new_pack.ooKAdL/_new 2025-12-11 18:44:53.462421609 +0100 @@ -43,7 +43,7 @@ %endif Name: ansible-core -Version: 2.20.0 +Version: 2.20.1 Release: 0 Summary: Radically simple IT automation License: GPL-3.0-or-later ++++++ ansible_core-2.20.0.tar.gz -> ansible_core-2.20.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.20.0/PKG-INFO new/ansible_core-2.20.1/PKG-INFO --- old/ansible_core-2.20.0/PKG-INFO 2025-11-05 00:27:13.000000000 +0100 +++ new/ansible_core-2.20.1/PKG-INFO 2025-12-09 17:24:07.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 2.4 Name: ansible-core -Version: 2.20.0 +Version: 2.20.1 Summary: Radically simple IT automation Author: Ansible Project Project-URL: Homepage, https://ansible.com/ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.20.0/ansible_core.egg-info/PKG-INFO new/ansible_core-2.20.1/ansible_core.egg-info/PKG-INFO --- old/ansible_core-2.20.0/ansible_core.egg-info/PKG-INFO 2025-11-05 00:27:13.000000000 +0100 +++ new/ansible_core-2.20.1/ansible_core.egg-info/PKG-INFO 2025-12-09 17:24:07.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 2.4 Name: ansible-core -Version: 2.20.0 +Version: 2.20.1 Summary: Radically simple IT automation Author: Ansible Project Project-URL: Homepage, https://ansible.com/ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.20.0/ansible_core.egg-info/SOURCES.txt new/ansible_core-2.20.1/ansible_core.egg-info/SOURCES.txt --- old/ansible_core-2.20.0/ansible_core.egg-info/SOURCES.txt 2025-11-05 00:27:13.000000000 +0100 +++ new/ansible_core-2.20.1/ansible_core.egg-info/SOURCES.txt 2025-12-09 17:24:07.000000000 +0100 @@ -1223,10 +1223,13 @@ test/integration/targets/ansible-test-sanity-replace-urlopen/ansible_collections/ns/col/plugins/modules/check-me.py test/integration/targets/ansible-test-sanity-runtime-metadata/aliases test/integration/targets/ansible-test-sanity-runtime-metadata/expected-no_version.txt +test/integration/targets/ansible-test-sanity-runtime-metadata/expected-prerelease.txt test/integration/targets/ansible-test-sanity-runtime-metadata/expected-version.txt test/integration/targets/ansible-test-sanity-runtime-metadata/runme.sh test/integration/targets/ansible-test-sanity-runtime-metadata/ansible_collections/ns/no_version/galaxy.yml test/integration/targets/ansible-test-sanity-runtime-metadata/ansible_collections/ns/no_version/meta/runtime.yml +test/integration/targets/ansible-test-sanity-runtime-metadata/ansible_collections/ns/prerelease/galaxy.yml +test/integration/targets/ansible-test-sanity-runtime-metadata/ansible_collections/ns/prerelease/meta/runtime.yml test/integration/targets/ansible-test-sanity-runtime-metadata/ansible_collections/ns/version/galaxy.yml test/integration/targets/ansible-test-sanity-runtime-metadata/ansible_collections/ns/version/meta/runtime.yml test/integration/targets/ansible-test-sanity-shebang/aliases @@ -4227,13 +4230,15 @@ test/integration/targets/user/tasks/test_umask.yml test/integration/targets/user/vars/main.yml test/integration/targets/var_blending/aliases +test/integration/targets/var_blending/error_handling.yml test/integration/targets/var_blending/inventory test/integration/targets/var_blending/runme.sh +test/integration/targets/var_blending/supersecretvaultsecret test/integration/targets/var_blending/test_var_blending.yml test/integration/targets/var_blending/test_vars.yml test/integration/targets/var_blending/vars_file.yml test/integration/targets/var_blending/group_vars/all -test/integration/targets/var_blending/group_vars/local +test/integration/targets/var_blending/group_vars/local/main.yml test/integration/targets/var_blending/host_vars/testhost test/integration/targets/var_blending/roles/test_var_blending/defaults/main.yml test/integration/targets/var_blending/roles/test_var_blending/files/foo.txt @@ -4241,6 +4246,7 @@ test/integration/targets/var_blending/roles/test_var_blending/templates/foo.j2 test/integration/targets/var_blending/roles/test_var_blending/vars/main.yml test/integration/targets/var_blending/roles/test_var_blending/vars/more_vars.yml +test/integration/targets/var_blending/vars/bad_vault.yml test/integration/targets/var_inheritance/aliases test/integration/targets/var_inheritance/tasks/main.yml test/integration/targets/var_precedence/aliases @@ -4881,6 +4887,7 @@ test/units/ansible_test/test_diff.py test/units/ansible_test/_internal/__init__.py test/units/ansible_test/_internal/test_util.py +test/units/ansible_test/_internal/ci/test_azp.py test/units/ansible_test/diff/add_binary_file.diff test/units/ansible_test/diff/add_text_file.diff test/units/ansible_test/diff/add_trailing_newline.diff @@ -5032,6 +5039,7 @@ test/units/module_utils/basic/test_get_file_attributes.py test/units/module_utils/basic/test_get_module_path.py test/units/module_utils/basic/test_heuristic_log_sanitize.py +test/units/module_utils/basic/test_human_to_bytes.py test/units/module_utils/basic/test_imports.py test/units/module_utils/basic/test_log.py test/units/module_utils/basic/test_no_log.py diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.20.0/changelogs/CHANGELOG-v2.20.rst new/ansible_core-2.20.1/changelogs/CHANGELOG-v2.20.rst --- old/ansible_core-2.20.0/changelogs/CHANGELOG-v2.20.rst 2025-11-05 00:27:13.000000000 +0100 +++ new/ansible_core-2.20.1/changelogs/CHANGELOG-v2.20.rst 2025-12-09 17:24:07.000000000 +0100 @@ -4,6 +4,26 @@ .. contents:: Topics +v2.20.1 +======= + +Release Summary +--------------- + +| Release Date: 2025-12-09 +| `Porting Guide <https://docs.ansible.com/ansible-core/2.20/porting_guides/porting_guide_core_2.20.html>`__ + +Bugfixes +-------- + +- Fix ``AnsibleModule.human_to_bytes()``, which was never adjusted after the standalone ``human_to_bytes()`` got a new parameter ``default_unit`` (https://github.com/ansible/ansible/pull/85259). +- Variable loading now uses file source instead of variables when invalidly formmated vars file is loaded. +- ansible-test - The runtime-metadata sanity test now ignores pre-release and build identifiers in collection versions. This prevents errors if a tombstone version is ``X.0.0``, while the collection's version is ``X.0.0-prerelease`` (https://github.com/ansible/ansible/issues/85193)." +- display - Fix ``getuser`` fallback error handling on Python 3.13 and later. (https://github.com/ansible/ansible/issues/86142) +- first_found - Correct the "Include tasks only if one of the files exists, otherwise skip" example. +- get_url - fix regex for GNU Digest line which is used in comparing checksums (https://github.com/ansible/ansible/issues/86132). +- local connection - Fix ``getuser`` fallback error handling on Python 3.13 and later. + v2.20.0 ======= diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.20.0/changelogs/changelog.yaml new/ansible_core-2.20.1/changelogs/changelog.yaml --- old/ansible_core-2.20.0/changelogs/changelog.yaml 2025-11-05 00:27:13.000000000 +0100 +++ new/ansible_core-2.20.1/changelogs/changelog.yaml 2025-12-09 17:24:07.000000000 +0100 @@ -393,3 +393,48 @@ - option_deprecation_help.yml - package_facts.yml release_date: '2025-10-29' + 2.20.1: + changes: + release_summary: '| Release Date: 2025-12-09 + + | `Porting Guide <https://docs.ansible.com/ansible-core/2.20/porting_guides/porting_guide_core_2.20.html>`__ + + ' + codename: Good Times Bad Times + fragments: + - 2.20.1_summary.yaml + release_date: '2025-12-09' + 2.20.1rc1: + changes: + bugfixes: + - Fix ``AnsibleModule.human_to_bytes()``, which was never adjusted after the + standalone ``human_to_bytes()`` got a new parameter ``default_unit`` (https://github.com/ansible/ansible/pull/85259). + - Variable loading now uses file source instead of variables when invalidly + formmated vars file is loaded. + - ansible-test - The runtime-metadata sanity test now ignores pre-release and + build identifiers in collection versions. This prevents errors if a tombstone + version is ``X.0.0``, while the collection's version is ``X.0.0-prerelease`` + (https://github.com/ansible/ansible/issues/85193)." + - display - Fix ``getuser`` fallback error handling on Python 3.13 and later. + (https://github.com/ansible/ansible/issues/86142) + - first_found - Correct the "Include tasks only if one of the files exists, + otherwise skip" example. + - get_url - fix regex for GNU Digest line which is used in comparing checksums + (https://github.com/ansible/ansible/issues/86132). + - local connection - Fix ``getuser`` fallback error handling on Python 3.13 + and later. + release_summary: '| Release Date: 2025-12-02 + + | `Porting Guide <https://docs.ansible.com/ansible-core/2.20/porting_guides/porting_guide_core_2.20.html>`__ + + ' + codename: Good Times Bad Times + fragments: + - 2.20.1rc1_summary.yaml + - 85193-runtime-metadata.yml + - 85259-fix-human_to_bytes.yml + - first-found-example.yml + - get_url_regex.yml + - getuser-exception-handling.yml + - varloaderror.yml + release_date: '2025-12-02' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.20.0/lib/ansible/module_utils/ansible_release.py new/ansible_core-2.20.1/lib/ansible/module_utils/ansible_release.py --- old/ansible_core-2.20.0/lib/ansible/module_utils/ansible_release.py 2025-11-05 00:27:13.000000000 +0100 +++ new/ansible_core-2.20.1/lib/ansible/module_utils/ansible_release.py 2025-12-09 17:24:07.000000000 +0100 @@ -17,6 +17,6 @@ from __future__ import annotations -__version__ = '2.20.0' +__version__ = '2.20.1' __author__ = 'Ansible, Inc.' __codename__ = "Good Times Bad Times" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.20.0/lib/ansible/module_utils/basic.py new/ansible_core-2.20.1/lib/ansible/module_utils/basic.py --- old/ansible_core-2.20.0/lib/ansible/module_utils/basic.py 2025-11-05 00:27:13.000000000 +0100 +++ new/ansible_core-2.20.1/lib/ansible/module_utils/basic.py 2025-12-09 17:24:07.000000000 +0100 @@ -2153,14 +2153,16 @@ with open(filename, 'a') as fh: fh.write(str) - def bytes_to_human(self, size): + @staticmethod + def bytes_to_human(size: int) -> str: return bytes_to_human(size) # for backwards compatibility pretty_bytes = bytes_to_human - def human_to_bytes(self, number, isbits=False): - return human_to_bytes(number, isbits) + @staticmethod + def human_to_bytes(number: str, isbits: bool = False) -> int: + return human_to_bytes(number, isbits=isbits) # # Backwards compat diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.20.0/lib/ansible/module_utils/common/text/formatters.py new/ansible_core-2.20.1/lib/ansible/module_utils/common/text/formatters.py --- old/ansible_core-2.20.0/lib/ansible/module_utils/common/text/formatters.py 2025-11-05 00:27:13.000000000 +0100 +++ new/ansible_core-2.20.1/lib/ansible/module_utils/common/text/formatters.py 2025-12-09 17:24:07.000000000 +0100 @@ -60,7 +60,7 @@ if 'Mb'/'Kb'/... is passed, the ValueError will be rased. When isbits is True, converts bits from a human-readable format to integer. - example: human_to_bytes('1Mb', isbits=True) returns 8388608 (int) - + example: human_to_bytes('1Mb', isbits=True) returns 1048576 (int) - string bits representation was passed and return as a number or bits. The function expects 'b' (lowercase) as a bit identifier, e.g. 'Mb'/'Kb'/etc. if 'MB'/'KB'/... is passed, the ValueError will be rased. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.20.0/lib/ansible/modules/get_url.py new/ansible_core-2.20.1/lib/ansible/modules/get_url.py --- old/ansible_core-2.20.0/lib/ansible/modules/get_url.py 2025-11-05 00:27:13.000000000 +0100 +++ new/ansible_core-2.20.1/lib/ansible/modules/get_url.py 2025-12-09 17:24:07.000000000 +0100 @@ -477,17 +477,13 @@ return urlsplit(checksum).scheme in supported_schemes -def parse_digest_lines(filename, lines): +def parse_digest_lines(filename: str, lines: list[str]) -> list[tuple[str, str]]: """Returns a list of tuple containing the filename and digest depending upon the lines provided - - Args: - filename (str): Name of the filename, used only when the digest is one-liner - lines (list): A list of lines containing filenames and checksums """ checksum_map = [] BSD_DIGEST_LINE = re.compile(r'^(\w+) ?\((?P<path>.+)\) ?= (?P<digest>[\w.]+)$') - GNU_DIGEST_LINE = re.compile(r'^(?P<digest>[\w.]+) ([ *])(?P<path>.+)$') + GNU_DIGEST_LINE = re.compile(r'^(?P<digest>[\w.]+)\s+(\*|\.\/|\.)?(?P<path>.+)$') if len(lines) == 1 and len(lines[0].split()) == 1: # Only a single line with a single string diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.20.0/lib/ansible/plugins/connection/local.py new/ansible_core-2.20.1/lib/ansible/plugins/connection/local.py --- old/ansible_core-2.20.0/lib/ansible/plugins/connection/local.py 2025-11-05 00:27:13.000000000 +0100 +++ new/ansible_core-2.20.1/lib/ansible/plugins/connection/local.py 2025-12-09 17:24:07.000000000 +0100 @@ -67,7 +67,8 @@ self.cwd = None try: self.default_user = getpass.getuser() - except KeyError: + except (ImportError, KeyError, OSError): + # deprecated: description='only OSError is required for Python 3.13+' python_version='3.12' display.vv("Current user (uid=%s) does not seem to exist on this system, leaving user empty." % os.getuid()) self.default_user = "" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.20.0/lib/ansible/plugins/lookup/first_found.py new/ansible_core-2.20.1/lib/ansible/plugins/lookup/first_found.py --- old/ansible_core-2.20.0/lib/ansible/plugins/lookup/first_found.py 2025-11-05 00:27:13.000000000 +0100 +++ new/ansible_core-2.20.1/lib/ansible/plugins/lookup/first_found.py 2025-12-09 17:24:07.000000000 +0100 @@ -79,7 +79,7 @@ - name: Include tasks only if one of the files exists, otherwise skip ansible.builtin.include_tasks: '{{ tasks_file }}' - when: tasks_file != "" + when: tasks_file is not none vars: tasks_file: "{{ lookup('ansible.builtin.first_found', files=['tasks.yaml', 'other_tasks.yaml'], errors='ignore') }}" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.20.0/lib/ansible/plugins/test/regex.yml new/ansible_core-2.20.1/lib/ansible/plugins/test/regex.yml --- old/ansible_core-2.20.0/lib/ansible/plugins/test/regex.yml 2025-11-05 00:27:13.000000000 +0100 +++ new/ansible_core-2.20.1/lib/ansible/plugins/test/regex.yml 2025-12-09 17:24:07.000000000 +0100 @@ -28,7 +28,7 @@ choices: [match, search, fullmatch] default: search -EXAMPLES: +EXAMPLES: | - name: check if string matches regex assert: that: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.20.0/lib/ansible/plugins/vars/host_group_vars.py new/ansible_core-2.20.1/lib/ansible/plugins/vars/host_group_vars.py --- old/ansible_core-2.20.0/lib/ansible/plugins/vars/host_group_vars.py 2025-11-05 00:27:13.000000000 +0100 +++ new/ansible_core-2.20.1/lib/ansible/plugins/vars/host_group_vars.py 2025-12-09 17:24:07.000000000 +0100 @@ -53,7 +53,7 @@ """ import os -from ansible.errors import AnsibleParserError +from ansible.errors import AnsibleError, AnsibleParserError from ansible.module_utils.common.text.converters import to_native from ansible.plugins.vars import BaseVarsPlugin from ansible.utils.path import basedir @@ -74,7 +74,10 @@ for found in found_files: new_data = loader.load_from_file(found, cache='all', unsafe=True, trusted_as_template=True) if new_data: # ignore empty files - data = combine_vars(data, new_data) + try: + data = combine_vars(data, new_data) + except AnsibleError as e: + raise AnsibleParserError(f"Could not process {found!r}.") from e return data def get_vars(self, loader, path, entities, cache=True): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.20.0/lib/ansible/release.py new/ansible_core-2.20.1/lib/ansible/release.py --- old/ansible_core-2.20.0/lib/ansible/release.py 2025-11-05 00:27:13.000000000 +0100 +++ new/ansible_core-2.20.1/lib/ansible/release.py 2025-12-09 17:24:07.000000000 +0100 @@ -17,6 +17,6 @@ from __future__ import annotations -__version__ = '2.20.0' +__version__ = '2.20.1' __author__ = 'Ansible, Inc.' __codename__ = "Good Times Bad Times" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.20.0/lib/ansible/utils/display.py new/ansible_core-2.20.1/lib/ansible/utils/display.py --- old/ansible_core-2.20.0/lib/ansible/utils/display.py 2025-11-05 00:27:13.000000000 +0100 +++ new/ansible_core-2.20.1/lib/ansible/utils/display.py 2025-12-09 17:24:07.000000000 +0100 @@ -174,7 +174,8 @@ try: username = getpass.getuser() - except KeyError: + except (ImportError, KeyError, OSError): + # deprecated: description='only OSError is required for Python 3.13+' python_version='3.12' # people like to make containers w/o actual valid passwd/shadow and use host uids username = 'uid=%s' % os.getuid() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.20.0/lib/ansible/utils/vars.py new/ansible_core-2.20.1/lib/ansible/utils/vars.py --- old/ansible_core-2.20.0/lib/ansible/utils/vars.py 2025-11-05 00:27:13.000000000 +0100 +++ new/ansible_core-2.20.1/lib/ansible/utils/vars.py 2025-12-09 17:24:07.000000000 +0100 @@ -72,9 +72,7 @@ myvars.append(dumps(x)) except Exception: myvars.append(to_native(x)) - raise AnsibleError("failed to combine variables, expected dicts but got a '{0}' and a '{1}': \n{2}\n{3}".format( - a.__class__.__name__, b.__class__.__name__, myvars[0], myvars[1]) - ) + raise AnsibleError(f"failed to combine variables, expected dicts but got a '{a.__class__.__name__}' and a '{b.__class__.__name__}'.") def combine_vars(a, b, merge=None): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.20.0/lib/ansible/vars/manager.py new/ansible_core-2.20.1/lib/ansible/vars/manager.py --- old/ansible_core-2.20.0/lib/ansible/vars/manager.py 2025-11-05 00:27:13.000000000 +0100 +++ new/ansible_core-2.20.1/lib/ansible/vars/manager.py 2025-12-09 17:24:07.000000000 +0100 @@ -349,18 +349,16 @@ data = preprocess_vars(self._loader.load_from_file(found_file, unsafe=True, cache='vaulted', trusted_as_template=True)) if data is not None: for item in data: - all_vars = _combine_and_track(all_vars, item, "play vars_files from '%s'" % vars_file) + all_vars = _combine_and_track(all_vars, item, f"play vars_files from {vars_file!r}") display.vvv(f"Read `vars_file` {found_file!r}.") break except AnsibleFileNotFound: # we continue on loader failures continue - except AnsibleParserError: + except (AnsibleParserError, AnsibleUndefinedVariable): raise - except AnsibleUndefinedVariable: - raise - except Exception as ex: - raise AnsibleParserError(f"Error reading `vars_files` file {vars_file!r}.", obj=vars_file) from ex + except AnsibleError as e: + raise AnsibleError(f"Invalid vars_files file {found_file!r}.") from e except AnsibleUndefinedVariable as ex: if host is not None: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.20.0/test/integration/targets/ansible-test-sanity-runtime-metadata/ansible_collections/ns/prerelease/galaxy.yml new/ansible_core-2.20.1/test/integration/targets/ansible-test-sanity-runtime-metadata/ansible_collections/ns/prerelease/galaxy.yml --- old/ansible_core-2.20.0/test/integration/targets/ansible-test-sanity-runtime-metadata/ansible_collections/ns/prerelease/galaxy.yml 1970-01-01 01:00:00.000000000 +0100 +++ new/ansible_core-2.20.1/test/integration/targets/ansible-test-sanity-runtime-metadata/ansible_collections/ns/prerelease/galaxy.yml 2025-12-09 17:24:07.000000000 +0100 @@ -0,0 +1,5 @@ +namespace: ns +name: prerelease +version: 3.0.0-prerelease +authors: + - Ansible diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.20.0/test/integration/targets/ansible-test-sanity-runtime-metadata/ansible_collections/ns/prerelease/meta/runtime.yml new/ansible_core-2.20.1/test/integration/targets/ansible-test-sanity-runtime-metadata/ansible_collections/ns/prerelease/meta/runtime.yml --- old/ansible_core-2.20.0/test/integration/targets/ansible-test-sanity-runtime-metadata/ansible_collections/ns/prerelease/meta/runtime.yml 1970-01-01 01:00:00.000000000 +0100 +++ new/ansible_core-2.20.1/test/integration/targets/ansible-test-sanity-runtime-metadata/ansible_collections/ns/prerelease/meta/runtime.yml 2025-12-09 17:24:07.000000000 +0100 @@ -0,0 +1,25 @@ +plugin_routing: + modules: + deprecated_module: + deprecation: + removal_version: 4.0.0 + warning_text: Will no longer be there. + tombstoned_module: + tombstone: + removal_version: 3.0.0 + warning_text: Is no longer there. + tombstoned_module_with_prerelease_version: + tombstone: + removal_version: 3.0.0-a1 + warning_text: Is no longer there. + tombstoned_module_with_prerelease_and_build_meta_version: + tombstone: + removal_version: 3.0.0-a1+bla.test.1234567 + warning_text: Is no longer there. + tombstoned_module_with_build_meta_version: + tombstone: + removal_version: 3.0.0+bla.test.1234567 + warning_text: Is no longer there. + module_with_invalid_removal_version: + tombstone: + removal_version: 4.0.0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.20.0/test/integration/targets/ansible-test-sanity-runtime-metadata/expected-prerelease.txt new/ansible_core-2.20.1/test/integration/targets/ansible-test-sanity-runtime-metadata/expected-prerelease.txt --- old/ansible_core-2.20.0/test/integration/targets/ansible-test-sanity-runtime-metadata/expected-prerelease.txt 1970-01-01 01:00:00.000000000 +0100 +++ new/ansible_core-2.20.1/test/integration/targets/ansible-test-sanity-runtime-metadata/expected-prerelease.txt 2025-12-09 17:24:07.000000000 +0100 @@ -0,0 +1 @@ +meta/runtime.yml:0:0: The tombstone removal_version ('4.0.0') must not be after the current version (SemanticVersion('3.0.0')) for dictionary value @ data['plugin_routing']['modules']['module_with_invalid_removal_version']['tombstone']['removal_version']. Got '4.0.0' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.20.0/test/integration/targets/ansible-test-sanity-runtime-metadata/runme.sh new/ansible_core-2.20.1/test/integration/targets/ansible-test-sanity-runtime-metadata/runme.sh --- old/ansible_core-2.20.0/test/integration/targets/ansible-test-sanity-runtime-metadata/runme.sh 2025-11-05 00:27:13.000000000 +0100 +++ new/ansible_core-2.20.1/test/integration/targets/ansible-test-sanity-runtime-metadata/runme.sh 2025-12-09 17:24:07.000000000 +0100 @@ -13,3 +13,8 @@ ansible-test sanity --test runtime-metadata --color --truncate 0 --failure-ok --lint "${@}" 1> actual-stdout.txt 2> actual-stderr.txt diff -u "${TEST_DIR}/expected-no_version.txt" actual-stdout.txt grep -F -f "${TEST_DIR}/expected-no_version.txt" actual-stderr.txt + +cd ../prerelease +ansible-test sanity --test runtime-metadata --color --truncate 0 --failure-ok --lint "${@}" 1> actual-stdout.txt 2> actual-stderr.txt +diff -u "${TEST_DIR}/expected-prerelease.txt" actual-stdout.txt +grep -F -f "${TEST_DIR}/expected-prerelease.txt" actual-stderr.txt diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.20.0/test/integration/targets/get_url/tasks/main.yml new/ansible_core-2.20.1/test/integration/targets/get_url/tasks/main.yml --- old/ansible_core-2.20.0/test/integration/targets/get_url/tasks/main.yml 2025-11-05 00:27:13.000000000 +0100 +++ new/ansible_core-2.20.1/test/integration/targets/get_url/tasks/main.yml 2025-12-09 17:24:07.000000000 +0100 @@ -1,20 +1,6 @@ # Test code for the get_url module # (c) 2014, Richard Isaacson <[email protected]> - -# This file is part of Ansible -# -# Ansible is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Ansible is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Ansible. If not, see <https://www.gnu.org/licenses/>. +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - name: Determine if python looks like it will support modern ssl features like SNI command: "{{ ansible_python.executable }} -c 'from ssl import SSLContext'" @@ -332,13 +318,13 @@ - name: create src file copy: - dest: '{{ files_dir }}/27617.txt' - content: "ptux" - -- name: create duplicate src file - copy: - dest: '{{ files_dir }}/71420.txt' + dest: '{{ files_dir }}/{{ item }}.txt' content: "ptux" + loop: + - 27617 + - 71420 + - 86132 + - 86132_single_space - name: create sha1 checksum file of src copy: @@ -346,6 +332,8 @@ content: | a97e6837f60cec6da4491bab387296bbcd72bdba 27617.txt a97e6837f60cec6da4491bab387296bbcd72bdba 71420.txt + a97e6837f60cec6da4491bab387296bbcd72bdba 86132.txt + a97e6837f60cec6da4491bab387296bbcd72bdba 86132_single_space.txt 3911340502960ca33aece01129234460bfeb2791 not_target1.txt 1b4b6adf30992cedb0f6edefd6478ff0a593b2e4 not_target2.txt @@ -355,6 +343,8 @@ content: | b1b6ce5073c8fac263a8fc5edfffdbd5dec1980c784e09c5bc69f8fb6056f006. 27617.txt b1b6ce5073c8fac263a8fc5edfffdbd5dec1980c784e09c5bc69f8fb6056f006. 71420.txt + b1b6ce5073c8fac263a8fc5edfffdbd5dec1980c784e09c5bc69f8fb6056f006. 86132.txt + b1b6ce5073c8fac263a8fc5edfffdbd5dec1980c784e09c5bc69f8fb6056f006. 86132_single_space.txt 30949cc401e30ac494d695ab8764a9f76aae17c5d73c67f65e9b558f47eff892 not_target1.txt d0dbfc1945bc83bf6606b770e442035f2c4e15c886ee0c22fb3901ba19900b5b not_target2.txt @@ -364,6 +354,8 @@ content: | b1b6ce5073c8fac263a8fc5edfffdbd5dec1980c784e09c5bc69f8fb6056f006. ./27617.txt b1b6ce5073c8fac263a8fc5edfffdbd5dec1980c784e09c5bc69f8fb6056f006. ./71420.txt + b1b6ce5073c8fac263a8fc5edfffdbd5dec1980c784e09c5bc69f8fb6056f006. ./86132.txt + b1b6ce5073c8fac263a8fc5edfffdbd5dec1980c784e09c5bc69f8fb6056f006. ./86132_single_space.txt 30949cc401e30ac494d695ab8764a9f76aae17c5d73c67f65e9b558f47eff892 ./not_target1.txt d0dbfc1945bc83bf6606b770e442035f2c4e15c886ee0c22fb3901ba19900b5b ./not_target2.txt @@ -373,6 +365,8 @@ content: | b1b6ce5073c8fac263a8fc5edfffdbd5dec1980c784e09c5bc69f8fb6056f006. *27617.txt b1b6ce5073c8fac263a8fc5edfffdbd5dec1980c784e09c5bc69f8fb6056f006. *71420.txt + b1b6ce5073c8fac263a8fc5edfffdbd5dec1980c784e09c5bc69f8fb6056f006. *86132.txt + b1b6ce5073c8fac263a8fc5edfffdbd5dec1980c784e09c5bc69f8fb6056f006. *86132_single_space.txt 30949cc401e30ac494d695ab8764a9f76aae17c5d73c67f65e9b558f47eff892 *not_target1.txt d0dbfc1945bc83bf6606b770e442035f2c4e15c886ee0c22fb3901ba19900b5b *not_target2.txt @@ -551,6 +545,61 @@ path: "{{ remote_tmp_dir }}/27617.txt" register: stat_result_sha256_checksum_only +- name: download 86132.txt with sha1 checksum url + get_url: + url: 'http://localhost:{{ http_port }}/86132.txt' + dest: '{{ remote_tmp_dir }}' + checksum: 'sha1:http://localhost:{{ http_port }}/sha1sum.txt' + register: result_sha1_86132 + +- stat: + path: "{{ remote_tmp_dir }}/86132.txt" + register: stat_result_sha1_86132 + +- name: download 86132.txt with sha256 checksum url + get_url: + url: 'http://localhost:{{ http_port }}/86132.txt' + dest: '{{ remote_tmp_dir }}/86132sha256.txt' + checksum: 'sha256:http://localhost:{{ http_port }}/sha256sum.txt' + register: result_sha256_86132 + +- stat: + path: "{{ remote_tmp_dir }}/86132.txt" + register: stat_result_sha256_86132 + +- name: download 86132.txt with sha256 checksum url with dot leading paths + get_url: + url: 'http://localhost:{{ http_port }}/86132.txt' + dest: '{{ remote_tmp_dir }}/86132sha256_with_dot.txt' + checksum: 'sha256:http://localhost:{{ http_port }}/sha256sum_with_dot.txt' + register: result_sha256_with_dot_86132 + +- stat: + path: "{{ remote_tmp_dir }}/86132sha256_with_dot.txt" + register: stat_result_sha256_with_dot_86132 + +- name: download 86132.txt with sha256 checksum url with asterisk leading paths + get_url: + url: 'http://localhost:{{ http_port }}/86132.txt' + dest: '{{ remote_tmp_dir }}/86132sha256_with_asterisk.txt' + checksum: 'sha256:http://localhost:{{ http_port }}/sha256sum_with_asterisk.txt' + register: result_sha256_with_asterisk_86132 + +- stat: + path: "{{ remote_tmp_dir }}/86132sha256_with_asterisk.txt" + register: stat_result_sha256_with_asterisk_86132 + +- name: download 86132_single_space.txt with sha256 checksum url + get_url: + url: 'http://localhost:{{ http_port }}/86132_single_space.txt' + dest: '{{ remote_tmp_dir }}/86132_single_space.txt' + checksum: 'sha256:http://localhost:{{ http_port }}/sha256sum.txt' + register: result_sha256_86132_single_space + +- stat: + path: "{{ remote_tmp_dir }}/86132_single_space.txt" + register: stat_result_sha256_86132_single_space + - name: Assert that the file was downloaded assert: that: @@ -579,6 +628,16 @@ - "stat_result_sha256_with_asterisk_71420.stat.exists == true" - "stat_result_sha256_with_file_scheme_71420.stat.exists == true" - "stat_result_sha256_checksum_only.stat.exists == true" + - result_sha1_86132 is changed + - result_sha256_86132 is changed + - result_sha256_with_dot_86132 is changed + - result_sha256_with_asterisk_86132 is changed + - "stat_result_sha1_86132.stat.exists == true" + - "stat_result_sha256_86132.stat.exists == true" + - "stat_result_sha256_with_dot_86132.stat.exists == true" + - "stat_result_sha256_with_asterisk_86132.stat.exists == true" + - result_sha256_86132_single_space is changed + - "stat_result_sha256_86132_single_space.stat.exists == true" - name: Test for incomplete data read (issue 85164) get_url: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.20.0/test/integration/targets/iptables/tasks/main.yml new/ansible_core-2.20.1/test/integration/targets/iptables/tasks/main.yml --- old/ansible_core-2.20.0/test/integration/targets/iptables/tasks/main.yml 2025-11-05 00:27:13.000000000 +0100 +++ new/ansible_core-2.20.1/test/integration/targets/iptables/tasks/main.yml 2025-12-09 17:24:07.000000000 +0100 @@ -35,4 +35,14 @@ # prevent attempts to upgrade the kernel and install kernel modules for a non-running kernel version exclude: "{{ 'kernel-core' if ansible_distribution == 'RedHat' else omit }}" +- name: install xt_comment for iptables `-m comment` tests on RHEL 10 + dnf: + name: + - kernel-modules-extra-{{ ansible_facts.kernel }} + state: present + exclude: + # prevent attempts to upgrade the kernel and install kernel modules for a non-running kernel version + - kernel-core + when: ansible_distribution == 'RedHat' + - import_tasks: chain_management.yml diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.20.0/test/integration/targets/var_blending/error_handling.yml new/ansible_core-2.20.1/test/integration/targets/var_blending/error_handling.yml --- old/ansible_core-2.20.0/test/integration/targets/var_blending/error_handling.yml 1970-01-01 01:00:00.000000000 +0100 +++ new/ansible_core-2.20.1/test/integration/targets/var_blending/error_handling.yml 2025-12-09 17:24:07.000000000 +0100 @@ -0,0 +1,14 @@ +- hosts: all + name: test vault errors + gather_facts: false + tasks: + + - name: bad included vault + include_vars: + file: vars/bad_vault.yml + tags: includevault, never + no_log: false + + - name: Show bad vault contents ... if i get here, it was a good vault! + debug: + msg: "{{ test_password }} {{ jdbc_test_password }} {{ api_test_password }}" File old/ansible_core-2.20.0/test/integration/targets/var_blending/group_vars/local is a regular file while file new/ansible_core-2.20.1/test/integration/targets/var_blending/group_vars/local is a directory diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.20.0/test/integration/targets/var_blending/runme.sh new/ansible_core-2.20.1/test/integration/targets/var_blending/runme.sh --- old/ansible_core-2.20.0/test/integration/targets/var_blending/runme.sh 2025-11-05 00:27:13.000000000 +0100 +++ new/ansible_core-2.20.1/test/integration/targets/var_blending/runme.sh 2025-12-09 17:24:07.000000000 +0100 @@ -3,3 +3,12 @@ set -eux ansible-playbook test_var_blending.yml -i inventory -e @test_vars.yml -v "$@" + +# check bad vault file erros +[ "$(ansible-playbook error_handling.yml -i inventory --vault-password-file supersecretvaultsecret -e @vars/bad_vault.yml 2>&1 | grep -c 'dummy')" -eq "0" ] +[ "$(ansible-playbook error_handling.yml -i inventory --vault-password-file supersecretvaultsecret --tags includevault 2>&1 | grep -c 'dummy')" -eq "0" ] + +# setup group file for bad vault tests +trap 'rm group_vars/local/bad_vault.yml' EXIT +ln -s "${PWD}/vars/bad_vault.yml" group_vars/local/ +[ "$(ansible-playbook error_handling.yml -i inventory --vault-password-file supersecretvaultsecret 2>&1 | grep -c 'dummy')" -eq "0" ] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.20.0/test/integration/targets/var_blending/supersecretvaultsecret new/ansible_core-2.20.1/test/integration/targets/var_blending/supersecretvaultsecret --- old/ansible_core-2.20.0/test/integration/targets/var_blending/supersecretvaultsecret 1970-01-01 01:00:00.000000000 +0100 +++ new/ansible_core-2.20.1/test/integration/targets/var_blending/supersecretvaultsecret 2025-12-09 17:24:07.000000000 +0100 @@ -0,0 +1 @@ +test diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.20.0/test/integration/targets/var_blending/vars/bad_vault.yml new/ansible_core-2.20.1/test/integration/targets/var_blending/vars/bad_vault.yml --- old/ansible_core-2.20.0/test/integration/targets/var_blending/vars/bad_vault.yml 1970-01-01 01:00:00.000000000 +0100 +++ new/ansible_core-2.20.1/test/integration/targets/var_blending/vars/bad_vault.yml 2025-12-09 17:24:07.000000000 +0100 @@ -0,0 +1,10 @@ +$ANSIBLE_VAULT;1.1;AES256 +65616232393566313961313431386633366639386133383230656230333934656366363636393730 +3266313739663639636161373033333865303461343936370a356463393635623664316464353061 +63396639643331303231616336663562303764653733326532316139643036336436396565653531 +3836383032626262620a316666363164626537346663383333376330623339633762363932613537 +32663462613532646139633364363136656132346661373331363164356162313762343337393666 +38653864363938316534333438643761623264376535336233656630376430346366333262313532 +33366662663137306431623464303561383730336466613166386136656364306436343032343631 +37396234633230626263373435623731616664653939343630393935626461396230663734373861 +3634 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.20.0/test/lib/ansible_test/_internal/ci/azp.py new/ansible_core-2.20.1/test/lib/ansible_test/_internal/ci/azp.py --- old/ansible_core-2.20.0/test/lib/ansible_test/_internal/ci/azp.py 2025-11-05 00:27:13.000000000 +0100 +++ new/ansible_core-2.20.1/test/lib/ansible_test/_internal/ci/azp.py 2025-12-09 17:24:07.000000000 +0100 @@ -2,6 +2,7 @@ from __future__ import annotations +import json import os import tempfile import uuid @@ -27,6 +28,7 @@ from ..util import ( display, + ApplicationError, MissingEnvironmentVariable, ) @@ -220,6 +222,19 @@ self.diff = [] def get_successful_merge_run_commits(self) -> set[str]: + """ + Return a set of recent successful merge commits from Azure Pipelines. + A warning will be displayed and no commits returned if an error occurs. + """ + try: + commits = self._get_successful_merge_run_commits() + except ApplicationError as ex: + commits = set() + display.warning(f'Cannot determine changes. All tests will be executed. Reason: {ex}') + + return commits + + def _get_successful_merge_run_commits(self) -> set[str]: """Return a set of recent successful merge commits from Azure Pipelines.""" parameters = dict( maxBuildsPerDefinition=100, # max 5000 @@ -230,20 +245,29 @@ repositoryId='%s/%s' % (self.org, self.project), ) - url = '%s%s/_apis/build/builds?api-version=6.0&%s' % (self.org_uri, self.project, urllib.parse.urlencode(parameters)) + url = '%s%s/_apis/build/builds?api-version=7.1&%s' % (self.org_uri, self.project, urllib.parse.urlencode(parameters)) http = HttpClient(self.args, always=True) response = http.get(url) - # noinspection PyBroadException try: - result = response.json() - except Exception: # pylint: disable=broad-except - # most likely due to a private project, which returns an HTTP 203 response with HTML - display.warning('Unable to find project. Cannot determine changes. All tests will be executed.') - return set() + result = json.loads(response.response) + result_type = 'JSON' + except json.JSONDecodeError: + result = ... + result_type = 'Non-JSON' - commits = set(build['sourceVersion'] for build in result['value']) + result_description = f'HTTP {response.status_code} {result_type} result' + + if response.status_code != 200 or result is ...: + raise ApplicationError(f'Unable to find project due to {result_description}.') + + try: + commits = {build['sourceVersion'] for build in result['value']} + except KeyError as ex: + raise ApplicationError(f'Missing {ex.args[0]!r} key in response from {result_description}.') from ex + except (ValueError, TypeError) as ex: + raise ApplicationError(f'Unexpected response format from {result_description}: {ex}') from ex return commits diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.20.0/test/lib/ansible_test/_util/controller/sanity/code-smell/runtime-metadata.py new/ansible_core-2.20.1/test/lib/ansible_test/_util/controller/sanity/code-smell/runtime-metadata.py --- old/ansible_core-2.20.0/test/lib/ansible_test/_util/controller/sanity/code-smell/runtime-metadata.py 2025-11-05 00:27:13.000000000 +0100 +++ new/ansible_core-2.20.1/test/lib/ansible_test/_util/controller/sanity/code-smell/runtime-metadata.py 2025-12-09 17:24:07.000000000 +0100 @@ -134,7 +134,7 @@ try: result = collection_detail.read_manifest_json('.') or collection_detail.read_galaxy_yml('.') version = SemanticVersion() - version.parse(result['version']) + version.parse(result['version'].split('-', 1)[0].split('+', 1)[0]) return version except Exception: # pylint: disable=broad-except # We do not care why it fails, in case we cannot get the version diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.20.0/test/units/ansible_test/_internal/ci/test_azp.py new/ansible_core-2.20.1/test/units/ansible_test/_internal/ci/test_azp.py --- old/ansible_core-2.20.0/test/units/ansible_test/_internal/ci/test_azp.py 1970-01-01 01:00:00.000000000 +0100 +++ new/ansible_core-2.20.1/test/units/ansible_test/_internal/ci/test_azp.py 2025-12-09 17:24:07.000000000 +0100 @@ -0,0 +1,96 @@ +from __future__ import annotations + +import argparse +import json +import os +import typing as t + +import pytest +import pytest_mock + +if t.TYPE_CHECKING: + from ansible_test._internal.ci.azp import AzurePipelinesChanges + + +def create_azure_pipelines_changes(mocker: pytest_mock.MockerFixture) -> AzurePipelinesChanges: + """Prepare an AzurePipelinesChanges instance for testing.""" + from ansible_test._internal.ci.azp import AzurePipelinesChanges + from ansible_test._internal.config import CommonConfig + + namespace = argparse.Namespace() + namespace.color = False + namespace.explain = False + namespace.verbosity = False + namespace.debug = False + namespace.truncate = False + namespace.redact = False + namespace.display_traceback = False + + config = CommonConfig(namespace, 'sanity') + + env = dict( + HOME=os.environ['HOME'], + SYSTEM_COLLECTIONURI='https://dev.azure.com/ansible/', + SYSTEM_TEAMPROJECT='ansible', + BUILD_REPOSITORY_PROVIDER='GitHub', + BUILD_SOURCEBRANCH='devel', + BUILD_SOURCEBRANCHNAME='devel', + ) + + mocker.patch.dict(os.environ, env, clear=True) + + return AzurePipelinesChanges(config) + + [email protected]("status_code,response,expected_commits,expected_warning", ( + # valid 200 responses + (200, dict(value=[]), None, None), + (200, dict(value=[dict(sourceVersion='abc')]), {'abc'}, None), + # invalid 200 responses + (200, 'not-json', None, "Unable to find project due to HTTP 200 Non-JSON result."), + (200, '"not-a-dict"', None, "Unexpected response format from HTTP 200 JSON result: string indices must be integers, not 'str'"), + (200, dict(value='not-a-list'), None, "Unexpected response format from HTTP 200 JSON result: string indices must be integers, not 'str'"), + (200, dict(value=['not-a-dict']), None, "Unexpected response format from HTTP 200 JSON result: string indices must be integers, not 'str'"), + (200, dict(), None, "Missing 'value' key in response from HTTP 200 JSON result."), + (200, dict(value=[{}]), None, "Missing 'sourceVersion' key in response from HTTP 200 JSON result."), + # non-200 responses + (404, '', None, "Unable to find project due to HTTP 404 Non-JSON result."), + (404, '""', None, "Unable to find project due to HTTP 404 JSON result."), + (404, dict(value=[]), None, "Unable to find project due to HTTP 404 JSON result."), +)) +def test_get_successful_merge_run_commits( + status_code: int, + response: object, + expected_commits: set[str] | None, + expected_warning: str | None, + mocker: pytest_mock.MockerFixture, +) -> None: + """Verify AZP commit retrieval handles invalid responses gracefully.""" + from ansible_test._internal.ci.azp import AzurePipelinesChanges + from ansible_test._internal.git import Git + from ansible_test._internal.http import HttpClient, HttpResponse + from ansible_test._internal.util import display + + if not isinstance(response, str): + response = json.dumps(response) + + if expected_warning: + expected_warning = f'Cannot determine changes. All tests will be executed. Reason: {expected_warning}' + + patched_get = mocker.patch.object(HttpClient, 'get', return_value=HttpResponse('GET', 'URL', status_code, response)) + patched_warning = mocker.patch.object(display, 'warning') + + mocker.patch.object(Git, 'run_git', return_value='') # avoid git + + spy_get_successful_merge_run_commits = mocker.spy(AzurePipelinesChanges, 'get_successful_merge_run_commits') + + create_azure_pipelines_changes(mocker) + + assert patched_get.call_count == 1 + + if expected_warning: + patched_warning.assert_called_once_with(expected_warning) + else: + patched_warning.assert_not_called() + + assert spy_get_successful_merge_run_commits.spy_return == (expected_commits or set()) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.20.0/test/units/module_utils/basic/test_human_to_bytes.py new/ansible_core-2.20.1/test/units/module_utils/basic/test_human_to_bytes.py --- old/ansible_core-2.20.0/test/units/module_utils/basic/test_human_to_bytes.py 1970-01-01 01:00:00.000000000 +0100 +++ new/ansible_core-2.20.1/test/units/module_utils/basic/test_human_to_bytes.py 2025-12-09 17:24:07.000000000 +0100 @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- +# Copyright: (c) 2025 Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import annotations + +import pytest + +from ansible.module_utils.basic import AnsibleModule + + [email protected]('value, isbits, expected', [ + ("4KB", False, 4096), + ("4KB", None, 4096), + ("4Kb", True, 4096), +]) +def test_validator_function(value: str, isbits: bool | None, expected: int) -> None: + assert AnsibleModule.human_to_bytes(value, isbits=isbits) == expected + + [email protected]('value, expected', [ + ("4KB", 4096), +]) +def test_validator_function_default_isbits(value: str, expected: int) -> None: + assert AnsibleModule.human_to_bytes(value) == expected + + [email protected]('value, isbits', [ + ("4Kb", False), + ("4KB", True), +]) +def test_validator_functions(value: str, isbits: bool) -> None: + with pytest.raises(ValueError): + AnsibleModule.human_to_bytes(value, isbits=isbits) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.20.0/test/units/modules/test_get_url.py new/ansible_core-2.20.1/test/units/modules/test_get_url.py --- old/ansible_core-2.20.0/test/units/modules/test_get_url.py 2025-11-05 00:27:13.000000000 +0100 +++ new/ansible_core-2.20.1/test/units/modules/test_get_url.py 2025-12-09 17:24:07.000000000 +0100 @@ -8,22 +8,59 @@ from ansible.modules.get_url import parse_digest_lines +FILENAME = "sample.txt" + @pytest.mark.parametrize( ("lines", "expected"), [ pytest.param( [ + "2a32d433bf82355a3f78318a5affa21866c9a98b151785494b386e6b08f40b25 sample.txt", + ], + [("2a32d433bf82355a3f78318a5affa21866c9a98b151785494b386e6b08f40b25", FILENAME)], + id="single-line-digest-single-space", + ), + pytest.param( + [ + "2a32d433bf82355a3f78318a5affa21866c9a98b151785494b386e6b08f40b25 sample.txt", + ], + [("2a32d433bf82355a3f78318a5affa21866c9a98b151785494b386e6b08f40b25", FILENAME)], + id="single-line-digest-multiple-spaces", + ), + pytest.param( + [ + "2a32d433bf82355a3f78318a5affa21866c9a98b151785494b386e6b08f40b25 .sample.txt", + ], + [("2a32d433bf82355a3f78318a5affa21866c9a98b151785494b386e6b08f40b25", FILENAME)], + id="single-line-digest-multiple-spaces-with-dot", + ), + pytest.param( + [ + "2a32d433bf82355a3f78318a5affa21866c9a98b151785494b386e6b08f40b25 *sample.txt", + ], + [("2a32d433bf82355a3f78318a5affa21866c9a98b151785494b386e6b08f40b25", FILENAME)], + id="single-line-digest-multiple-spaces-with-asterisk", + ), + pytest.param( + [ + "2a32d433bf82355a3f78318a5affa21866c9a98b151785494b386e6b08f40b25 ./sample.txt", + ], + [("2a32d433bf82355a3f78318a5affa21866c9a98b151785494b386e6b08f40b25", FILENAME)], + id="single-line-digest-multiple-spaces-with-dot-and-slash", + ), + pytest.param( + [ "a97e6837f60cec6da4491bab387296bbcd72bdba", ], - [("a97e6837f60cec6da4491bab387296bbcd72bdba", "sample.txt")], + [("a97e6837f60cec6da4491bab387296bbcd72bdba", FILENAME)], id="single-line-digest", ), pytest.param( [ "a97e6837f60cec6da4491bab387296bbcd72bdba sample.txt", ], - [("a97e6837f60cec6da4491bab387296bbcd72bdba", "sample.txt")], + [("a97e6837f60cec6da4491bab387296bbcd72bdba", FILENAME)], id="GNU-style-digest", ), pytest.param( @@ -33,7 +70,7 @@ [ ( "b1b6ce5073c8fac263a8fc5edfffdbd5dec1980c784e09c5bc69f8fb6056f006.", - "sample.txt", + FILENAME, ) ], id="BSD-style-digest", @@ -41,5 +78,4 @@ ], ) def test_parse_digest_lines(lines, expected): - filename = "sample.txt" - assert parse_digest_lines(filename, lines) == expected + assert parse_digest_lines(filename=FILENAME, lines=lines) == expected diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible_core-2.20.0/test/units/playbook/test_task.py new/ansible_core-2.20.1/test/units/playbook/test_task.py --- old/ansible_core-2.20.0/test/units/playbook/test_task.py 2025-11-05 00:27:13.000000000 +0100 +++ new/ansible_core-2.20.1/test/units/playbook/test_task.py 2025-12-09 17:24:07.000000000 +0100 @@ -59,16 +59,16 @@ self.assertEqual(t.get_validated_value('delay', t.fattributes.get('delay'), delay, None), expected) bad_params = [ - ('E', AnsibleError), - ('1.E', AnsibleError), - ('E.1', AnsibleError), + 'E', + '1.E', + 'E.1', ] - for delay, expected in bad_params: - with self.subTest(f'type "{type(delay)} was cast to float w/o error', delay=delay, expected=expected): + for delay in bad_params: + with self.subTest(f'type "{type(delay)} was cast to float w/o error', delay=delay): p = dict(delay=delay) p.update(task_base) t = Task().load_data(p) - with self.assertRaises(expected): + with self.assertRaises(AnsibleError): dummy = t.get_validated_value('delay', t.fattributes.get('delay'), delay, None) def test_task_auto_name_with_role(self): ++++++ ansible_core-2.20.0.tar.gz.sha256 -> ansible_core-2.20.1.tar.gz.sha256 ++++++ --- /work/SRC/openSUSE:Factory/ansible-core/ansible_core-2.20.0.tar.gz.sha256 2025-11-21 16:55:28.943336474 +0100 +++ /work/SRC/openSUSE:Factory/.ansible-core.new.1939/ansible_core-2.20.1.tar.gz.sha256 2025-12-11 18:44:52.758392029 +0100 @@ -1 +1 @@ -cd73faf28a056c933bc1eee8f66ab597e7ec7309d42c8a6e5d6e4294c4a78b54 ansible_core-2.20.0.tar.gz +a891e5f90cd46626778f0f3d545ec1115840c9b50e8adf25944c5e1748452106 ansible_core-2.20.1.tar.gz
