"""Step definitions for ServiceRetryWiring settings override tests.""" from __future__ import annotations import asyncio from typing import Any from behave import given, then, when # --------------------------------------------------------------------------- # Settings individual override scenarios # --------------------------------------------------------------------------- @given("I have Settings with non-default retry_max_attempts {value:d}") def step_settings_max_attempts(context: Any, value: int) -> None: import os from cleveragents.config.settings import Settings os.environ["CLEVERAGENTS_RETRY_MAX_ATTEMPTS"] = str(value) try: context.settings = Settings( database_url="sqlite:///test_retry.db", mock_providers=True, env="test", ) finally: os.environ.pop("CLEVERAGENTS_RETRY_MAX_ATTEMPTS", None) @when("I create a ServiceRetryWiring from those max-attempts Settings") def step_create_wiring_max_attempts(context: Any) -> None: from cleveragents.application.services.service_retry_wiring import ( ServiceRetryWiring, ) context.wiring = ServiceRetryWiring(context.settings) @given("I have Settings with non-default circuit_breaker_failure_threshold {value:d}") def step_settings_cb_threshold(context: Any, value: int) -> None: import os from cleveragents.config.settings import Settings os.environ["CLEVERAGENTS_CB_FAILURE_THRESHOLD"] = str(value) try: context.settings = Settings( database_url="sqlite:///test_retry.db", mock_providers=True, env="test", ) finally: os.environ.pop("CLEVERAGENTS_CB_FAILURE_THRESHOLD", None) @when("I create a ServiceRetryWiring from those cb-threshold Settings") def step_create_wiring_cb_threshold(context: Any) -> None: from cleveragents.application.services.service_retry_wiring import ( ServiceRetryWiring, ) context.wiring = ServiceRetryWiring(context.settings) @then("the plan_service circuit breaker should have failure_threshold {value:d}") def step_check_cb_threshold_override(context: Any, value: int) -> None: cb = context.wiring.get_circuit_breaker("plan_service") assert cb is not None assert cb.failure_threshold == value @when('I check is_circuit_open for "{name}"') def step_check_is_circuit_open_unknown(context: Any, name: str) -> None: context.unknown_circuit_open = context.wiring.is_circuit_open(name) @then("the circuit should report not open") def step_verify_circuit_not_open(context: Any) -> None: assert context.unknown_circuit_open is False @when("I async_execute the function with circuit breaker enabled") def step_async_execute_with_cb(context: Any) -> None: loop = asyncio.new_event_loop() try: context.async_result = loop.run_until_complete( context.wiring.async_execute( service_name="plan_service", operation_name="test_async_cb_retry", func=context.async_test_func, idempotent=True, ) ) context.async_exec_error = None except Exception as exc: context.async_exec_error = exc context.async_result = None finally: loop.close() @given("I have Settings with non-default retry_base_delay {value:g}") def step_settings_base_delay(context: Any, value: float) -> None: import os from cleveragents.config.settings import Settings os.environ["CLEVERAGENTS_RETRY_BASE_DELAY"] = str(value) try: context.settings = Settings( database_url="sqlite:///test_retry.db", mock_providers=True, env="test", ) finally: os.environ.pop("CLEVERAGENTS_RETRY_BASE_DELAY", None) @when("I create a ServiceRetryWiring from those base-delay Settings") def step_create_wiring_base_delay(context: Any) -> None: from cleveragents.application.services.service_retry_wiring import ( ServiceRetryWiring, ) context.wiring = ServiceRetryWiring(context.settings) @then("the plan_service policy should have base_delay {value:g}") def step_check_base_delay_override(context: Any, value: float) -> None: policy = context.wiring.get_policy("plan_service") assert policy.retry.base_delay == value @given("I have Settings with non-default circuit_breaker_recovery_timeout {value:g}") def step_settings_cb_recovery_timeout(context: Any, value: float) -> None: import os from cleveragents.config.settings import Settings os.environ["CLEVERAGENTS_CB_RECOVERY_TIMEOUT"] = str(value) try: context.settings = Settings( database_url="sqlite:///test_retry.db", mock_providers=True, env="test", ) finally: os.environ.pop("CLEVERAGENTS_CB_RECOVERY_TIMEOUT", None) @when("I create a ServiceRetryWiring from those recovery-timeout Settings") def step_create_wiring_recovery_timeout(context: Any) -> None: from cleveragents.application.services.service_retry_wiring import ( ServiceRetryWiring, ) context.wiring = ServiceRetryWiring(context.settings) @then("the plan_service circuit breaker should have recovery_timeout {value:g}") def step_check_recovery_timeout_override(context: Any, value: float) -> None: cb = context.wiring.get_circuit_breaker("plan_service") assert cb is not None assert cb.recovery_timeout == value @given("I have Settings with non-default circuit_breaker_cooldown {value:g}") def step_settings_cb_cooldown(context: Any, value: float) -> None: import os from cleveragents.config.settings import Settings os.environ["CLEVERAGENTS_CB_COOLDOWN"] = str(value) try: context.settings = Settings( database_url="sqlite:///test_retry.db", mock_providers=True, env="test", ) finally: os.environ.pop("CLEVERAGENTS_CB_COOLDOWN", None) @when("I create a ServiceRetryWiring from those cooldown Settings") def step_create_wiring_cooldown(context: Any) -> None: from cleveragents.application.services.service_retry_wiring import ( ServiceRetryWiring, ) context.wiring = ServiceRetryWiring(context.settings) @then("the plan_service circuit breaker should have cooldown_seconds {value:g}") def step_check_cooldown_override(context: Any, value: float) -> None: cb = context.wiring.get_circuit_breaker("plan_service") assert cb is not None assert cb.cooldown_seconds == value @given("I have Settings with non-default retry_max_delay {value:g}") def step_settings_max_delay(context: Any, value: float) -> None: import os from cleveragents.config.settings import Settings os.environ["CLEVERAGENTS_RETRY_MAX_DELAY"] = str(value) try: context.settings = Settings( database_url="sqlite:///test_retry.db", mock_providers=True, env="test", ) finally: os.environ.pop("CLEVERAGENTS_RETRY_MAX_DELAY", None) @when("I create a ServiceRetryWiring from those max-delay Settings") def step_create_wiring_max_delay(context: Any) -> None: from cleveragents.application.services.service_retry_wiring import ( ServiceRetryWiring, ) context.wiring = ServiceRetryWiring(context.settings) @then("the plan_service policy should have max_delay {value:g}") def step_check_max_delay_override(context: Any, value: float) -> None: policy = context.wiring.get_policy("plan_service") assert policy.retry.max_delay == value @given("I have Settings with non-default retry_jitter {value}") def step_settings_jitter(context: Any, value: str) -> None: import os from cleveragents.config.settings import Settings os.environ["CLEVERAGENTS_RETRY_JITTER"] = value try: context.settings = Settings( database_url="sqlite:///test_retry.db", mock_providers=True, env="test", ) finally: os.environ.pop("CLEVERAGENTS_RETRY_JITTER", None) @when("I create a ServiceRetryWiring from those jitter Settings") def step_create_wiring_jitter(context: Any) -> None: from cleveragents.application.services.service_retry_wiring import ( ServiceRetryWiring, ) context.wiring = ServiceRetryWiring(context.settings) @then("the plan_service policy should have jitter {value}") def step_check_jitter_override(context: Any, value: str) -> None: policy = context.wiring.get_policy("plan_service") expected = value == "True" assert policy.retry.jitter == expected