mirror of
https://gitea.osmocom.org/sim-card/pysim.git
synced 2026-09-28 15:06:33 +03:00
2b7abdcf96
The color scheme takes either - a raw escape sequence like "\033[33m" (pySim-read, pySim-prog, contrib/csv-to-pgsql.py) - a cmd2 color object (pySim-shell) Color of cmd2 >= 3.0.0 is a StrEnum, which led to pySim-shell warnings like yellowWARNING: EF.DIR seems to be empty! with a stray reset at the end. Fixed by exclusing Enum from the raw sequence branch. Change-Id: I8bae9fc3c54f1dab481d743d3b68e32e9d09267a
155 lines
6.4 KiB
Python
Executable File
155 lines
6.4 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
# (C) 2025 by sysmocom - s.f.m.c. GmbH
|
|
# All Rights Reserved
|
|
#
|
|
# Author: Philipp Maier <pmaier@sysmocom.de>
|
|
#
|
|
# This program is free software: you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation, either version 2 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
import unittest
|
|
import logging
|
|
import cmd2
|
|
from packaging import version
|
|
from pySim.log import PySimLogger
|
|
import io
|
|
import sys
|
|
from inspect import currentframe, getframeinfo
|
|
|
|
if version.parse(cmd2.__version__) >= version.parse("3.0.0"):
|
|
from cmd2 import Color # pylint: disable=no-name-in-module
|
|
YELLOW = Color.YELLOW
|
|
else: # cmd2>=2.6.2
|
|
from cmd2 import Fg # pylint: disable=no-name-in-module
|
|
YELLOW = Fg.YELLOW
|
|
|
|
log = PySimLogger.get(__name__)
|
|
|
|
TEST_MSG_DEBUG = "this is a debug message"
|
|
TEST_MSG_INFO = "this is an info message"
|
|
TEST_MSG_WARNING = "this is a warning message"
|
|
TEST_MSG_ERROR = "this is an error message"
|
|
TEST_MSG_CRITICAL = "this is a critical message"
|
|
|
|
expected_message = None
|
|
|
|
class PySimLogger_Test(unittest.TestCase):
|
|
|
|
def setUp(self):
|
|
# PySimLogger.setup() is global, so a print callback left installed here fires for
|
|
# every PySimLogger message emitted by any test module that runs later in the same process
|
|
# ... where it asserts against a stale 'expected_message' and fails a test that has nothing
|
|
# to do with logging. Great fun!
|
|
# Restore before each test.
|
|
saved = (PySimLogger.print_callback, PySimLogger.verbose)
|
|
def _restore():
|
|
PySimLogger.print_callback, PySimLogger.verbose = saved
|
|
self.addCleanup(_restore)
|
|
|
|
def __test_01_safe_defaults_one(self, callback, message:str):
|
|
# When log messages are sent to an unconfigured PySimLogger class, we expect the unmodified message being
|
|
# logged to stdout, just as if it were printed via a normal print() statement.
|
|
log_output = io.StringIO()
|
|
sys.stdout = log_output
|
|
callback(message)
|
|
assert(log_output.getvalue().strip() == message)
|
|
sys.stdout = sys.__stdout__
|
|
|
|
def test_01_safe_defaults(self):
|
|
# When log messages are sent to an unconfigured PySimLogger class, we expect that all messages are logged,
|
|
# regardless of the logging level.
|
|
self.__test_01_safe_defaults_one(log.debug, TEST_MSG_DEBUG)
|
|
self.__test_01_safe_defaults_one(log.info, TEST_MSG_INFO)
|
|
self.__test_01_safe_defaults_one(log.warning, TEST_MSG_WARNING)
|
|
self.__test_01_safe_defaults_one(log.error, TEST_MSG_ERROR)
|
|
self.__test_01_safe_defaults_one(log.critical, TEST_MSG_CRITICAL)
|
|
|
|
@staticmethod
|
|
def _test_print_callback(message):
|
|
assert(message.strip() == expected_message)
|
|
|
|
def test_02_normal(self):
|
|
# When the PySimLogger is set up with its default values, we expect formatted log messages on all logging
|
|
# levels.
|
|
global expected_message
|
|
PySimLogger.setup(self._test_print_callback)
|
|
expected_message = "DEBUG: " + TEST_MSG_DEBUG
|
|
log.debug(TEST_MSG_DEBUG)
|
|
expected_message = "INFO: " + TEST_MSG_INFO
|
|
log.info(TEST_MSG_INFO)
|
|
expected_message = "WARNING: " + TEST_MSG_WARNING
|
|
log.warning(TEST_MSG_WARNING)
|
|
expected_message = "ERROR: " + TEST_MSG_ERROR
|
|
log.error(TEST_MSG_ERROR)
|
|
expected_message = "CRITICAL: " + TEST_MSG_CRITICAL
|
|
log.critical(TEST_MSG_CRITICAL)
|
|
|
|
def test_03_verbose(self):
|
|
# When the PySimLogger is set up with its default values, we expect verbose formatted log messages on all
|
|
# logging levels.
|
|
global expected_message
|
|
PySimLogger.setup(self._test_print_callback)
|
|
PySimLogger.set_verbose(True)
|
|
frame = currentframe()
|
|
expected_message = __name__ + "." + str(getframeinfo(frame).lineno + 1) + " -- DEBUG: " + TEST_MSG_DEBUG
|
|
log.debug(TEST_MSG_DEBUG)
|
|
expected_message = __name__ + "." + str(getframeinfo(frame).lineno + 1) + " -- INFO: " + TEST_MSG_INFO
|
|
log.info(TEST_MSG_INFO)
|
|
expected_message = __name__ + "." + str(getframeinfo(frame).lineno + 1) + " -- WARNING: " + TEST_MSG_WARNING
|
|
log.warning(TEST_MSG_WARNING)
|
|
expected_message = __name__ + "." + str(getframeinfo(frame).lineno + 1) + " -- ERROR: " + TEST_MSG_ERROR
|
|
log.error(TEST_MSG_ERROR)
|
|
expected_message = __name__ + "." + str(getframeinfo(frame).lineno + 1) + " -- CRITICAL: " + TEST_MSG_CRITICAL
|
|
log.critical(TEST_MSG_CRITICAL)
|
|
|
|
def test_04_level(self):
|
|
# When the PySimLogger is set up with its default values, we expect formatted log messages but since we will
|
|
# limit the log level to INFO, we should not see any messages of level DEBUG
|
|
global expected_message
|
|
PySimLogger.setup(self._test_print_callback)
|
|
PySimLogger.set_level(logging.INFO)
|
|
|
|
# We test this in non verbose mode, this will also confirm that disabeling the verbose mode works.
|
|
PySimLogger.set_verbose(False)
|
|
|
|
# Debug messages should not appear
|
|
expected_message = None
|
|
log.debug(TEST_MSG_DEBUG)
|
|
|
|
# All other messages should appear normally
|
|
expected_message = "INFO: " + TEST_MSG_INFO
|
|
log.info(TEST_MSG_INFO)
|
|
expected_message = "WARNING: " + TEST_MSG_WARNING
|
|
log.warning(TEST_MSG_WARNING)
|
|
expected_message = "ERROR: " + TEST_MSG_ERROR
|
|
log.error(TEST_MSG_ERROR)
|
|
expected_message = "CRITICAL: " + TEST_MSG_CRITICAL
|
|
log.critical(TEST_MSG_CRITICAL)
|
|
|
|
def test_05_color(self):
|
|
# A color is either
|
|
# - raw escape sequence
|
|
# - cmd2 color object
|
|
global expected_message
|
|
expected_message = "\033[33mWARNING: " + TEST_MSG_WARNING + "\033[0m"
|
|
|
|
PySimLogger.setup(self._test_print_callback, {logging.WARN: "\033[33m"})
|
|
log.warning(TEST_MSG_WARNING)
|
|
|
|
PySimLogger.setup(self._test_print_callback, {logging.WARN: YELLOW})
|
|
log.warning(TEST_MSG_WARNING) # don't leak cmd2 Color StrEnum
|
|
|
|
if __name__ == '__main__':
|
|
unittest.main()
|