Files
cleveragents-core/robot/resource_cli_tree.robot
freemo ad91b4e89d feat(cli): add resource tree and inspect commands
Add tree, inspect, link-child, and unlink-child subcommands to the
agents resource CLI group. Extend ResourceRegistryService with
link_child, unlink_child, get_children, and get_resource_tree methods.

- tree: display resource hierarchy with --depth, --type, and format options
- inspect: show resource details with --tree and --file options
- link-child/unlink-child: manage DAG edges with cycle detection
- 24 Behave scenarios, 4 Robot integration tests, ASV benchmarks
- CLI reference documentation in docs/reference/resource_cli.md
2026-02-20 08:48:33 -05:00

125 lines
6.8 KiB
Plaintext

*** Settings ***
Documentation Resource CLI Tree and Inspect Integration Tests
Library Process
Library OperatingSystem
*** Variables ***
${PYTHON} python
*** Test Cases ***
Resource Tree Shows Root Resource
[Documentation] Run resource tree on a resource with no children
${script}= Catenate SEPARATOR=\n
... import json
... from datetime import datetime, UTC
... from sqlalchemy import create_engine, event
... from sqlalchemy.orm import sessionmaker
... from cleveragents.infrastructure.database.models import Base
... from cleveragents.application.services.resource_registry_service import ResourceRegistryService
... engine = create_engine("sqlite:///:memory:")
... @event.listens_for(engine, "connect")
... def _fk(conn, _): conn.cursor().execute("PRAGMA foreign_keys=ON")
... Base.metadata.create_all(engine)
... factory = sessionmaker(bind=engine, expire_on_commit=False)
... svc = ResourceRegistryService(session_factory=factory)
... svc.bootstrap_builtin_types()
... svc.register_resource(type_name="git-checkout", name="local/tree-test", location="/tmp/tt", properties={"path": "/tmp/tt"})
... tree = svc.get_resource_tree("local/tree-test")
... assert len(tree) == 1
... node = tree[0]
... assert node["resource"].name == "local/tree-test"
... assert node["children"] == []
... print("Resource tree root test passed")
${result}= Run Process ${PYTHON} -c ${script}
Should Be Equal As Integers ${result.rc} 0 Tree root test failed: ${result.stderr}
Should Contain ${result.stdout} Resource tree root test passed
Resource Inspect Shows Details
[Documentation] Inspect a resource and verify basic details
${script}= Catenate SEPARATOR=\n
... import json
... from datetime import datetime, UTC
... from sqlalchemy import create_engine, event
... from sqlalchemy.orm import sessionmaker
... from cleveragents.infrastructure.database.models import Base
... from cleveragents.application.services.resource_registry_service import ResourceRegistryService
... engine = create_engine("sqlite:///:memory:")
... @event.listens_for(engine, "connect")
... def _fk(conn, _): conn.cursor().execute("PRAGMA foreign_keys=ON")
... Base.metadata.create_all(engine)
... factory = sessionmaker(bind=engine, expire_on_commit=False)
... svc = ResourceRegistryService(session_factory=factory)
... svc.bootstrap_builtin_types()
... res = svc.register_resource(type_name="git-checkout", name="local/inspect-test", location="/tmp/it", properties={"path": "/tmp/it"})
... shown = svc.show_resource("local/inspect-test")
... assert shown.name == "local/inspect-test"
... assert shown.resource_type_name == "git-checkout"
... assert shown.location == "/tmp/it"
... print("Resource inspect test passed")
${result}= Run Process ${PYTHON} -c ${script}
Should Be Equal As Integers ${result.rc} 0 Inspect test failed: ${result.stderr}
Should Contain ${result.stdout} Resource inspect test passed
Link And Unlink Child Via Service
[Documentation] Link a child via service and then unlink it
${script}= Catenate SEPARATOR=\n
... import json
... from datetime import datetime, UTC
... from sqlalchemy import create_engine, event
... from sqlalchemy.orm import sessionmaker
... from cleveragents.infrastructure.database.models import Base
... from cleveragents.application.services.resource_registry_service import ResourceRegistryService
... engine = create_engine("sqlite:///:memory:")
... @event.listens_for(engine, "connect")
... def _fk(conn, _): conn.cursor().execute("PRAGMA foreign_keys=ON")
... Base.metadata.create_all(engine)
... factory = sessionmaker(bind=engine, expire_on_commit=False)
... svc = ResourceRegistryService(session_factory=factory)
... svc.bootstrap_builtin_types()
... svc.register_resource(type_name="git-checkout", name="local/link-p", location="/tmp/lp", properties={"path": "/tmp/lp"})
... svc.register_resource(type_name="fs-directory", name="local/link-c", location="/tmp/lc", properties={"path": "/tmp/lc"})
... svc.link_child("local/link-p", "local/link-c")
... children = svc.get_children("local/link-p")
... assert len(children) == 1
... assert children[0].name == "local/link-c"
... svc.unlink_child("local/link-p", "local/link-c")
... children = svc.get_children("local/link-p")
... assert len(children) == 0
... print("Link and unlink child passed")
${result}= Run Process ${PYTHON} -c ${script}
Should Be Equal As Integers ${result.rc} 0 Link/unlink test failed: ${result.stderr}
Should Contain ${result.stdout} Link and unlink child passed
Resource Tree With Children Shows Hierarchy
[Documentation] Resource tree with linked children shows hierarchy
${script}= Catenate SEPARATOR=\n
... import json
... from datetime import datetime, UTC
... from sqlalchemy import create_engine, event
... from sqlalchemy.orm import sessionmaker
... from cleveragents.infrastructure.database.models import Base
... from cleveragents.application.services.resource_registry_service import ResourceRegistryService
... engine = create_engine("sqlite:///:memory:")
... @event.listens_for(engine, "connect")
... def _fk(conn, _): conn.cursor().execute("PRAGMA foreign_keys=ON")
... Base.metadata.create_all(engine)
... factory = sessionmaker(bind=engine, expire_on_commit=False)
... svc = ResourceRegistryService(session_factory=factory)
... svc.bootstrap_builtin_types()
... svc.register_resource(type_name="git-checkout", name="local/tree-parent", location="/tmp/tp", properties={"path": "/tmp/tp"})
... svc.register_resource(type_name="fs-directory", name="local/tree-child", location="/tmp/tc", properties={"path": "/tmp/tc"})
... svc.link_child("local/tree-parent", "local/tree-child")
... tree = svc.get_resource_tree("local/tree-parent")
... assert len(tree) == 1
... root = tree[0]
... assert root["resource"].name == "local/tree-parent"
... assert len(root["children"]) == 1
... child_node = root["children"][0]
... assert child_node["resource"].name == "local/tree-child"
... print("Tree with children test passed")
${result}= Run Process ${PYTHON} -c ${script}
Should Be Equal As Integers ${result.rc} 0 Tree children test failed: ${result.stderr}
Should Contain ${result.stdout} Tree with children test passed
*** Keywords ***