From 13c5a816ef94110101cfd4df37cad8cf5ac09f95 Mon Sep 17 00:00:00 2001 From: "d.kovalenko" Date: Thu, 2 Apr 2026 09:26:54 +0300 Subject: [PATCH] New test with complex envs via "--metadata-from-json" option --- tests/integration/e2eworkspace.py | 21 +++++++- tests/integration/test_set002__e2e.py | 69 ++++++++++++++++++++++++++- 2 files changed, 87 insertions(+), 3 deletions(-) diff --git a/tests/integration/e2eworkspace.py b/tests/integration/e2eworkspace.py index f5e3ece..15818d2 100644 --- a/tests/integration/e2eworkspace.py +++ b/tests/integration/e2eworkspace.py @@ -5,6 +5,8 @@ import tempfile import subprocess import logging +import typing + from pathlib import Path # ///////////////////////////////////////////////////////////////////////////// @@ -22,7 +24,14 @@ def cleanup(self): if self.root.exists(): shutil.rmtree(self.root) - def generate_report(self, name: str, test_code: str, metadata: dict = None): + def generate_report( + self, + name: str, + test_code: str, + metadata: typing.Optional[ + typing.Union[typing.Dict[str, typing.Any], str] + ] = None, + ) -> str: test_file = self.root / f"test_{name}.py" test_file.write_text(test_code) @@ -42,9 +51,17 @@ def generate_report(self, name: str, test_code: str, metadata: dict = None): str(test_file), ] - if metadata: + if metadata is None: + pass + elif type(metadata) is str: + cmd.extend(["--metadata-from-json", metadata]) + elif type(metadata) is dict: for k, v in metadata.items(): cmd.extend(["--metadata", str(k), str(v)]) + else: + raise RuntimeError( + "Unsupported metadata type [{}].".format(type(metadata).__name__) + ) result = subprocess.run(cmd, capture_output=True, text=True) diff --git a/tests/integration/test_set002__e2e.py b/tests/integration/test_set002__e2e.py index 63ae496..2bc42ba 100644 --- a/tests/integration/test_set002__e2e.py +++ b/tests/integration/test_set002__e2e.py @@ -4,6 +4,7 @@ import typing import bs4 import re +import json from packaging.version import Version @@ -953,7 +954,7 @@ def test_e2e_006__merge_conflicting_metadata(): # ------------------------------------------------------------------------ -def test_e2e_007__merge_nested_metadata_extension(): +def test_e2e_007__merge_nested_metadata_extension__via_tests(): """ Verify that nested dictionaries (like PgProBackup or Packages) are extended, not overwritten, when merging two reports. @@ -1012,4 +1013,70 @@ def test_b(request): return +# ------------------------------------------------------------------------ +def test_e2e_008__merge_nested_metadata_extension__via_cmdline(): + """ + Verify that nested dictionaries (like PgProBackup or Packages) + are extended, not overwritten, when merging two reports. + """ + ws = E2EWorkspace(prefix="e2e_nested_merge_") + try: + # 1. Report from Test A: Basic environment and some packages + # We use a pytest_configure hook to inject complex dicts into metadata + metadata_a = { + "Packages": {"pytest": "8.3.4", "pluggy": "1.5.0"}, + "PgProBackup": {"Binary": "pg_probackup3", "Version": "3.3.0"}, + } + code_a = """ +def test_a(request): + assert True +""" + ws.generate_report( + "run_a", + code_a, + metadata=json.dumps(metadata_a), + ) + + # 2. Report from Test B: Adding 'testgres' and extra backup info + code_b = """ +def test_b(request): + assert True +""" + metadata_b = { + "Packages": {"testgres": "1.10.0"}, + "PgProBackup": {"Src Commit ID": "70fa46d35b12a"}, + } + ws.generate_report( + "run_b", + code_b, + metadata=json.dumps(metadata_b), + ) + + # 3. Merge them + output_html = ws.root / "merged_complex.html" + result = ws.run_merger(["-i", str(ws.reports_dir), "-o", str(output_html)]) + + # 4. Assertions + assert result.returncode == 0 + content = output_html.read_text() + + # Check Packages: must contain all three! + assert "pytest" in content + assert "8.3.4" in content + assert "testgres" in content + assert "1.10.0" in content + + # Check PgProBackup: must be merged into one block + assert "Binary" in content + assert "pg_probackup3" in content + assert "Src Commit ID" in content + assert "70fa46d35b12a" in content + + finally: + pass + + ws.cleanup() + return + + # //////////////////////////////////////////////////////////////////////////////