Skip to content

Commit 605a7d9

Browse files
committed
coverage
1 parent c15c159 commit 605a7d9

File tree

1 file changed

+60
-28
lines changed

1 file changed

+60
-28
lines changed

lambdas/shared/tests/test_common/test_log_decorator.py

Lines changed: 60 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,30 @@ def setUp(self):
1717
self.mock_logger_exception = self.logger_exception_patcher.start()
1818
self.logger_error_patcher = patch("common.log_decorator.logger.error")
1919
self.mock_logger_error = self.logger_error_patcher.start()
20+
self.firehose_client_patcher = patch("common.log_decorator.firehose_client")
21+
self.mock_firehose_client = self.firehose_client_patcher.start()
22+
# patch common.log_decorator.time
23+
self.mock_generate_send = patch("common.log_decorator.generate_and_send_logs").start()
2024

2125
def tearDown(self):
2226
patch.stopall()
2327

24-
@patch("common.log_decorator.firehose_client")
2528
def test_send_log_to_firehose_success(self, mock_firehose_client):
2629
"""Test send_log_to_firehose with successful firehose response"""
2730
# Arrange
2831
test_log_data = {"function_name": "test_func", "result": "success"}
2932
mock_response = {"ResponseMetadata": {"HTTPStatusCode": 200}}
30-
mock_firehose_client.put_record.return_value = mock_response
33+
self.mock_firehose_client.put_record.return_value = mock_response
34+
35+
# Act
36+
send_log_to_firehose(self.test_stream, test_log_data)
37+
38+
# Assert
39+
expected_record = {"Data": json.dumps({"event": test_log_data}).encode("utf-8")}
40+
self.mock_firehose_client.put_record.assert_called_once_with(
41+
DeliveryStreamName=self.test_stream,
42+
Record=expected_record
43+
)
3144

3245
# Act
3346
send_log_to_firehose(self.test_stream, test_log_data)
@@ -39,26 +52,24 @@ def test_send_log_to_firehose_success(self, mock_firehose_client):
3952
Record=expected_record
4053
)
4154

42-
@patch("common.log_decorator.firehose_client")
43-
def test_send_log_to_firehose_exception(self, mock_firehose_client):
55+
def test_send_log_to_firehose_exception(self):
4456
"""Test send_log_to_firehose with firehose exception"""
4557
# Arrange
4658
test_log_data = {"function_name": "test_func", "result": "error"}
47-
mock_firehose_client.put_record.side_effect = Exception("Firehose error")
59+
self.mock_firehose_client.put_record.side_effect = Exception("Firehose error")
4860

4961
# Act
5062
send_log_to_firehose(self.test_stream, test_log_data)
5163

5264
# Assert
53-
mock_firehose_client.put_record.assert_called_once()
65+
self.mock_firehose_client.put_record.assert_called_once()
5466
self.mock_logger_exception.assert_called_once_with(
5567
"Error sending log to Firehose: %s",
56-
mock_firehose_client.put_record.side_effect
68+
self.mock_firehose_client.put_record.side_effect
5769
)
5870

59-
@patch("common.log_decorator.send_log_to_firehose")
6071
@patch("time.time")
61-
def test_generate_and_send_logs_success(self, mock_time, mock_send_log):
72+
def test_generate_and_send_logs_success(self, mock_time):
6273
"""Test generate_and_send_logs with successful log generation"""
6374
# Arrange
6475
mock_time.return_value = 1000.5
@@ -78,11 +89,10 @@ def test_generate_and_send_logs_success(self, mock_time, mock_send_log):
7889
"result": "success"
7990
}
8091
self.mock_logger_error.assert_not_called()
81-
mock_send_log.assert_called_once_with(self.test_stream, expected_log_data)
92+
self.mock_send_log.assert_called_once_with(self.test_stream, expected_log_data)
8293

83-
@patch("common.log_decorator.send_log_to_firehose")
8494
@patch("time.time")
85-
def test_generate_and_send_logs_error(self, mock_time, mock_send_log):
95+
def test_generate_and_send_logs_error(self, mock_time):
8696
"""Test generate_and_send_logs with error log generation"""
8797
# Arrange
8898
mock_time.return_value = 1000.75
@@ -102,17 +112,16 @@ def test_generate_and_send_logs_error(self, mock_time, mock_send_log):
102112
"error": "Test error"
103113
}
104114
self.mock_logger_error.assert_called_once_with(json.dumps(expected_log_data))
105-
mock_send_log.assert_called_once_with(self.test_stream, expected_log_data)
115+
self.mock_send_log.assert_called_once_with(self.test_stream, expected_log_data)
106116

107-
@patch("common.log_decorator.generate_and_send_logs")
108117
@patch("common.log_decorator.time")
109118
@patch("common.log_decorator.datetime")
110-
def test_logging_decorator_success(self, mock_datetime, mock_time, mock_generate_send):
119+
def test_logging_decorator_success(self, mock_datetime, mock_time):
111120
"""Test logging_decorator with successful function execution"""
112121
# Arrange
113122
mock_datetime.now.return_value = datetime(2023, 1, 1, 12, 0, 0)
114123
mock_time.time.return_value = 1000.0
115-
mock_generate_send.return_value = None
124+
self.mock_generate_send.return_value = None
116125

