92c3bd8732
CI / benchmark-publish (pull_request) Has been skipped
CI / push-validation (pull_request) Successful in 37s
CI / helm (pull_request) Successful in 38s
CI / lint (pull_request) Successful in 1m35s
CI / build (pull_request) Successful in 59s
CI / typecheck (pull_request) Successful in 1m50s
CI / security (pull_request) Successful in 1m48s
CI / quality (pull_request) Successful in 1m42s
CI / e2e_tests (pull_request) Successful in 4m42s
CI / integration_tests (pull_request) Successful in 6m36s
CI / unit_tests (pull_request) Successful in 8m53s
CI / docker (pull_request) Successful in 1m45s
CI / coverage (pull_request) Successful in 12m51s
CI / benchmark-regression (push) Has been skipped
CI / status-check (pull_request) Successful in 3s
CI / benchmark-publish (push) Has started running
CI / helm (push) Successful in 36s
CI / lint (push) Successful in 55s
CI / build (push) Successful in 56s
CI / quality (push) Successful in 1m28s
CI / typecheck (push) Successful in 1m29s
CI / security (push) Successful in 1m35s
CI / push-validation (push) Successful in 22s
CI / e2e_tests (push) Successful in 4m33s
CI / integration_tests (push) Successful in 4m38s
CI / unit_tests (push) Successful in 6m41s
CI / docker (push) Successful in 1m34s
CI / coverage (push) Successful in 10m47s
CI / status-check (push) Successful in 3s
CI / benchmark-regression (pull_request) Successful in 1h2m16s
Replaced direct create_engine usage with StaticPool-based connection in resource_dag.robot to prevent SQLite connection sharing issues in tests. Updated cycle detection test to use distinct resource types (git-checkout and fs-directory) instead of the same type for both resources, improving test coverage of cross-type cycle detection. Split from PR #1204 per reviewer request for atomic commits. ISSUES CLOSED: #1226
122 lines
10 KiB
Plaintext
122 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.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:///:memory:", poolclass=StaticPool, connect_args={"check_same_thread": False})
|
|
... @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.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:///:memory:", poolclass=StaticPool, connect_args={"check_same_thread": False})
|
|
... @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.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:///:memory:", poolclass=StaticPool, connect_args={"check_same_thread": False})
|
|
... @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 ***
|