Skip to content

Commit c7a8479

Browse files
committed
test(gateway): add unit test for gateway manager
1 parent f05c111 commit c7a8479

File tree

4 files changed

+59
-8
lines changed

4 files changed

+59
-8
lines changed

pyproject.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,12 @@ myst_parser = ">=0.18.1,<1.1.0"
6060
sphinx = "^5.3.0"
6161
sphinx_rtd_theme = "^1.1.1"
6262

63+
[tool.pytest.ini_options]
64+
filterwarnings = [
65+
"ignore:.*pkg_resources\\.declare_namespace.*:DeprecationWarning",
66+
"ignore:::pkg_resources",
67+
]
68+
6369
[tool.pylint]
6470
load-plugins = ["pylint_per_file_ignores"]
6571
disable = "missing-module-docstring"

scw_serverless/config/route.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from dataclasses import dataclass
22
from enum import Enum
3-
from typing import Optional
3+
from typing import Any, Optional
44

55
from scw_serverless.config.utils import _SerializableDataClass
66

@@ -27,8 +27,17 @@ class GatewayRoute(_SerializableDataClass):
2727
target: Optional[str] = None
2828

2929
def validate(self) -> None:
30-
"""Validates a route."""
30+
"""Validate a route."""
3131
if not self.relative_url:
3232
raise RuntimeError("Route relative_url must be defined")
3333
if not self.target:
3434
raise RuntimeError("Route target must be defined")
35+
for method in self.http_methods or []:
36+
if method not in HTTPMethod:
37+
raise RuntimeError(f"Route contains invalid method {method.value}")
38+
39+
def asdict(self) -> dict[str, Any]:
40+
serialized = super().asdict()
41+
if self.http_methods:
42+
serialized["http_methods"] = [method.value for method in self.http_methods]
43+
return serialized

scw_serverless/gateway/gateway_manager.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ def update_routes(self) -> None:
6565
for function in routed_functions:
6666
if function.name not in created_functions:
6767
raise RuntimeError(
68-
f"Could not update route to function {function.name}"
68+
f"Could not update route to function {function.name} "
6969
+ "because it was not deployed"
7070
)
7171

tests/test_gateway/test_gateway_manager.py

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import pytest
22
import responses
33
import scaleway.function.v1beta1 as sdk
4+
from responses.matchers import header_matcher, json_params_matcher, query_param_matcher
45
from scaleway import Client
56

67
from scw_serverless.app import Serverless
@@ -31,7 +32,7 @@ def app_gateway_manager() -> GatewayManager:
3132
client = Client(
3233
access_key="SCWXXXXXXXXXXXXXXXXX",
3334
# The uuid is validated
34-
secret_key="498cce73-2a07-4e8c-b8ef-8f988e3c6929",
35+
secret_key="498cce73-2a07-4e8c-b8ef-8f988e3c6929", # nosec # false positive
3536
default_region=constants.DEFAULT_REGION,
3637
)
3738
return GatewayManager(app, MOCK_GATEWAY_URL, MOCK_GATEWAY_API_KEY, client)
@@ -60,15 +61,50 @@ def test_gateway_manager_update_routes(
6061
constants.SCALEWAY_FNC_API_URL + "/namespaces",
6162
json={"namespaces": [namespace]},
6263
)
64+
# We have to provide a stop gap otherwise list_namepaces_all() will keep
65+
# making API calls.
66+
mocked_responses.get(
67+
constants.SCALEWAY_FNC_API_URL + "/namespaces",
68+
json={"namespaces": []},
69+
)
6370

6471
mocked_responses.get(
6572
constants.SCALEWAY_FNC_API_URL + "/functions",
73+
match=[query_param_matcher({"namespace_id": namespace["id"], "page": 1})],
74+
json={
75+
"functions": [
76+
{
77+
"name": function.name,
78+
"domain_name": HELLO_WORLD_MOCK_DOMAIN,
79+
"secret_environment_variables": [],
80+
}
81+
]
82+
},
83+
)
84+
mocked_responses.get(
85+
constants.SCALEWAY_FNC_API_URL + "/functions",
86+
match=[query_param_matcher({"namespace_id": namespace["id"], "page": 2})],
87+
json={"functions": []},
88+
)
89+
90+
# We should attempt to delete the route
91+
mocked_responses.delete(
92+
MOCK_GATEWAY_URL + "/scw", # type: ignore
6693
match=[
67-
responses.matchers.query_param_matcher(
68-
{"namespace_id": namespace["id"], "page": 1}
69-
)
94+
header_matcher({"X-Auth-Token": MOCK_GATEWAY_API_KEY}),
95+
json_params_matcher(params=function.gateway_route.asdict()), # type: ignore
96+
],
97+
)
98+
# We should attempt to create the route
99+
mocked_responses.post(
100+
MOCK_GATEWAY_URL + "/scw", # type: ignore
101+
match=[
102+
header_matcher({"X-Auth-Token": MOCK_GATEWAY_API_KEY}),
103+
json_params_matcher(
104+
params=function.gateway_route.asdict() # type: ignore
105+
| {"target": "https://" + HELLO_WORLD_MOCK_DOMAIN}
106+
),
70107
],
71-
json={"functions": []},
72108
)
73109

74110
app_gateway_manager.update_routes()

0 commit comments

Comments
 (0)