Skip to content

Conversation

@radofuchs
Copy link
Contributor

@radofuchs radofuchs commented Oct 23, 2025

Description

Type of change

  • Refactor
  • New feature
  • Bug fix
  • CVE fix
  • Optimization
  • Documentation Update
  • Configuration Update
  • Bump-up service version
  • Bump-up dependent library
  • Bump-up library or tool used for development (does not change the final image)
  • CI configuration change
  • Konflux configuration change
  • Unit tests improvement
  • Integration tests improvement
  • End to end tests improvement

Related Tickets & Documents

  • Related Issue #
  • Closes #

Checklist before requesting a review

  • I have performed a self-review of my code.
  • PR has passed all pre-merge test jobs.
  • If it is a core feature, I have added thorough tests.

Testing

  • Please provide detailed steps to perform tests related to this code change.
  • How were the fix/results from this change verified? Please provide relevant screenshots or results.

Summary by CodeRabbit

Tests

  • Tests
    • Refactored end-to-end test configuration to use environment variables instead of hard-coded values, enabling greater flexibility in test environments while maintaining backward compatibility with sensible defaults.

@radofuchs radofuchs requested a review from are-ces October 23, 2025 11:48
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 23, 2025

Walkthrough

This PR removes hard-coded REST API service hostname and port specifications from e2e test feature files and introduces environment variable-based configuration in the test infrastructure code. Multiple feature files are updated to rely on defaults or external configuration instead of explicit localhost:8080 declarations.

Changes

Cohort / File(s) Summary
Feature file Background cleanup
tests/e2e/features/authorized_noop.feature, tests/e2e/features/authorized_noop_token.feature, tests/e2e/features/conversations.feature, tests/e2e/features/feedback.feature, tests/e2e/features/health.feature, tests/e2e/features/info.feature, tests/e2e/features/query.feature, tests/e2e/features/rest_api.feature, tests/e2e/features/smoketests.feature, tests/e2e/features/streaming_query.feature
Removed explicit REST API hostname (localhost) and port (8080) configuration steps from Background; service prefix (/v1) remains. Tests now rely on environment-based or default endpoint resolution.
Environment variable configuration
tests/e2e/features/steps/common.py
Added imports and initialization of context properties (hostname, port, hostname_llama, port_llama) from environment variables E2E_LSC_HOSTNAME, E2E_LSC_PORT, E2E_LLAMA_HOSTNAME, E2E_LLAMA_PORT with defaults (localhost, 8080, localhost, 8321).
Service endpoint construction
tests/e2e/features/environment.py
Updated _fetch_models_from_service() signature to remove hostname and port parameters, now resolving URL from environment variables instead. Updated health check and conversations cleanup to use context-derived host/port values.

Sequence Diagram(s)

sequenceDiagram
    participant Test as Feature Test
    participant Common as common.py
    participant Env as environment.py
    participant EnvVar as Environment Variables

    Note over Common: Before: Hard-coded localhost:8080
    Note over Common: After: Environment-based config

    Test->>Common: Start scenario
    Common->>EnvVar: Read E2E_LSC_HOSTNAME (or default localhost)
    EnvVar-->>Common: hostname value
    Common->>EnvVar: Read E2E_LSC_PORT (or default 8080)
    EnvVar-->>Common: port value
    Common->>Common: context.hostname, context.port initialized

    Test->>Env: _fetch_models_from_service()
    Env->>EnvVar: Read E2E_LSC_HOSTNAME, E2E_LSC_PORT
    EnvVar-->>Env: hostname, port
    Env->>Env: Build URL dynamically
    Env-->>Test: Return models dict
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Rationale: While 10 feature files contain repetitive, low-complexity deletions (removing identical lines), the logic changes in environment.py and common.py require separate reasoning—specifically the signature change to _fetch_models_from_service(), the environment variable initialization pattern, and how context values are propagated to health check and cleanup logic.

Possibly related PRs

Suggested reviewers

  • tisnik

🐰 Hops through test configs with glee,
No more localhost bound to be!
Environment vars now set the way,
Defaults dance where hard-codes played.
Flexible endpoints, here to stay! 🎯✨

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The pull request title "fix constant hostname in e2e tests" is clearly related to the main changes in the changeset. The PR removes hardcoded hostname and port declarations from multiple e2e feature files and updates the test environment setup to use environment-variable-based configuration with defaults. The title accurately identifies the core issue being addressed—the presence of constant/hardcoded hostnames in e2e tests—and indicates that this is being fixed. While the title could be more explicit about the solution (e.g., specifying "use environment variables"), it is sufficiently clear and specific that a reviewer scanning the history would understand the PR addresses hardcoded hostname configuration in e2e tests.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
tests/e2e/features/environment.py (1)

