Files
brent.edwards 92e2585358
CI / lint (pull_request) Successful in 39s
CI / helm (pull_request) Successful in 32s
CI / build (pull_request) Successful in 32s
CI / push-validation (pull_request) Successful in 31s
CI / quality (pull_request) Successful in 1m0s
CI / security (pull_request) Successful in 1m2s
CI / typecheck (pull_request) Successful in 1m40s
CI / unit_tests (pull_request) Successful in 6m25s
CI / docker (pull_request) Successful in 1m27s
CI / coverage (pull_request) Successful in 10m51s
CI / integration_tests (pull_request) Successful in 22m36s
CI / status-check (pull_request) Successful in 3s
fix: add missing validations/unit-tests.yaml example
Add the missing workflow validation example and keep the #1039 TDD regression active by removing the expected-fail tag and updating scenario narrative.\n\nTo satisfy the required full quality gates, stabilize flaky integration behavior encountered during this issue run: use a shared SQLAlchemy session in resource DAG scripts, isolate RxPY validation temp paths per test run, extend transient subprocess timeouts/retry behavior, and clear stale pabot worker artifacts before integration runs so repeated nox executions are reliable.\n\nISSUES CLOSED: #1039
2026-05-30 00:09:20 -04:00

125 lines
10 KiB
Plaintext

