fix(tests): update resource_dag.robot SQLite pool and cycle detection types #1228

Merged
HAL9000 merged 1 commits from fix/m6-resource-dag-robot-sqlite into master 2026-04-25 02:12:38 +00:00
3 changed files with 21 additions and 7 deletions
+8
View File
2
@@ -339,6 +339,14 @@ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
a `sqlite3.IntegrityError: UNIQUE constraint failed` crash when `agents plan use` was
called on an action that already had arguments registered via `action create`. (#4197)
- Updated `resource_dag.robot` to use `StaticPool`-based SQLite connections
(`poolclass=StaticPool`, `connect_args={"check_same_thread": False}`) in
all three test cases, preventing connection sharing issues in the test
environment. Updated cycle detection test to use distinct resource types
(`robot/cycle-a` and `robot/cycle-b`) instead of a single shared type,
improving coverage of cross-type cycle detection. Split from PR #1204
per reviewer request for atomic commits. (#1226)
---
## [3.8.0] -- 2026-04-05
+1
View File
@@ -25,3 +25,4 @@ Below are some of the specific details of various contributions.
* HAL 9000 has contributed automated bug fixes, CLI output formatting improvements, and ongoing maintenance as part of the CleverAgents automation system.
* HAL 9000 has contributed the file edit encoding parameter fix (PR #8258 / issue #7559).
* HAL 9000 has contributed the architecture-pool-supervisor milestone assignment feature (PR #8188 / issue #7521): added `forgejo_update_pull_request` permission and documented the PR workflow for major spec changes, enabling automatic milestone assignment for specification PRs.
* HAL 9000 has contributed the resource_dag.robot SQLite pool and cycle detection fix (PR #1228 / issue #1226): updated all three test cases to use StaticPool-based SQLite connections and improved cycle detection test coverage with distinct resource types.
+12 -7
View File
@@ -11,11 +11,12 @@ Link Child And Verify Tree
... 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
Outdated
Review

This change is correct. StaticPool with connect_args={"check_same_thread": False} is the proper pattern for SQLite in-memory databases in test environments. The distinct resource types (robot/cycle-a / robot/cycle-b) with cross-referencing child_types properly exercise cross-type cycle detection.


Automated by CleverAgents Bot
Supervisor: PR Review | Agent: ca-pr-self-reviewer

✅ **This change is correct.** StaticPool with `connect_args={"check_same_thread": False}` is the proper pattern for SQLite in-memory databases in test environments. The distinct resource types (`robot/cycle-a` / `robot/cycle-b`) with cross-referencing `child_types` properly exercise cross-type cycle detection. --- **Automated by CleverAgents Bot** Supervisor: PR Review | Agent: ca-pr-self-reviewer
... from cleveragents.domain.models.core.resource import Resource, PhysVirt, ResourceCapabilities
... engine = create_engine("sqlite:///:memory:")
... 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)
@@ -47,11 +48,12 @@ Cycle Detection Rejects A To B To A
... 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:")
... 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)
@@ -59,10 +61,12 @@ Cycle Detection Rejects A To B To A
... shared_session = factory()
... rt_repo = ResourceTypeRepository(lambda: shared_session)
... res_repo = ResourceRepository(lambda: shared_session)
... spec = ResourceTypeSpec(name="robot/cycle-type", description="Cycle", resource_kind=ResourceKind.PHYSICAL, sandbox_strategy=SandboxStrategy.NONE, user_addable=True, cli_args=[], parent_types=[], child_types=["robot/cycle-type"], auto_discovery=None, equivalence=None, handler=None, capabilities={"read": True, "write": True, "sandbox": True, "checkpoint": False}, built_in=False)
... rt_repo.create(spec)
... a = Resource(resource_id="01HDAGCYC000000000000000A1", name=None, resource_type_name="robot/cycle-type", 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-type", classification=PhysVirt.PHYSICAL, properties={}, location=None, capabilities=ResourceCapabilities(), created_at=datetime.now(tz=UTC), updated_at=datetime.now(tz=UTC))
... 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")
@@ -84,11 +88,12 @@ Auto Discover Children
... 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:")
... 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)