Files
cleveragents-core/robot/e2e/wf16_devcontainer.robot
T
hurui200320 e2b127b7e5
CI / lint (pull_request) Successful in 37s
CI / typecheck (pull_request) Successful in 1m18s
CI / security (pull_request) Successful in 56s
CI / quality (pull_request) Successful in 48s
CI / build (pull_request) Successful in 30s
CI / helm (pull_request) Successful in 41s
CI / push-validation (pull_request) Successful in 28s
CI / integration_tests (pull_request) Successful in 4m32s
CI / e2e_tests (pull_request) Successful in 4m42s
CI / coverage (pull_request) Successful in 13m24s
CI / unit_tests (pull_request) Successful in 3m13s
CI / docker (pull_request) Successful in 1m36s
CI / status-check (pull_request) Successful in 1s
CI / benchmark-regression (push) Failing after 0s
CI / benchmark-publish (push) Failing after 0s
CI / push-validation (push) Successful in 12s
CI / build (push) Successful in 15s
CI / helm (push) Successful in 16s
CI / lint (push) Successful in 43s
CI / typecheck (push) Successful in 51s
CI / security (push) Successful in 51s
CI / e2e_tests (push) Successful in 2m14s
CI / quality (push) Successful in 3m44s
CI / integration_tests (push) Successful in 7m0s
CI / unit_tests (push) Successful in 8m33s
CI / coverage (push) Successful in 6m21s
CI / docker (push) Successful in 1m31s
CI / status-check (push) Successful in 2s
fix(e2e): replace naive OpenAI key-presence check with live API probe in E2E suite setups
The existing actor-selection logic in several E2E suite setups checked only
whether OPENAI_API_KEY was present (non-empty). A valid key that has hit its
quota limit passes that check but fails at runtime with HTTP 429, causing the
test to fail even though Anthropic credits are available.

Changes:
- Add robot/e2e/check_openai_key.py: stdlib-only (urllib.request) script that
  sends a minimal chat-completion request ('Hi', max_tokens=1, gpt-4o-mini) to
  the OpenAI API. Exits 0 on HTTP 200; exits 1 for quota (429), auth (401),
  network errors, or any other failure.
- Add 'Resolve LLM Actor' keyword to robot/e2e/common_e2e.resource: runs the
  probe script via ${PYTHON} and returns the openai_model argument (default
  openai/gpt-4o) on success, or the anthropic_model argument (default
  anthropic/claude-sonnet-4-20250514) on failure. Skips the probe entirely when
  OPENAI_API_KEY is not set.
- Update m6_acceptance.robot, wf04_multi_project.robot, wf05_db_migration.robot,
  wf07_cicd.robot, and wf16_devcontainer.robot to use 'Resolve LLM Actor'
  instead of the inline has_openai boolean check.

No production source code (src/) is modified. The decision to fall back to
Anthropic is made once per suite setup, before any test runs.

Closes #10198
2026-04-17 18:00:47 +08:00

147 lines
6.5 KiB
Plaintext

