ec0b7631d0
CI / lint (push) Successful in 12s
CI / build (push) Successful in 15s
CI / quality (push) Successful in 23s
CI / typecheck (push) Successful in 36s
CI / benchmark-regression (push) Has been skipped
CI / security (push) Successful in 46s
CI / unit_tests (push) Successful in 3m3s
CI / integration_tests (push) Successful in 3m31s
CI / docker (push) Successful in 40s
CI / coverage (push) Successful in 5m34s
CI / benchmark-publish (push) Successful in 19m15s
CI / benchmark-publish (pull_request) Has been skipped
CI / lint (pull_request) Successful in 13s
CI / build (pull_request) Successful in 14s
CI / quality (pull_request) Successful in 17s
CI / security (pull_request) Successful in 34s
CI / typecheck (pull_request) Has been cancelled
CI / unit_tests (pull_request) Has been cancelled
CI / coverage (pull_request) Has been cancelled
CI / benchmark-regression (pull_request) Has been cancelled
CI / integration_tests (pull_request) Has been cancelled
CI / docker (pull_request) Has been cancelled
Renamed src/cleveragents/acp/ to src/cleveragents/a2a/ and all 13 Acp* classes to A2a* per ADR-047 (A2A Standard Adoption). Updated all imports, structlog event names (acp.* → a2a.*), field names (acp_version → a2a_version), and test references across the entire codebase. This is a cosmetic rename only — no behavioral changes. ISSUES CLOSED: #688
136 lines
6.2 KiB
Plaintext
136 lines
6.2 KiB
Plaintext
*** Settings ***
|
|
Documentation Integration smoke tests for async resource cleanup (#321).
|
|
... Validates that AsyncResourceTracker, enhanced bridge cleanup,
|
|
... A2aEventQueue.close(), and StateManager.close() work end-to-end
|
|
... by executing small Python driver scripts in a subprocess.
|
|
|
|
Library OperatingSystem
|
|
Library Process
|
|
Library String
|
|
Resource ${CURDIR}/common.resource
|
|
|
|
Test Setup Setup Async Cleanup Test Environment
|
|
Test Teardown Cleanup Async Cleanup Test Environment
|
|
|
|
*** Variables ***
|
|
${PYTHON} python
|
|
${WORKSPACE_ROOT} ${CURDIR}/..
|
|
${TEST_FILE} ${EMPTY}
|
|
${TEST_OUTPUT} ${EMPTY}
|
|
${TIMEOUT} 30s
|
|
|
|
*** Test Cases ***
|
|
Test AsyncResourceTracker Register And Close
|
|
[Documentation] Register a resource and close it via close_all
|
|
${script} = Catenate SEPARATOR=\n
|
|
... import sys, asyncio
|
|
... sys.path.insert(0, '${WORKSPACE_ROOT}/src')
|
|
... from cleveragents.core.async_cleanup import AsyncResourceTracker
|
|
...
|
|
... class FakeResource:
|
|
... ${SPACE}${SPACE}${SPACE}${SPACE}def __init__(self): self.closed = False
|
|
... ${SPACE}${SPACE}${SPACE}${SPACE}async def close(self): self.closed = True
|
|
...
|
|
... async def main():
|
|
... ${SPACE}${SPACE}${SPACE}${SPACE}tracker = AsyncResourceTracker()
|
|
... ${SPACE}${SPACE}${SPACE}${SPACE}res = FakeResource()
|
|
... ${SPACE}${SPACE}${SPACE}${SPACE}tracker.register("test-res", res)
|
|
... ${SPACE}${SPACE}${SPACE}${SPACE}assert tracker.open_count == 1
|
|
... ${SPACE}${SPACE}${SPACE}${SPACE}await tracker.close_all()
|
|
... ${SPACE}${SPACE}${SPACE}${SPACE}assert res.closed
|
|
... ${SPACE}${SPACE}${SPACE}${SPACE}assert tracker.open_count == 0
|
|
... ${SPACE}${SPACE}${SPACE}${SPACE}print("PASS: register and close", flush=True)
|
|
...
|
|
... asyncio.run(main())
|
|
Create File ${TEST_FILE} ${script}
|
|
${result} = Run Process ${PYTHON} ${TEST_FILE}
|
|
... stdout=${TEST_OUTPUT} stderr=STDOUT timeout=${TIMEOUT}
|
|
Should Be Equal As Integers ${result.rc} 0
|
|
${output} = Get File ${TEST_OUTPUT}
|
|
Should Contain ${output} PASS: register and close
|
|
|
|
Test AsyncResourceTracker Timeout Warning
|
|
[Documentation] Verify forced-termination warning for slow resource
|
|
${script} = Catenate SEPARATOR=\n
|
|
... import sys, asyncio, logging
|
|
... sys.path.insert(0, '${WORKSPACE_ROOT}/src')
|
|
... from cleveragents.core.async_cleanup import AsyncResourceTracker
|
|
...
|
|
... handler = logging.StreamHandler(sys.stdout)
|
|
... handler.setLevel(logging.WARNING)
|
|
... logging.getLogger("cleveragents.core.async_cleanup").addHandler(handler)
|
|
...
|
|
... class SlowResource:
|
|
... ${SPACE}${SPACE}${SPACE}${SPACE}async def close(self): await asyncio.sleep(10)
|
|
...
|
|
... async def main():
|
|
... ${SPACE}${SPACE}${SPACE}${SPACE}tracker = AsyncResourceTracker()
|
|
... ${SPACE}${SPACE}${SPACE}${SPACE}tracker.register("slow", SlowResource())
|
|
... ${SPACE}${SPACE}${SPACE}${SPACE}await tracker.close_all(timeout=0.05)
|
|
... ${SPACE}${SPACE}${SPACE}${SPACE}assert len(tracker.timed_out_resources) == 1
|
|
... ${SPACE}${SPACE}${SPACE}${SPACE}print("PASS: timeout warning", flush=True)
|
|
...
|
|
... asyncio.run(main())
|
|
Create File ${TEST_FILE} ${script}
|
|
${result} = Run Process ${PYTHON} ${TEST_FILE}
|
|
... stdout=${TEST_OUTPUT} stderr=STDOUT timeout=${TIMEOUT}
|
|
Should Be Equal As Integers ${result.rc} 0
|
|
${output} = Get File ${TEST_OUTPUT}
|
|
Should Contain ${output} PASS: timeout warning
|
|
|
|
Test A2aEventQueue Close
|
|
[Documentation] Verify A2aEventQueue.close() removes subscriptions
|
|
${script} = Catenate SEPARATOR=\n
|
|
... import sys
|
|
... sys.path.insert(0, '${WORKSPACE_ROOT}/src')
|
|
... from cleveragents.a2a.events import A2aEventQueue
|
|
...
|
|
... q = A2aEventQueue()
|
|
... q.subscribe_local(lambda e: None)
|
|
... q.subscribe_local(lambda e: None)
|
|
... assert len(q._subscriptions) == 2
|
|
... q.close()
|
|
... assert len(q._subscriptions) == 0
|
|
... print("PASS: event queue close", flush=True)
|
|
Create File ${TEST_FILE} ${script}
|
|
${result} = Run Process ${PYTHON} ${TEST_FILE}
|
|
... stdout=${TEST_OUTPUT} stderr=STDOUT timeout=${TIMEOUT}
|
|
Should Be Equal As Integers ${result.rc} 0
|
|
${output} = Get File ${TEST_OUTPUT}
|
|
Should Contain ${output} PASS: event queue close
|
|
|
|
Test StateManager Close
|
|
[Documentation] Verify StateManager.close() marks manager as closed
|
|
${script} = Catenate SEPARATOR=\n
|
|
... import sys, tempfile
|
|
... sys.path.insert(0, '${WORKSPACE_ROOT}/src')
|
|
... from pathlib import Path
|
|
... from cleveragents.langgraph.state import StateManager, GraphState
|
|
...
|
|
... d = tempfile.mkdtemp()
|
|
... mgr = StateManager(initial_state=GraphState(), checkpoint_dir=Path(d))
|
|
... assert not mgr.is_closed
|
|
... mgr.close()
|
|
... assert mgr.is_closed
|
|
... print("PASS: state manager close", flush=True)
|
|
Create File ${TEST_FILE} ${script}
|
|
${result} = Run Process ${PYTHON} ${TEST_FILE}
|
|
... stdout=${TEST_OUTPUT} stderr=STDOUT timeout=${TIMEOUT}
|
|
Should Be Equal As Integers ${result.rc} 0
|
|
${output} = Get File ${TEST_OUTPUT}
|
|
Should Contain ${output} PASS: state manager close
|
|
|
|
*** Keywords ***
|
|
Setup Async Cleanup Test Environment
|
|
[Documentation] Create temp dir for test scripts
|
|
${temp_dir} = Evaluate tempfile.mkdtemp() modules=tempfile
|
|
Set Test Variable ${TEMP_DIR} ${temp_dir}
|
|
Set Test Variable ${TEST_FILE} ${temp_dir}/async_cleanup_test.py
|
|
Set Test Variable ${TEST_OUTPUT} ${temp_dir}/async_cleanup_output.txt
|
|
|
|
Cleanup Async Cleanup Test Environment
|
|
[Documentation] Remove temp dir
|
|
Run Keyword And Ignore Error Remove File ${TEST_FILE}
|
|
Run Keyword And Ignore Error Remove File ${TEST_OUTPUT}
|
|
Run Keyword And Ignore Error Remove Directory ${TEMP_DIR} recursive=True
|