Files
cleveragents-core/features/config_resolution.feature
T

183 lines
7.6 KiB
Gherkin

Feature: Config service with multi-level resolution
As a developer
I want a config service that resolves values through a precedence chain
So that CLI flags, env vars, project scope, global config, and defaults all work correctly
Background:
Given a clean config service test environment
# --- Resolution levels ---
Scenario: Default value is returned when nothing else is set
When I resolve config key "core.log_level"
Then the resolved value should be "INFO"
And the resolved source should be "default"
Scenario: Global config file overrides default
Given I have written global config key "core.log_level" with value "DEBUG"
When I resolve config key "core.log_level"
Then the resolved value should be "DEBUG"
And the resolved source should be "global"
Scenario: Environment variable overrides global config
Given I have written global config key "core.log_level" with value "DEBUG"
And the environment variable "CLEVERAGENTS_CORE_LOG_LEVEL" is set to "WARNING"
When I resolve config key "core.log_level"
Then the resolved value should be "WARNING"
And the resolved source should be "env_var"
Scenario: CLI flag overrides environment variable
Given the environment variable "CLEVERAGENTS_CORE_LOG_LEVEL" is set to "WARNING"
When I resolve config key "core.log_level" with CLI value "ERROR"
Then the resolved value should be "ERROR"
And the resolved source should be "cli_flag"
Scenario: Project-scoped value overrides global config
Given I have written global config key "core.log_level" with value "DEBUG"
And I have written project "myproj" config key "core.log_level" with value "TRACE"
When I resolve config key "core.log_level" for project "myproj"
Then the resolved value should be "TRACE"
And the resolved source should be "project"
Scenario: Env var still overrides project-scoped value
Given I have written project "myproj" config key "core.log_level" with value "TRACE"
And the environment variable "CLEVERAGENTS_CORE_LOG_LEVEL" is set to "ERROR"
When I resolve config key "core.log_level" for project "myproj"
Then the resolved value should be "ERROR"
And the resolved source should be "env_var"
# --- Env var interpolation ---
Scenario: Env var name matches CLEVERAGENTS convention
When I look up the env var for key "core.log_level"
Then the env var name should be "CLEVERAGENTS_CORE_LOG_LEVEL"
Scenario: Env var interpolation for plan keys
When I look up the env var for key "plan.max_retries"
Then the env var name should be "CLEVERAGENTS_PLAN_MAX_RETRIES"
Scenario: Env var interpolation for provider keys
When I look up the env var for key "provider.temperature"
Then the env var name should be "CLEVERAGENTS_PROVIDER_TEMPERATURE"
# --- Unknown key rejection ---
Scenario: Resolving an unknown key raises an error
When I attempt to resolve unknown key "bogus.nonexistent"
Then the config ValueError message should contain "Unknown configuration key"
Scenario: Validating an unknown key raises an error
When I attempt to validate unknown key "invalid.key"
Then the config ValueError message should contain "Unknown configuration key"
# --- Type validation ---
Scenario: Integer value is coerced from string
Given the environment variable "CLEVERAGENTS_CORE_SERVER_PORT" is set to "9090"
When I resolve config key "core.server_port"
Then the resolved value should be integer 9090
Scenario: Boolean value true is coerced from string
Given the environment variable "CLEVERAGENTS_CORE_DEBUG_ENABLED" is set to "true"
When I resolve config key "core.debug_enabled"
Then the resolved value should be boolean true
Scenario: Boolean value false is coerced from string
Given the environment variable "CLEVERAGENTS_CORE_DEBUG_ENABLED" is set to "false"
When I resolve config key "core.debug_enabled"
Then the resolved value should be boolean false
Scenario: Float value is coerced from string
Given the environment variable "CLEVERAGENTS_PROVIDER_TEMPERATURE" is set to "0.9"
When I resolve config key "provider.temperature"
Then the resolved value should be float 0.9
Scenario: Invalid boolean string raises TypeError
When I attempt to validate type for key "core.debug_enabled" with value "notabool"
Then the config TypeError message should contain "Cannot convert"
Scenario: Invalid integer string raises TypeError
When I attempt to validate type for key "core.server_port" with value "notanumber"
Then the config TypeError message should contain "Type mismatch"
# --- Verbose resolution chain ---
Scenario: Verbose mode returns full resolution chain
When I resolve config key "core.log_level" with verbose mode
Then the resolution chain should have 5 entries
And the chain should include source "cli_flag"
And the chain should include source "env_var"
And the chain should include source "project"
And the chain should include source "global"
And the chain should include source "default"
# --- Key registry ---
Scenario: Registry contains core keys
Then the registry should contain key "core.log_level"
And the registry should contain key "core.debug_enabled"
And the registry should contain key "core.env"
Scenario: Registry contains plan keys
Then the registry should contain key "plan.auto_apply"
And the registry should contain key "plan.max_retries"
And the registry should contain key "plan.timeout_seconds"
Scenario: Registry contains provider keys
Then the registry should contain key "provider.default_provider"
And the registry should contain key "provider.default_model"
And the registry should contain key "provider.temperature"
Scenario: Registry contains sandbox keys
Then the registry should contain key "sandbox.strategy"
And the registry should contain key "sandbox.auto_cleanup"
And the registry should contain key "sandbox.max_age_hours"
Scenario: Registry contains context keys
Then the registry should contain key "context.max_files"
And the registry should contain key "context.max_tokens"
Scenario: Registry contains index keys
Then the registry should contain key "index.enabled"
And the registry should contain key "index.backend"
# --- TOML file management ---
Scenario: Writing and reading TOML config roundtrips
Given I write config data with key "core.log_level" and value "TRACE"
When I read the config file
Then the config data should contain key "core.log_level" with value "TRACE"
Scenario: Config directory is auto-created
When I write config data to a new directory
Then the config directory should exist
Scenario: Non-project-scopable keys ignore project scope
Given I have written project "proj" config key "core.database_url" with value "sqlite:///other.db"
When I resolve config key "core.database_url" for project "proj"
Then the resolved source should be "default"
# --- Resolve all ---
Scenario: Resolve all returns all registered keys
When I resolve all keys
Then the result should contain all registered keys
# --- Set value ---
Scenario: Set value persists to TOML file
When I set config value "core.log_level" to "CRITICAL"
And I read the config file
Then the config data should contain key "core.log_level" with value "CRITICAL"
# --- Entry lookup ---
Scenario: Get entry returns ConfigEntry for valid key
When I get entry for key "core.log_level"
Then the entry should have section "core"
And the entry should have python type "str"
Scenario: Get entry returns None for unknown key
When I get entry for key "nonexistent.key"
Then the entry should be None