1
0
Fork 0
forked from s3lph/matemat

Logging config unit tests.

This commit is contained in:
s3lph 2018-07-14 12:55:09 +02:00
parent a4967b1338
commit 8f82420d7f
2 changed files with 95 additions and 9 deletions

View file

@ -2,23 +2,19 @@
from typing import Any, Dict, Iterable, List, Tuple, Union from typing import Any, Dict, Iterable, List, Tuple, Union
import os import os
import io
import sys import sys
import logging import logging
from configparser import ConfigParser from configparser import ConfigParser
def parse_logging(symbolic_level: str, symbolic_target: str) -> Tuple[int, logging.Handler]: def parse_logging(symbolic_level: str, symbolic_target: str) -> Tuple[int, logging.Handler]:
level: int = logging.NOTSET
try: try:
level = int(symbolic_level) level: int = int(symbolic_level)
except ValueError: except ValueError:
try: try:
level = int(logging.getLevelName(symbolic_level)) level = int(logging.getLevelName(symbolic_level))
except KeyError:
pass
except ValueError: except ValueError:
pass raise ValueError(f'Unknown log level: {symbolic_level}')
if symbolic_target == 'stderr': if symbolic_target == 'stderr':
target: logging.Handler = logging.StreamHandler(sys.stderr) target: logging.Handler = logging.StreamHandler(sys.stderr)
elif symbolic_target == 'stdout': elif symbolic_target == 'stdout':
@ -50,7 +46,7 @@ def parse_config_file(paths: Union[str, Iterable[str]]) -> Dict[str, Any]:
# Log level # Log level
'log_level': logging.INFO, 'log_level': logging.INFO,
# Log target: An IO stream (stderr, stdout, ...) or a filename # Log target: An IO stream (stderr, stdout, ...) or a filename
'log_handler': 'stderr', 'log_handler': logging.StreamHandler(),
# Variables passed to pagelets # Variables passed to pagelets
'pagelet_variables': dict() 'pagelet_variables': dict()
} }
@ -78,7 +74,7 @@ def parse_config_file(paths: Union[str, Iterable[str]]) -> Dict[str, Any]:
config['staticroot'] = parser['Matemat'].get('StaticPath', os.path.expanduser(config['staticroot'])) config['staticroot'] = parser['Matemat'].get('StaticPath', os.path.expanduser(config['staticroot']))
config['log_level'], config['log_handler'] =\ config['log_level'], config['log_handler'] =\
parse_logging(parser['Matemat'].get('LogLevel', config['log_level']), parse_logging(parser['Matemat'].get('LogLevel', config['log_level']),
parser['Matemat'].get('LogTarget', config['log_handler'])) parser['Matemat'].get('LogTarget', 'stderr'))
config['templateroot'] = parser['Matemat'].get('TemplatePath', os.path.expanduser(config['templateroot'])) config['templateroot'] = parser['Matemat'].get('TemplatePath', os.path.expanduser(config['templateroot']))
# Read all values from the [Pagelets] section, if present. These values are passed to pagelet functions # Read all values from the [Pagelets] section, if present. These values are passed to pagelet functions

View file

