Skip to content

Commit 27d99e2

Browse files
committed
added e2e tests for authorized endpoint for noop and noop-with-token auth modules
1 parent c017e78 commit 27d99e2

File tree

9 files changed

+309
-55
lines changed

9 files changed

+309
-55
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
name: Lightspeed Core Service (LCS)
2+
service:
3+
host: 0.0.0.0
4+
port: 8080
5+
auth_enabled: false
6+
workers: 1
7+
color_log: true
8+
access_log: true
9+
llama_stack:
10+
# Uses a remote llama-stack service
11+
# The instance would have already been started with a llama-stack-run.yaml file
12+
use_as_library_client: false
13+
# Alternative for "as library use"
14+
# use_as_library_client: true
15+
# library_client_config_path: <path-to-llama-stack-run.yaml-file>
16+
url: http://llama-stack:8321
17+
api_key: xyzzy
18+
user_data_collection:
19+
feedback_enabled: true
20+
feedback_storage: "/tmp/data/feedback"
21+
transcripts_enabled: true
22+
transcripts_storage: "/tmp/data/transcripts"
23+
24+
authentication:
25+
module: "noop-with-token"

tests/e2e/features/authorized.feature

Lines changed: 0 additions & 34 deletions
This file was deleted.
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
Feature: Authorized endpoint API tests for the noop authentication module
2+
3+
Background:
4+
Given The service is started locally
5+
And REST API service hostname is localhost
6+
And REST API service port is 8080
7+
And REST API service prefix is /v1
8+
9+
Scenario: Check if the authorized endpoint works fine when user_id and auth header are not provided
10+
Given The system is in default state
11+
When I access endpoint "authorized" using HTTP POST method
12+
"""
13+
{"placeholder":"abc"}
14+
"""
15+
Then The status code of the response is 200
16+
And The body of the response is the following
17+
"""
18+
{"user_id": "00000000-0000-0000-0000-000","username": "lightspeed-user"}
19+
"""
20+
21+
Scenario: Check if the authorized endpoint works when auth token is not provided
22+
Given The system is in default state
23+
When I access endpoint "authorized" using HTTP POST method with user_id "test_user"
24+
Then The status code of the response is 200
25+
And The body of the response is the following
26+
"""
27+
{"user_id": "test_user","username": "lightspeed-user"}
28+
"""
29+
30+
Scenario: Check if the authorized endpoint works when user_id is not provided
31+
Given The system is in default state
32+
And I set the Authorization header to Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6Ikpva
33+
When I access endpoint "authorized" using HTTP POST method without user_id
34+
Then The status code of the response is 200
35+
And The body of the response is the following
36+
"""
37+
{"user_id": "00000000-0000-0000-0000-000","username": "lightspeed-user"}
38+
"""
39+
40+
Scenario: Check if the authorized endpoint works when providing empty user_id
41+
Given The system is in default state
42+
And I set the Authorization header to Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6Ikpva
43+
When I access endpoint "authorized" using HTTP POST method with user_id ""
44+
Then The status code of the response is 200
45+
And The body of the response is the following
46+
"""
47+
{"user_id": "","username": "lightspeed-user"}
48+
"""
49+
50+
Scenario: Check if the authorized endpoint works when providing proper user_id
51+
Given The system is in default state
52+
And I set the Authorization header to Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6Ikpva
53+
When I access endpoint "authorized" using HTTP POST method with user_id "test_user"
54+
Then The status code of the response is 200
55+
And The body of the response is the following
56+
"""
57+
{"user_id": "test_user","username": "lightspeed-user"}
58+
"""
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
@Authorized
2+
Feature: Authorized endpoint API tests for the noop-with-token
3+
4+
Background:
5+
Given The service is started locally
6+
And REST API service hostname is localhost
7+
And REST API service port is 8080
8+
And REST API service prefix is /v1
9+
10+
Scenario: Check if the authorized endpoint fails when user_id and auth header are not provided
11+
Given The system is in default state
12+
When I access endpoint "authorized" using HTTP POST method
13+
"""
14+
{"placeholder":"abc"}
15+
"""
16+
Then The status code of the response is 400
17+
And The body of the response is the following
18+
"""
19+
{"detail": "No Authorization header found"}
20+
"""
21+
22+
Scenario: Check if the authorized endpoint works when user_id is not provided
23+
Given The system is in default state
24+
And I set the Authorization header to Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6Ikpva
25+
When I access endpoint "authorized" using HTTP POST method without user_id
26+
Then The status code of the response is 200
27+
And The body of the response is the following
28+
"""
29+
{"user_id": "00000000-0000-0000-0000-000","username": "lightspeed-user"}
30+
"""
31+
32+
Scenario: Check if the authorized endpoint works when providing empty user_id
33+
Given The system is in default state
34+
And I set the Authorization header to Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6Ikpva
35+
When I access endpoint "authorized" using HTTP POST method with user_id ""
36+
Then The status code of the response is 200
37+
And The body of the response is the following
38+
"""
39+
{"user_id": "","username": "lightspeed-user"}
40+
"""
41+
42+
Scenario: Check if the authorized endpoint works when providing proper user_id
43+
Given The system is in default state
44+
And I set the Authorization header to Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6Ikpva
45+
When I access endpoint "authorized" using HTTP POST method with user_id "test_user"
46+
Then The status code of the response is 200
47+
And The body of the response is the following
48+
"""
49+
{"user_id": "test_user","username": "lightspeed-user"}
50+
"""
51+
52+
Scenario: Check if the authorized endpoint works with proper user_id but bearer token is not present
53+
Given The system is in default state
54+
When I access endpoint "authorized" using HTTP POST method with user_id "test_user"
55+
Then The status code of the response is 400
56+
And The body of the response is the following
57+
"""
58+
{"detail": "No Authorization header found"}
59+
"""
60+
61+
Scenario: Check if the authorized endpoint works when auth token is malformed
62+
Given The system is in default state
63+
And I set the Authorization header to BearereyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6Ikpva
64+
When I access endpoint "authorized" using HTTP POST method with user_id "test_user"
65+
Then The status code of the response is 400
66+
And The body of the response is the following
67+
"""
68+
{"detail": "No token found in Authorization header"}
69+
"""

