Skip to content
This repository was archived by the owner on Sep 27, 2026. It is now read-only.

🧪 Add tests for TimeoutConfig error handling - #46

Closed
b3nw wants to merge 12 commits into
devfrom
test-timeout-config-value-error-4306463590870926663
Closed

b3nw wants to merge 12 commits into
devfrom
test-timeout-config-value-error-4306463590870926663

Conversation

@b3nw

@b3nw b3nw commented Apr 25, 2026

Copy link
Copy Markdown
Owner

🎯 What: Adds missing test for the error handling path of TimeoutConfig._get_env_float when an environment variable contains an invalid, non-float string. Also adds a test for the valid custom override case.
📊 Coverage: Ensures that invalid environment variables (like non-floats for TIMEOUT_CONNECT) are handled properly (returns default value and logs a warning), as well as normal overriding functionality.
✨ Result: Improved test coverage and reliability for HTTP configuration parsing, ensuring misconfigured environment variables do not lead to crashes.


PR created automatically by Jules for task 4306463590870926663 started by @b3nw

b3nw and others added 10 commits April 24, 2026 19:40
…ardization, and utilities

Core infrastructure improvements:
- Smart 'latest' model alias resolution with cost-based tiebreaking
- Standardized error responses with proper HTTP status codes and error.code field
- ProxyExhaustionError for structured credential exhaustion reporting
- TerminalRequestError for non-rotatable errors (404, model not found)
- Per-provider retry count override via MAX_RETRIES_{PROVIDER} env var
- Retry 429 rate_limit errors with backoff instead of rotating
- Cached token pricing in streaming cost calculation
- Split quota stats into current_period and global/lifetime views
- Log rotation for proxy.log and proxy_debug.log (RotatingFileHandler)
- Include latest virtual models in /v1/models endpoint
- Resolve singleton cache pollution for dynamic providers
- Fork-specific README and .gitignore updates
…ased model filtering, and enhanced X-Initiator heuristic
Test suite designed to catch breakage from branch re-organization without
sending queries to real LLM providers. Covers all critical integration
points that previously broke silently during deployment.

Coverage:
- Anthropic↔OpenAI format translation & streaming
- Error classification (determines retry/rotation behavior)
- Request sanitization (prevents 400s from invalid params)
- Provider-specific request transforms
- Model alias & latest registry parsing
- Usage tracking (windows, quota groups, custom caps)
- Credential discovery, deduplication, env:// URI
- Provider plugin registration & singleton pattern
- Proxy endpoint routing & auth

All tests use synthetic credentials and mocked HTTP.
Runs in ~2.3s. Zero API cost.
…flow

Replaces the old manifest-driven multi-branch replay system with a
simpler linear commit stack. Changes are made via fixup!/autosquash.
Upstream syncs are a single git rebase.

Includes:
- AGENTS.md: entry point for all AI coding agents
- .agent/rules/claude.md: Claude-specific SSH/deployment notes
- .agent/rules/llm-proxy.md: container layout and deployment pipeline
- .agent/skills/upstream-sync/SKILL.md: sync workflow reference
Custom provider for Google Vertex AI Express Mode API keys that uses
x-goog-api-key header authentication against the Vertex AI
OpenAI-compatible endpoint. Supports non-streaming and streaming
chat completions with automatic model discovery.

Models are prefixed as vertex/ (e.g. vertex/gemini-3.1-flash-lite-preview).
Env vars: VERTEX_PROJECT, VERTEX_LOCATION, VERTEX_API_KEY_N
@google-labs-jules

Copy link
Copy Markdown

👋 Jules, reporting for duty! I'm here to lend a hand with this pull request.

When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down.

I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job!

For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a new test suite for the TimeoutConfig class to ensure environment variables are correctly parsed for timeout settings. The feedback suggests expanding the test coverage to include all available timeout methods and factory methods, while also recommending the use of pytest.mark.parametrize to streamline the test implementation and reduce redundancy.

Comment thread tests/test_timeout_config.py Outdated
Comment on lines +13 to +35
class TestTimeoutConfig:
"""Test TimeoutConfig reading from env vars and default fallbacks."""

def test_timeout_config_value_error(self):
"""Test that ValueError is caught and handled when env var is not a float."""
# Using TIMEOUT_CONNECT as it maps to _CONNECT
with mock.patch.dict(os.environ, {"TIMEOUT_CONNECT": "not-a-float"}):
with mock.patch("rotator_library.timeout_config.lib_logger.warning") as mock_warning:
result = TimeoutConfig.connect()

# Should return the default value
assert result == TimeoutConfig._CONNECT

# Should log a warning about the invalid value
mock_warning.assert_called_once_with(
f"Invalid value for TIMEOUT_CONNECT: not-a-float. Using default: {TimeoutConfig._CONNECT}"
)

def test_timeout_config_custom_valid(self):
"""Test that valid custom float values from env vars are returned."""
with mock.patch.dict(os.environ, {"TIMEOUT_CONNECT": "45.5"}):
result = TimeoutConfig.connect()
assert result == 45.5

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The current tests only cover the connect() method and a single error case. Since TimeoutConfig provides several other timeout methods (write, pool, read_streaming, read_non_streaming) and factory methods for httpx.Timeout (streaming, non_streaming), it is important to verify that these also correctly handle environment variable overrides and defaults. This ensures that typos in environment variable keys are caught and that the httpx.Timeout objects are correctly configured. Additionally, leveraging pytest.mark.parametrize would make the tests more concise and utilize the already imported pytest module.

