Files
cleveragents-core/robot/rxpy_route_validation.robot
brent.edwards 92e2585358
CI / lint (pull_request) Successful in 39s
CI / helm (pull_request) Successful in 32s
CI / build (pull_request) Successful in 32s
CI / push-validation (pull_request) Successful in 31s
CI / quality (pull_request) Successful in 1m0s
CI / security (pull_request) Successful in 1m2s
CI / typecheck (pull_request) Successful in 1m40s
CI / unit_tests (pull_request) Successful in 6m25s
CI / docker (pull_request) Successful in 1m27s
CI / coverage (pull_request) Successful in 10m51s
CI / integration_tests (pull_request) Successful in 22m36s
CI / status-check (pull_request) Successful in 3s
fix: add missing validations/unit-tests.yaml example
Add the missing workflow validation example and keep the #1039 TDD regression active by removing the expected-fail tag and updating scenario narrative.\n\nTo satisfy the required full quality gates, stabilize flaky integration behavior encountered during this issue run: use a shared SQLAlchemy session in resource DAG scripts, isolate RxPY validation temp paths per test run, extend transient subprocess timeouts/retry behavior, and clear stale pabot worker artifacts before integration runs so repeated nox executions are reliable.\n\nISSUES CLOSED: #1039
2026-05-30 00:09:20 -04:00

360 lines
13 KiB
Plaintext