tests/e2e/features/environment.py

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,11 @@
99

1010
import subprocess
1111
import time
12-
from behave.model import Scenario
12+
from behave.model import Scenario, Feature
1313
from behave.runner import Context
1414

15+
from tests.e2e.utils.utils import switch_config_and_restart
16+
1517
try:
1618
import os # noqa: F401
1719
except ImportError as e:
@@ -82,5 +84,22 @@ def after_scenario(context: Context, scenario: Scenario) -> None:
8284
print(f"Warning: Could not restore Llama Stack connection: {e}")
8385

8486

85-
def before_feature(context: Context, feature: Scenario) -> None:
87+
def before_feature(context: Context, feature: Feature) -> None:
8688
"""Run before each feature file is exercised."""
89+
if "Authorized" in feature.tags:
90+
context.backup_file = switch_config_and_restart(
91+
"lightspeed-stack.yaml",
92+
"tests/e2e/configuration/lightspeed-stack-auth-noop-token.yaml",
93+
"lightspeed-stack",
94+
)
95+
96+
97+
def after_feature(context: Context, feature: Feature) -> None:
98+
"""Run after each feature file is exercised."""
99+
if "Authorized" in feature.tags:
100+
switch_config_and_restart(
101+
"lightspeed-stack.yaml",
102+
context.backup_file,
103+
"lightspeed-stack",
104+
cleanup=True,
105+
)

tests/e2e/features/steps/auth.py

Lines changed: 70 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,79 @@
11
"""Implementation of common test steps."""
22

3-
from behave import given, then # pyright: ignore[reportAttributeAccessIssue]
3+
import requests
4+
from behave import given, when # pyright: ignore[reportAttributeAccessIssue]
45
from behave.runner import Context
6+
from tests.e2e.utils.utils import normalize_endpoint, switch_config_and_restart
57

68

7-
@then("The body of the response has proper username")
8-
def check_body_username(context: Context) -> None:
9-
"""Check that the username is correct in response."""
10-
# TODO: add step implementation
11-
assert context is not None
9+
@given("I set the Authorization header to {header_value}")
10+
def set_authorization_header_custom(context: Context, header_value: str) -> None:
11+
"""Set a custom Authorization header value."""
12+
if not hasattr(context, "auth_headers"):
13+
context.auth_headers = {}
14+
context.auth_headers["Authorization"] = header_value
15+
print(f"🔑 Set Authorization header to: {header_value}")
1216

