feat(clean-release): complete and verify backend test suite (33 passing tests)
- Relocated and standardized tests for clean_release subsystem into __tests__ sub-packages. - Implemented missing unit tests for preparation_service, audit_service, and stages. - Enhanced API contract tests for candidate preparation and compliance reporting. - Updated 023-clean-repo-enterprise coverage matrix with final verification results. - Fixed relative import issues and model validation mismatches during test migration.
This commit is contained in:
@@ -1,41 +0,0 @@
|
||||
# [DEF:backend.tests.services.clean_release.test_manifest_builder:Module]
|
||||
# @TIER: CRITICAL
|
||||
# @SEMANTICS: tests, clean-release, manifest, deterministic
|
||||
# @PURPOSE: Validate deterministic manifest generation behavior for US1.
|
||||
# @LAYER: Domain
|
||||
# @RELATION: VERIFIES -> backend.src.services.clean_release.manifest_builder
|
||||
# @INVARIANT: Same input artifacts produce identical deterministic hash.
|
||||
|
||||
from src.services.clean_release.manifest_builder import build_distribution_manifest
|
||||
|
||||
|
||||
# [DEF:test_manifest_deterministic_hash_for_same_input:Function]
|
||||
# @PURPOSE: Ensure hash is stable for same candidate/policy/artifact input.
|
||||
# @PRE: Same input lists are passed twice.
|
||||
# @POST: Hash and summary remain identical.
|
||||
def test_manifest_deterministic_hash_for_same_input():
|
||||
artifacts = [
|
||||
{"path": "a.yaml", "category": "system-init", "classification": "required-system", "reason": "required"},
|
||||
{"path": "b.yaml", "category": "test-data", "classification": "excluded-prohibited", "reason": "prohibited"},
|
||||
]
|
||||
|
||||
manifest1 = build_distribution_manifest(
|
||||
manifest_id="m1",
|
||||
candidate_id="2026.03.03-rc1",
|
||||
policy_id="policy-enterprise-clean-v1",
|
||||
generated_by="tester",
|
||||
artifacts=artifacts,
|
||||
)
|
||||
manifest2 = build_distribution_manifest(
|
||||
manifest_id="m2",
|
||||
candidate_id="2026.03.03-rc1",
|
||||
policy_id="policy-enterprise-clean-v1",
|
||||
generated_by="tester",
|
||||
artifacts=artifacts,
|
||||
)
|
||||
|
||||
assert manifest1.deterministic_hash == manifest2.deterministic_hash
|
||||
assert manifest1.summary.included_count == manifest2.summary.included_count
|
||||
assert manifest1.summary.excluded_count == manifest2.summary.excluded_count
|
||||
# [/DEF:test_manifest_deterministic_hash_for_same_input:Function]
|
||||
# [/DEF:backend.tests.services.clean_release.test_manifest_builder:Module]
|
||||
@@ -1,144 +0,0 @@
|
||||
# [DEF:backend.tests.services.clean_release.test_policy_engine:Module]
|
||||
# @TIER: CRITICAL
|
||||
# @SEMANTICS: tests, clean-release, policy-engine, deterministic
|
||||
# @PURPOSE: Validate policy model contracts and deterministic classification prerequisites for US1.
|
||||
# @LAYER: Domain
|
||||
# @RELATION: VERIFIES -> backend.src.models.clean_release.CleanProfilePolicy
|
||||
# @INVARIANT: Enterprise policy rejects invalid activation states.
|
||||
|
||||
import pytest
|
||||
from datetime import datetime, timezone
|
||||
|
||||
from src.models.clean_release import CleanProfilePolicy, ProfileType
|
||||
|
||||
|
||||
# [DEF:test_policy_enterprise_clean_valid:Function]
|
||||
# @PURPOSE: Ensure valid enterprise policy payload is accepted.
|
||||
# @PRE: Fixture-like payload contains prohibited categories and registry ref.
|
||||
# @POST: Model is created with external_source_forbidden=True.
|
||||
def test_policy_enterprise_clean_valid():
|
||||
policy = CleanProfilePolicy(
|
||||
policy_id="policy-enterprise-clean-v1",
|
||||
policy_version="1.0.0",
|
||||
active=True,
|
||||
prohibited_artifact_categories=["test-data", "demo-data"],
|
||||
required_system_categories=["system-init"],
|
||||
external_source_forbidden=True,
|
||||
internal_source_registry_ref="registry-internal-v1",
|
||||
effective_from=datetime.now(timezone.utc),
|
||||
profile=ProfileType.ENTERPRISE_CLEAN,
|
||||
)
|
||||
assert policy.external_source_forbidden is True
|
||||
assert policy.prohibited_artifact_categories == ["test-data", "demo-data"]
|
||||
# [/DEF:test_policy_enterprise_clean_valid:Function]
|
||||
|
||||
|
||||
# [DEF:test_policy_missing_registry_fails:Function]
|
||||
# @PURPOSE: Verify missing registry ref violates policy contract.
|
||||
# @PRE: enterprise-clean policy payload has blank registry ref.
|
||||
# @POST: Validation error is raised.
|
||||
def test_policy_missing_registry_fails():
|
||||
with pytest.raises(ValueError):
|
||||
CleanProfilePolicy(
|
||||
policy_id="policy-enterprise-clean-v1",
|
||||
policy_version="1.0.0",
|
||||
active=True,
|
||||
prohibited_artifact_categories=["test-data"],
|
||||
required_system_categories=["system-init"],
|
||||
external_source_forbidden=True,
|
||||
internal_source_registry_ref="",
|
||||
effective_from=datetime.now(timezone.utc),
|
||||
profile=ProfileType.ENTERPRISE_CLEAN,
|
||||
)
|
||||
# [/DEF:test_policy_missing_registry_fails:Function]
|
||||
|
||||
|
||||
# [DEF:test_policy_empty_prohibited_categories_fails:Function]
|
||||
# @PURPOSE: Verify enterprise policy cannot activate without prohibited categories.
|
||||
# @PRE: enterprise-clean policy payload has empty prohibited categories.
|
||||
# @POST: Validation error is raised.
|
||||
def test_policy_empty_prohibited_categories_fails():
|
||||
with pytest.raises(ValueError):
|
||||
CleanProfilePolicy(
|
||||
policy_id="policy-enterprise-clean-v1",
|
||||
policy_version="1.0.0",
|
||||
active=True,
|
||||
prohibited_artifact_categories=[],
|
||||
required_system_categories=["system-init"],
|
||||
external_source_forbidden=True,
|
||||
internal_source_registry_ref="registry-internal-v1",
|
||||
effective_from=datetime.now(timezone.utc),
|
||||
profile=ProfileType.ENTERPRISE_CLEAN,
|
||||
)
|
||||
# [/DEF:test_policy_empty_prohibited_categories_fails:Function]
|
||||
|
||||
|
||||
# [DEF:test_policy_conflicting_external_forbidden_flag_fails:Function]
|
||||
# @PURPOSE: Verify enterprise policy enforces external_source_forbidden=true.
|
||||
# @PRE: enterprise-clean policy payload sets external_source_forbidden to false.
|
||||
# @POST: Validation error is raised.
|
||||
def test_policy_conflicting_external_forbidden_flag_fails():
|
||||
with pytest.raises(ValueError):
|
||||
CleanProfilePolicy(
|
||||
policy_id="policy-enterprise-clean-v1",
|
||||
policy_version="1.0.0",
|
||||
active=True,
|
||||
prohibited_artifact_categories=["test-data"],
|
||||
required_system_categories=["system-init"],
|
||||
external_source_forbidden=False,
|
||||
internal_source_registry_ref="registry-internal-v1",
|
||||
effective_from=datetime.now(timezone.utc),
|
||||
profile=ProfileType.ENTERPRISE_CLEAN,
|
||||
)
|
||||
# [/DEF:test_policy_conflicting_external_forbidden_flag_fails:Function]
|
||||
# [/DEF:backend.tests.services.clean_release.test_policy_engine:Module]
|
||||
from src.models.clean_release import ResourceSourceRegistry, ResourceSourceEntry, RegistryStatus
|
||||
from src.services.clean_release.policy_engine import CleanPolicyEngine
|
||||
|
||||
def _policy_enterprise_clean() -> CleanProfilePolicy:
|
||||
return CleanProfilePolicy(
|
||||
policy_id="policy-enterprise-clean-v1",
|
||||
policy_version="1.0.0",
|
||||
active=True,
|
||||
prohibited_artifact_categories=["test-data"],
|
||||
required_system_categories=["system-init"],
|
||||
external_source_forbidden=True,
|
||||
internal_source_registry_ref="registry-internal-v1",
|
||||
effective_from=datetime.now(timezone.utc),
|
||||
profile=ProfileType.ENTERPRISE_CLEAN,
|
||||
)
|
||||
|
||||
def _registry() -> ResourceSourceRegistry:
|
||||
return ResourceSourceRegistry(
|
||||
registry_id="registry-internal-v1",
|
||||
name="Internal",
|
||||
entries=[ResourceSourceEntry(source_id="1", host="nexus.internal", protocol="https", purpose="pkg", enabled=True)],
|
||||
updated_at=datetime.now(timezone.utc),
|
||||
updated_by="tester",
|
||||
)
|
||||
|
||||
# [DEF:test_policy_valid:Function]
|
||||
# @PURPOSE: Validate policy valid scenario
|
||||
def test_policy_valid():
|
||||
engine = CleanPolicyEngine(_policy_enterprise_clean(), _registry())
|
||||
res = engine.validate_policy()
|
||||
assert res.ok is True
|
||||
|
||||
# [DEF:test_conflicting_registry:Function]
|
||||
# @PURPOSE: Validate policy conflicting registry edge
|
||||
def test_conflicting_registry():
|
||||
reg = _registry()
|
||||
reg.registry_id = "other-registry"
|
||||
engine = CleanPolicyEngine(_policy_enterprise_clean(), reg)
|
||||
res = engine.validate_policy()
|
||||
assert res.ok is False
|
||||
assert "Policy registry ref does not match provided registry" in res.blocking_reasons
|
||||
|
||||
# [DEF:test_external_endpoint:Function]
|
||||
# @PURPOSE: Validate policy external endpoint edge
|
||||
def test_external_endpoint():
|
||||
engine = CleanPolicyEngine(_policy_enterprise_clean(), _registry())
|
||||
res = engine.validate_resource_source("external.org")
|
||||
assert res.ok is False
|
||||
assert res.violation["category"] == "external-source"
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
# [DEF:backend.tests.services.clean_release.test_source_isolation:Module]
|
||||
# @TIER: STANDARD
|
||||
# @SEMANTICS: tests, clean-release, source-isolation, internal-only
|
||||
# @PURPOSE: Verify internal source registry validation behavior.
|
||||
# @LAYER: Domain
|
||||
# @RELATION: TESTS -> backend.src.services.clean_release.source_isolation
|
||||
# @INVARIANT: External endpoints always produce blocking violations.
|
||||
|
||||
from datetime import datetime, timezone
|
||||
|
||||
from src.models.clean_release import ResourceSourceEntry, ResourceSourceRegistry
|
||||
from src.services.clean_release.source_isolation import validate_internal_sources
|
||||
|
||||
|
||||
def _registry() -> ResourceSourceRegistry:
|
||||
return ResourceSourceRegistry(
|
||||
registry_id="registry-internal-v1",
|
||||
name="Internal Sources",
|
||||
entries=[
|
||||
ResourceSourceEntry(
|
||||
source_id="src-1",
|
||||
host="repo.intra.company.local",
|
||||
protocol="https",
|
||||
purpose="artifact-repo",
|
||||
enabled=True,
|
||||
),
|
||||
ResourceSourceEntry(
|
||||
source_id="src-2",
|
||||
host="pypi.intra.company.local",
|
||||
protocol="https",
|
||||
purpose="package-mirror",
|
||||
enabled=True,
|
||||
),
|
||||
],
|
||||
updated_at=datetime.now(timezone.utc),
|
||||
updated_by="tester",
|
||||
status="active",
|
||||
)
|
||||
|
||||
|
||||
def test_validate_internal_sources_all_internal_ok():
|
||||
result = validate_internal_sources(
|
||||
registry=_registry(),
|
||||
endpoints=["repo.intra.company.local", "pypi.intra.company.local"],
|
||||
)
|
||||
assert result["ok"] is True
|
||||
assert result["violations"] == []
|
||||
|
||||
|
||||
def test_validate_internal_sources_external_blocked():
|
||||
result = validate_internal_sources(
|
||||
registry=_registry(),
|
||||
endpoints=["repo.intra.company.local", "pypi.org"],
|
||||
)
|
||||
assert result["ok"] is False
|
||||
assert len(result["violations"]) == 1
|
||||
assert result["violations"][0]["category"] == "external-source"
|
||||
assert result["violations"][0]["blocked_release"] is True
|
||||
Reference in New Issue
Block a user