*** Settings ***
Documentation Integration tests for RxPY route validation in run command
Library Process
Library OperatingSystem
Library String
Library Collections
Resource ${CURDIR}/v2_paths.resource
Suite Setup Setup Test Environment
Suite Teardown Cleanup Test Environment
*** Variables ***
${TEST_DIR} ${TEMPDIR}/rxpy_validation_test
${RXPY_CONFIG} ${TEST_DIR}/rxpy_config.yaml
${LANGGRAPH_CONFIG} ${TEST_DIR}/langgraph_config.yaml
${CONTEXT_DIR} ${TEST_DIR}/test_contexts
${UNIQUE_ID} ${EMPTY}
${RXPY_RUN_MODE_ERROR} RxPY stream routes are only supported in run mode unless allowed. Use --allow-rxpy-in-run-mode to bypass.
*** Test Cases ***
Test Run Command Rejects RxPY Routes
[Documentation] Verify run command rejects RxPY stream routes
[Tags] rxpy validation run
Create RxPY Config File
# Try to run with RxPY routes - should fail
${result} = Run Process ${PYTHON} -m cleveragents actor run
... -c ${RXPY_CONFIG}
... --unsafe
... test-actor test
... stderr=STDOUT timeout=120s on_timeout=kill
Should Not Be Equal As Integers ${result.rc} 0 Command should have failed
Should Contain ${result.stdout} ${RXPY_RUN_MODE_ERROR}
Should Contain ${result.stdout} allow-rxpy-in-run-mode
Test Run Command With Context Does Not Create Context
[Documentation] Verify that no context is created when RxPY validation fails
[Tags] rxpy validation context
${context_name} = Set Variable rxpy_test_ctx_${UNIQUE_ID}
Create RxPY Config File
# Ensure context doesn't exist
Delete Context If Exists ${context_name}
# Try to run with --context flag
${result} = Run Process ${PYTHON} -m cleveragents actor run
... -c ${RXPY_CONFIG}
... --unsafe
... --context ${context_name}
... --context-dir ${CONTEXT_DIR}
... test-actor test
... stderr=STDOUT timeout=120s on_timeout=kill
Should Not Be Equal As Integers ${result.rc} 0 Command should have failed
Should Contain ${result.stdout} ${RXPY_RUN_MODE_ERROR}
# Verify context was NOT created
${context_exists} = Context Exists ${context_name}
Should Not Be True ${context_exists} Context should not have been created
Test Run Command With LangGraph Routes Succeeds
[Documentation] Verify run command works with LangGraph routes
[Tags] langgraph validation run slow
Create LangGraph Config File
# Run with LangGraph routes - should succeed
${context_name} = Set Variable rxpy_test_ctx_${UNIQUE_ID}
${result} = Run Process ${PYTHON} -m cleveragents actor run
... -c ${LANGGRAPH_CONFIG}
... --context-dir ${CONTEXT_DIR}
... test-actor test
... stderr=STDOUT timeout=120s on_timeout=kill
# For now, might fail on actual execution but shouldn't have route validation error
${output} = Set Variable ${result.stdout}
Should Not Contain ${output} ${RXPY_RUN_MODE_ERROR}
Test Run Command Accepts RxPY Routes When Allowed
[Documentation] Verify actor run works with RxPY routes when allowed
[Tags] rxpy run slow
Create RxPY Config File
${context_name} = Set Variable rxpy_test_ctx_${UNIQUE_ID}
${result} = Run Process ${PYTHON} -m cleveragents actor run
... -c ${RXPY_CONFIG}
... --unsafe
... --allow-rxpy-in-run-mode
... --context ${context_name}
... --context-dir ${CONTEXT_DIR}
... test-actor test
... stderr=STDOUT
... timeout=120s on_timeout=kill
Should Be Equal As Integers ${result.rc} 0
Should Not Contain ${result.stdout} ${RXPY_RUN_MODE_ERROR}
Test Error Message Content
[Documentation] Verify error message contains helpful information
[Tags] rxpy validation error-message
Create RxPY Config File
${result} = Run Process ${PYTHON} -m cleveragents actor run
... -c ${RXPY_CONFIG}
... --unsafe
... test-actor test
... stderr=STDOUT timeout=120s on_timeout=kill
Should Not Be Equal As Integers ${result.rc} 0
# Check error message contains all important information
${output} = Convert To Lower Case ${result.stdout}
Should Contain ${output} nested
Should Contain ${output} completion detection
Should Contain ${output} run mode
Should Contain ${output} langgraph
Test Run With Nested Switch Operators
[Documentation] Verify run command rejects configs with nested switch operators
[Tags] rxpy nested validation
Create Nested Switch Config File
${result} = Run Process ${PYTHON} -m cleveragents actor run
... -c ${TEST_DIR}/nested_switch_config.yaml
... --unsafe
... test-actor test
... stderr=STDOUT timeout=120s on_timeout=kill
Should Not Be Equal As Integers ${result.rc} 0
Should Contain ${result.stdout} ${RXPY_RUN_MODE_ERROR}
Test Mixed Route Types Detection
[Documentation] Verify detection works with mix of RxPY and LangGraph routes
[Tags] rxpy mixed validation
Create Mixed Routes Config File
# Should detect RxPY routes even if LangGraph routes also present
${result} = Run Process ${PYTHON} -m cleveragents actor run
... -c ${TEST_DIR}/mixed_config.yaml
... --unsafe
... test-actor test
... stderr=STDOUT timeout=120s on_timeout=kill
Should Not Be Equal As Integers ${result.rc} 0
Should Contain ${result.stdout} ${RXPY_RUN_MODE_ERROR}
Test Context File Not Created On Multiple Runs
[Documentation] Verify repeated failed runs do not create context
[Tags] rxpy context validation
${context_name} = Set Variable rxpy_multi_test_${UNIQUE_ID}
Create RxPY Config File
Delete Context If Exists ${context_name}
# Run multiple times
FOR ${i} IN RANGE 3
${result} = Run Process ${PYTHON} -m cleveragents actor run
... -c ${RXPY_CONFIG}
... --unsafe
... --context ${context_name}
... --context-dir ${CONTEXT_DIR}
... test-actor test
... stderr=STDOUT timeout=120s on_timeout=kill
Should Not Be Equal As Integers ${result.rc} 0
END
# Verify context still doesn't exist after multiple attempts
${context_exists} = Context Exists ${context_name}
Should Not Be True ${context_exists}
*** Keywords ***
Setup Test Environment
[Documentation] Setup test environment
# Generate unique ID for this test run first, then scope all temp paths
# to that ID so parallel suites cannot collide on shared temp files.
${timestamp} = Get Time epoch
Set Suite Variable ${UNIQUE_ID} ${timestamp}
${test_dir} = Set Variable ${TEMPDIR}/rxpy_validation_test_${timestamp}
${rxpy_config} = Set Variable ${test_dir}/rxpy_config.yaml
${langgraph_config} = Set Variable ${test_dir}/langgraph_config.yaml
${context_dir} = Set Variable ${test_dir}/test_contexts
Set Suite Variable ${TEST_DIR} ${test_dir}
Set Suite Variable ${RXPY_CONFIG} ${rxpy_config}
Set Suite Variable ${LANGGRAPH_CONFIG} ${langgraph_config}
Set Suite Variable ${CONTEXT_DIR} ${context_dir}
Create Directory ${TEST_DIR}
Create Directory ${CONTEXT_DIR}
Cleanup Test Environment
[Documentation] Clean up test environment
Remove Directory ${TEST_DIR} recursive=True
Create RxPY Config File
[Documentation] Create a test config with RxPY stream routes
${config} = Catenate SEPARATOR=\n
... actors:
... ${SPACE*2}echo_actor:
... ${SPACE*4}type: tool
... ${SPACE*4}config:
... ${SPACE*6}tools:
... ${SPACE*8}- echo
... ${SPACE*6}safe_mode: true
... ${EMPTY}
... routes:
... ${SPACE*2}echo_stream:
... ${SPACE*4}type: stream
... ${SPACE*4}stream_type: cold
... ${SPACE*4}operators:
... ${SPACE*6}- type: map
... ${SPACE*8}params:
... ${SPACE*10}actor: echo_actor
... ${SPACE*4}publications:
... ${SPACE*6}- __output__
... ${EMPTY}
... merges:
... ${SPACE*2}- sources: [__input__]
... ${SPACE*4}target: echo_stream
Create File ${RXPY_CONFIG} ${config}
Create LangGraph Config File
[Documentation] Create a test config with LangGraph routes
${config} = Catenate SEPARATOR=\n
... actors:
... ${SPACE*2}echo_actor:
... ${SPACE*4}type: tool
... ${SPACE*4}config:
... ${SPACE*6}tools:
... ${SPACE*8}- echo
... ${SPACE*6}safe_mode: true
... ${EMPTY}
... routes:
... ${SPACE*2}main:
... ${SPACE*4}type: graph
... ${SPACE*4}nodes:
... ${SPACE*6}- id: start
... ${SPACE*8}actor: echo_actor
... ${SPACE*4}edges:
... ${SPACE*6}- from: __input__
... ${SPACE*8}to: start
... ${SPACE*6}- from: start
... ${SPACE*8}to: __output__
... ${EMPTY}
... merges:
... ${SPACE*2}- sources: [__input__]
... ${SPACE*4}target: main
Create File ${LANGGRAPH_CONFIG} ${config}
Create Nested Switch Config File
[Documentation] Create a config with nested switch operators
${config} = Catenate SEPARATOR=\n
... actors:
... ${SPACE*2}test_actor:
... ${SPACE*4}type: tool
... ${SPACE*4}config:
... ${SPACE*6}tools:
... ${SPACE*8}- echo
... ${SPACE*6}safe_mode: true
... ${EMPTY}
... routes:
... ${SPACE*2}main:
... ${SPACE*4}type: stream
... ${SPACE*4}stream_type: cold
... ${SPACE*4}operators:
... ${SPACE*6}- type: switch
... ${SPACE*8}params:
... ${SPACE*10}cases:
... ${SPACE*12}- condition: "test"
... ${SPACE*14}route: nested_route
... ${SPACE*2}nested_route:
... ${SPACE*4}type: stream
... ${SPACE*4}stream_type: cold
... ${SPACE*4}operators:
... ${SPACE*6}- type: map
... ${SPACE*8}params:
... ${SPACE*10}actor: test_actor
... ${SPACE*4}publications:
... ${SPACE*6}- __output__
... ${EMPTY}
... merges:
... ${SPACE*2}- sources: [__input__]
... ${SPACE*4}target: main
Create File ${TEST_DIR}/nested_switch_config.yaml ${config}
Create Mixed Routes Config File
[Documentation] Create a config with both RxPY and LangGraph routes
${config} = Catenate SEPARATOR=\n
... actors:
... ${SPACE*2}test_actor:
... ${SPACE*4}type: tool
... ${SPACE*4}config:
... ${SPACE*6}tools:
... ${SPACE*8}- echo
... ${SPACE*6}safe_mode: true
... ${EMPTY}
... routes:
... ${SPACE*2}stream_route:
... ${SPACE*4}type: stream
... ${SPACE*4}stream_type: cold
... ${SPACE*4}operators:
... ${SPACE*6}- type: map
... ${SPACE*8}params:
... ${SPACE*10}actor: test_actor
... ${SPACE*4}publications:
... ${SPACE*6}- __output__
... ${SPACE*2}graph_route:
... ${SPACE*4}type: graph
... ${SPACE*4}entry_point: start
... ${SPACE*4}nodes:
... ${SPACE*6}start:
... ${SPACE*8}type: actor
... ${SPACE*8}actor: test_actor
... ${SPACE*4}edges:
... ${SPACE*6}- source: start
... ${SPACE*8}target: end
... ${EMPTY}
... merges:
... ${SPACE*2}- sources: [__input__]
... ${SPACE*4}target: stream_route
Create File ${TEST_DIR}/mixed_config.yaml ${config}
Delete Context If Exists
[Documentation] Delete a context if it exists
[Arguments] ${context_name}
${result} = Run Process ${PYTHON} -m cleveragents context delete
... ${context_name}
... --context-dir ${CONTEXT_DIR}
... --yes
... stderr=STDOUT
# Don't fail if context doesn't exist
Log Deleted context ${context_name} (if it existed)
Context Exists
[Documentation] Check if a context exists
[Arguments] ${context_name}
${result} = Run Process ${PYTHON} -m cleveragents context show
... ${context_name}
... --context-dir ${CONTEXT_DIR}
... stderr=STDOUT
# If return code is 0, context exists
${exists} = Evaluate ${result.rc} == 0
RETURN ${exists}