25-48: Update docstring and consider centralizing environment variable access.

The docstring doesn't mention that the function now reads configuration from environment variables. Additionally, the environment variables E2E_LSC_HOSTNAME and E2E_LSC_PORT are read both here and in tests/e2e/features/steps/common.py, creating duplication.

Apply this diff to update the docstring:

-def _fetch_models_from_service() -> dict:
-    """Query /v1/models endpoint and return first LLM model.
+def _fetch_models_from_service() -> dict:
+    """Query /v1/models endpoint and return first LLM model.
+    
+    Reads service endpoint from E2E_LSC_HOSTNAME and E2E_LSC_PORT environment variables.

Consider refactoring to use context.hostname and context.port if they're already set, or centralizing the environment variable reading logic in a single location to avoid duplication and potential inconsistencies.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f4f6684 and 31b2f10.

📒 Files selected for processing (12)
  • tests/e2e/features/authorized_noop.feature (0 hunks)
  • tests/e2e/features/authorized_noop_token.feature (0 hunks)
  • tests/e2e/features/conversations.feature (0 hunks)
  • tests/e2e/features/environment.py (4 hunks)
  • tests/e2e/features/feedback.feature (0 hunks)
  • tests/e2e/features/health.feature (0 hunks)
  • tests/e2e/features/info.feature (0 hunks)
  • tests/e2e/features/query.feature (0 hunks)
  • tests/e2e/features/rest_api.feature (0 hunks)
  • tests/e2e/features/smoketests.feature (0 hunks)
  • tests/e2e/features/steps/common.py (1 hunks)
  • tests/e2e/features/streaming_query.feature (0 hunks)
💤 Files with no reviewable changes (10)
  • tests/e2e/features/conversations.feature
  • tests/e2e/features/feedback.feature
  • tests/e2e/features/query.feature
  • tests/e2e/features/authorized_noop.feature
  • tests/e2e/features/info.feature
  • tests/e2e/features/rest_api.feature
  • tests/e2e/features/authorized_noop_token.feature
  • tests/e2e/features/health.feature
  • tests/e2e/features/streaming_query.feature
  • tests/e2e/features/smoketests.feature
🧰 Additional context used
📓 Path-based instructions (3)
**/*.py

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.py: All modules start with descriptive module-level docstrings explaining purpose
Use logger = logging.getLogger(name) for module logging after import logging
Define type aliases at module level for clarity
All functions require docstrings with brief descriptions
Provide complete type annotations for all function parameters and return types
Use typing_extensions.Self in model validators where appropriate
Use modern union syntax (str | int) and Optional[T] or T | None consistently
Function names use snake_case with descriptive, action-oriented prefixes (get_, validate_, check_)
Avoid in-place parameter modification; return new data structures instead of mutating arguments
Use appropriate logging levels: debug, info, warning, error with clear messages
All classes require descriptive docstrings explaining purpose
Class names use PascalCase with conventional suffixes (Configuration, Error/Exception, Resolver, Interface)
Abstract base classes should use abc.ABC and @AbstractMethod for interfaces
Provide complete type annotations for all class attributes
Follow Google Python docstring style for modules, classes, and functions, including Args, Returns, Raises, Attributes sections as needed

Files:

  • tests/e2e/features/environment.py
  • tests/e2e/features/steps/common.py
tests/**/*.py

📄 CodeRabbit inference engine (CLAUDE.md)

tests/**/*.py: Use pytest-mock to create AsyncMock objects for async interactions in tests
Use the shared auth mock constant: MOCK_AUTH = ("mock_user_id", "mock_username", False, "mock_token") in tests

Files:

  • tests/e2e/features/environment.py
  • tests/e2e/features/steps/common.py
tests/e2e/features/steps/**/*.py

📄 CodeRabbit inference engine (CLAUDE.md)

Place behave step definitions under tests/e2e/features/steps/

Files:

  • tests/e2e/features/steps/common.py
🔇 Additional comments (2)
tests/e2e/features/environment.py (2)

158-161: Verify context attributes are set before use.

