Make sure that image comparison survives random order. (#1240) (#1241)

(cherry picked from commit 880bc24ff0)

Co-authored-by: Felix Fontein <felix@fontein.de>
This commit is contained in:
patchback[bot] 2026-02-07 18:43:51 +01:00 committed by GitHub
parent 9c0fa75c8f
commit cc9432f3fa
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 59 additions and 8 deletions

View File

@ -6,3 +6,4 @@
dependencies: dependencies:
- setup_docker - setup_docker
- setup_docker_python_deps - setup_docker_python_deps
- setup_utils

View File

@ -76,7 +76,7 @@
- info_1.images | length == 2 - info_1.images | length == 2
- info_1.images[0].Id == pulled_images.results[0].image.Id - info_1.images[0].Id == pulled_images.results[0].image.Id
- info_1.images[1].Id == pulled_images.results[0].image.Id - info_1.images[1].Id == pulled_images.results[0].image.Id
- tag_1_check == tag_1 - tag_1_check | internal__normalize_image("image") == tag_1 | internal__normalize_image("image")
- name: Tag image 1 (idempotent, check mode) - name: Tag image 1 (idempotent, check mode)
docker_image_tag: docker_image_tag:
@ -102,7 +102,7 @@
- tag_2 is not changed - tag_2 is not changed
- tag_2.diff.before == tag_2.diff.after - tag_2.diff.before == tag_2.diff.after
- tag_2.diff.before.images | length == 2 - tag_2.diff.before.images | length == 2
- tag_2_check == tag_2 - tag_2_check | internal__normalize_image("image") == tag_2 | internal__normalize_image("image")
- name: Tag image 1 (idempotent, different input format, check mode) - name: Tag image 1 (idempotent, different input format, check mode)
docker_image_tag: docker_image_tag:
@ -130,7 +130,7 @@
- tag_3 is not changed - tag_3 is not changed
- tag_3.diff.before == tag_3.diff.after - tag_3.diff.before == tag_3.diff.after
- tag_3.diff.before.images | length == 2 - tag_3.diff.before.images | length == 2
- tag_3_check == tag_3 - tag_3_check | internal__normalize_image("image") == tag_3 | internal__normalize_image("image")
- name: Tag image 1 (one more, check mode) - name: Tag image 1 (one more, check mode)
docker_image_tag: docker_image_tag:
@ -173,7 +173,7 @@
- info_4.images[0].Id == pulled_images.results[0].image.Id - info_4.images[0].Id == pulled_images.results[0].image.Id
- info_4.images[1].Id == pulled_images.results[0].image.Id - info_4.images[1].Id == pulled_images.results[0].image.Id
- info_4.images[2].Id == pulled_images.results[0].image.Id - info_4.images[2].Id == pulled_images.results[0].image.Id
- tag_4_check == tag_4 - tag_4_check | internal__normalize_image("image") == tag_4 | internal__normalize_image("image")
- name: Tag image 2 (only change missing one, check mode) - name: Tag image 2 (only change missing one, check mode)
docker_image_tag: docker_image_tag:
@ -219,7 +219,7 @@
- info_5.images[1].Id == pulled_images.results[0].image.Id - info_5.images[1].Id == pulled_images.results[0].image.Id
- info_5.images[2].Id == pulled_images.results[1].image.Id - info_5.images[2].Id == pulled_images.results[1].image.Id
- info_5.images[3].Id == pulled_images.results[0].image.Id - info_5.images[3].Id == pulled_images.results[0].image.Id
- tag_5_check == tag_5 - tag_5_check | internal__normalize_image("image") == tag_5 | internal__normalize_image("image")
- name: Tag image 2 (idempotent, check mode) - name: Tag image 2 (idempotent, check mode)
docker_image_tag: docker_image_tag:
@ -249,7 +249,7 @@
- tag_6 is not changed - tag_6 is not changed
- tag_6.diff.before == tag_6.diff.after - tag_6.diff.before == tag_6.diff.after
- tag_6.diff.before.images | length == 3 - tag_6.diff.before.images | length == 3
- tag_6_check == tag_6 - tag_6_check | internal__normalize_image("image") == tag_6 | internal__normalize_image("image")
- name: Tag image 2 (only change wrong ones, check mode) - name: Tag image 2 (only change wrong ones, check mode)
docker_image_tag: docker_image_tag:
@ -296,7 +296,7 @@
- info_7.images[1].Id == pulled_images.results[1].image.Id - info_7.images[1].Id == pulled_images.results[1].image.Id
- info_7.images[2].Id == pulled_images.results[1].image.Id - info_7.images[2].Id == pulled_images.results[1].image.Id
- info_7.images[3].Id == pulled_images.results[0].image.Id - info_7.images[3].Id == pulled_images.results[0].image.Id
- tag_7_check == tag_7 - tag_7_check | internal__normalize_image("image") == tag_7 | internal__normalize_image("image")
- name: Tag image 2 (idempotent, check mode) - name: Tag image 2 (idempotent, check mode)
docker_image_tag: docker_image_tag:
@ -326,7 +326,7 @@
- tag_8 is not changed - tag_8 is not changed
- tag_8.diff.before == tag_8.diff.after - tag_8.diff.before == tag_8.diff.after
- tag_8.diff.before.images | length == 3 - tag_8.diff.before.images | length == 3
- tag_8_check == tag_8 - tag_8_check | internal__normalize_image("image") == tag_8 | internal__normalize_image("image")
- name: Tag image 3 (source image has digest) - name: Tag image 3 (source image has digest)
docker_image_tag: docker_image_tag:

View File

@ -0,0 +1,46 @@
# Copyright (c) 2026, Felix Fontein <felix@fontein.de>
# 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
from __future__ import annotations
from collections.abc import Mapping, Sequence
def _normalize_image_impl(data):
identity = data.get("Identity")
if not isinstance(identity, Mapping):
return data
pull = identity.get("Pull")
if not isinstance(pull, Sequence):
return data
new_identity = dict(identity)
new_identity["Pull"] = sorted(identity["Pull"], key=lambda entry: entry.get("Repository") or "")
new_data = dict(data)
new_data["Identity"] = new_identity
return new_data
def _process(data, place_parts, place_index, processor):
if place_index == len(place_parts):
return processor(data)
new_data = dict(data)
new_data[place_parts[place_index]] = _process(data[place_parts[place_index]], place_parts, place_index + 1, processor)
return new_data
def normalize_image(data, *places):
if not places:
return _normalize_image_impl(data)
for place in places:
data = _process(data, place.split("."), 0, _normalize_image_impl)
return data
class FilterModule:
"""Utilities for community.docker tests."""
def filters(self):
return {
'internal__normalize_image': normalize_image,
}

View File

@ -0,0 +1,4 @@
---
# 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