Skip to content

Commit eb413a0

Browse files
committed
[PRMP-1048] tests
1 parent 806ab90 commit eb413a0

File tree

2 files changed

+409
-0
lines changed

2 files changed

+409
-0
lines changed
Lines changed: 235 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,235 @@
1+
import json
2+
import pytest
3+
from botocore.exceptions import ClientError
4+
from handlers.concurrency_controller_handler import lambda_handler, validate_event
5+
from unittest.mock import MagicMock
6+
7+
8+
@pytest.fixture
9+
def mock_concurrency_controller_service(mocker):
10+
mocked_class = mocker.patch(
11+
"handlers.concurrency_controller_handler.ConcurrencyControllerService"
12+
)
13+
mocked_instance = mocked_class.return_value
14+
yield mocked_instance
15+
16+
17+
@pytest.fixture
18+
def mock_logger(mocker):
19+
return mocker.patch("handlers.concurrency_controller_handler.logger")
20+
21+
22+
@pytest.fixture
23+
def valid_event():
24+
return {
25+
"targetFunction": "test-lambda-function",
26+
"reservedConcurrency": 10
27+
}
28+
29+
30+
@pytest.fixture
31+
def event_with_zero_concurrency():
32+
return {
33+
"targetFunction": "test-lambda-function",
34+
"reservedConcurrency": 0
35+
}
36+
37+
38+
def test_lambda_handler_success(valid_event, context, mock_concurrency_controller_service):
39+
expected_response = {
40+
"statusCode": 200,
41+
"body": {
42+
"message": "Concurrency updated successfully",
43+
"function": "test-lambda-function",
44+
"reservedConcurrency": 10
45+
}
46+
}
47+
48+
mock_concurrency_controller_service.update_function_concurrency.return_value = expected_response
49+
50+
result = lambda_handler(valid_event, context)
51+
52+
mock_concurrency_controller_service.update_function_concurrency.assert_called_once_with(
53+
"test-lambda-function", 10
54+
)
55+
56+
assert result == expected_response
57+
58+
59+
def test_lambda_handler_with_zero_concurrency(
60+
event_with_zero_concurrency, context, mock_concurrency_controller_service
61+
):
62+
expected_response = {
63+
"statusCode": 200,
64+
"body": {
65+
"message": "Concurrency updated successfully",
66+
"function": "test-lambda-function",
67+
"reservedConcurrency": 0
68+
}
69+
}
70+
71+
mock_concurrency_controller_service.update_function_concurrency.return_value = expected_response
72+
73+
result = lambda_handler(event_with_zero_concurrency, context)
74+
75+
mock_concurrency_controller_service.update_function_concurrency.assert_called_once_with(
76+
"test-lambda-function", 0
77+
)
78+
79+
assert result == expected_response
80+
81+
82+
def test_lambda_handler_with_large_concurrency(context, mock_concurrency_controller_service):
83+
event = {
84+
"targetFunction": "test-lambda-function",
85+
"reservedConcurrency": 1000
86+
}
87+
88+
expected_response = {
89+
"statusCode": 200,
90+
"body": {
91+
"message": "Concurrency updated successfully",
92+
"function": "test-lambda-function",
93+
"reservedConcurrency": 1000
94+
}
95+
}
96+
97+
mock_concurrency_controller_service.update_function_concurrency.return_value = expected_response
98+
99+
result = lambda_handler(event, context)
100+
101+
mock_concurrency_controller_service.update_function_concurrency.assert_called_once_with(
102+
"test-lambda-function", 1000
103+
)
104+
105+
assert result == expected_response
106+
107+
108+
def test_validate_event_success(valid_event):
109+
target_function, reserved_concurrency = validate_event(valid_event)
110+
111+
assert target_function == "test-lambda-function"
112+
assert reserved_concurrency == 10
113+
114+
115+
def test_validate_event_missing_target_function(mock_logger):
116+
event = {
117+
"reservedConcurrency": 10
118+
}
119+
120+
with pytest.raises(ValueError) as exc_info:
121+
validate_event(event)
122+
123+
assert str(exc_info.value) == "targetFunction is required"
124+
mock_logger.error.assert_called_once_with("Missing required parameter: targetFunction")
125+
126+
127+
def test_validate_event_missing_reserved_concurrency(mock_logger):
128+
event = {
129+
"targetFunction": "test-lambda-function"
130+
}
131+
132+
with pytest.raises(ValueError) as exc_info:
133+
validate_event(event)
134+
135+
assert str(exc_info.value) == "reservedConcurrency is required"
136+
mock_logger.error.assert_called_once_with("Missing required parameter: reservedConcurrency")
137+
138+
139+
def test_validate_event_both_parameters_missing(mock_logger):
140+
event = {}
141+
142+
with pytest.raises(ValueError) as exc_info:
143+
validate_event(event)
144+
145+
# Should fail on first missing parameter
146+
assert str(exc_info.value) == "targetFunction is required"
147+
148+
149+
def test_validate_event_empty_target_function(mock_logger):
150+
event = {
151+
"targetFunction": "",
152+
"reservedConcurrency": 10
153+
}
154+
155+
with pytest.raises(ValueError) as exc_info:
156+
validate_event(event)
157+
158+
assert str(exc_info.value) == "targetFunction is required"
159+
mock_logger.error.assert_called_once_with("Missing required parameter: targetFunction")
160+
161+
162+
def test_validate_event_reserved_concurrency_zero_is_valid():
163+
event = {
164+
"targetFunction": "test-lambda-function",
165+
"reservedConcurrency": 0
166+
}
167+
168+
target_function, reserved_concurrency = validate_event(event)
169+
170+
assert target_function == "test-lambda-function"
171+
assert reserved_concurrency == 0
172+
173+
174+
def test_validate_event_with_additional_fields():
175+
event = {
176+
"targetFunction": "test-lambda-function",
177+
"reservedConcurrency": 10,
178+
"extraField": "should-be-ignored"
179+
}
180+
181+
target_function, reserved_concurrency = validate_event(event)
182+
183+
assert target_function == "test-lambda-function"
184+
assert reserved_concurrency == 10
185+
186+
187+
def test_lambda_handler_service_raises_resource_not_found(
188+
valid_event, context, mock_concurrency_controller_service
189+
):
190+
error_response = {
191+
'Error': {
192+
'Code': 'ResourceNotFoundException',
193+
'Message': 'Function not found'
194+
}
195+
}
196+
197+
mock_concurrency_controller_service.update_function_concurrency.side_effect = ClientError(
198+
error_response, 'PutFunctionConcurrency'
199+
)
200+
201+
result = lambda_handler(valid_event, context)
202+
203+
# The decorators convert exceptions to API Gateway error responses
204+
assert result['statusCode'] == 500
205+
body = json.loads(result['body'])
206+
assert body['message'] == 'Failed to utilise AWS client/resource'
207+
assert body['err_code'] == 'GWY_5001'
208+
209+
210+
def test_lambda_handler_service_raises_invalid_parameter(
211+
context, mock_concurrency_controller_service
212+
):
213+
event = {
214+
"targetFunction": "test-lambda-function",
215+
"reservedConcurrency": -1
216+
}
217+
218+
error_response = {
219+
'Error': {
220+
'Code': 'InvalidParameterValueException',
221+
'Message': 'Reserved concurrency value must be non-negative'
222+
}
223+
}
224+
225+
mock_concurrency_controller_service.update_function_concurrency.side_effect = ClientError(
226+
error_response, 'PutFunctionConcurrency'
227+
)
228+
229+
result = lambda_handler(event, context)
230+
231+
# The decorators convert exceptions to API Gateway error responses
232+
assert result['statusCode'] == 500
233+
body = json.loads(result['body'])
234+
assert body['message'] == 'Failed to utilise AWS client/resource'
235+
assert body['err_code'] == 'GWY_5001'

0 commit comments

Comments
 (0)