*** Settings ***
Documentation E2E test for Workflow Example 16: Devcontainer-Driven Development
... (supervised automation profile).
...
... Exercises the devcontainer-specific plan lifecycle:
... devcontainer auto-detection during resource registration,
... lazy container build during plan execution, tool invocation
... routing to the container workspace, and apply writing changes
... back to the host filesystem via bind mount.
...
... **Devcontainer-specific assertions** are strict and contribute
... to AC validation. If one or more AC indicators are missing,
... the test records each unmet AC and fails explicitly rather
... than skipping or passing silently.
...
... The test is tagged ``tdd_expected_fail`` because devcontainer
... features are not yet fully wired. The
... ``tdd_expected_fail_listener`` inverts the failure to a pass
... in CI until all AC indicators are present.
...
... Zero mocking — real CLI, real LLM API keys.
Resource common_e2e.resource
Suite Setup WF16 Suite Setup
Suite Teardown E2E Suite Teardown
Force Tags E2E
*** Variables ***
${ACTION_PREFIX} local/wf16-devcontainer-action
${RESOURCE_PREFIX} local/wf16-devcontainer-repo
${PROJECT_PREFIX} local/wf16-devcontainer-project
*** Keywords ***
WF16 Suite Setup
[Documentation] E2E Suite Setup plus database initialisation, unique suffix
... generation, and dynamic actor selection for WF16 tests.
[Tags] tdd_issue tdd_issue_4188 tdd_expected_fail
E2E Suite Setup
# Initialise the database so CLI commands work in all tests.
# Use --force because the workspace may already contain an initialised project.
${init}= Run CleverAgents Command init --force --yes
Should Be Equal As Integers ${init.rc} 0
# Generate a unique suffix for resource/project names to avoid UNIQUE
# constraint collisions when tests run in parallel or are re-run
# against the same database (uuid4 provides ~4 billion possibilities).
${suffix}= Evaluate __import__('uuid').uuid4().hex[:12]
Set Suite Variable ${RUN_SUFFIX} ${suffix}
Set Suite Variable ${ACTION_NAME} ${ACTION_PREFIX}-${suffix}
Set Suite Variable ${RESOURCE_NAME} ${RESOURCE_PREFIX}-${suffix}
Set Suite Variable ${PROJECT_NAME} ${PROJECT_PREFIX}-${suffix}
# Probe the OpenAI API to confirm the key is usable before selecting actor.
# Falls back to Anthropic when the key is absent or quota-exhausted.
# Uses gpt-4o-mini for cost optimization — WF16 exercises plan lifecycle
# mechanics (not LLM quality), so a smaller model suffices.
${actor}= Resolve LLM Actor openai_model=openai/gpt-4o-mini
Set Suite Variable ${SELECTED_ACTOR} ${actor}
Create Devcontainer Repo
[Documentation] Create a temp git repo with devcontainer configuration.
... Returns the path to the created repository.
${repo}= Create Temp Git Repo wf16-devcontainer-${RUN_SUFFIX}
Create Directory ${repo}${/}.devcontainer
Create Directory ${repo}${/}src
${devcontainer_json}= Catenate SEPARATOR=\n
... {
... ${SPACE}${SPACE}"name": "wf16-dev",
... ${SPACE}${SPACE}"image": "mcr.microsoft.com/devcontainers/python:3.12@sha256:3de8f04c3748897ff3aa32b11ee18306d6c56556f4d548a276d0ff397b28b9da",
... ${SPACE}${SPACE}"customizations": {
... ${SPACE}${SPACE}${SPACE}${SPACE}"vscode": {
... ${SPACE}${SPACE}${SPACE}${SPACE}${SPACE}${SPACE}"extensions": ["ms-python.python"]
... ${SPACE}${SPACE}${SPACE}${SPACE}}
... ${SPACE}${SPACE}}
... }
Create File ${repo}${/}.devcontainer${/}devcontainer.json ${devcontainer_json}
${app_content}= Catenate SEPARATOR=\n
... """Main application module."""
... ${EMPTY}
... ${EMPTY}
... def main():
... ${SPACE}${SPACE}${SPACE}${SPACE}"""Entry point."""
... ${SPACE}${SPACE}${SPACE}${SPACE}print("Hello from devcontainer app")
... ${SPACE}${SPACE}${SPACE}${SPACE}return 0
Create File ${repo}${/}src${/}app.py ${app_content}
${test_content}= Catenate SEPARATOR=\n
... """Tests for the application."""
... from src.app import main
... ${EMPTY}
... ${EMPTY}
... def test_main():
... ${SPACE}${SPACE}${SPACE}${SPACE}assert main() == 0
Create File ${repo}${/}src${/}test_app.py ${test_content}
Create File ${repo}${/}src${/}__init__.py \n
Create File ${repo}${/}requirements.txt pytest>=7.0\n
${r_add}= Run Process git add . cwd=${repo} timeout=60s on_timeout=kill
Should Be Equal As Integers ${r_add.rc} 0 msg=git add failed (rc=${r_add.rc})
${r_commit}= Run Process git commit -m Initial devcontainer project cwd=${repo} timeout=60s on_timeout=kill
Should Be Equal As Integers ${r_commit.rc} 0 msg=git commit failed (rc=${r_commit.rc})
RETURN ${repo}
WF16 Test Teardown
[Documentation] Log diagnostic context on failure for debugging.
... Captures plan status when a plan ID is available.
${plan_id}= Get Variable Value ${WF16_PLAN_ID} ${EMPTY}
IF '${plan_id}' != ''
${status} ${result}= Run Keyword And Ignore Error
... Run CleverAgents Command plan status ${plan_id} --format json expected_rc=None timeout=30s
IF '${status}' == 'PASS'
Log Teardown plan status: ${result.stdout} WARN
END
END
*** Test Cases ***
WF16 Devcontainer Driven Development Supervised Profile
[Documentation] Supervised-profile workflow exercising devcontainer-specific
... behaviors: auto-detection during resource registration,
... lazy container build during execution, tool invocation
... routing to the container workspace, and apply writing
... changes back to the host filesystem via bind mount.
...
... Devcontainer-specific assertions are enforced via
... explicit AC checks. Missing AC indicators are collected
... and reported as explicit test failures.
...
... Tagged ``tdd_expected_fail`` because devcontainer features
... are not yet fully wired; the listener inverts the failure
... to a CI pass until all AC indicators are present.
[Tags] tdd_issue tdd_issue_4188 tdd_expected_fail tdd_issue_1208
# Timeout budget: 35 minutes test-level timeout. Per-step timeouts sum
# higher in theory, but retries and conditional paths are mutually
# exclusive — realistic worst-case is well under 35 minutes.
[Timeout] 35 minutes
[Teardown] WF16 Test Teardown
Skip If No LLM Keys
${ac_checks_missing}= Evaluate []
Set Test Variable ${WF16_PLAN_ID} ${EMPTY}