1317

14-
@given("I remove the auth header")
15-
def remove_auth_header(context: Context) -> None:
16-
"""Remove the auth header."""
17-
# TODO: add step implementation
18-
assert context is not None
18+
@given("I set up authorized test environment")
19+
def setup_authorized_test_environment(context: Context) -> None:
20+
"""Set up the test environment with noop-with-token authentication."""
21+
print(
22+
"🔧 Setting up authorized endpoint test with noop-with-token authentication..."
23+
)
1924

25+
# Switch to noop-with-token configuration
26+
backup_file = switch_config_and_restart(
27+
"lightspeed-stack.yaml",
28+
"tests/e2e/configuration/lightspeed-stack-auth-noop-token.yaml",
29+
"lightspeed-stack",
30+
)
2031

21-
@given("I modify the auth header so that the user is it authorized")
22-
def modify_auth_header(context: Context) -> None:
23-
"""Modify the auth header making the user unauthorized."""
24-
# TODO: add step implementation
25-
assert context is not None
32+
# Store backup file path in context for later restoration
33+
context.backup_file = backup_file
34+
print(f"📋 Backup file stored: {backup_file}")
35+
36+
37+
@when("I access endpoint {endpoint} using HTTP POST method with user_id {user_id}")
38+
def access_rest_api_endpoint_post(
39+
context: Context, endpoint: str, user_id: str
40+
) -> None:
41+
"""Send POST HTTP request with payload in the endpoint as parameter to tested service.
42+
43+
The response is stored in `context.response` attribute.
44+
"""
45+
endpoint = normalize_endpoint(endpoint)
46+
user_id = user_id.replace('"', "")
47+
base = f"http://{context.hostname}:{context.port}"
48+
path = f"{endpoint}?user_id={user_id}".replace("//", "/")
49+
url = base + path
50+
51+
if not hasattr(context, "auth_headers"):
52+
context.auth_headers = {}
53+
54+
# perform REST API call
55+
context.response = requests.post(
56+
url, json="", headers=context.auth_headers, timeout=10
57+
)
58+
59+
60+
@when("I access endpoint {endpoint} using HTTP POST method without user_id")
61+
def access_rest_api_endpoint_post_without_param(
62+
context: Context, endpoint: str
63+
) -> None:
64+
"""Send POST HTTP request without user_id payload.
65+
66+
The response is stored in `context.response` attribute.
67+
"""
68+
endpoint = normalize_endpoint(endpoint)
69+
base = f"http://{context.hostname}:{context.port}"
70+
path = f"{endpoint}".replace("//", "/")
71+
url = base + path
72+
73+
if not hasattr(context, "auth_headers"):
74+
context.auth_headers = {}
75+
76+
# perform REST API call
77+
context.response = requests.post(
78+
url, json="", headers=context.auth_headers, timeout=10
79+
)

tests/e2e/features/steps/common_http.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -241,16 +241,17 @@ def access_rest_api_endpoint_get(context: Context, endpoint: str) -> None:
241241
context.response = requests.get(url, timeout=DEFAULT_TIMEOUT)
242242

243243

244-
@when("I access endpoint {endpoint:w} using HTTP POST method")
244+
@when("I access endpoint {endpoint} using HTTP POST method")
245245
def access_rest_api_endpoint_post(context: Context, endpoint: str) -> None:
246246
"""Send POST HTTP request with JSON payload to tested service.
247247
248248
The JSON payload is retrieved from `context.text` attribute,
249249
which must not be None. The response is stored in
250250
`context.response` attribute.
251251
"""
252+
endpoint = normalize_endpoint(endpoint)
252253
base = f"http://{context.hostname}:{context.port}"
253-
path = f"{context.api_prefix}/{endpoint}".replace("//", "/")
254+
path = f"{endpoint}".replace("//", "/")
254255
url = base + path
255256

256257
assert context.text is not None, "Payload needs to be specified"

tests/e2e/test_list.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
features/smoketests.feature
2-
features/authorized.feature
2+
features/authorized_noop.feature
3+
features/authorized_noop_token.feature
34
features/conversations.feature
45
features/feedback.feature
56
features/health.feature

0 commit comments

Comments
 (0)