class TestTimeoutConfig:
    """Test TimeoutConfig reading from env vars and default fallbacks."""

    @pytest.mark.parametrize("method, env_var, default", [
        ("connect", "TIMEOUT_CONNECT", 30.0),
        ("write", "TIMEOUT_WRITE", 30.0),
        ("pool", "TIMEOUT_POOL", 60.0),
        ("read_streaming", "TIMEOUT_READ_STREAMING", 300.0),
        ("read_non_streaming", "TIMEOUT_READ_NON_STREAMING", 600.0),
    ])
    def test_timeout_methods(self, method, env_var, default):
        """Test that each timeout method returns the correct default and handles overrides."""
        # Test default value
        assert getattr(TimeoutConfig, method)() == default

        # Test valid override
        with mock.patch.dict(os.environ, {env_var: "45.5"}):
            assert getattr(TimeoutConfig, method)() == 45.5

        # Test invalid override (ValueError handling)
        with mock.patch.dict(os.environ, {env_var: "not-a-float"}):
            with mock.patch("rotator_library.timeout_config.lib_logger.warning") as mock_warning:
                assert getattr(TimeoutConfig, method)() == default
                mock_warning.assert_called_once_with(
                    f"Invalid value for {env_var}: not-a-float. Using default: {default}"
                )

    def test_timeout_factory_methods(self):
        """Test that streaming and non_streaming return correct httpx.Timeout objects."""
        s_timeout = TimeoutConfig.streaming()
        assert s_timeout.connect == 30.0
        assert s_timeout.read == 300.0
        assert s_timeout.write == 30.0
        assert s_timeout.pool == 60.0

        ns_timeout = TimeoutConfig.non_streaming()
        assert ns_timeout.connect == 30.0
        assert ns_timeout.read == 600.0
        assert ns_timeout.write == 30.0
        assert ns_timeout.pool == 60.0

@b3nw

b3nw commented Apr 25, 2026

Copy link
Copy Markdown
Owner Author

[Gemini-CLI Review Skill] @jules Reviewing this PR against the checklist and Gemini Code Assist feedback:

  1. [Gemini Code Assist] Coverage Expansion: Please expand the test suite to include all available timeout methods (read, write, pool) and factory methods to ensure consistent behavior across the TimeoutConfig class.
  2. [Gemini Code Assist] Parametrization: Use pytest.mark.parametrize to refactor these tests. This will allow you to test multiple environment variables and invalid values without redundant code.
  3. [Boundary/Edge] Extreme Values: Add test cases for extreme valid floats (e.g., 0.0, 0.0001) and negative values (if the implementation handles them as invalid/default).

🎯 **What:** Adds missing test for the error handling path of `TimeoutConfig._get_env_float` when an environment variable contains an invalid, non-float string. Also adds tests for the valid custom override case.
📊 **Coverage:** Ensures that invalid environment variables (like non-floats for `TIMEOUT_CONNECT`) are handled properly (returns default value and logs a warning), as well as normal overriding functionality. Covers extreme numbers, boundary conditions, valid floats, invalid strings, parametrizing the code correctly, and making sure to test all available internal variables.
✨ **Result:** Improved test coverage and reliability for HTTP configuration parsing, ensuring misconfigured environment variables do not lead to crashes.
@b3nw
b3nw marked this pull request as ready for review April 26, 2026 03:23
@google-labs-jules

Copy link
Copy Markdown

[Gemini-CLI Review Skill] @jules Reviewing this PR against the checklist and Gemini Code Assist feedback:

  1. [Gemini Code Assist] Coverage Expansion: Please expand the test suite to include all available timeout methods (read, write, pool) and factory methods to ensure consistent behavior across the TimeoutConfig class.
  2. [Gemini Code Assist] Parametrization: Use pytest.mark.parametrize to refactor these tests. This will allow you to test multiple environment variables and invalid values without redundant code.
  3. [Boundary/Edge] Extreme Values: Add test cases for extreme valid floats (e.g., 0.0, 0.0001) and negative values (if the implementation handles them as invalid/default).

I have updated tests/test_timeout_config.py to address all of this feedback. The tests now use pytest.mark.parametrize to cover all timeout methods (connect, write, pool, read_streaming, read_non_streaming). I've also added tests for extreme valid float values (0.0, 0.0001, -5.0), and included checks for the streaming and non_streaming factory methods.

🎯 **What:** Adds missing test for the error handling path of `TimeoutConfig._get_env_float` when an environment variable contains an invalid, non-float string. Also adds tests for the valid custom override case.
📊 **Coverage:** Ensures that invalid environment variables (like non-floats for `TIMEOUT_CONNECT`) are handled properly (returns default value and logs a warning), as well as normal overriding functionality. Covers extreme numbers, boundary conditions, valid floats, invalid strings, parametrizing the code correctly, and making sure to test all available internal variables.
✨ **Result:** Improved test coverage and reliability for HTTP configuration parsing, ensuring misconfigured environment variables do not lead to crashes.
@b3nw

b3nw commented Apr 26, 2026

Copy link
Copy Markdown
Owner Author

[Gemini-CLI Review Skill] Consolidated into the linear commit stack on dev.

@b3nw b3nw closed this Apr 26, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant