Skip to content

Conversation

@radofuchs
Copy link
Contributor

@radofuchs radofuchs commented Dec 2, 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

Tools used to create PR

Identify any AI code assistants used in this PR (for transparency and review context)

  • Assisted-by: Cursor

Related Tickets & Documents

  • Related Issue #LCORE-730
  • Closes #LCORE-730

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

Release Notes

  • New Features

    • Introduced conversation caching functionality with SQLite-based storage
    • Added ability to update conversation topic summaries
  • Tests

    • Added comprehensive end-to-end test suite for conversation cache API endpoints, covering CRUD operations and error scenarios
  • Bug Fixes

    • Enhanced HTTP error reporting with improved JSON response parsing

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 2, 2025

Walkthrough

This PR adds conversation cache configuration and comprehensive end-to-end tests for the Conversation Cache V2 API. It introduces SQLite-based cache configuration across multiple test environments, defines extensive Gherkin test scenarios for cache operations, and implements test infrastructure and step definitions for conversation endpoint validation.

Changes

Cohort / File(s) Change Summary
Configuration Files
lightspeed-stack.yaml, tests/e2e/configuration/lightspeed-stack-auth-noop-token.yaml, tests/e2e/configuration/lightspeed-stack-no-cache.yaml
Added top-level conversation_cache configuration block with SQLite type and db_path to main and test configs; created new test config without cache to validate error handling.
E2E Test Feature
tests/e2e/features/conversation_cache_v2.feature
Added comprehensive end-to-end test suite covering Conversation Cache V2 API operations: listing conversations, retrieving by ID, deleting, updating topic summaries, schema validation, authorization failures, non-existent conversations, and resilience scenarios.
E2E Test Infrastructure
tests/e2e/features/environment.py
Added NoCacheConfig scenario tag handling to switch between cache and no-cache configurations and manage lightspeed-stack container restart.
E2E HTTP Test Utilities
tests/e2e/features/steps/common_http.py
Enhanced status code assertion to parse JSON response bodies for richer error messages.
E2E Conversation Test Steps
tests/e2e/features/steps/conversation.py
Added eight new step methods: three PUT-based conversation update endpoints (generic, specific ID, empty topic_summary), and five conversation validation checks (metadata presence, topic summary, message count, model/provider, chat history integrity).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Feature file complexity: conversation_cache_v2.feature is extensive with many scenarios, though many follow repetitive patterns (error cases across endpoints).
  • Test step heterogeneity: Eight new methods in conversation.py with varied functionality (PUT operations + validation checks).
  • Configuration consistency: Multiple YAML files with straightforward but repetitive additions; new no-cache test variant introduces branching logic.
  • Areas requiring attention:
    • Gherkin scenario coverage completeness and edge case handling in conversation_cache_v2.feature
    • Validation logic accuracy in new conversation step methods, particularly model/provider tracking and chat_history structure checks
    • Configuration switching mechanism in environment.py for proper test isolation

Possibly related PRs

Suggested reviewers

  • tisnik

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 title clearly and specifically summarizes the main change: adding new end-to-end tests for the conversation v2 API, which is the primary focus across all modified and added test files.
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: 0

🧹 Nitpick comments (1)
tests/e2e/features/conversation_cache_v2.feature (1)

13-28: Known bug documented with @Skip tag.

The scenario correctly documents a known issue (AttributeError with empty vector DB causing 500 error) and is marked for skipping. Consider tracking this in the issue tracker if not already done.

Would you like me to open a new issue to track the empty vector DB bug, or is this already tracked in LCORE-730?

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c07604a and 4453331.