117126
@logging_decorator(self.test_prefix, self.test_stream)
118127
def test_function(x, y):
@@ -125,24 +134,23 @@ def test_function(x, y):
125134
self.assertEqual(result, {"statusCode": 200, "result": 5})
126135

127136
# Verify generate_and_send_logs was called with correct parameters
128-
mock_generate_send.assert_called_once()
129-
call_args = mock_generate_send.call_args[0]
130-
call_kwargs = mock_generate_send.call_args[1]
137+
self.mock_generate_send.assert_called_once()
138+
call_args = self.mock_generate_send.call_args[0]
139+
call_kwargs = self.mock_generate_send.call_args[1]
131140
self.assertEqual(call_args[0], self.test_stream) # stream_name
132141
self.assertEqual(call_args[1], 1000.0) # start_time
133142
self.assertEqual(call_args[2]["function_name"], f"{self.test_prefix}_test_function") # base_log_data
134143
self.assertEqual(call_kwargs['additional_log_data'], {"statusCode": 200, "result": 5}) # additional_log_data
135144
self.assertNotIn("is_error_log", call_kwargs) # Should not be error log
136145

137-
@patch("common.log_decorator.generate_and_send_logs")
138146
@patch("common.log_decorator.time")
139147
@patch("common.log_decorator.datetime")
140-
def test_logging_decorator_exception(self, mock_datetime, mock_time, mock_generate_send):
148+
def test_logging_decorator_exception(self, mock_datetime, mock_time):
141149
"""Test logging_decorator with function raising exception"""
142150
# Arrange
143151
mock_datetime.now.return_value = datetime(2023, 1, 1, 12, 0, 0)
144152
mock_time.time.return_value = 1000.0
145-
mock_generate_send.return_value = None
153+
self.mock_generate_send.return_value = None
146154

147155
@logging_decorator(self.test_prefix, self.test_stream)
148156
def test_function_with_error():
@@ -153,21 +161,20 @@ def test_function_with_error():
153161
test_function_with_error()
154162

155163
# Verify generate_and_send_logs was called with error parameters
156-
mock_generate_send.assert_called_once()
157-
call_args = mock_generate_send.call_args[0]
158-
call_kwargs = mock_generate_send.call_args[1]
164+
self.mock_generate_send.assert_called_once()
165+
call_args = self.mock_generate_send.call_args[0]
166+
call_kwargs = self.mock_generate_send.call_args[1]
159167

160168
self.assertEqual(call_args[0], self.test_stream) # stream_name
161169
self.assertEqual(call_args[1], 1000.0) # start_time
162170
self.assertEqual(call_args[2]["function_name"], f"{self.test_prefix}_test_function_with_error") # base_log_data
163171
self.assertEqual(call_args[3], {"statusCode": 500, "error": "Test error"}) # additional_log_data
164172
self.assertTrue(call_kwargs.get("is_error_log", False)) # Should be error log
165173

166-
@patch("common.log_decorator.generate_and_send_logs")
167-
def test_logging_decorator_preserves_function_metadata(self, mock_generate_send):
174+
def test_logging_decorator_preserves_function_metadata(self):
168175
"""Test that the decorator preserves the original function's metadata"""
169176
# Arrange
170-
mock_generate_send.return_value = None
177+
self.mock_generate_send.return_value = None
171178

172179
@logging_decorator(self.test_prefix, self.test_stream)
173180
def documented_function():
@@ -177,3 +184,28 @@ def documented_function():
177184
# Act & Assert
178185
self.assertEqual(documented_function.__name__, "documented_function")
179186
self.assertEqual(documented_function.__doc__, "This is a test function with documentation")
187+
188+
def test_send_log_to_firehose_exception_logging(self):
189+
"""Test that logger.exception is called when firehose_client.put_record throws an error"""
190+
# Arrange
191+
test_log_data = {"function_name": "test_func", "result": "error"}
192+
test_error = Exception("Firehose connection failed")
193+
self.mock_firehose_client.put_record.side_effect = test_error
194+
195+
# Act
196+
send_log_to_firehose(self.test_stream, test_log_data)
197+
198+
# Assert
199+
# Verify firehose_client.put_record was called
200+
expected_record = {"Data": json.dumps({"event": test_log_data}).encode("utf-8")}
201+
self.mock_firehose_client.put_record.assert_called_once_with(
202+
DeliveryStreamName=self.test_stream,
203+
Record=expected_record
204+
)
205+
206+
# Verify logger.exception was called with the correct message and error
207+
self.mock_logger_exception.assert_called_once_with(
208+
"Error sending log to Firehose: %s",
209+
test_error
210+
)
211+

0 commit comments

Comments
 (0)