Skip to content

[FEATURE] Chaos test scenarios for transient failure recovery #134

Description

@koydas

🎯 Goal

Validate that the retry and error classification logic holds under simulated failure conditions — and prevent regressions as resilience features are added.

📍 Context

  • Repo: autonomous-dev-loop
  • Domain: Robustness validation
  • Component: scripts/tests/anthropic_client.test.mjs, scripts/tests/groq_client.test.mjs, scripts/tests/llm_client.test.mjs, scripts/tests/smoke.test.mjs

🚀 Description

The test suite is already comprehensive for happy-path and input validation scenarios. What is missing is targeted failure injection:

  • groq_client.test.mjs covers 429 retry — good. No equivalent for 5xx.
  • anthropic_client.test.mjs has no retry count verification tests (no check on exact number of fetch calls).
  • llm_client.test.mjs does not verify that provider fallback is blocked on permanent 4xx errors.
  • No test injects a network-level error (connection reset) to verify it is treated as retryable.
  • No test verifies timeout abort behaviour.
  • smoke.test.mjs has no scenario for a run that fails transiently and recovers.

Dependencies resolved: #109 (error taxonomy) ✅ and #111 (retry utility) ✅ are both merged. scripts/lib/retry.mjs, scripts/lib/error_taxonomy.mjs, and scripts/lib/anthropic_client.mjs (with retryWithBackoff) are all in place.

🧩 Scope

In:

  • scripts/tests/groq_client.test.mjs: add cases for HTTP 500, 502, 503, 504 — verify each is retried up to maxAttempts then throws.
  • scripts/tests/anthropic_client.test.mjs: add cases for 500/503 retry (exact call count), 401 immediate throw (1 call only), network reset retried.
  • scripts/tests/llm_client.test.mjs:
    • Verify fallback to secondary provider does NOT occur when primary returns 401.
    • Verify fallback DOES occur when primary returns 503 and exhausts retries.
  • scripts/tests/retry.test.mjs:
    • Backoff sequence correctness (~200, ~400, ~800 ms before jitter).
    • Timeout abort (AbortError) counted as a retryable attempt.
    • Retry-After header respected.
  • scripts/tests/smoke.test.mjs: add one scenario — first LLM call returns 503, second succeeds — verify output is correct and attempt counter is 2.
  • scripts/lib/anthropic_client.mjs: fix network TypeError currently marked as retryable: false — should be retryable.

Out:

  • E2E tests requiring real network calls to Anthropic or Groq.
  • Performance benchmarks.

🧪 Acceptance criteria

  • When a 401 error occurs in callLLM, the secondary provider is never called and exactly one fetch call is made.
  • When a network error (TypeError) occurs in callAnthropic, the retry count increases by 1 and the error is treated as retryable.
  • When a timeout (AbortError) occurs, it is counted as a retryable attempt and the retry count increases by 1.
  • When Retry-After header is present, the retry delay matches the header value (using fake timers — no real setTimeout).
  • When all retry attempts are exhausted, the final error is thrown without additional fetch calls.
  • A mocked 503 response on callAnthropic is retried and eventually returns the mocked success response (exact call count asserted).
  • A mocked 503 response that persists across all attempts throws after exactly maxAttempts total calls.
  • callLLM with a primary provider returning 503 and exhausting retries: secondary provider IS called.
  • HTTP 500, 502, 503, 504 on callGroq are each retried up to maxAttempts then throw.
  • Smoke: first LLM call returns 503, second succeeds — output is correct and attempt counter is 2.

⚙️ Constraints

  • All tests must be deterministic — no flakiness from timing.
  • No new test dependencies beyond what is already used in the suite.
  • Tests must pass with node --test scripts/tests/*.test.mjs without any additional flags.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestready-for-devIssue validated and ready for automated implementation

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions