Files
microsoft--agent-framework/python/scripts/dependencies/tests/test_dependency_bounds_release.py
T
Evan Mattson e90b6de5a7 Python: Improve python package management operations (#7274)
* improve package mgmt timings

* Address Python release validation review feedback
2026-07-23 22:14:10 +00:00

218 lines
6.6 KiB
Python

# Copyright (c) Microsoft. All rights reserved.
import json
import sys
from pathlib import Path
from subprocess import CompletedProcess
import pytest
from scripts.dependencies._dependency_bounds_release_impl import (
_PROBE_RESULT_PREFIX,
ReleaseProbePlan,
_build_release_probe_command,
_build_release_probe_plan,
_build_release_project_map,
_changed_release_project_paths,
_parse_probe_payload,
run_release_mode,
)
from scripts.dependencies.validate_dependency_bounds import main
def _write_project(path: Path, content: str) -> None:
path.mkdir(parents=True, exist_ok=True)
(path / "pyproject.toml").write_text(content)
def test_release_probe_uses_only_the_required_internal_dependency_closure(tmp_path: Path) -> None:
_write_project(
tmp_path,
"""
[project]
name = "agent-framework"
version = "1.2.0"
requires-python = ">=3.10"
dependencies = ["agent-framework-core[all]==1.2.0"]
[tool.uv.workspace]
members = ["packages/*"]
[tool.flit.module]
name = "agent_framework_meta"
""",
)
_write_project(
tmp_path / "packages/core",
"""
[project]
name = "agent-framework-core"
version = "1.2.0"
requires-python = ">=3.10"
dependencies = ["pydantic>=2,<3"]
[project.optional-dependencies]
all = ["agent-framework-connector>=1,<2"]
dev = ["pytest>=9"]
[tool.flit.module]
name = "agent_framework"
""",
)
_write_project(
tmp_path / "packages/connector",
"""
[project]
name = "agent-framework-connector"
version = "1.0.0"
requires-python = ">=3.10"
dependencies = ["agent-framework-core>=1,<2", "httpx>=0.27,<1"]
[tool.flit.module]
name = "agent_framework_connector"
""",
)
_write_project(
tmp_path / "packages/provider",
"""
[project]
name = "agent-framework-provider"
version = "1.0.0"
requires-python = ">=3.11"
dependencies = ["agent-framework-core>=1,<2", "openai>=2,<3"]
[tool.flit.module]
name = "agent_framework_provider"
""",
)
projects = _build_release_project_map(tmp_path)
provider_plan = _build_release_probe_plan(tmp_path, projects["agent-framework-provider"], projects)
provider_editables = "\n".join(provider_plan.editable_specs)
assert "packages/provider" in provider_editables
assert "packages/core" in provider_editables
assert "packages/connector" not in provider_editables
assert provider_plan.python_version == "3.11"
root_plan = _build_release_probe_plan(tmp_path, projects["agent-framework"], projects)
root_editables = "\n".join(root_plan.editable_specs)
assert "packages/core" in root_editables
assert "packages/connector" in root_editables
assert "pytest" not in root_plan.reported_distributions
assert root_plan.python_version == "3.10"
def test_release_probe_command_is_lock_independent_and_uses_bound_resolution(tmp_path: Path) -> None:
plan = ReleaseProbePlan(
project_path=Path("packages/openai"),
package_name="agent-framework-openai",
editable_specs=(str(tmp_path / "packages/openai"), str(tmp_path / "packages/core")),
import_modules=("agent_framework_openai",),
reported_distributions=("agent-framework-openai", "openai"),
python_version="3.11",
)
command = _build_release_probe_command(plan, resolution="lowest-direct")
assert "--no-project" in command
assert command[command.index("--resolution") + 1] == "lowest-direct"
assert command[command.index("--python") + 1] == "3.11"
assert command[command.index("--prerelease") + 1] == "if-necessary-or-explicit"
assert command.count("--with-editable") == 2
assert "pytest" not in command
assert "pyright" not in command
overridden_command = _build_release_probe_command(plan, resolution="highest", python_override="3.12")
assert overridden_command[overridden_command.index("--python") + 1] == "3.12"
def test_changed_release_projects_are_relative_to_python_workspace(tmp_path: Path, monkeypatch) -> None:
def fake_run(*args, **kwargs) -> CompletedProcess[str]:
return CompletedProcess(
args=args[0],
returncode=0,
stdout="pyproject.toml\npackages/core/pyproject.toml\nREADME.md\n",
stderr="",
)
monkeypatch.setattr("scripts.dependencies._dependency_bounds_release_impl.subprocess.run", fake_run)
assert _changed_release_project_paths(tmp_path, "upstream/main") == {Path("."), Path("packages/core")}
def test_parse_probe_payload_uses_the_last_valid_marker() -> None:
first_payload = json.dumps({"versions": {"openai": "2.25.0"}})
last_payload = {"imports": ["agent_framework_openai"], "versions": {"openai": "2.47.0"}}
stdout = "\n".join((
f"{_PROBE_RESULT_PREFIX}{first_payload}",
"unrelated subprocess output",
f"{_PROBE_RESULT_PREFIX}{json.dumps(last_payload)}",
))
assert _parse_probe_payload(stdout) == last_payload
assert _parse_probe_payload(f"{_PROBE_RESULT_PREFIX}not-json") is None
assert _parse_probe_payload(f"{_PROBE_RESULT_PREFIX}[]") is None
assert _parse_probe_payload("unrelated subprocess output") is None
def test_run_release_mode_dry_run_uses_selected_package_python_floor(tmp_path: Path) -> None:
_write_project(
tmp_path,
"""
[project]
name = "agent-framework"
version = "1.2.0"
requires-python = ">=3.10"
dependencies = []
[tool.uv.workspace]
members = ["packages/*"]
[tool.flit.module]
name = "agent_framework_meta"
""",
)
_write_project(
tmp_path / "packages/provider",
"""
[project]
name = "agent-framework-provider"
version = "1.0.0"
requires-python = ">=3.11"
dependencies = []
[tool.flit.module]
name = "agent_framework_provider"
""",
)
output_json = tmp_path / "release-results.json"
exit_code = run_release_mode(
workspace_root=tmp_path,
base_ref="HEAD",
package_filter="provider",
parallelism=2,
python_override=None,
deadline_seconds=300,
dry_run=True,
output_json=output_json,
)
assert exit_code == 0
report = json.loads(output_json.read_text())
assert report["python_override"] is None
assert report["summary"] == {"probes_total": 2, "probes_passed": 2, "probes_failed": 0}
assert {probe["python"] for probe in report["probes"]} == {"3.11"}
assert {probe["status"] for probe in report["probes"]} == {"dry-run"}
def test_release_mode_rejects_blank_base_ref(monkeypatch, capsys) -> None:
monkeypatch.setattr(sys, "argv", ["validate_dependency_bounds", "--mode", "release", "--base-ref", " "])
with pytest.raises(SystemExit) as exc_info:
main()
assert exc_info.value.code == 2
assert "release mode requires --base-ref" in capsys.readouterr().err