mirror of
https://github.com/ansible-collections/community.docker.git
synced 2025-12-15 11:32:05 +00:00
* Remove long deprecated version fields. * Add first JSON event parsing tests. * Improve image layer event parsing for Compose 5+. * Add 'Working' to image working actions. * Add changelog fragment. * Shorten lines. * Adjust docker_compose_v2_run tests.
593 lines
20 KiB
Python
593 lines
20 KiB
Python
# Copyright 2022 Red Hat | Ansible
|
|
# 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
|
|
|
|
import pytest
|
|
|
|
from ansible_collections.community.docker.plugins.module_utils._compose_v2 import (
|
|
Event,
|
|
parse_events,
|
|
parse_json_events,
|
|
)
|
|
|
|
from .compose_v2_test_cases import EVENT_TEST_CASES
|
|
|
|
|
|
EXTRA_TEST_CASES: list[tuple[str, str, bool, bool, str, list[Event], list[str]]] = [
|
|
(
|
|
"2.24.2-manual-build-dry-run",
|
|
"2.24.2",
|
|
True,
|
|
False,
|
|
" DRY-RUN MODE - build service foobar \n"
|
|
" DRY-RUN MODE - ==> ==> writing image dryRun-8843d7f92416211de9ebb963ff4ce28125932878 \n"
|
|
" DRY-RUN MODE - ==> ==> naming to my-python \n"
|
|
" DRY-RUN MODE - Network compose_default Creating\n"
|
|
" DRY-RUN MODE - Network compose_default Created\n"
|
|
" DRY-RUN MODE - Container compose-foobar-1 Creating\n"
|
|
" DRY-RUN MODE - Container compose-foobar-1 Created\n"
|
|
" DRY-RUN MODE - Container ompose-foobar-1 Starting\n"
|
|
" DRY-RUN MODE - Container ompose-foobar-1 Started\n",
|
|
[
|
|
Event(
|
|
"service",
|
|
"foobar",
|
|
"Building",
|
|
None,
|
|
),
|
|
Event(
|
|
"network",
|
|
"compose_default",
|
|
"Creating",
|
|
None,
|
|
),
|
|
Event(
|
|
"network",
|
|
"compose_default",
|
|
"Created",
|
|
None,
|
|
),
|
|
Event(
|
|
"container",
|
|
"compose-foobar-1",
|
|
"Creating",
|
|
None,
|
|
),
|
|
Event(
|
|
"container",
|
|
"compose-foobar-1",
|
|
"Created",
|
|
None,
|
|
),
|
|
Event(
|
|
"container",
|
|
"ompose-foobar-1",
|
|
"Starting",
|
|
None,
|
|
),
|
|
Event(
|
|
"container",
|
|
"ompose-foobar-1",
|
|
"Started",
|
|
None,
|
|
),
|
|
],
|
|
[],
|
|
),
|
|
(
|
|
# https://github.com/ansible-collections/community.docker/issues/785
|
|
"2.20.0-manual-pull",
|
|
"2.20.0",
|
|
False,
|
|
False,
|
|
"4f4fb700ef54 Waiting\n"
|
|
"238022553356 Downloading 541B/541B\n"
|
|
"972e292d3a60 Downloading 106kB/10.43MB\n"
|
|
"f2543dc9f0a9 Downloading 25.36kB/2.425MB\n"
|
|
"972e292d3a60 Downloading 5.925MB/10.43MB\n"
|
|
"f2543dc9f0a9 Downloading 2.219MB/2.425MB\n"
|
|
"f2543dc9f0a9 Extracting 32.77kB/2.425MB\n"
|
|
"4f4fb700ef54 Downloading 32B/32B\n"
|
|
"f2543dc9f0a9 Extracting 2.425MB/2.425MB\n"
|
|
"972e292d3a60 Extracting 131.1kB/10.43MB\n"
|
|
"972e292d3a60 Extracting 10.43MB/10.43MB\n"
|
|
"238022553356 Extracting 541B/541B\n"
|
|
"4f4fb700ef54 Extracting 32B/32B\n",
|
|
[
|
|
Event(
|
|
"image-layer",
|
|
"4f4fb700ef54",
|
|
"Waiting",
|
|
None,
|
|
),
|
|
Event(
|
|
"image-layer",
|
|
"238022553356",
|
|
"Downloading",
|
|
None,
|
|
),
|
|
Event(
|
|
"image-layer",
|
|
"972e292d3a60",
|
|
"Downloading",
|
|
None,
|
|
),
|
|
Event(
|
|
"image-layer",
|
|
"f2543dc9f0a9",
|
|
"Downloading",
|
|
None,
|
|
),
|
|
Event(
|
|
"image-layer",
|
|
"972e292d3a60",
|
|
"Downloading",
|
|
None,
|
|
),
|
|
Event(
|
|
"image-layer",
|
|
"f2543dc9f0a9",
|
|
"Downloading",
|
|
None,
|
|
),
|
|
Event(
|
|
"image-layer",
|
|
"f2543dc9f0a9",
|
|
"Extracting",
|
|
None,
|
|
),
|
|
Event(
|
|
"image-layer",
|
|
"4f4fb700ef54",
|
|
"Downloading",
|
|
None,
|
|
),
|
|
Event(
|
|
"image-layer",
|
|
"f2543dc9f0a9",
|
|
"Extracting",
|
|
None,
|
|
),
|
|
Event(
|
|
"image-layer",
|
|
"972e292d3a60",
|
|
"Extracting",
|
|
None,
|
|
),
|
|
Event(
|
|
"image-layer",
|
|
"972e292d3a60",
|
|
"Extracting",
|
|
None,
|
|
),
|
|
Event(
|
|
"image-layer",
|
|
"238022553356",
|
|
"Extracting",
|
|
None,
|
|
),
|
|
Event(
|
|
"image-layer",
|
|
"4f4fb700ef54",
|
|
"Extracting",
|
|
None,
|
|
),
|
|
],
|
|
[],
|
|
),
|
|
(
|
|
# https://github.com/ansible-collections/community.docker/issues/787
|
|
"2.20.3-logrus-warn",
|
|
"2.20.3",
|
|
False,
|
|
False,
|
|
'time="2024-02-02T08:14:10+01:00" level=warning msg="a network with name influxNetwork exists but was not'
|
|
' created for project \\"influxdb\\".\\nSet `external: true` to use an existing network"\n',
|
|
[],
|
|
[
|
|
'a network with name influxNetwork exists but was not created for project "influxdb".\nSet `external: true` to use an existing network',
|
|
],
|
|
),
|
|
(
|
|
# https://github.com/ansible-collections/community.docker/issues/807
|
|
"2.20.3-image-warning-error",
|
|
"2.20.3",
|
|
False,
|
|
True,
|
|
" dummy3 Warning \n"
|
|
" dummy2 Warning \n"
|
|
" dummy Error \n"
|
|
" dummy4 Warning Foo bar \n"
|
|
" dummy5 Error Bar baz bam \n",
|
|
[
|
|
Event(
|
|
"unknown",
|
|
"dummy",
|
|
"Error",
|
|
None,
|
|
),
|
|
Event(
|
|
"unknown",
|
|
"dummy5",
|
|
"Error",
|
|
"Bar baz bam",
|
|
),
|
|
],
|
|
[
|
|
"Unspecified warning for dummy3",
|
|
"Unspecified warning for dummy2",
|
|
"dummy4: Foo bar",
|
|
],
|
|
),
|
|
(
|
|
# https://github.com/ansible-collections/community.docker/issues/911
|
|
"2.28.1-image-pull-skipped",
|
|
"2.28.1",
|
|
False,
|
|
False,
|
|
# fmt: off
|
|
" bash_1 Skipped \n bash_2 Pulling \n bash_2 Pulled \n",
|
|
# fmt: on
|
|
[
|
|
Event(
|
|
"unknown",
|
|
"bash_1",
|
|
"Skipped",
|
|
None,
|
|
),
|
|
Event(
|
|
"service",
|
|
"bash_2",
|
|
"Pulling",
|
|
None,
|
|
),
|
|
Event(
|
|
"service",
|
|
"bash_2",
|
|
"Pulled",
|
|
None,
|
|
),
|
|
],
|
|
[],
|
|
),
|
|
(
|
|
# https://github.com/ansible-collections/community.docker/issues/948
|
|
"2.28.1-unknown", # TODO: find out actual version!
|
|
"2.28.1", # TODO: find out actual version!
|
|
False,
|
|
True,
|
|
" prometheus Pulling \n"
|
|
" prometheus Pulled \n"
|
|
'network internet-monitoring-front-tier was found but has incorrect label com.docker.compose.network set to "internet-monitoring-front-tier"\n',
|
|
[
|
|
Event(
|
|
"service",
|
|
"prometheus",
|
|
"Pulling",
|
|
None,
|
|
),
|
|
Event(
|
|
"service",
|
|
"prometheus",
|
|
"Pulled",
|
|
None,
|
|
),
|
|
Event(
|
|
"unknown",
|
|
"",
|
|
"Error",
|
|
'network internet-monitoring-front-tier was found but has incorrect label com.docker.compose.network set to "internet-monitoring-front-tier"',
|
|
),
|
|
],
|
|
[],
|
|
),
|
|
(
|
|
# https://github.com/ansible-collections/community.docker/issues/978
|
|
"2.28.1-unknown", # TODO: find out actual version!
|
|
"2.28.1", # TODO: find out actual version!
|
|
False,
|
|
True,
|
|
" Network create_users_db_default Creating\n"
|
|
" Network create_users_db_default Created\n"
|
|
" Container create_users_db-init Creating\n"
|
|
" Container create_users_db-init Created\n"
|
|
" Container create_users_db-init Starting\n"
|
|
" Container create_users_db-init Started\n"
|
|
" Container create_users_db-init Waiting\n"
|
|
"container create_users_db-init exited (0)\n",
|
|
[
|
|
Event(
|
|
"network",
|
|
"create_users_db_default",
|
|
"Creating",
|
|
None,
|
|
),
|
|
Event(
|
|
"network",
|
|
"create_users_db_default",
|
|
"Created",
|
|
None,
|
|
),
|
|
Event(
|
|
"container",
|
|
"create_users_db-init",
|
|
"Creating",
|
|
None,
|
|
),
|
|
Event(
|
|
"container",
|
|
"create_users_db-init",
|
|
"Created",
|
|
None,
|
|
),
|
|
Event(
|
|
"container",
|
|
"create_users_db-init",
|
|
"Starting",
|
|
None,
|
|
),
|
|
Event(
|
|
"container",
|
|
"create_users_db-init",
|
|
"Started",
|
|
None,
|
|
),
|
|
Event(
|
|
"container",
|
|
"create_users_db-init",
|
|
"Waiting",
|
|
None,
|
|
),
|
|
Event(
|
|
"unknown",
|
|
"",
|
|
"Error",
|
|
"container create_users_db-init exited (0)",
|
|
),
|
|
],
|
|
[],
|
|
),
|
|
]
|
|
|
|
_ALL_TEST_CASES = EVENT_TEST_CASES + EXTRA_TEST_CASES
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"test_id, compose_version, dry_run, nonzero_rc, stderr, events, warnings",
|
|
_ALL_TEST_CASES,
|
|
ids=[tc[0] for tc in _ALL_TEST_CASES],
|
|
)
|
|
def test_parse_events(
|
|
test_id: str,
|
|
compose_version: str,
|
|
dry_run: bool,
|
|
nonzero_rc: bool,
|
|
stderr: str,
|
|
events: list[Event],
|
|
warnings: list[str],
|
|
) -> None:
|
|
collected_warnings = []
|
|
|
|
def collect_warning(msg: str) -> None:
|
|
collected_warnings.append(msg)
|
|
|
|
collected_events = parse_events(
|
|
stderr.encode("utf-8"),
|
|
dry_run=dry_run,
|
|
warn_function=collect_warning,
|
|
nonzero_rc=nonzero_rc,
|
|
)
|
|
|
|
print(collected_events)
|
|
print(collected_warnings)
|
|
|
|
assert collected_events == events
|
|
assert collected_warnings == warnings
|
|
|
|
|
|
JSON_TEST_CASES: list[tuple[str, str, str, list[Event], list[str]]] = [
|
|
(
|
|
"pull-compose-2",
|
|
"2.40.3",
|
|
'{"level":"warning","msg":"/tmp/ansible.f9pcm_i3.test/ansible-docker-test-3c46cd06-pull/docker-compose.yml: the attribute `version`'
|
|
' is obsolete, it will be ignored, please remove it to avoid potential confusion","time":"2025-12-06T13:16:30Z"}\n'
|
|
'{"id":"ansible-docker-test-3c46cd06-cont","text":"Pulling"}\n'
|
|
'{"id":"63a26ae4e8a8","parent_id":"ansible-docker-test-3c46cd06-cont","text":"Pulling fs layer"}\n'
|
|
'{"id":"63a26ae4e8a8","parent_id":"ansible-docker-test-3c46cd06-cont","text":"Downloading","status":"[\\u003e '
|
|
' ] 6.89kB/599.9kB","current":6890,"total":599883,"percent":1}\n'
|
|
'{"id":"63a26ae4e8a8","parent_id":"ansible-docker-test-3c46cd06-cont","text":"Download complete","percent":100}\n'
|
|
'{"id":"63a26ae4e8a8","parent_id":"ansible-docker-test-3c46cd06-cont","text":"Extracting","status":"[==\\u003e '
|
|
' ] 32.77kB/599.9kB","current":32768,"total":599883,"percent":5}\n'
|
|
'{"id":"63a26ae4e8a8","parent_id":"ansible-docker-test-3c46cd06-cont","text":"Extracting","status":"[============'
|
|
'======================================\\u003e] 599.9kB/599.9kB","current":599883,"total":599883,"percent":100}\n'
|
|
'{"id":"63a26ae4e8a8","parent_id":"ansible-docker-test-3c46cd06-cont","text":"Extracting","status":"[============'
|
|
'======================================\\u003e] 599.9kB/599.9kB","current":599883,"total":599883,"percent":100}\n'
|
|
'{"id":"63a26ae4e8a8","parent_id":"ansible-docker-test-3c46cd06-cont","text":"Pull complete","percent":100}\n'
|
|
'{"id":"ansible-docker-test-3c46cd06-cont","text":"Pulled"}\n',
|
|
[
|
|
Event(
|
|
"unknown",
|
|
None,
|
|
"Warning",
|
|
"/tmp/ansible.f9pcm_i3.test/ansible-docker-test-3c46cd06-pull/docker-compose.yml: the attribute `version` is obsolete,"
|
|
" it will be ignored, please remove it to avoid potential confusion",
|
|
),
|
|
Event(
|
|
"image",
|
|
"ansible-docker-test-3c46cd06-cont",
|
|
"Pulling",
|
|
None,
|
|
),
|
|
Event(
|
|
"image-layer",
|
|
"63a26ae4e8a8",
|
|
"Pulling fs layer",
|
|
None,
|
|
),
|
|
Event(
|
|
"image-layer",
|
|
"63a26ae4e8a8",
|
|
"Downloading",
|
|
"[> ] 6.89kB/599.9kB",
|
|
),
|
|
Event(
|
|
"image-layer",
|
|
"63a26ae4e8a8",
|
|
"Download complete",
|
|
None,
|
|
),
|
|
Event(
|
|
"image-layer",
|
|
"63a26ae4e8a8",
|
|
"Extracting",
|
|
"[==> ] 32.77kB/599.9kB",
|
|
),
|
|
Event(
|
|
"image-layer",
|
|
"63a26ae4e8a8",
|
|
"Extracting",
|
|
"[==================================================>] 599.9kB/599.9kB",
|
|
),
|
|
Event(
|
|
"image-layer",
|
|
"63a26ae4e8a8",
|
|
"Extracting",
|
|
"[==================================================>] 599.9kB/599.9kB",
|
|
),
|
|
Event(
|
|
"image-layer",
|
|
"63a26ae4e8a8",
|
|
"Pull complete",
|
|
None,
|
|
),
|
|
Event(
|
|
"image",
|
|
"ansible-docker-test-3c46cd06-cont",
|
|
"Pulled",
|
|
None,
|
|
),
|
|
],
|
|
[],
|
|
),
|
|
(
|
|
"pull-compose-5",
|
|
"5.0.0",
|
|
'{"level":"warning","msg":"/tmp/ansible.1n0q46aj.test/ansible-docker-test-b2fa9191-pull/docker-compose.yml: the attribute'
|
|
' `version` is obsolete, it will be ignored, please remove it to avoid potential confusion","time":"2025-12-06T13:08:22Z"}\n'
|
|
'{"id":"Image ghcr.io/ansible-collections/simple-1:tag","status":"Working","text":"Pulling"}\n'
|
|
'{"id":"63a26ae4e8a8","parent_id":"Image ghcr.io/ansible-collections/simple-1:tag","status":"Working"}\n'
|
|
'{"id":"63a26ae4e8a8","parent_id":"Image ghcr.io/ansible-collections/simple-1:tag","status":"Working","text":"[\\u003e '
|
|
' ] 6.89kB/599.9kB","current":6890,"total":599883,"percent":1}\n'
|
|
'{"id":"63a26ae4e8a8","parent_id":"Image ghcr.io/ansible-collections/simple-1:tag","status":"Working","text":"[=============='
|
|
'====================================\\u003e] 599.9kB/599.9kB","current":599883,"total":599883,"percent":100}\n'
|
|
'{"id":"63a26ae4e8a8","parent_id":"Image ghcr.io/ansible-collections/simple-1:tag","status":"Working"}\n'
|
|
'{"id":"63a26ae4e8a8","parent_id":"Image ghcr.io/ansible-collections/simple-1:tag","status":"Done","percent":100}\n'
|
|
'{"id":"63a26ae4e8a8","parent_id":"Image ghcr.io/ansible-collections/simple-1:tag","status":"Working","text":"[==\\u003e '
|
|
' ] 32.77kB/599.9kB","current":32768,"total":599883,"percent":5}\n'
|
|
'{"id":"63a26ae4e8a8","parent_id":"Image ghcr.io/ansible-collections/simple-1:tag","status":"Working","text":"[=============='
|
|
'====================================\\u003e] 599.9kB/599.9kB","current":599883,"total":599883,"percent":100}\n'
|
|
'{"id":"63a26ae4e8a8","parent_id":"Image ghcr.io/ansible-collections/simple-1:tag","status":"Working","text":"[=============='
|
|
'====================================\\u003e] 599.9kB/599.9kB","current":599883,"total":599883,"percent":100}\n'
|
|
'{"id":"63a26ae4e8a8","parent_id":"Image ghcr.io/ansible-collections/simple-1:tag","status":"Done","percent":100}\n'
|
|
'{"id":"Image ghcr.io/ansible-collections/simple-1:tag","status":"Done","text":"Pulled"}\n',
|
|
[
|
|
Event(
|
|
"unknown",
|
|
None,
|
|
"Warning",
|
|
"/tmp/ansible.1n0q46aj.test/ansible-docker-test-b2fa9191-pull/docker-compose.yml: the attribute `version`"
|
|
" is obsolete, it will be ignored, please remove it to avoid potential confusion",
|
|
),
|
|
Event(
|
|
"image",
|
|
"ghcr.io/ansible-collections/simple-1:tag",
|
|
"Pulling",
|
|
"Working",
|
|
),
|
|
Event(
|
|
"image-layer",
|
|
"ghcr.io/ansible-collections/simple-1:tag",
|
|
"Working",
|
|
None,
|
|
),
|
|
Event(
|
|
"image-layer",
|
|
"ghcr.io/ansible-collections/simple-1:tag",
|
|
"Working",
|
|
"[> ] 6.89kB/599.9kB",
|
|
),
|
|
Event(
|
|
"image-layer",
|
|
"ghcr.io/ansible-collections/simple-1:tag",
|
|
"Working",
|
|
"[==================================================>] 599.9kB/599.9kB",
|
|
),
|
|
Event(
|
|
"image-layer",
|
|
"ghcr.io/ansible-collections/simple-1:tag",
|
|
"Working",
|
|
None,
|
|
),
|
|
Event(
|
|
"image-layer", "ghcr.io/ansible-collections/simple-1:tag", "Done", None
|
|
),
|
|
Event(
|
|
"image-layer",
|
|
"ghcr.io/ansible-collections/simple-1:tag",
|
|
"Working",
|
|
"[==> ] 32.77kB/599.9kB",
|
|
),
|
|
Event(
|
|
"image-layer",
|
|
"ghcr.io/ansible-collections/simple-1:tag",
|
|
"Working",
|
|
"[==================================================>] 599.9kB/599.9kB",
|
|
),
|
|
Event(
|
|
"image-layer",
|
|
"ghcr.io/ansible-collections/simple-1:tag",
|
|
"Working",
|
|
"[==================================================>] 599.9kB/599.9kB",
|
|
),
|
|
Event(
|
|
"image-layer", "ghcr.io/ansible-collections/simple-1:tag", "Done", None
|
|
),
|
|
Event(
|
|
"image", "ghcr.io/ansible-collections/simple-1:tag", "Pulled", "Done"
|
|
),
|
|
],
|
|
[],
|
|
),
|
|
]
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"test_id, compose_version, stderr, events, warnings",
|
|
JSON_TEST_CASES,
|
|
ids=[tc[0] for tc in JSON_TEST_CASES],
|
|
)
|
|
def test_parse_json_events(
|
|
test_id: str,
|
|
compose_version: str,
|
|
stderr: str,
|
|
events: list[Event],
|
|
warnings: list[str],
|
|
) -> None:
|
|
collected_warnings = []
|
|
|
|
def collect_warning(msg: str) -> None:
|
|
collected_warnings.append(msg)
|
|
|
|
collected_events = parse_json_events(
|
|
stderr.encode("utf-8"),
|
|
warn_function=collect_warning,
|
|
)
|
|
|
|
print(collected_events)
|
|
print(collected_warnings)
|
|
|
|
assert collected_events == events
|
|
assert collected_warnings == warnings
|