1+ import unittest
2+ from unittest .mock import patch , MagicMock , call
3+ import logging_decorators
4+ import json
5+ import time
6+
7+ class TestLoggingDecorators (unittest .TestCase ):
8+ def setUp (self ):
9+ # Patch logger and firehose_client
10+ self .logger_patcher = patch ('logging_decorators.logger' )
11+ self .mock_logger = self .logger_patcher .start ()
12+ self .firehose_patcher = patch ('logging_decorators.firehose_client' )
13+ self .mock_firehose = self .firehose_patcher .start ()
14+
15+ def tearDown (self ):
16+ self .logger_patcher .stop ()
17+ self .firehose_patcher .stop ()
18+
19+ def test_send_log_to_firehose_success (self ):
20+ log_data = {"foo" : "bar" }
21+ logging_decorators .send_log_to_firehose (log_data )
22+ self .mock_firehose .put_record .assert_called_once ()
23+ self .mock_logger .info .assert_called_with ("Log sent to Firehose" )
24+
25+ def test_send_log_to_firehose_exception (self ):
26+ self .mock_firehose .put_record .side_effect = Exception ("fail!" )
27+ log_data = {"foo" : "bar" }
28+ logging_decorators .send_log_to_firehose (log_data )
29+ self .mock_logger .exception .assert_called ()
30+ self .assertIn ("Error sending log to Firehose" , self .mock_logger .exception .call_args [0 ][0 ])
31+
32+ def test_generate_and_send_logs_info (self ):
33+ start_time = time .time () - 1
34+ base_log_data = {"base" : "data" }
35+ additional_log_data = {"extra" : "info" }
36+ logging_decorators .generate_and_send_logs (start_time , base_log_data , additional_log_data )
37+ self .mock_logger .info .assert_called ()
38+ self .mock_firehose .put_record .assert_called_once ()
39+
40+ def test_generate_and_send_logs_error (self ):
41+ start_time = time .time () - 1
42+ base_log_data = {"base" : "data" }
43+ additional_log_data = {"extra" : "info" }
44+ logging_decorators .generate_and_send_logs (start_time , base_log_data , additional_log_data , is_error_log = True )
45+ self .mock_logger .error .assert_called ()
46+ self .mock_firehose .put_record .assert_called_once ()
47+
48+ def test_process_diagnostics_dict (self ):
49+ diagnostics = {"statusCode" : 400 , "error_message" : "bad request" }
50+ result = logging_decorators .process_diagnostics (diagnostics , "file.csv" , "msg-1" )
51+ self .assertEqual (result ["status" ], "fail" )
52+ self .assertEqual (result ["statusCode" ], 400 )
53+ self .assertEqual (result ["diagnostics" ], "bad request" )
54+
55+ def test_process_diagnostics_string (self ):
56+ diagnostics = "some error"
57+ result = logging_decorators .process_diagnostics (diagnostics , "file.csv" , "msg-1" )
58+ self .assertEqual (result ["status" ], "fail" )
59+ self .assertEqual (result ["statusCode" ], 500 )
60+ self .assertEqual (result ["diagnostics" ], "Unable to determine diagnostics issue" )
61+
62+ def test_process_diagnostics_missing_keys (self ):
63+ result = logging_decorators .process_diagnostics (None , "file_key_missing" , "unknown" )
64+ self .assertEqual (result ["status" ], "fail" )
65+ self .assertEqual (result ["statusCode" ], 500 )
66+ self .assertIn ("unhandled error" , result ["diagnostics" ])
67+
68+ def test_process_diagnostics_success (self ):
69+ result = logging_decorators .process_diagnostics (None , "file.csv" , "msg-1" )
70+ self .assertEqual (result ["status" ], "success" )
71+ self .assertEqual (result ["statusCode" ], 200 )
72+ self .assertIn ("Operation completed successfully" , result ["diagnostics" ])
73+
74+ def test_convert_message_to_ack_row_logging_decorator_success (self ):
75+ @logging_decorators .convert_message_to_ack_row_logging_decorator
76+ def dummy_func (message , created_at_formatted_string ):
77+ return "ok"
78+
79+ message = {
80+ "file_key" : "file.csv" ,
81+ "row_id" : "row-1" ,
82+ "vaccine_type" : "type" ,
83+ "supplier" : "sup" ,
84+ "local_id" : "loc" ,
85+ "operation_requested" : "op"
86+ }
87+ result = dummy_func (message , "2024-08-20T12:00:00Z" )
88+ self .assertEqual (result , "ok" )
89+ self .mock_logger .info .assert_called ()
90+ self .mock_firehose .put_record .assert_called ()
91+
92+ def test_convert_message_to_ack_row_logging_decorator_exception (self ):
93+ @logging_decorators .convert_message_to_ack_row_logging_decorator
94+ def dummy_func (message , created_at_formatted_string ):
95+ raise ValueError ("fail!" )
96+
97+ message = {
98+ "file_key" : "file.csv" ,
99+ "row_id" : "row-1" ,
100+ "vaccine_type" : "type" ,
101+ "supplier" : "sup" ,
102+ "local_id" : "loc" ,
103+ "operation_requested" : "op"
104+ }
105+ with self .assertRaises (ValueError ):
106+ dummy_func (message , "2024-08-20T12:00:00Z" )
107+ self .mock_logger .error .assert_called ()
108+ self .mock_firehose .put_record .assert_called ()
109+
110+ def test_ack_lambda_handler_logging_decorator_success (self ):
111+ @logging_decorators .ack_lambda_handler_logging_decorator
112+ def dummy_lambda (event , context ):
113+ return "lambda-ok"
114+
115+ result = dummy_lambda ({}, {})
116+ self .assertEqual (result , "lambda-ok" )
117+ self .mock_logger .info .assert_called ()
118+ self .mock_firehose .put_record .assert_called ()
119+
120+ def test_ack_lambda_handler_logging_decorator_exception (self ):
121+ @logging_decorators .ack_lambda_handler_logging_decorator
122+ def dummy_lambda (event , context ):
123+ raise RuntimeError ("fail!" )
124+
125+ with self .assertRaises (RuntimeError ):
126+ dummy_lambda ({}, {})
127+ self .mock_logger .error .assert_called ()
128+ self .mock_firehose .put_record .assert_called ()
129+
130+ if __name__ == "__main__" :
131+ unittest .main ()
0 commit comments