Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,6 @@ conversation_cache:

authentication:
module: "noop-with-token"
inference:
default_provider: openai
default_model: gpt-4o-mini
3 changes: 3 additions & 0 deletions tests/e2e/configuration/library-mode/lightspeed-stack.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ user_data_collection:
transcripts_storage: "/tmp/data/transcripts"
authentication:
module: "noop"
inference:
default_provider: openai
default_model: gpt-4o-mini
mcp_servers:
# Mock server with client-provided auth - should appear in mcp-auth/client-options response
- name: "github-api"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,6 @@ conversation_cache:

authentication:
module: "noop-with-token"
inference:
default_provider: openai
default_model: gpt-4o-mini
3 changes: 3 additions & 0 deletions tests/e2e/configuration/server-mode/lightspeed-stack.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ user_data_collection:
transcripts_storage: "/tmp/data/transcripts"
authentication:
module: "noop"
inference:
default_provider: openai
default_model: gpt-4o-mini
mcp_servers:
# Mock server with client-provided auth - should appear in mcp-auth/client-options response
- name: "github-api"
Expand Down
89 changes: 89 additions & 0 deletions tests/e2e/features/rlsapi_v1.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
@Authorized
Feature: rlsapi v1 /infer endpoint API tests

Background:
Given The service is started locally
And REST API service prefix is /v1

Scenario: Basic inference with minimal request (question only)
Given The system is in default state
And I set the Authorization header to Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6Ikpva
When I use "infer" to ask question with authorization header
"""
{"question": "How do I list files in Linux?"}
"""
Then The status code of the response is 200
And The rlsapi response should have valid structure

Scenario: Inference with full context (systeminfo populated)
Given The system is in default state
And I set the Authorization header to Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6Ikpva
When I use "infer" to ask question with authorization header
"""
{"question": "How do I configure SELinux?", "context": {"systeminfo": {"os": "RHEL", "version": "9.3", "arch": "x86_64"}}}
"""
Then The status code of the response is 200
And The rlsapi response should have valid structure

Scenario: Request without authorization returns 401
Given The system is in default state
When I use "infer" to ask question
"""
{"question": "How do I list files?"}
"""
Then The status code of the response is 401
And The body of the response is the following
"""
{
"detail": {
"response": "Missing or invalid credentials provided by client",
"cause": "No Authorization header found"
}
}
"""

Scenario: Request with empty bearer token returns 401
Given The system is in default state
And I set the Authorization header to Bearer
When I use "infer" to ask question with authorization header
"""
{"question": "How do I list files?"}
"""
Then The status code of the response is 401
And The body of the response contains No token found in Authorization header

Scenario: Empty/whitespace question returns 422
Given The system is in default state
And I set the Authorization header to Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6Ikpva
When I use "infer" to ask question with authorization header
"""
{"question": " "}
"""
Then The status code of the response is 422
And The body of the response contains Question cannot be empty

Scenario: Response contains valid structure (data.text, data.request_id)
Given The system is in default state
And I set the Authorization header to Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6Ikpva
When I use "infer" to ask question with authorization header
"""
{"question": "What is RHEL?"}
"""
Then The status code of the response is 200
And The rlsapi response should have valid structure

Scenario: Multiple requests generate unique request_ids
Given The system is in default state
And I set the Authorization header to Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6Ikpva
When I use "infer" to ask question with authorization header
"""
{"question": "First question"}
"""
Then The status code of the response is 200
And I store the rlsapi request_id
When I use "infer" to ask question with authorization header
"""
{"question": "Second question"}
"""
Then The status code of the response is 200
And The rlsapi request_id should be different from the stored one
65 changes: 65 additions & 0 deletions tests/e2e/features/steps/rlsapi_v1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
"""rlsapi v1 endpoint test steps."""

from behave import then, step # pyright: ignore[reportAttributeAccessIssue]
from behave.runner import Context


@then("The rlsapi response should have valid structure")
def check_rlsapi_response_structure(context: Context) -> None:
"""Check that rlsapi v1 response has valid structure.

Validates that the response contains:
- data.text (non-empty string)
- data.request_id (non-empty string)
"""
assert context.response is not None, "Request needs to be performed first"
response_json = context.response.json()

assert "data" in response_json, "Response missing 'data' field"
data = response_json["data"]

assert "text" in data, "Response data missing 'text' field"
assert isinstance(data["text"], str), "data.text must be a string"
assert len(data["text"]) > 0, "data.text must not be empty"

assert "request_id" in data, "Response data missing 'request_id' field"
assert isinstance(data["request_id"], str), "data.request_id must be a string"
assert len(data["request_id"]) > 0, "data.request_id must not be empty"


@step("I store the rlsapi request_id")
def store_rlsapi_request_id(context: Context) -> None:
"""Store the request_id from rlsapi response for later comparison."""
assert context.response is not None, "Request needs to be performed first"
response_json = context.response.json()

assert "data" in response_json, "Response missing 'data' field"
assert "request_id" in response_json["data"], "Response data missing 'request_id'"
assert isinstance(
response_json["data"]["request_id"], str
), "data.request_id must be a string"
assert (
len(response_json["data"]["request_id"]) > 0
), "data.request_id must not be empty"

context.stored_request_id = response_json["data"]["request_id"]


@then("The rlsapi request_id should be different from the stored one")
def check_rlsapi_request_id_different(context: Context) -> None:
"""Verify that the current request_id differs from the stored one."""
assert context.response is not None, "Request needs to be performed first"
assert hasattr(context, "stored_request_id"), "No request_id was stored previously"

response_json = context.response.json()
assert "data" in response_json, "Response missing 'data' field"
assert "request_id" in response_json["data"], "Response data missing 'request_id'"

current_request_id = response_json["data"]["request_id"]
assert isinstance(current_request_id, str), "data.request_id must be a string"
assert len(current_request_id) > 0, "data.request_id must not be empty"
stored_request_id = context.stored_request_id

assert (
current_request_id != stored_request_id
), f"request_id should be unique, but got same value: {current_request_id}"
1 change: 1 addition & 0 deletions tests/e2e/test_list.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@ features/feedback.feature
features/health.feature
features/info.feature
features/query.feature
features/rlsapi_v1.feature
features/streaming_query.feature
features/rest_api.feature
Loading