Files
cleveragents-core/features/client/server_http_client.feature
freemo 5f7bba3e96 feat(client): add server http client
Implement ServerHttpClient with httpx for server communication including:
- Health check endpoint (GET /health)
- Version negotiation (GET /version, POST /version/negotiate)
- Pagination helpers for list endpoints
- Per-request timeout and retry policy with exponential backoff
- Request/response logging with auth header redaction
- TLS verification toggle with warning when disabled
- Server error responses mapped to domain errors (A2aNotAvailableError, etc.)
- Client-specific exceptions (ServerConnectionError, ServerTimeoutError,
  ServerVersionMismatchError)
- Settings fields: server_base_url, server_api_token, server_tls_verify,
  server_request_timeout
- Factory function create_client_from_settings wired to Settings
- httpx added to pyproject.toml dependencies
- Behave scenarios (23 scenarios, 72 steps)
- Robot Framework smoke tests
- ASV benchmark for connection overhead baseline
- Reference documentation at docs/reference/server_client_http.md

ISSUES CLOSED: #335
2026-03-24 20:28:19 +00:00

176 lines
7.8 KiB
Gherkin

@phase2 @client @http
Feature: Server HTTP client
As a developer
I want an HTTP client for server communication
So that I can perform health checks, version negotiation, and paginated queries
# ---------------------------------------------------------------------------
# Construction and configuration
# ---------------------------------------------------------------------------
Scenario: Create client with default settings
Given a ServerHttpClient with default settings
Then the client base_url should be "http://localhost:8080"
And the client tls_verify should be true
And the client timeout should be 30.0
Scenario: Create client with custom settings
Given a ServerHttpClient with base_url "https://example.com" and token "tok_test123abcdefghij"
Then the client base_url should be "https://example.com"
And the client tls_verify should be true
Scenario: TLS verification disabled logs warning
Given a ServerHttpClient with tls_verify disabled
Then the client tls_verify should be false
# ---------------------------------------------------------------------------
# Health check
# ---------------------------------------------------------------------------
Scenario: Health check returns true for healthy server
Given a ServerHttpClient with a mock healthy server
When I call health_check on the http client
Then the health check result should be true
Scenario: Health check returns false for unreachable server
Given a ServerHttpClient with an unreachable server
When I call health_check on the http client
Then the health check result should be false
# ---------------------------------------------------------------------------
# Version retrieval
# ---------------------------------------------------------------------------
Scenario: Get version returns server version string
Given a ServerHttpClient with a mock version server returning "2.1.0"
When I call get_version on the http client
Then the version result should be "2.1.0"
# ---------------------------------------------------------------------------
# Version negotiation
# ---------------------------------------------------------------------------
Scenario: Negotiate version succeeds with compatible version
Given a ServerHttpClient with a mock negotiate server returning "1.0"
When I call negotiate_version on the http client
Then the http client negotiated version should be "1.0"
Scenario: Negotiate version fails when server returns empty
Given a ServerHttpClient with a mock negotiate server returning empty
When I call negotiate_version on the http client expecting error
Then a ServerVersionMismatchError should be raised from http client
# ---------------------------------------------------------------------------
# Pagination
# ---------------------------------------------------------------------------
Scenario: List endpoint parses paginated object response
Given a ServerHttpClient with a mock paginated endpoint returning 3 items
When I call list_endpoint with page 1 per_page 10
Then the page result should have 3 items
And the page result should have total 3
Scenario: List endpoint parses list response
Given a ServerHttpClient with a mock list endpoint returning 5 items
When I call list_endpoint with page 1 per_page 10
Then the page result should have 5 items
And the page result has_next should be false
# ---------------------------------------------------------------------------
# Error mapping
# ---------------------------------------------------------------------------
Scenario: Server 503 raises A2aNotAvailableError
Given a ServerHttpClient with a mock server returning 503
When I call get_version and capture the error
Then an A2aNotAvailableError should be raised from the http client
Scenario: Server 502 raises ServerConnectionError
Given a ServerHttpClient with a mock server returning 502
When I call get_version and capture the error
Then a ServerConnectionError should be raised from the http client
Scenario: Server 401 raises ServerConnectionError with auth message
Given a ServerHttpClient with a mock server returning 401
When I call get_version and capture the error
Then a ServerConnectionError should be raised from the http client
# ---------------------------------------------------------------------------
# Retry logic
# ---------------------------------------------------------------------------
Scenario: Retries on 500 for idempotent GET
Given a ServerHttpClient with a mock server that fails twice then succeeds
When I call get_version on the http client
Then the version result should be "1.0.0"
# ---------------------------------------------------------------------------
# Auth header redaction
# ---------------------------------------------------------------------------
Scenario: Auth headers are redacted in log output
Given request headers with an Authorization bearer token
When I redact the headers
Then the Authorization value should be "***REDACTED***"
And the Accept header should not be redacted
# ---------------------------------------------------------------------------
# Client lifecycle
# ---------------------------------------------------------------------------
Scenario: Close is a safe no-op
Given a ServerHttpClient with default settings
When I call close on the http client
Then no error should be raised from the http client
# ---------------------------------------------------------------------------
# Factory from settings
# ---------------------------------------------------------------------------
Scenario: create_client_from_settings raises when URL not configured
When I call create_client_from_settings without a configured URL
Then a ValueError should be raised with URL configuration message from factory
Scenario: create_client_from_settings creates client when URL is set
When I call create_client_from_settings with a configured URL
Then a ServerHttpClient should be returned
# ---------------------------------------------------------------------------
# Client exception attributes
# ---------------------------------------------------------------------------
Scenario: ServerConnectionError carries url and cause attributes
Given a ServerConnectionError with url "https://x.com" and cause
Then the error url attribute should be "https://x.com"
And the error cause attribute should not be None
Scenario: ServerTimeoutError carries timeout_seconds attribute
Given a ServerTimeoutError with 10.0 seconds
Then the error timeout_seconds attribute should be 10.0
Scenario: ServerVersionMismatchError carries version attributes
Given a ServerVersionMismatchError with client "2.0" and server versions
Then the error client_version attribute should be "2.0"
And the error server_versions attribute should contain "1.0"
# ---------------------------------------------------------------------------
# Backoff helper
# ---------------------------------------------------------------------------
Scenario: Backoff delay grows exponentially and is capped
When I compute backoff delay for attempt 0 with base 1.0 and max 10.0
Then the delay should be 1.0
When I compute backoff delay for attempt 5 with base 1.0 and max 10.0
Then the delay should be 10.0
# ---------------------------------------------------------------------------
# PageResult attributes
# ---------------------------------------------------------------------------
Scenario: PageResult stores pagination metadata
Given a PageResult with 2 items page 1 per_page 10 total 20 has_next true
Then the page result page should be 1
And the page result per_page should be 10
And the page result total should be 20
And the page result has_next should be true