forked from cleveragents/cleveragents-core
e4c01492d5
Aligned the `agents actor run` command signature with the specification by introducing positional NAME and PROMPT arguments. The --config/-c option is preserved as an optional fallback for direct YAML invocation. When NAME is provided without --config, the actor is resolved from the Actor Registry. Updated both actor_run.py and actor.py run commands. Added backward compatibility: if --config is provided, it takes precedence over name-based resolution. Review fixes applied (code review round 1): - P1-1: Narrowed bare `except Exception` to `except NotFoundError` in _resolve_config_files to avoid masking infrastructure errors. - P1-2: Moved _resolve_config_files call inside the try block in run() so container/registry init errors get user-friendly messages. Added `except click.exceptions.Exit: raise` to let typer.Exit propagate through the broadened try scope. - P1-3: Added atexit.register cleanup for temp files created by _resolve_config_files (resource leak fix). - P1-4: Added CHANGELOG.md entry for the breaking CLI change. - P2-1: Extracted duplicated _resolve_config_files to shared module `_resolve_actor.py`; both actor.py and actor_run.py now import it. - P2-2: Added guard for actors with no configuration data (config_blob=None) to produce a clear error instead of invalid YAML. - P2-3/P2-4: Added 5 BDD scenarios exercising the real resolve_config_files function (registry path, yaml_text path, config_blob fallback, no-config-data error, not-found error). - P2-5: Added @coverage tags to all new BDD scenarios. - P3-1: Added timeout=120s and on_timeout=kill to Robot tests. - Fixed rxpy_route_validation.robot tests that used the removed --prompt/-p option (replaced with positional NAME + PROMPT args). Review fixes applied (code review round 2): - P2-1: Aligned actor_run.py exception handler from `CleverAgentsException` to `CleverAgentsError`, matching actor.py so infrastructure errors from registry resolution get user-friendly messages instead of falling through to the generic handler. - P2-2: Changed `yaml.dump` to `yaml.safe_dump` in _resolve_actor.py for fail-fast behavior on unexpected types, consistent with the codebase's dominant pattern. - P3-6: Replaced defensive `getattr(actor, ...)` calls with direct Pydantic model attribute access (`actor.yaml_text`, `actor.config_blob`) for type-checker coverage. - P3-1: Switched BDD temp file cleanup from post-assertion `unlink()` to `context.add_cleanup()` for leak-proof teardown. - P2-3/P3-2/P3-3/P3-4: Added 3 BDD edge-case scenarios (empty config_blob dict, infrastructure error propagation, empty string name) and 1 Robot test case (actor_app registry resolution). Review fixes applied (code review round 3): - P1-1: Migrated 48 remaining `-p` invocations across 9 Robot test files to the new positional `NAME PROMPT` pattern (context_delete_all_yes, load_context_test, scientific_paper_e2e_test, routing_prefix_stripping, scientific_paper_basic, scientific_paper_writer_test, context_management_test, initial_next_command_test, system_prompt_template_rendering). - P2-1: Documented `--config/-c` as a spec deviation in `_resolve_actor.py` module docstring (spec lines 4562-4566 define `actor run` with no --config option; issue #901 AC accepts keeping it as optional). - P2-2: Corrected `--config` help text from "fallback" to "overrides registry-based name resolution" — the option takes precedence, not the other way around. - P3-1: Added `.strip()` to `yaml_text` emptiness check in `_resolve_actor.py` to handle whitespace-only values that would otherwise bypass the `config_blob` fallback. - P3-2: Added `from None` to the no-configuration-data `typer.Exit(code=2)` for consistency with the not-found path. - P3-3: Added BDD scenario testing `--config` precedence for `actor_run_app` (was only tested for `actor_app`). - P3-4: Strengthened config_blob BDD scenario to verify generated YAML is parseable via `yaml.safe_load` round-trip. - P3-7: Replaced hardcoded `/tmp/dummy.yaml` with `tempfile.gettempdir()` for portability. - P3-8: Moved 5 inline imports to module level per CONTRIBUTING.md §1292-1294 (3x `import click`, 1x InfrastructureError in steps; 1x `import typer` in robot helper). - P3-9: Added `encoding="utf-8"` to `_write_yaml` in Robot helper for consistency with production code. Review fixes applied (code review round 4): - P2-1: Wrapped `yaml.safe_dump` in `_resolve_actor.py` with `try/except yaml.YAMLError` so non-serialisable config_blob values produce a user-friendly error message instead of a raw traceback. - P2-2: Moved remaining inline `import yaml` to module level in `actor_run_signature_steps.py` per CONTRIBUTING.md §1292-1294. - P2-3: Replaced 3 bare `assert` statements in Robot helper `helper_actor_run_signature.py` with diagnostic `if/print/sys.exit` pattern matching the rest of the file, improving failure diagnostics. Review fixes applied (code review round 5): - P3-4: Replaced per-call `atexit.register(lambda)` in `_resolve_actor.py` with a module-level `_temp_files` set and a single `atexit` handler (`_cleanup_temp_files`) to prevent unbounded handler accumulation in same-process usage (e.g. test suites running multiple CliRunner invocations). - P3-1/P3-2/P3-3: Added 4 BDD scenarios: whitespace-only `yaml_text` fallback to config_blob, config-precedence registry-not-consulted assertion for both `actor_app` and `actor_run_app`, multiple `--config` files with positional NAME. - P4-1: Strengthened error-path BDD assertions to verify error message content (not-found, no-config-data, serialisation-error) alongside exit codes via captured stderr. - P4-2: Added Robot test case for `actor_app` unknown-name error path and corresponding helper function. ISSUES CLOSED: #901
337 lines
12 KiB
Plaintext
337 lines
12 KiB
Plaintext
*** Settings ***
|
|
Documentation Integration tests for context delete with --all and --yes flags
|
|
... SEC1: Uses simple_echo_config.yaml which requires code blocks.
|
|
Library Process
|
|
Library OperatingSystem
|
|
Library String
|
|
Library DateTime
|
|
Resource ${CURDIR}/v2_paths.resource
|
|
Force Tags code_blocks
|
|
Suite Setup Setup Test Environment
|
|
Suite Teardown Cleanup Test Environment
|
|
|
|
*** Variables ***
|
|
${PYTHON} python
|
|
${SIMPLE_CONFIG} ${V2_CONFIG_DIR}/simple_echo_config.yaml
|
|
${CONTEXT_DIR} ${TEMPDIR}/test_contexts_delete_all_yes
|
|
${UNIQUE_ID} ${EMPTY}
|
|
${TEMP} ${EMPTY}
|
|
|
|
*** Test Cases ***
|
|
Test Delete Single Context With Yes Flag
|
|
[Documentation] Test context delete with --yes bypasses confirmation
|
|
${context_name} = Set Variable delete_yes_${UNIQUE_ID}
|
|
|
|
# Create context
|
|
Run Process ${PYTHON} -m cleveragents actor run
|
|
... -c ${SIMPLE_CONFIG}
|
|
... --context ${context_name}
|
|
... --context-dir ${CONTEXT_DIR}
|
|
... --unsafe
|
|
... --allow-rxpy-in-run-mode
|
|
... test-actor "test message"
|
|
|
|
Directory Should Exist ${CONTEXT_DIR}/${context_name}
|
|
|
|
# Delete it with --yes flag
|
|
${result} = Run Process ${PYTHON} -m cleveragents context delete
|
|
... ${context_name}
|
|
... --context-dir ${CONTEXT_DIR}
|
|
... --yes
|
|
|
|
Should Be Equal As Integers ${result.rc} 0
|
|
Directory Should Not Exist ${CONTEXT_DIR}/${context_name}
|
|
Should Contain ${result.stdout} deleted
|
|
|
|
Test Delete Single Context With Short Yes Flag
|
|
[Documentation] Test context delete with -y shorthand flag
|
|
${context_name} = Set Variable delete_short_${UNIQUE_ID}
|
|
|
|
# Create context
|
|
Run Process ${PYTHON} -m cleveragents actor run
|
|
... -c ${SIMPLE_CONFIG}
|
|
... --context ${context_name}
|
|
... --context-dir ${CONTEXT_DIR}
|
|
... --unsafe
|
|
... --allow-rxpy-in-run-mode
|
|
... test-actor "test message"
|
|
|
|
Directory Should Exist ${CONTEXT_DIR}/${context_name}
|
|
|
|
# Delete it with -y flag
|
|
${result} = Run Process ${PYTHON} -m cleveragents context delete
|
|
... ${context_name}
|
|
... --context-dir ${CONTEXT_DIR}
|
|
... -y
|
|
|
|
Should Be Equal As Integers ${result.rc} 0
|
|
Directory Should Not Exist ${CONTEXT_DIR}/${context_name}
|
|
|
|
Test Delete Single Context With Confirmation Accept
|
|
[Documentation] Test context delete with confirmation accepted
|
|
${context_name} = Set Variable delete_confirm_${UNIQUE_ID}
|
|
|
|
# Create context
|
|
Run Process ${PYTHON} -m cleveragents actor run
|
|
... -c ${SIMPLE_CONFIG}
|
|
... --context ${context_name}
|
|
... --context-dir ${CONTEXT_DIR}
|
|
... --unsafe
|
|
... --allow-rxpy-in-run-mode
|
|
... test-actor "test message"
|
|
|
|
Directory Should Exist ${CONTEXT_DIR}/${context_name}
|
|
|
|
# Delete with confirmation (answer 'y')
|
|
${result} = Run Process ${PYTHON} -m cleveragents context delete
|
|
... ${context_name}
|
|
... --context-dir ${CONTEXT_DIR}
|
|
... stdin=y\n
|
|
|
|
Should Be Equal As Integers ${result.rc} 0
|
|
Directory Should Not Exist ${CONTEXT_DIR}/${context_name}
|
|
|
|
Test Delete Single Context With Confirmation Reject
|
|
[Documentation] Test context delete with confirmation rejected
|
|
${context_name} = Set Variable delete_reject_${UNIQUE_ID}
|
|
|
|
# Create context
|
|
Run Process ${PYTHON} -m cleveragents actor run
|
|
... -c ${SIMPLE_CONFIG}
|
|
... --context ${context_name}
|
|
... --context-dir ${CONTEXT_DIR}
|
|
... --unsafe
|
|
... --allow-rxpy-in-run-mode
|
|
... test-actor "test message"
|
|
|
|
Directory Should Exist ${CONTEXT_DIR}/${context_name}
|
|
|
|
# Delete with confirmation rejected (answer 'n')
|
|
${result} = Run Process ${PYTHON} -m cleveragents context delete
|
|
... ${context_name}
|
|
... --context-dir ${CONTEXT_DIR}
|
|
... stdin=n\n
|
|
|
|
Should Be Equal As Integers ${result.rc} 0
|
|
Directory Should Exist ${CONTEXT_DIR}/${context_name}
|
|
Should Contain ${result.stdout} cancelled
|
|
|
|
Test Delete All Contexts With All And Yes Flags
|
|
[Documentation] Test delete all contexts with --all --yes
|
|
[Setup] Empty Directory ${CONTEXT_DIR}
|
|
${ctx1} = Set Variable all_ctx1_${UNIQUE_ID}
|
|
${ctx2} = Set Variable all_ctx2_${UNIQUE_ID}
|
|
${ctx3} = Set Variable all_ctx3_${UNIQUE_ID}
|
|
|
|
# Create multiple contexts
|
|
Run Process ${PYTHON} -m cleveragents actor run
|
|
... -c ${SIMPLE_CONFIG}
|
|
... --context ${ctx1}
|
|
... --context-dir ${CONTEXT_DIR}
|
|
... --unsafe
|
|
... --allow-rxpy-in-run-mode
|
|
... test-actor "test"
|
|
|
|
Run Process ${PYTHON} -m cleveragents actor run
|
|
... -c ${SIMPLE_CONFIG}
|
|
... --context ${ctx2}
|
|
... --context-dir ${CONTEXT_DIR}
|
|
... --unsafe
|
|
... --allow-rxpy-in-run-mode
|
|
... test-actor "test"
|
|
|
|
Run Process ${PYTHON} -m cleveragents actor run
|
|
... -c ${SIMPLE_CONFIG}
|
|
... --context ${ctx3}
|
|
... --context-dir ${CONTEXT_DIR}
|
|
... --unsafe
|
|
... --allow-rxpy-in-run-mode
|
|
... test-actor "test"
|
|
|
|
Directory Should Exist ${CONTEXT_DIR}/${ctx1}
|
|
Directory Should Exist ${CONTEXT_DIR}/${ctx2}
|
|
Directory Should Exist ${CONTEXT_DIR}/${ctx3}
|
|
|
|
# Delete all with --all --yes
|
|
${result} = Run Process ${PYTHON} -m cleveragents context delete
|
|
... --all
|
|
... --yes
|
|
... --context-dir ${CONTEXT_DIR}
|
|
|
|
Should Be Equal As Integers ${result.rc} 0
|
|
Directory Should Not Exist ${CONTEXT_DIR}/${ctx1}
|
|
Directory Should Not Exist ${CONTEXT_DIR}/${ctx2}
|
|
Directory Should Not Exist ${CONTEXT_DIR}/${ctx3}
|
|
Should Contain ${result.stdout} Deleted 3 context
|
|
|
|
Test Delete All With Confirmation Accept
|
|
[Documentation] Test delete all with confirmation accepted
|
|
[Setup] Empty Directory ${CONTEXT_DIR}
|
|
${ctx1} = Set Variable all_confirm1_${UNIQUE_ID}
|
|
${ctx2} = Set Variable all_confirm2_${UNIQUE_ID}
|
|
|
|
# Create contexts
|
|
Run Process ${PYTHON} -m cleveragents actor run
|
|
... -c ${SIMPLE_CONFIG}
|
|
... --context ${ctx1}
|
|
... --context-dir ${CONTEXT_DIR}
|
|
... --unsafe
|
|
... --allow-rxpy-in-run-mode
|
|
... test-actor "test"
|
|
|
|
Run Process ${PYTHON} -m cleveragents actor run
|
|
... -c ${SIMPLE_CONFIG}
|
|
... --context ${ctx2}
|
|
... --context-dir ${CONTEXT_DIR}
|
|
... --unsafe
|
|
... --allow-rxpy-in-run-mode
|
|
... test-actor "test"
|
|
|
|
# Delete all with confirmation
|
|
${result} = Run Process ${PYTHON} -m cleveragents context delete
|
|
... --all
|
|
... --context-dir ${CONTEXT_DIR}
|
|
... stdin=y\n
|
|
|
|
Should Be Equal As Integers ${result.rc} 0
|
|
Directory Should Not Exist ${CONTEXT_DIR}/${ctx1}
|
|
Directory Should Not Exist ${CONTEXT_DIR}/${ctx2}
|
|
Should Contain ${result.stdout} Found
|
|
Should Contain ${result.stdout} to delete
|
|
|
|
Test Delete All With Confirmation Reject
|
|
[Documentation] Test delete all with confirmation rejected
|
|
[Setup] Empty Directory ${CONTEXT_DIR}
|
|
${ctx1} = Set Variable all_reject1_${UNIQUE_ID}
|
|
${ctx2} = Set Variable all_reject2_${UNIQUE_ID}
|
|
|
|
# Create contexts
|
|
Run Process ${PYTHON} -m cleveragents actor run
|
|
... -c ${SIMPLE_CONFIG}
|
|
... --context ${ctx1}
|
|
... --context-dir ${CONTEXT_DIR}
|
|
... --unsafe
|
|
... --allow-rxpy-in-run-mode
|
|
... test-actor "test"
|
|
|
|
Run Process ${PYTHON} -m cleveragents actor run
|
|
... -c ${SIMPLE_CONFIG}
|
|
... --context ${ctx2}
|
|
... --context-dir ${CONTEXT_DIR}
|
|
... --unsafe
|
|
... --allow-rxpy-in-run-mode
|
|
... test-actor "test"
|
|
|
|
# Delete all with confirmation rejected
|
|
${result} = Run Process ${PYTHON} -m cleveragents context delete
|
|
... --all
|
|
... --context-dir ${CONTEXT_DIR}
|
|
... stdin=n\n
|
|
|
|
Should Be Equal As Integers ${result.rc} 0
|
|
Directory Should Exist ${CONTEXT_DIR}/${ctx1}
|
|
Directory Should Exist ${CONTEXT_DIR}/${ctx2}
|
|
Should Contain ${result.stdout} cancelled
|
|
|
|
Test Error When Both Name And All Provided
|
|
[Documentation] Test error when both NAME and --all are provided
|
|
${result} = Run Process ${PYTHON} -m cleveragents context delete
|
|
... test_context
|
|
... --all
|
|
... --context-dir ${CONTEXT_DIR}
|
|
|
|
Should Not Be Equal As Integers ${result.rc} 0
|
|
Should Contain Any ${result.stderr} ${result.stdout} Cannot specify NAME when using --all
|
|
|
|
Test Error When Neither Name Nor All Provided
|
|
[Documentation] Test error when neither NAME nor --all is provided
|
|
${result} = Run Process ${PYTHON} -m cleveragents context delete
|
|
... --context-dir ${CONTEXT_DIR}
|
|
|
|
Should Not Be Equal As Integers ${result.rc} 0
|
|
Should Contain Any ${result.stderr} ${result.stdout} Must specify NAME or use --all
|
|
|
|
Test Delete All When No Contexts Exist
|
|
[Documentation] Test delete all when directory is empty
|
|
# Ensure directory is empty
|
|
Empty Directory ${CONTEXT_DIR}
|
|
|
|
${result} = Run Process ${PYTHON} -m cleveragents context delete
|
|
... --all
|
|
... --yes
|
|
... --context-dir ${CONTEXT_DIR}
|
|
|
|
Should Be Equal As Integers ${result.rc} 0
|
|
Should Contain ${result.stdout} No contexts found
|
|
|
|
Test Delete Non Existent Context
|
|
[Documentation] Test deleting a context that doesn't exist
|
|
${result} = Run Process ${PYTHON} -m cleveragents context delete
|
|
... non_existent_context_${UNIQUE_ID}
|
|
... --yes
|
|
... --context-dir ${CONTEXT_DIR}
|
|
|
|
Should Not Be Equal As Integers ${result.rc} 0
|
|
Should Contain Any ${result.stderr} ${result.stdout} does not exist
|
|
|
|
Test Delete All Shows Context List Before Deletion
|
|
[Documentation] Test that --all shows context list before confirmation
|
|
[Setup] Empty Directory ${CONTEXT_DIR}
|
|
${ctx1} = Set Variable list_ctx1_${UNIQUE_ID}
|
|
${ctx2} = Set Variable list_ctx2_${UNIQUE_ID}
|
|
${ctx3} = Set Variable list_ctx3_${UNIQUE_ID}
|
|
|
|
# Create contexts
|
|
Run Process ${PYTHON} -m cleveragents actor run
|
|
... -c ${SIMPLE_CONFIG}
|
|
... --context ${ctx1}
|
|
... --context-dir ${CONTEXT_DIR}
|
|
... --unsafe
|
|
... --allow-rxpy-in-run-mode
|
|
... test-actor "test"
|
|
|
|
Run Process ${PYTHON} -m cleveragents actor run
|
|
... -c ${SIMPLE_CONFIG}
|
|
... --context ${ctx2}
|
|
... --context-dir ${CONTEXT_DIR}
|
|
... --unsafe
|
|
... --allow-rxpy-in-run-mode
|
|
... test-actor "test"
|
|
|
|
Run Process ${PYTHON} -m cleveragents actor run
|
|
... -c ${SIMPLE_CONFIG}
|
|
... --context ${ctx3}
|
|
... --context-dir ${CONTEXT_DIR}
|
|
... --unsafe
|
|
... --allow-rxpy-in-run-mode
|
|
... test-actor "test"
|
|
|
|
# Delete all with confirmation to see list
|
|
${result} = Run Process ${PYTHON} -m cleveragents context delete
|
|
... --all
|
|
... --context-dir ${CONTEXT_DIR}
|
|
... stdin=n\n
|
|
|
|
Should Contain ${result.stdout} Found 3 context
|
|
Should Contain ${result.stdout} ${ctx1}
|
|
Should Contain ${result.stdout} ${ctx2}
|
|
Should Contain ${result.stdout} ${ctx3}
|
|
|
|
*** Keywords ***
|
|
Setup Test Environment
|
|
${timestamp} = Get Current Date result_format=%Y%m%d_%H%M%S
|
|
${random} = Evaluate random.randint(1000, 9999) modules=random
|
|
Set Suite Variable ${UNIQUE_ID} ${timestamp}_${random}
|
|
Set Suite Variable ${TEMP} ${TEMPDIR}/ca_delete_test_${UNIQUE_ID}
|
|
Set Suite Variable ${CONTEXT_DIR} ${TEMP}/contexts
|
|
Create Directory ${TEMP}
|
|
Create Directory ${CONTEXT_DIR}
|
|
|
|
Cleanup Test Environment
|
|
Run Keyword And Ignore Error Remove Directory ${TEMP} recursive=True
|
|
|
|
Should Contain Any
|
|
[Arguments] ${text1} ${text2} ${expected}
|
|
${combined} = Set Variable ${text1}${text2}
|
|
Should Contain ${combined} ${expected}
|