📒 Files selected for processing (7)
  • lightspeed-stack.yaml (1 hunks)
  • tests/e2e/configuration/lightspeed-stack-auth-noop-token.yaml (1 hunks)
  • tests/e2e/configuration/lightspeed-stack-no-cache.yaml (1 hunks)
  • tests/e2e/features/conversation_cache_v2.feature (1 hunks)
  • tests/e2e/features/environment.py (1 hunks)
  • tests/e2e/features/steps/common_http.py (1 hunks)
  • tests/e2e/features/steps/conversation.py (3 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
tests/e2e/features/**/*.feature

📄 CodeRabbit inference engine (CLAUDE.md)

Use behave (BDD) framework with Gherkin feature files for end-to-end tests

Files:

  • tests/e2e/features/conversation_cache_v2.feature
tests/**/*.py

📄 CodeRabbit inference engine (CLAUDE.md)

Use pytest-mock with AsyncMock objects for mocking in tests

Files:

  • tests/e2e/features/steps/common_http.py
  • tests/e2e/features/environment.py
  • tests/e2e/features/steps/conversation.py
🧠 Learnings (6)
📚 Learning: 2025-09-02T11:09:40.404Z
Learnt from: radofuchs
Repo: lightspeed-core/lightspeed-stack PR: 485
File: tests/e2e/features/environment.py:87-95
Timestamp: 2025-09-02T11:09:40.404Z
Learning: In the lightspeed-stack e2e tests, noop authentication tests use the default lightspeed-stack.yaml configuration, while noop-with-token tests use the Authorized tag to trigger a config swap to the specialized noop-with-token configuration file.

Applied to files:

  • tests/e2e/configuration/lightspeed-stack-auth-noop-token.yaml
  • tests/e2e/configuration/lightspeed-stack-no-cache.yaml
  • tests/e2e/features/environment.py
📚 Learning: 2025-09-02T11:15:02.411Z
Learnt from: radofuchs
Repo: lightspeed-core/lightspeed-stack PR: 485
File: tests/e2e/test_list.txt:2-3
Timestamp: 2025-09-02T11:15:02.411Z
Learning: In the lightspeed-stack e2e tests, the Authorized tag is intentionally omitted from noop authentication tests because they are designed to test against the default lightspeed-stack.yaml configuration rather than the specialized noop-with-token configuration.

Applied to files:

  • tests/e2e/configuration/lightspeed-stack-auth-noop-token.yaml
  • tests/e2e/configuration/lightspeed-stack-no-cache.yaml
📚 Learning: 2025-11-24T16:58:04.410Z
Learnt from: CR
Repo: lightspeed-core/lightspeed-stack PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:58:04.410Z
Learning: Applies to tests/e2e/features/**/*.feature : Use behave (BDD) framework with Gherkin feature files for end-to-end tests

Applied to files:

  • tests/e2e/features/conversation_cache_v2.feature
📚 Learning: 2025-11-24T16:58:04.410Z
Learnt from: CR
Repo: lightspeed-core/lightspeed-stack PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:58:04.410Z
Learning: Applies to tests/e2e/test_list.txt : Maintain test list in `tests/e2e/test_list.txt` for end-to-end tests

Applied to files:

  • tests/e2e/features/conversation_cache_v2.feature
📚 Learning: 2025-08-25T09:05:18.350Z
Learnt from: radofuchs
Repo: lightspeed-core/lightspeed-stack PR: 445
File: tests/e2e/features/health.feature:50-53
Timestamp: 2025-08-25T09:05:18.350Z
Learning: The step definition for ignoring specific fields in response body comparisons is implemented in tests/e2e/features/steps/common_http.py at line 175 as `then('The body of the response, ignoring the "{field}" field, is the following')`.

Applied to files:

  • tests/e2e/features/steps/common_http.py
📚 Learning: 2025-08-25T09:11:38.701Z
Learnt from: radofuchs
Repo: lightspeed-core/lightspeed-stack PR: 445
File: tests/e2e/features/environment.py:0-0
Timestamp: 2025-08-25T09:11:38.701Z
Learning: In the Behave Python testing framework, the Context object is created once for the entire test run and reused across all features and scenarios. Custom attributes added to the context persist until explicitly cleared, so per-scenario state should be reset in hooks to maintain test isolation.

Applied to files:

  • tests/e2e/features/environment.py
🧬 Code graph analysis (2)
tests/e2e/features/environment.py (1)
tests/e2e/utils/utils.py (2)
  • switch_config (98-106)
  • restart_container (130-144)
tests/e2e/features/steps/conversation.py (2)
src/models/responses.py (2)
  • endpoint (1325-1329)
  • model (1522-1526)
tests/e2e/utils/utils.py (1)
  • replace_placeholders (147-160)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: build-pr
  • GitHub Check: e2e_tests (ci)
  • GitHub Check: e2e_tests (azure)
  • GitHub Check: Konflux kflux-prd-rh02 / lightspeed-stack-on-pull-request
🔇 Additional comments (21)
tests/e2e/features/steps/common_http.py (1)

123-132: LGTM! Enhanced error reporting for test failures.

The improved error message now includes the response body (JSON or text) when status code mismatches occur, which significantly aids debugging. The fallback pattern (try JSON, fall back to text) is appropriate.

tests/e2e/features/environment.py (2)

82-90: LGTM! NoCacheConfig scenario handling properly implemented.

The implementation follows the established pattern for scenario-specific configuration switching (consistent with InvalidFeedbackStorageConfig). The immediate config switch and container restart ensures the no-cache configuration is active before the scenario runs.


98-100: LGTM! Cleanup properly restores configuration.

The after_scenario hook correctly restores the feature configuration and restarts the container, ensuring test isolation.

tests/e2e/configuration/lightspeed-stack-no-cache.yaml (1)

1-28: LGTM! No-cache configuration for testing error scenarios.

This configuration file correctly omits the conversation_cache block to enable testing of error handling when the cache is not configured. The inline comment (line 24) clearly documents the intent.

tests/e2e/features/conversation_cache_v2.feature (7)

88-141: LGTM! Comprehensive GET by ID testing with schema validation.

The test scenario covers the happy path with multiple messages (2 turns), validates full metadata structure, and includes detailed JSON schema validation. The schema correctly enforces message structure with user/assistant types.


192-209: LGTM! Resilience testing when llama-stack is down.

This scenario validates that conversation retrieval continues to work when the llama-stack connection is disrupted, which is critical for system resilience. The test properly verifies that cached data remains accessible.


212-218: LGTM! Error handling for missing cache configuration.

The @NoCacheConfig scenario correctly validates that the system returns a 500 error with an appropriate message when the conversation cache is not configured. This aligns with the new lightspeed-stack-no-cache.yaml configuration file.


225-244: LGTM! DELETE endpoint testing with verification.

The scenario properly tests deletion and verifies the conversation is gone by attempting to retrieve it (expecting 404). The use of ignoring the "conversation_id" field comparison is appropriate for the success response.


287-307: LGTM! Resilience testing for DELETE operations.

This scenario validates that conversation deletion continues to work even when llama-stack is down, ensuring cached operations remain functional during upstream service disruptions.


314-334: LGTM! PUT endpoint testing with persistence verification.

The scenario tests topic summary updates and verifies the change persists by retrieving the conversation list and checking the updated value. This ensures the PUT operation correctly modifies the cache.


385-397: LGTM! Input validation testing for empty topic summary.

The scenario correctly tests that empty topic summaries are rejected with a 422 validation error. The expected error message "String should have at least 1 character" indicates proper Pydantic validation.

tests/e2e/features/steps/conversation.py (8)

95-119: LGTM! PUT endpoint implementation follows established patterns.

The implementation properly:

  • Asserts required context attributes exist
  • Constructs the URL following the same pattern as GET/DELETE
  • Handles the <EMPTY> token for testing empty string validation (line 112-113)
  • Uses requests.put with JSON payload

122-140: LGTM! Specific conversation ID variant properly implemented.

This step definition allows testing with explicit conversation IDs (for malformed ID testing, non-existent IDs, etc.), complementing the "from above" variant. The implementation is consistent and correct.


143-164: LGTM! Empty topic summary testing properly supported.

This dedicated step definition enables testing of validation errors when an empty topic_summary is provided. The explicit {"topic_summary": ""} payload is appropriate for testing the 422 validation error case.


182-200: LGTM! Metadata validation is thorough.

The validation step properly checks:

  • Presence of required fields (last_message_timestamp, topic_summary)
  • Type validation (timestamp should be number)
  • Value constraints (timestamp should be positive)
  • Non-null constraints for topic_summary

203-214: LGTM! Topic summary validation is precise.

The step definition enables verification of updated topic summaries after PUT operations, which is essential for testing persistence of updates.


267-278: LGTM! Message count validation is straightforward.

The step correctly validates the number of entries in the chat_history array, which corresponds to the number of conversation turns (not individual messages).


281-316: LGTM! Comprehensive chat history metadata validation.

This validation step thoroughly checks:

  • Each turn has required fields (provider, model, messages, started_at, completed_at)
  • Each turn has exactly 2 messages (user + assistant)
  • Messages have correct types and content fields
  • All fields are non-empty

The detailed assertions with turn indices provide clear debugging information when failures occur.


319-343: LGTM! Model and provider validation with placeholder support.

The step correctly:

  • Uses replace_placeholders to handle {MODEL} and {PROVIDER} tokens
  • Validates all turns use the expected model/provider
  • Provides clear error messages with turn indices
tests/e2e/configuration/lightspeed-stack-auth-noop-token.yaml (1)

24-28: LGTM! Conversation cache configuration added.

The sqlite-based conversation cache configuration is consistent with the main configuration file. The /tmp/data/conversation-cache.db path is appropriate for ephemeral test data. Verify that the /tmp/data directory is created before tests run—check test setup and initialization scripts to ensure this directory exists or is properly created as part of test infrastructure setup.

lightspeed-stack.yaml (1)

24-28: LGTM! Conversation cache configuration added.

The sqlite-based conversation cache is properly configured. The inline comment clarifies persistence behavior across requests and cleanup between test runs. However, manual verification is needed to confirm this file's deployment context (development/test vs. production) and whether the /tmp path is appropriate for the intended environment.

@asimurka
Copy link
Contributor

asimurka commented Dec 2, 2025

LGTM

@radofuchs radofuchs merged commit a29b069 into lightspeed-core:main Dec 2, 2025
21 of 23 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