*** Settings ***
Documentation Resource DAG Linking and Discovery Tests
Library Process
Library OperatingSystem
*** Test Cases ***
Link Child And Verify Tree
[Documentation] Link a child resource and verify it appears in children list
${script}= Catenate SEPARATOR=\n
... import json
... from datetime import datetime, UTC
... from sqlalchemy import create_engine, event
... from sqlalchemy.pool import StaticPool
... from sqlalchemy.orm import sessionmaker
... from sqlalchemy.pool import StaticPool
... from cleveragents.infrastructure.database.models import Base
... from cleveragents.infrastructure.database.repositories import ResourceTypeRepository, ResourceRepository
... from cleveragents.domain.models.core.resource_type import ResourceTypeSpec, ResourceKind, SandboxStrategy
... from cleveragents.domain.models.core.resource import Resource, PhysVirt, ResourceCapabilities
... engine = create_engine("sqlite://", connect_args={"check_same_thread": False}, poolclass=StaticPool)
... @event.listens_for(engine, "connect")
... def _fk(conn, _): conn.cursor().execute("PRAGMA foreign_keys=ON")
... Base.metadata.create_all(engine)
... factory = sessionmaker(bind=engine)
... shared_session = factory()
... rt_repo = ResourceTypeRepository(lambda: shared_session)
... res_repo = ResourceRepository(lambda: shared_session)
... parent_spec = ResourceTypeSpec(name="robot/dag-parent", description="Parent", resource_kind=ResourceKind.PHYSICAL, sandbox_strategy=SandboxStrategy.NONE, user_addable=True, cli_args=[], parent_types=[], child_types=["robot/dag-child"], auto_discovery=None, equivalence=None, handler=None, capabilities={"read": True, "write": True, "sandbox": True, "checkpoint": False}, built_in=False)
... child_spec = ResourceTypeSpec(name="robot/dag-child", description="Child", resource_kind=ResourceKind.PHYSICAL, sandbox_strategy=SandboxStrategy.NONE, user_addable=True, cli_args=[], parent_types=[], child_types=[], auto_discovery=None, equivalence=None, handler=None, capabilities={"read": True, "write": True, "sandbox": True, "checkpoint": False}, built_in=False)
... rt_repo.create(parent_spec)
... rt_repo.create(child_spec)
... p = Resource(resource_id="01HDAGR0B0T0000000PARENT01", name=None, resource_type_name="robot/dag-parent", classification=PhysVirt.PHYSICAL, properties={}, location=None, capabilities=ResourceCapabilities(), created_at=datetime.now(tz=UTC), updated_at=datetime.now(tz=UTC))
... c = Resource(resource_id="01HDAGR0B0T00000CHXND00001", name=None, resource_type_name="robot/dag-child", classification=PhysVirt.PHYSICAL, properties={}, location=None, capabilities=ResourceCapabilities(), created_at=datetime.now(tz=UTC), updated_at=datetime.now(tz=UTC))
... res_repo.create(p)
... res_repo.create(c)
... res_repo.link_child("01HDAGR0B0T0000000PARENT01", "01HDAGR0B0T00000CHXND00001")
... children = res_repo.get_children("01HDAGR0B0T0000000PARENT01")
... assert len(children) == 1, f"Expected 1 child, got {len(children)}"
... assert children[0].resource_id == "01HDAGR0B0T00000CHXND00001"
... shared_session.close()
... print("Link child and verify tree passed")
${result}= Run Process ${PYTHON} -c ${script} timeout=60s on_timeout=kill
Should Be Equal As Integers ${result.rc} 0 Link test failed: ${result.stderr}
Should Contain ${result.stdout} Link child and verify tree passed
Cycle Detection Rejects A To B To A
[Documentation] Linking A->B then B->A should raise CycleDetectedError
${script}= Catenate SEPARATOR=\n
... from datetime import datetime, UTC
... from sqlalchemy import create_engine, event
... from sqlalchemy.pool import StaticPool
... from sqlalchemy.orm import sessionmaker
... from sqlalchemy.pool import StaticPool
... from cleveragents.infrastructure.database.models import Base
... from cleveragents.infrastructure.database.repositories import ResourceTypeRepository, ResourceRepository, CycleDetectedError
... from cleveragents.domain.models.core.resource_type import ResourceTypeSpec, ResourceKind, SandboxStrategy
... from cleveragents.domain.models.core.resource import Resource, PhysVirt, ResourceCapabilities
... engine = create_engine("sqlite://", connect_args={"check_same_thread": False}, poolclass=StaticPool)
... @event.listens_for(engine, "connect")
... def _fk(conn, _): conn.cursor().execute("PRAGMA foreign_keys=ON")
... Base.metadata.create_all(engine)
... factory = sessionmaker(bind=engine)
... shared_session = factory()
... rt_repo = ResourceTypeRepository(lambda: shared_session)
... res_repo = ResourceRepository(lambda: shared_session)
... spec_a = ResourceTypeSpec(name="robot/cycle-a", description="Cycle A", resource_kind=ResourceKind.PHYSICAL, sandbox_strategy=SandboxStrategy.NONE, user_addable=True, cli_args=[], parent_types=[], child_types=["robot/cycle-b"], auto_discovery=None, equivalence=None, handler=None, capabilities={"read": True, "write": True, "sandbox": True, "checkpoint": False}, built_in=False)
... spec_b = ResourceTypeSpec(name="robot/cycle-b", description="Cycle B", resource_kind=ResourceKind.PHYSICAL, sandbox_strategy=SandboxStrategy.NONE, user_addable=True, cli_args=[], parent_types=[], child_types=["robot/cycle-a"], auto_discovery=None, equivalence=None, handler=None, capabilities={"read": True, "write": True, "sandbox": True, "checkpoint": False}, built_in=False)
... rt_repo.create(spec_a)
... rt_repo.create(spec_b)
... a = Resource(resource_id="01HDAGCYC000000000000000A1", name=None, resource_type_name="robot/cycle-a", classification=PhysVirt.PHYSICAL, properties={}, location=None, capabilities=ResourceCapabilities(), created_at=datetime.now(tz=UTC), updated_at=datetime.now(tz=UTC))
... b = Resource(resource_id="01HDAGCYC000000000000000B1", name=None, resource_type_name="robot/cycle-b", classification=PhysVirt.PHYSICAL, properties={}, location=None, capabilities=ResourceCapabilities(), created_at=datetime.now(tz=UTC), updated_at=datetime.now(tz=UTC))
... res_repo.create(a)
... res_repo.create(b)
... res_repo.link_child("01HDAGCYC000000000000000A1", "01HDAGCYC000000000000000B1")
... try:
... ${SPACE * 4}res_repo.link_child("01HDAGCYC000000000000000B1", "01HDAGCYC000000000000000A1")
... ${SPACE * 4}assert False, "Should have raised CycleDetectedError"
... except CycleDetectedError:
... ${SPACE * 4}print("Cycle detection passed")
... finally:
... ${SPACE * 4}shared_session.close()
${result}= Run Process ${PYTHON} -c ${script} timeout=60s on_timeout=kill
Should Be Equal As Integers ${result.rc} 0 Cycle test failed: ${result.stderr}
Should Contain ${result.stdout} Cycle detection passed
Auto Discover Children
[Documentation] Auto-discover creates child resources per type rules
${script}= Catenate SEPARATOR=\n
... import json
... from datetime import datetime, UTC
... from sqlalchemy import create_engine, event
... from sqlalchemy.pool import StaticPool
... from sqlalchemy.orm import sessionmaker
... from sqlalchemy.pool import StaticPool
... from cleveragents.infrastructure.database.models import Base
... from cleveragents.infrastructure.database.repositories import ResourceTypeRepository, ResourceRepository
... from cleveragents.domain.models.core.resource_type import ResourceTypeSpec, ResourceKind, SandboxStrategy
... from cleveragents.domain.models.core.resource import Resource, PhysVirt, ResourceCapabilities
... engine = create_engine("sqlite://", connect_args={"check_same_thread": False}, poolclass=StaticPool)
... @event.listens_for(engine, "connect")
... def _fk(conn, _): conn.cursor().execute("PRAGMA foreign_keys=ON")
... Base.metadata.create_all(engine)
... factory = sessionmaker(bind=engine)
... shared_session = factory()
... rt_repo = ResourceTypeRepository(lambda: shared_session)
... res_repo = ResourceRepository(lambda: shared_session)
... parent_spec = ResourceTypeSpec(name="robot/disc-parent", description="Discoverer", resource_kind=ResourceKind.PHYSICAL, sandbox_strategy=SandboxStrategy.NONE, user_addable=True, cli_args=[], parent_types=[], child_types=["robot/disc-child"], auto_discovery={"enabled": True, "rules": [{"type": "robot/disc-child", "pattern": "*"}]}, equivalence=None, handler=None, capabilities={"read": True, "write": True, "sandbox": True, "checkpoint": False}, built_in=False)
... child_spec = ResourceTypeSpec(name="robot/disc-child", description="Discovered", resource_kind=ResourceKind.PHYSICAL, sandbox_strategy=SandboxStrategy.NONE, user_addable=True, cli_args=[], parent_types=[], child_types=[], auto_discovery=None, equivalence=None, handler=None, capabilities={"read": True, "write": True, "sandbox": True, "checkpoint": False}, built_in=False)
... rt_repo.create(parent_spec)
... rt_repo.create(child_spec)
... p = Resource(resource_id="01HDAGR0B0TDSC00PARENT0001", name=None, resource_type_name="robot/disc-parent", classification=PhysVirt.PHYSICAL, properties={}, location=None, capabilities=ResourceCapabilities(), created_at=datetime.now(tz=UTC), updated_at=datetime.now(tz=UTC))
... res_repo.create(p)
... created = res_repo.auto_discover_children("01HDAGR0B0TDSC00PARENT0001")
... assert len(created) >= 1, f"Expected >=1 children, got {len(created)}"
... assert created[0].resource_type_name == "robot/disc-child"
... children = res_repo.get_children("01HDAGR0B0TDSC00PARENT0001")
... assert len(children) >= 1, f"Expected >=1 linked children, got {len(children)}"
... shared_session.close()
... print("Auto discover children passed")
${result}= Run Process ${PYTHON} -c ${script} timeout=60s on_timeout=kill
Should Be Equal As Integers ${result.rc} 0 Auto discover test failed: ${result.stderr}
Should Contain ${result.stdout} Auto discover children passed
*** Keywords ***