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
23 from ricxappframe.logger.mdclogger import Level, MDCLogger
24 from .mdclogtestutils import TestMdcLogUtils
27 class TestMdcLog(unittest.TestCase):
28 """Unit tests for mdclog.py"""
31 self.logger = MDCLogger()
36 def test_that_get_level_returns_the_current_log_level(self):
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)
49 def test_that_set_level_does_not_accept_incorrect_level(self):
51 self.logger.set_level(Level.INFO)
52 self.logger.set_level(55)
53 self.assertEqual(self.logger.get_level(), Level.INFO)
55 @patch('ricxappframe.logger.mdclogger.MDCLogger._output_log')
56 def test_that_logs_with_lower_than_current_level_(self, output_mock):
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")
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")
69 @patch('ricxappframe.logger.mdclogger.MDCLogger._output_log')
70 def test_that_logs_with_lower_than_current_level_are_not_logged(self, output_mock):
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")
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")
83 @patch('ricxappframe.logger.mdclogger.MDCLogger._output_log')
84 def test_that_log_contains_correct_criticality(self, output_mock):
86 self.logger.set_level(Level.DEBUG)
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")
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")
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")
110 @patch('ricxappframe.logger.mdclogger.MDCLogger._output_log')
111 def test_that_log_contains_correct_timestamp(self, output_mock, mock_time):
113 mock_time.return_value = 1554806251.4388545
114 self.logger.error("timestamp test")
116 logs = TestMdcLogUtils.get_logs_as_json(output_mock.call_args_list)
117 self.assertEqual(logs[0]["ts"], 1554806251439)
119 @patch('ricxappframe.logger.mdclogger.MDCLogger._output_log')
120 def test_that_log_contains_correct_message(self, output_mock):
122 self.logger.error("message test")
123 logs = TestMdcLogUtils.get_logs_as_json(output_mock.call_args_list)
125 self.assertEqual(logs[0]["msg"], "message test")
127 @patch('ricxappframe.logger.mdclogger.MDCLogger._output_log')
128 def test_that_log_message_is_escaped_to_valid_json_string(self, output_mock):
130 self.logger.set_level(Level.DEBUG)
132 self.logger.info(r'\ and "')
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 "')
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')
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")
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)
160 @patch('ricxappframe.logger.mdclogger.MDCLogger._output_log')
161 def test_that_mdc_values_are_logged_correctly(self, output_mock):
163 self.logger.add_mdc("key1", "value1")
164 self.logger.add_mdc("key2", "value2")
165 self.logger.error("mdc test")
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")
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"])
178 def test_that_mdc_values_can_be_added_and_removed(self):
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)
191 @patch('ricxappframe.logger.mdclogger.MDCLogger._output_log')
192 def test_multiple_logger_instances(self, output_mock):
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")
201 logger1.error("error msg")
202 logger2.error("warning msg")
204 logs = TestMdcLogUtils.get_logs_as_json(output_mock.call_args_list)
205 self.assertEqual(2, output_mock.call_count)
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)
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)
222 if __name__ == '__main__':