Similar to the issue at line 111, this code assumes context.hostname and context.port are set by the "Given The service is started locally" step. Ensure all feature files that use the Feedback tag include this prerequisite step.

The verification script from the previous comment will help confirm this.


102-111: No verification issues found—the code is safe.

The original concern assumes context attributes may not be set when after_scenario runs, but this isn't a risk in Behave. In Behave, Background steps execute before every scenario, including those marked @skip. Since all 10 feature files include "Given The service is started locally" in their Background section (verified in the script output), context.hostname_llama and context.port_llama are guaranteed to be populated before any scenario executes. The code at lines 102–111 correctly uses these attributes, and the defensive hasattr() check on line 90 for llama_stack_was_running is appropriate.

Comment on lines 8 to +15
@given("The service is started locally")
def service_is_started_locally(context: Context) -> None:
"""Check the service status."""
assert context is not None
context.hostname = os.getenv("E2E_LSC_HOSTNAME", "localhost")
context.port = os.getenv("E2E_LSC_PORT", "8080")
context.hostname_llama = os.getenv("E2E_LLAMA_HOSTNAME", "localhost")
context.port_llama = os.getenv("E2E_LLAMA_PORT", "8321")
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Update the docstring and verify port type expectations.

The docstring states "Check the service status" but the function actually configures the context with hostname and port values from environment variables. Additionally, ports are stored as strings, but downstream code may expect integers.

Apply this diff to update the docstring:

 @given("The service is started locally")
 def service_is_started_locally(context: Context) -> None:
-    """Check the service status."""
+    """Configure context with service hostnames and ports from environment variables."""
     assert context is not None

Run the following script to verify whether downstream code expects ports as integers:


🏁 Script executed:

#!/bin/bash
# Description: Check if port values are used in numeric contexts or string interpolation

# Search for usage of context.port and context.port_llama
rg -n -C3 'context\.port' tests/e2e/

Length of output: 12969


Update docstring and convert port strings to integers for type consistency.

The docstring "Check the service status" is misleading—the function actually configures context with hostname and port values from environment variables. Additionally, os.getenv() returns strings, but other code (e.g., set_service_port in common_http.py) sets context.port as an integer, creating a type inconsistency.

Apply this diff:

 @given("The service is started locally")
 def service_is_started_locally(context: Context) -> None:
-    """Check the service status."""
+    """Configure context with service hostnames and ports from environment variables."""
     assert context is not None
     context.hostname = os.getenv("E2E_LSC_HOSTNAME", "localhost")
-    context.port = os.getenv("E2E_LSC_PORT", "8080")
+    context.port = int(os.getenv("E2E_LSC_PORT", "8080"))
     context.hostname_llama = os.getenv("E2E_LLAMA_HOSTNAME", "localhost")
-    context.port_llama = os.getenv("E2E_LLAMA_PORT", "8321")
+    context.port_llama = int(os.getenv("E2E_LLAMA_PORT", "8321"))
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
@given("The service is started locally")
def service_is_started_locally(context: Context) -> None:
"""Check the service status."""
assert context is not None
context.hostname = os.getenv("E2E_LSC_HOSTNAME", "localhost")
context.port = os.getenv("E2E_LSC_PORT", "8080")
context.hostname_llama = os.getenv("E2E_LLAMA_HOSTNAME", "localhost")
context.port_llama = os.getenv("E2E_LLAMA_PORT", "8321")
@given("The service is started locally")
def service_is_started_locally(context: Context) -> None:
"""Configure context with service hostnames and ports from environment variables."""
assert context is not None
context.hostname = os.getenv("E2E_LSC_HOSTNAME", "localhost")
context.port = int(os.getenv("E2E_LSC_PORT", "8080"))
context.hostname_llama = os.getenv("E2E_LLAMA_HOSTNAME", "localhost")
context.port_llama = int(os.getenv("E2E_LLAMA_PORT", "8321"))
🤖 Prompt for AI Agents
In tests/e2e/features/steps/common.py around lines 8 to 15, the docstring is
misleading and port values are left as strings; update the docstring to describe
that the function configures context hostnames and ports from environment
variables, and convert E2E_LSC_PORT and E2E_LLAMA_PORT to integers (with safe
defaults) before assigning to context.port and context.port_llama so their types
match other code that expects ints.

@radofuchs radofuchs merged commit 6844055 into lightspeed-core:main Oct 23, 2025
18 of 20 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants