Fixes typo in `examples/pong_xapp.py`
[ric-plt/xapp-frame-py.git] / tests / test_Logger.py
1 # Copyright (c) 2019 AT&T Intellectual Property.
2 # Copyright (c) 2018-2019 Nokia.
3 #
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
7 #
8 #     http://www.apache.org/licenses/LICENSE-2.0
9 #
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15 #
16 # This source code is part of the near-RT RIC (RAN Intelligent Controller)
17 # platform project (RICP).
18 #
19 """Unit tests for Logger.py"""
20 import unittest
21 from unittest.mock import patch
22
23 from ricxappframe.logger.mdclogger import Level, MDCLogger
24 from .mdclogtestutils import TestMdcLogUtils
25
26
27 class TestMdcLog(unittest.TestCase):
28     """Unit tests for mdclog.py"""
29
30     def setUp(self):
31         self.logger = MDCLogger()
32
33     def tearDown(self):
34         pass
35
36     def test_that_get_level_returns_the_current_log_level(self):
37
38         # default level is ERROR
39         self.assertEqual(self.logger.get_level(), Level.ERROR)
40         self.logger.set_level(Level.INFO)
41         self.assertEqual(self.logger.get_level(), Level.INFO)
42         self.logger.set_level(Level.WARNING)
43         self.assertEqual(self.logger.get_level(), Level.WARNING)
44         self.logger.set_level(Level.ERROR)
45         self.assertEqual(self.logger.get_level(), Level.ERROR)
46         self.logger.set_level(Level.DEBUG)
47         self.assertEqual(self.logger.get_level(), Level.DEBUG)
48
49     def test_that_set_level_does_not_accept_incorrect_level(self):
50
51         self.logger.set_level(Level.INFO)
52         self.logger.set_level(55)
53         self.assertEqual(self.logger.get_level(), Level.INFO)
54
55     @patch('ricxappframe.logger.mdclogger.MDCLogger._output_log')
56     def test_that_logs_with_lower_than_current_level_(self, output_mock):
57
58         self.logger.set_level(Level.WARNING)
59         self.logger.log(Level.DEBUG, "DEBUG")
60         self.logger.log(Level.INFO, "INFO")
61         self.logger.log(Level.WARNING, "WARNING")
62         self.logger.log(Level.ERROR, "ERROR")
63
64         self.assertEqual(2, output_mock.call_count)
65         logs = TestMdcLogUtils.get_logs_as_json(output_mock.call_args_list)
66         self.assertEqual(logs[0]["msg"], "WARNING")
67         self.assertEqual(logs[1]["msg"], "ERROR")
68
69     @patch('ricxappframe.logger.mdclogger.MDCLogger._output_log')
70     def test_that_logs_with_lower_than_current_level_are_not_logged(self, output_mock):
71
72         self.logger.set_level(Level.WARNING)
73         self.logger.log(Level.DEBUG, "DEBUG")
74         self.logger.log(Level.INFO, "INFO")
75         self.logger.log(Level.WARNING, "WARNING")
76         self.logger.log(Level.ERROR, "ERROR")
77
78         self.assertEqual(2, output_mock.call_count)
79         logs = TestMdcLogUtils.get_logs_as_json(output_mock.call_args_list)
80         self.assertEqual(logs[0]["msg"], "WARNING")
81         self.assertEqual(logs[1]["msg"], "ERROR")
82
83     @patch('ricxappframe.logger.mdclogger.MDCLogger._output_log')
84     def test_that_log_contains_correct_criticality(self, output_mock):
85
86         self.logger.set_level(Level.DEBUG)
87
88         self.logger.log(Level.DEBUG, "debug test log")
89         self.logger.log(Level.INFO, "info test log")
90         self.logger.log(Level.WARNING, "warning test log")
91         self.logger.log(Level.ERROR, "error test log")
92
93         self.logger.debug("another debug test log")
94         self.logger.info("another info test log")
95         self.logger.warning("another warning test log")
96         self.logger.error("another error test log")
97
98         self.assertEqual(8, output_mock.call_count)
99         logs = TestMdcLogUtils.get_logs_as_json(output_mock.call_args_list)
100         self.assertEqual(logs[0]["crit"], "DEBUG")
101         self.assertEqual(logs[1]["crit"], "INFO")
102         self.assertEqual(logs[2]["crit"], "WARNING")
103         self.assertEqual(logs[3]["crit"], "ERROR")
104         self.assertEqual(logs[4]["crit"], "DEBUG")
105         self.assertEqual(logs[5]["crit"], "INFO")
106         self.assertEqual(logs[6]["crit"], "WARNING")
107         self.assertEqual(logs[7]["crit"], "ERROR")
108
109     @patch('time.time')
110     @patch('ricxappframe.logger.mdclogger.MDCLogger._output_log')
111     def test_that_log_contains_correct_timestamp(self, output_mock, mock_time):
112
113         mock_time.return_value = 1554806251.4388545
114         self.logger.error("timestamp test")
115
116         logs = TestMdcLogUtils.get_logs_as_json(output_mock.call_args_list)
117         self.assertEqual(logs[0]["ts"], 1554806251439)
118
119     @patch('ricxappframe.logger.mdclogger.MDCLogger._output_log')
120     def test_that_log_contains_correct_message(self, output_mock):
121
122         self.logger.error("message test")
123         logs = TestMdcLogUtils.get_logs_as_json(output_mock.call_args_list)
124         print(logs)
125         self.assertEqual(logs[0]["msg"], "message test")
126
127     @patch('ricxappframe.logger.mdclogger.MDCLogger._output_log')
128     def test_that_log_message_is_escaped_to_valid_json_string(self, output_mock):
129
130         self.logger.set_level(Level.DEBUG)
131
132         self.logger.info(r'\ and "')
133
134         logs = TestMdcLogUtils.get_logs(output_mock.call_args_list)
135         self.assertTrue(r'\\ and \"' in logs[0])
136         logs = TestMdcLogUtils.get_logs_as_json(output_mock.call_args_list)
137         self.assertEqual(logs[0]["msg"], r'\ and "')
138
139     @patch('ricxappframe.logger.mdclogger.MDCLogger._output_log')
140     def test_that_empty_mdc_is_logged_correctly(self, output_mock):
141         self.logger.mdclog_format_init(configmap_monitor=True)
142         self.logger.error("empty mdc test")
143         self.logger.error(output_mock.call_args_list)
144         logs = TestMdcLogUtils.get_logs_as_json(output_mock.call_args_list)
145         self.assertEqual(logs[0]["msg"], 'empty mdc test')
146
147     @patch('ricxappframe.logger.mdclogger.MDCLogger._output_log')
148     def test_that_config_map_is_monitored_correctly(self, output_mock):
149         src = open("//tmp//log", "w")
150         src.write("log-level: debug\n")
151         src.close()
152         self.logger.filename = "/tmp/log"
153         self.logger.dirname = "/tmp/"
154         self.logger.mdc = {"PID": "", "SYSTEM_NAME": "", "HOST_NAME": "", "SERVICE_NAME": "", "CONTAINER_NAME": "", "POD_NAME": ""}
155         self.logger.get_env_params_values()
156         self.logger.parse_file()
157         self.logger.error("Hello")
158         self.assertEqual(self.logger.get_level(), Level.DEBUG)
159
160     @patch('ricxappframe.logger.mdclogger.MDCLogger._output_log')
161     def test_that_mdc_values_are_logged_correctly(self, output_mock):
162
163         self.logger.add_mdc("key1", "value1")
164         self.logger.add_mdc("key2", "value2")
165         self.logger.error("mdc test")
166
167         logs = TestMdcLogUtils.get_logs_as_json(output_mock.call_args_list)
168         self.assertEqual(logs[0]["mdc"]["key1"], "value1")
169         self.assertEqual(logs[0]["mdc"]["key2"], "value2")
170
171     @patch('ricxappframe.logger.mdclogger.MDCLogger._output_log')
172     def test_that_mdc_pid_logged_correctly(self, output_mock):
173         self.logger.mdclog_format_init(configmap_monitor=True)
174         self.logger.error("mdc test")
175         logs = TestMdcLogUtils.get_logs_as_json(output_mock.call_args_list)
176         self.assertTrue(logs[0]["mdc"]["PID"])
177
178     def test_that_mdc_values_can_be_added_and_removed(self):
179
180         self.logger.add_mdc("key1", "value1")
181         self.logger.add_mdc("key2", "value2")
182         self.assertEqual(self.logger.get_mdc("key2"), "value2")
183         self.assertEqual(self.logger.get_mdc("key1"), "value1")
184         self.assertEqual(self.logger.get_mdc("non_existent"), None)
185         self.logger.remove_mdc("key1")
186         self.assertEqual(self.logger.get_mdc("key1"), None)
187         self.logger.remove_mdc("non_existent")
188         self.logger.clean_mdc()
189         self.assertEqual(self.logger.get_mdc("key2"), None)
190
191     @patch('ricxappframe.logger.mdclogger.MDCLogger._output_log')
192     def test_multiple_logger_instances(self, output_mock):
193
194         logger1 = MDCLogger("logger1")
195         logger2 = MDCLogger("logger2")
196         logger1.add_mdc("logger1_key1", "logger1_value1")
197         logger1.add_mdc("logger1_key2", "logger1_value2")
198         logger2.add_mdc("logger2_key1", "logger2_value1")
199         logger2.add_mdc("logger2_key2", "logger2_value2")
200
201         logger1.error("error msg")
202         logger2.error("warning msg")
203
204         logs = TestMdcLogUtils.get_logs_as_json(output_mock.call_args_list)
205         self.assertEqual(2, output_mock.call_count)
206
207         self.assertEqual(logs[0]["id"], "logger1")
208         self.assertEqual(logs[0]["crit"], "ERROR")
209         self.assertEqual(logs[0]["msg"], "error msg")
210         self.assertEqual(logs[0]["mdc"]["logger1_key1"], "logger1_value1")
211         self.assertEqual(logs[0]["mdc"]["logger1_key2"], "logger1_value2")
212         self.assertEqual(len(logs[0]["mdc"]), 2)
213
214         self.assertEqual(logs[1]["id"], "logger2")
215         self.assertEqual(logs[1]["crit"], "ERROR")
216         self.assertEqual(logs[1]["msg"], "warning msg")
217         self.assertEqual(logs[1]["mdc"]["logger2_key1"], "logger2_value1")
218         self.assertEqual(logs[1]["mdc"]["logger2_key2"], "logger2_value2")
219         self.assertEqual(len(logs[1]["mdc"]), 2)
220
221
222 if __name__ == '__main__':
223     unittest.main()