1 # Copyright (c) 2019 AT&T Intellectual Property.
2 # Copyright (c) 2018-2019 Nokia.
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
8 # http://www.apache.org/licenses/LICENSE-2.0
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.
16 # This source code is part of the near-RT RIC (RAN Intelligent Controller)
17 # platform project (RICP).
19 """Unit tests for Logger.py"""
21 from unittest.mock import patch
26 from mdclogpy import Logger
27 from mdclogpy import Level
29 from .mdclogtestutils import TestMdcLogUtils
32 class TestMdcLog(unittest.TestCase):
33 """Unit tests for mdclog.py"""
36 self.logger = Logger()
42 def test_that_get_level_returns_the_current_log_level(self):
44 # default level is ERROR
45 self.assertEqual(self.logger.get_level(), Level.ERROR)
46 self.logger.set_level(Level.INFO)
47 self.assertEqual(self.logger.get_level(), Level.INFO)
48 self.logger.set_level(Level.WARNING)
49 self.assertEqual(self.logger.get_level(), Level.WARNING)
50 self.logger.set_level(Level.ERROR)
51 self.assertEqual(self.logger.get_level(), Level.ERROR)
52 self.logger.set_level(Level.DEBUG)
53 self.assertEqual(self.logger.get_level(), Level.DEBUG)
55 def test_that_set_level_does_not_accept_incorrect_level(self):
57 self.logger.set_level(Level.INFO)
58 self.logger.set_level(55)
59 self.assertEqual(self.logger.get_level(), Level.INFO)
61 @patch('mdclogpy.Logger._output_log')
62 def test_that_logs_with_lower_than_current_level_(self, output_mock):
64 self.logger.set_level(Level.WARNING)
65 self.logger.log(Level.DEBUG, "DEBUG")
66 self.logger.log(Level.INFO, "INFO")
67 self.logger.log(Level.WARNING, "WARNING")
68 self.logger.log(Level.ERROR, "ERROR")
70 self.assertEqual(2, output_mock.call_count)
71 logs = TestMdcLogUtils.get_logs_as_json(output_mock.call_args_list)
72 self.assertEqual(logs[0]["msg"], "WARNING")
73 self.assertEqual(logs[1]["msg"], "ERROR")
75 @patch('mdclogpy.Logger._output_log')
76 def test_that_logs_with_lower_than_current_level_are_not_logged(self, output_mock):
78 self.logger.set_level(Level.WARNING)
79 self.logger.log(Level.DEBUG, "DEBUG")
80 self.logger.log(Level.INFO, "INFO")
81 self.logger.log(Level.WARNING, "WARNING")
82 self.logger.log(Level.ERROR, "ERROR")
84 self.assertEqual(2, output_mock.call_count)
85 logs = TestMdcLogUtils.get_logs_as_json(output_mock.call_args_list)
86 self.assertEqual(logs[0]["msg"], "WARNING")
87 self.assertEqual(logs[1]["msg"], "ERROR")
89 @patch('mdclogpy.Logger._output_log')
90 def test_that_log_contains_correct_criticality(self, output_mock):
92 self.logger.set_level(Level.DEBUG)
94 self.logger.log(Level.DEBUG, "debug test log")
95 self.logger.log(Level.INFO, "info test log")
96 self.logger.log(Level.WARNING, "warning test log")
97 self.logger.log(Level.ERROR, "error test log")
99 self.logger.debug("another debug test log")
100 self.logger.info("another info test log")
101 self.logger.warning("another warning test log")
102 self.logger.error("another error test log")
104 self.assertEqual(8, output_mock.call_count)
105 logs = TestMdcLogUtils.get_logs_as_json(output_mock.call_args_list)
106 self.assertEqual(logs[0]["crit"], "DEBUG")
107 self.assertEqual(logs[1]["crit"], "INFO")
108 self.assertEqual(logs[2]["crit"], "WARNING")
109 self.assertEqual(logs[3]["crit"], "ERROR")
110 self.assertEqual(logs[4]["crit"], "DEBUG")
111 self.assertEqual(logs[5]["crit"], "INFO")
112 self.assertEqual(logs[6]["crit"], "WARNING")
113 self.assertEqual(logs[7]["crit"], "ERROR")
116 @patch('mdclogpy.Logger._output_log')
117 def test_that_log_contains_correct_timestamp(self, output_mock, mock_time):
119 mock_time.return_value = 1554806251.4388545
120 self.logger.error("timestamp test")
122 logs = TestMdcLogUtils.get_logs_as_json(output_mock.call_args_list)
123 self.assertEqual(logs[0]["ts"], 1554806251439)
125 @patch('mdclogpy.Logger._output_log')
126 def test_that_log_contains_correct_message(self, output_mock):
128 self.logger.error("message test")
129 logs = TestMdcLogUtils.get_logs_as_json(output_mock.call_args_list)
131 self.assertEqual(logs[0]["msg"], "message test")
133 @patch('mdclogpy.Logger._output_log')
134 def test_that_log_message_is_escaped_to_valid_json_string(self, output_mock):
136 self.logger.set_level(Level.DEBUG)
138 self.logger.info('\ and "')
140 logs = TestMdcLogUtils.get_logs(output_mock.call_args_list)
141 self.assertTrue(r'\\ and \"' in logs[0])
142 logs = TestMdcLogUtils.get_logs_as_json(output_mock.call_args_list)
143 self.assertEqual(logs[0]["msg"], '\ and "')
145 @patch('mdclogpy.Logger._output_log')
146 def test_that_empty_mdc_is_logged_correctly(self, output_mock):
147 self.logger.mdclog_format_init(configmap_monitor=True)
148 self.logger.error("empty mdc test")
149 logs = TestMdcLogUtils.get_logs_as_json(output_mock.call_args_list)
150 self.assertEqual(logs[0]["msg"],'empty mdc test')
152 @patch('mdclogpy.Logger._output_log')
153 def test_that_config_map_is_monitored_correctly(self, output_mock):
154 src = open("//tmp//log","w")
155 src.write("log-level: debug\n")
157 self.logger.filename = "/tmp/log"
158 self.logger.dirname = "/tmp/"
159 self.logger.mdc = {"PID":"","SYSTEM_NAME":"","HOST_NAME":"","SERVICE_NAME":"","CONTAINER_NAME":"","POD_NAME":""}
160 self.logger.get_env_params_values()
161 self.logger.parse_file()
162 self.logger.error("Hello")
163 self.assertEqual(self.logger.get_level(),Level.DEBUG)
165 @patch('mdclogpy.Logger._output_log')
166 def test_that_mdc_values_are_logged_correctly(self, output_mock):
168 self.logger.add_mdc("key1", "value1")
169 self.logger.add_mdc("key2", "value2")
170 self.logger.error("mdc test")
172 logs = TestMdcLogUtils.get_logs_as_json(output_mock.call_args_list)
173 self.assertEqual(logs[0]["mdc"]["key1"], "value1")
174 self.assertEqual(logs[0]["mdc"]["key2"], "value2")
176 @patch('mdclogpy.Logger._output_log')
177 def test_that_mdc_pid_logged_correctly(self, output_mock):
178 self.logger.mdclog_format_init(configmap_monitor=True)
179 self.logger.error("mdc test")
180 logs = TestMdcLogUtils.get_logs_as_json(output_mock.call_args_list)
181 self.assertTrue(logs[0]["mdc"]["PID"])
184 def test_that_mdc_values_can_be_added_and_removed(self):
186 self.logger.add_mdc("key1", "value1")
187 self.logger.add_mdc("key2", "value2")
188 self.assertEqual(self.logger.get_mdc("key2"), "value2")
189 self.assertEqual(self.logger.get_mdc("key1"), "value1")
190 self.assertEqual(self.logger.get_mdc("non_existent"), None)
191 self.logger.remove_mdc("key1")
192 self.assertEqual(self.logger.get_mdc("key1"), None)
193 self.logger.remove_mdc("non_existent")
194 self.logger.clean_mdc()
195 self.assertEqual(self.logger.get_mdc("key2"), None)
199 @patch('mdclogpy.Logger._output_log')
200 def test_update_mdc_log_level_severity(self, output_mock):
201 self.logger.update_mdc_log_level_severity("error")
202 self.logger.update_mdc_log_level_severity("warning")
203 self.logger.update_mdc_log_level_severity("info")
204 self.logger.update_mdc_log_level_severity("debug")
205 self.logger.update_mdc_log_level_severity("")
207 @patch('mdclogpy.Logger._output_log')
208 def test_output_log(self, output_mock):
209 self.logger._output_log("Logger")
211 @patch('mdclogpy.Logger._output_log')
212 def test_register_log_change_notify(self, output_mock):
213 self.logger.dirname = "/tmp/"
214 self.logger.filename = "/tmp/log"
215 self.logger.register_log_change_notify()
217 @patch('mdclogpy.Logger._output_log')
218 def test_multiple_logger_instances(self, output_mock):
220 logger1 = Logger("logger1")
221 logger2 = Logger("logger2")
222 logger1.add_mdc("logger1_key1", "logger1_value1")
223 logger1.add_mdc("logger1_key2", "logger1_value2")
224 logger2.add_mdc("logger2_key1", "logger2_value1")
225 logger2.add_mdc("logger2_key2", "logger2_value2")
226 mdclogpy.add_mdc("key", "value")
228 logger1.error("error msg")
229 logger2.error("warning msg")
230 mdclogpy.error("info msg")
232 logs = TestMdcLogUtils.get_logs_as_json(output_mock.call_args_list)
233 self.assertEqual(3, output_mock.call_count)
235 self.assertEqual(logs[0]["id"], "logger1")
236 self.assertEqual(logs[0]["crit"], "ERROR")
237 self.assertEqual(logs[0]["msg"], "error msg")
238 self.assertEqual(logs[0]["mdc"]["logger1_key1"], "logger1_value1")
239 self.assertEqual(logs[0]["mdc"]["logger1_key2"], "logger1_value2")
240 self.assertEqual(len(logs[0]["mdc"]), 2)
242 self.assertEqual(logs[1]["id"], "logger2")
243 self.assertEqual(logs[1]["crit"], "ERROR")
244 self.assertEqual(logs[1]["msg"], "warning msg")
245 self.assertEqual(logs[1]["mdc"]["logger2_key1"], "logger2_value1")
246 self.assertEqual(logs[1]["mdc"]["logger2_key2"], "logger2_value2")
247 self.assertEqual(len(logs[1]["mdc"]), 2)
249 self.assertEqual(logs[2]["id"], sys.argv[0])
250 self.assertEqual(logs[2]["crit"], "ERROR")
251 self.assertEqual(logs[2]["msg"], "info msg")
252 self.assertEqual(logs[2]["mdc"]["key"], "value")
253 self.assertEqual(len(logs[2]["mdc"]), 1)
255 if __name__ == '__main__':