@ -5,6 +5,8 @@ from unittest import TestCase
from unittest.mock import patch from unittest.mock import patch
from io import StringIO from io import StringIO
import logging
import sys
from matemat.webserver import parse_config_file from matemat.webserver import parse_config_file
@ -19,6 +21,9 @@ Port = 8080
StaticPath =/var/test/static StaticPath =/var/test/static
TemplatePath= /var/test/templates TemplatePath= /var/test/templates
LogLevel = CRITICAL
LogTarget = /tmp/log/matemat_test.log
[Pagelets] [Pagelets]
Name=Matemat Name=Matemat
(Unit Test) (Unit Test)
@ -34,6 +39,29 @@ Port=443
Name=Matemat (Unit Test 2) Name=Matemat (Unit Test 2)
''' '''
_LOG_NONE_CONFIG = '''
[Matemat]
LogTarget=none
'''
_LOG_STDOUT_CONFIG = '''
[Matemat]
LogTarget=stdout
'''
_LOG_STDERR_CONFIG = '''
[Matemat]
LogTarget=stderr
'''
_LOG_GARBAGE_PORT = '''
[Matemat]
Port=iwanttobeavalidporttoo'''
_LOG_GARBAGE_LOGLEVEL = '''
[Matemat]
LogLevel=thisisnotaloglevel'''
class IterOpenMock: class IterOpenMock:
""" """
@ -59,7 +87,7 @@ class IterOpenMock:
class TestConfig(TestCase): class TestConfig(TestCase):
def test_parse_config_empty_defualt_values(self): def test_parse_config_empty_default_values(self):
""" """
Test that default values are set when reading an empty config file. Test that default values are set when reading an empty config file.
""" """
@ -72,12 +100,17 @@ class TestConfig(TestCase):
self.assertIn('port', config) self.assertIn('port', config)
self.assertIn('staticroot', config) self.assertIn('staticroot', config)
self.assertIn('templateroot', config) self.assertIn('templateroot', config)
self.assertIn('log_level', config)
self.assertIn('log_handler', config)
self.assertIn('pagelet_variables', config) self.assertIn('pagelet_variables', config)
# Make sure all mandatory values are set to their default # Make sure all mandatory values are set to their default
self.assertEqual('::', config['listen']) self.assertEqual('::', config['listen'])
self.assertEqual(80, config['port']) self.assertEqual(80, config['port'])
self.assertEqual('/var/matemat/static', config['staticroot']) self.assertEqual('/var/matemat/static', config['staticroot'])
self.assertEqual('/var/matemat/templates', config['templateroot']) self.assertEqual('/var/matemat/templates', config['templateroot'])
self.assertEqual(logging.INFO, config['log_level'])
self.assertIsInstance(config['log_handler'], logging.StreamHandler)
self.assertEqual(sys.stderr, config['log_handler'].stream)
self.assertIsInstance(config['pagelet_variables'], dict) self.assertIsInstance(config['pagelet_variables'], dict)
self.assertEqual(0, len(config['pagelet_variables'])) self.assertEqual(0, len(config['pagelet_variables']))
@ -94,6 +127,8 @@ class TestConfig(TestCase):
self.assertIn('port', config) self.assertIn('port', config)
self.assertIn('staticroot', config) self.assertIn('staticroot', config)
self.assertIn('templateroot', config) self.assertIn('templateroot', config)
self.assertIn('log_level', config)
self.assertIn('log_handler', config)
self.assertIn('pagelet_variables', config) self.assertIn('pagelet_variables', config)
self.assertIn('Name', config['pagelet_variables']) self.assertIn('Name', config['pagelet_variables'])
self.assertIn('UploadDir', config['pagelet_variables']) self.assertIn('UploadDir', config['pagelet_variables'])
@ -103,6 +138,9 @@ class TestConfig(TestCase):
self.assertEqual(8080, config['port']) self.assertEqual(8080, config['port'])
self.assertEqual('/var/test/static', config['staticroot']) self.assertEqual('/var/test/static', config['staticroot'])
self.assertEqual('/var/test/templates', config['templateroot']) self.assertEqual('/var/test/templates', config['templateroot'])
self.assertEqual(logging.CRITICAL, config['log_level'])
self.assertIsInstance(config['log_handler'], logging.FileHandler)
self.assertEqual('/tmp/log/matemat_test.log', config['log_handler'].baseFilename)
self.assertEqual('Matemat\n(Unit Test)', config['pagelet_variables']['Name']) self.assertEqual('Matemat\n(Unit Test)', config['pagelet_variables']['Name'])
self.assertEqual('/var/test/static/upload', config['pagelet_variables']['UploadDir']) self.assertEqual('/var/test/static/upload', config['pagelet_variables']['UploadDir'])
self.assertEqual('/var/test/db/test.db', config['pagelet_variables']['DatabaseFile']) self.assertEqual('/var/test/db/test.db', config['pagelet_variables']['DatabaseFile'])
@ -134,3 +172,55 @@ class TestConfig(TestCase):
self.assertEqual('Matemat (Unit Test 2)', config['pagelet_variables']['Name']) self.assertEqual('Matemat (Unit Test 2)', config['pagelet_variables']['Name'])
self.assertEqual('/var/test/static/upload', config['pagelet_variables']['UploadDir']) self.assertEqual('/var/test/static/upload', config['pagelet_variables']['UploadDir'])
self.assertEqual('/var/test/db/test.db', config['pagelet_variables']['DatabaseFile']) self.assertEqual('/var/test/db/test.db', config['pagelet_variables']['DatabaseFile'])
def test_parse_config_logging_none(self):
"""
Test that "LogTaget=none" disables logging.
"""
# Mock the open() function to return a config file example with disabled logging
with patch('builtins.open', return_value=StringIO(_LOG_NONE_CONFIG)):
# The filename is only a placeholder, file content is determined by mocking open
config = parse_config_file('test')
# Make sure the returned log handler is a null handler
self.assertIsInstance(config['log_handler'], logging.NullHandler)
def test_parse_config_logging_stdout(self):
"""
Test that "LogTaget=stdout" logs to sys.stdout.
"""
# Mock the open() function to return a config file example with stdout logging
with patch('builtins.open', return_value=StringIO(_LOG_STDOUT_CONFIG)):
# The filename is only a placeholder, file content is determined by mocking open
config = parse_config_file('test')
# Make sure the returned log handler is a stdout handler
self.assertIsInstance(config['log_handler'], logging.StreamHandler)
self.assertEqual(sys.stdout, config['log_handler'].stream)
def test_parse_config_logging_stderr(self):
"""
Test that "LogTaget=stderr" logs to sys.stderr.
"""
# Mock the open() function to return a config file example with stdout logging
with patch('builtins.open', return_value=StringIO(_LOG_STDERR_CONFIG)):
# The filename is only a placeholder, file content is determined by mocking open
config = parse_config_file('test')
# Make sure the returned log handler is a stdout handler
self.assertIsInstance(config['log_handler'], logging.StreamHandler)
self.assertEqual(sys.stderr, config['log_handler'].stream)
def test_parse_config_garbage(self):
"""
Test that garbage config raises ValueErrors.
"""
# Mock the open() function to return a config file example with a non-numeric port
with patch('builtins.open', return_value=StringIO(_LOG_GARBAGE_PORT)):
# Make sure a ValueError is raised
with self.assertRaises(ValueError):
# The filename is only a placeholder, file content is determined by mocking open
parse_config_file('test')
# Mock the open() function to return a config file example with a non-numeric log level with invalid symbol
with patch('builtins.open', return_value=StringIO(_LOG_GARBAGE_LOGLEVEL)):
# Make sure a ValueError is raised
with self.assertRaises(ValueError):
# The filename is only a placeholder, file content is determined by mocking open
parse_config_file('test')