2017-01-16 14:44:08 +00:00
|
|
|
from fontTools.misc.loggingTools import (
|
2018-06-19 16:54:50 +01:00
|
|
|
LevelFormatter,
|
|
|
|
Timer,
|
|
|
|
configLogger,
|
|
|
|
ChannelsFilter,
|
|
|
|
LogMixin,
|
|
|
|
)
|
2021-03-29 11:45:58 +02:00
|
|
|
from io import StringIO
|
2017-01-16 14:44:08 +00:00
|
|
|
import logging
|
|
|
|
import textwrap
|
|
|
|
import time
|
|
|
|
import re
|
|
|
|
import pytest
|
|
|
|
|
|
|
|
|
|
|
|
def logger_name_generator():
|
|
|
|
basename = "fontTools.test#"
|
|
|
|
num = 1
|
|
|
|
while True:
|
2022-12-13 11:26:36 +00:00
|
|
|
yield basename + str(num)
|
2017-01-16 14:44:08 +00:00
|
|
|
num += 1
|
|
|
|
|
2022-12-13 11:26:36 +00:00
|
|
|
|
2017-01-16 14:44:08 +00:00
|
|
|
unique_logger_name = logger_name_generator()
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture
|
|
|
|
def logger():
|
|
|
|
log = logging.getLogger(next(unique_logger_name))
|
|
|
|
configLogger(logger=log, level="DEBUG", stream=StringIO())
|
|
|
|
return log
|
|
|
|
|
|
|
|
|
|
|
|
def test_LevelFormatter():
|
|
|
|
stream = StringIO()
|
|
|
|
handler = logging.StreamHandler(stream)
|
|
|
|
formatter = LevelFormatter(
|
|
|
|
fmt={
|
2022-12-13 11:26:36 +00:00
|
|
|
"*": "[%(levelname)s] %(message)s",
|
|
|
|
"DEBUG": "%(name)s [%(levelname)s] %(message)s",
|
|
|
|
"INFO": "%(message)s",
|
|
|
|
}
|
|
|
|
)
|
2017-01-16 14:44:08 +00:00
|
|
|
handler.setFormatter(formatter)
|
|
|
|
name = next(unique_logger_name)
|
|
|
|
log = logging.getLogger(name)
|
|
|
|
log.setLevel(logging.DEBUG)
|
|
|
|
log.addHandler(handler)
|
|
|
|
|
|
|
|
log.debug("this uses a custom format string")
|
|
|
|
log.info("this also uses a custom format string")
|
|
|
|
log.warning("this one uses the default format string")
|
|
|
|
|
2022-12-13 11:26:36 +00:00
|
|
|
assert stream.getvalue() == textwrap.dedent(
|
|
|
|
"""\
|
2017-01-16 14:44:08 +00:00
|
|
|
%s [DEBUG] this uses a custom format string
|
|
|
|
this also uses a custom format string
|
|
|
|
[WARNING] this one uses the default format string
|
2022-12-13 11:26:36 +00:00
|
|
|
"""
|
|
|
|
% name
|
|
|
|
)
|
2017-01-16 14:44:08 +00:00
|
|
|
|
|
|
|
|
|
|
|
class TimerTest(object):
|
|
|
|
def test_split(self):
|
|
|
|
timer = Timer()
|
|
|
|
time.sleep(0.01)
|
2022-12-13 11:26:36 +00:00
|
|
|
fist_lap = timer.split()
|
2017-01-16 14:44:08 +00:00
|
|
|
assert timer.elapsed == fist_lap
|
2017-01-25 10:07:09 +00:00
|
|
|
time.sleep(0.1)
|
2017-01-16 14:44:08 +00:00
|
|
|
second_lap = timer.split()
|
2017-01-17 14:12:14 +00:00
|
|
|
assert second_lap > fist_lap
|
2017-01-16 14:44:08 +00:00
|
|
|
assert timer.elapsed == second_lap
|
|
|
|
|
|
|
|
def test_time(self):
|
|
|
|
timer = Timer()
|
|
|
|
time.sleep(0.01)
|
|
|
|
overall_time = timer.time()
|
2017-01-17 14:12:14 +00:00
|
|
|
assert overall_time > 0
|
2017-01-16 14:44:08 +00:00
|
|
|
|
|
|
|
def test_context_manager(self):
|
|
|
|
with Timer() as t:
|
|
|
|
time.sleep(0.01)
|
2017-01-17 14:12:14 +00:00
|
|
|
assert t.elapsed > 0
|
2017-01-16 14:44:08 +00:00
|
|
|
|
|
|
|
def test_using_logger(self, logger):
|
2022-12-13 11:26:36 +00:00
|
|
|
with Timer(logger, "do something"):
|
2017-01-16 14:44:08 +00:00
|
|
|
time.sleep(0.01)
|
|
|
|
|
|
|
|
assert re.match(
|
2019-04-01 13:53:59 -07:00
|
|
|
r"Took [0-9]\.[0-9]{3}s to do something",
|
2022-12-13 11:26:36 +00:00
|
|
|
logger.handlers[0].stream.getvalue(),
|
|
|
|
)
|
2017-01-16 14:44:08 +00:00
|
|
|
|
|
|
|
def test_using_logger_calling_instance(self, logger):
|
|
|
|
timer = Timer(logger)
|
|
|
|
with timer():
|
|
|
|
time.sleep(0.01)
|
|
|
|
|
|
|
|
assert re.match(
|
2022-12-13 11:26:36 +00:00
|
|
|
r"elapsed time: [0-9]\.[0-9]{3}s", logger.handlers[0].stream.getvalue()
|
|
|
|
)
|
2017-01-16 14:44:08 +00:00
|
|
|
|
|
|
|
# do it again but with custom level
|
2022-12-13 11:26:36 +00:00
|
|
|
with timer("redo it", level=logging.WARNING):
|
2017-01-16 14:44:08 +00:00
|
|
|
time.sleep(0.02)
|
|
|
|
|
|
|
|
assert re.search(
|
2019-04-01 13:53:59 -07:00
|
|
|
r"WARNING: Took [0-9]\.[0-9]{3}s to redo it",
|
2022-12-13 11:26:36 +00:00
|
|
|
logger.handlers[0].stream.getvalue(),
|
|
|
|
)
|
2017-01-16 14:44:08 +00:00
|
|
|
|
|
|
|
def test_function_decorator(self, logger):
|
|
|
|
timer = Timer(logger)
|
|
|
|
|
|
|
|
@timer()
|
|
|
|
def test1():
|
|
|
|
time.sleep(0.01)
|
2022-12-13 11:26:36 +00:00
|
|
|
|
|
|
|
@timer("run test 2", level=logging.INFO)
|
2017-01-16 14:44:08 +00:00
|
|
|
def test2():
|
|
|
|
time.sleep(0.02)
|
|
|
|
|
|
|
|
test1()
|
|
|
|
|
|
|
|
assert re.match(
|
2019-01-22 16:36:15 +01:00
|
|
|
r"Took [0-9]\.[0-9]{3}s to run 'test1'",
|
2022-12-13 11:26:36 +00:00
|
|
|
logger.handlers[0].stream.getvalue(),
|
|
|
|
)
|
2017-01-16 14:44:08 +00:00
|
|
|
|
|
|
|
test2()
|
|
|
|
|
|
|
|
assert re.search(
|
2022-12-13 11:26:36 +00:00
|
|
|
r"Took [0-9]\.[0-9]{3}s to run test 2", logger.handlers[0].stream.getvalue()
|
|
|
|
)
|
2017-01-16 14:44:08 +00:00
|
|
|
|
|
|
|
|
|
|
|
def test_ChannelsFilter(logger):
|
|
|
|
n = logger.name
|
2022-12-13 11:26:36 +00:00
|
|
|
filtr = ChannelsFilter(n + ".A.B", n + ".C.D")
|
2017-01-16 14:44:08 +00:00
|
|
|
handler = logger.handlers[0]
|
|
|
|
handler.addFilter(filtr)
|
|
|
|
stream = handler.stream
|
|
|
|
|
2022-12-13 11:26:36 +00:00
|
|
|
logging.getLogger(n + ".A.B").debug("this record passes through")
|
|
|
|
assert "this record passes through" in stream.getvalue()
|
2017-01-16 14:44:08 +00:00
|
|
|
|
2022-12-13 11:26:36 +00:00
|
|
|
logging.getLogger(n + ".A.B.C").debug("records from children also pass")
|
|
|
|
assert "records from children also pass" in stream.getvalue()
|
2017-01-16 14:44:08 +00:00
|
|
|
|
2022-12-13 11:26:36 +00:00
|
|
|
logging.getLogger(n + ".C.D").debug("this one as well")
|
|
|
|
assert "this one as well" in stream.getvalue()
|
2017-01-16 14:44:08 +00:00
|
|
|
|
2022-12-13 11:26:36 +00:00
|
|
|
logging.getLogger(n + ".A.B.").debug("also this one")
|
|
|
|
assert "also this one" in stream.getvalue()
|
2017-01-16 14:44:08 +00:00
|
|
|
|
|
|
|
before = stream.getvalue()
|
2022-12-13 11:26:36 +00:00
|
|
|
logging.getLogger(n + ".A.F").debug("but this one does not!")
|
2017-01-16 14:44:08 +00:00
|
|
|
assert before == stream.getvalue()
|
|
|
|
|
2022-12-13 11:26:36 +00:00
|
|
|
logging.getLogger(n + ".C.DE").debug("neither this one!")
|
2017-01-16 14:44:08 +00:00
|
|
|
assert before == stream.getvalue()
|
2017-04-11 18:40:52 +01:00
|
|
|
|
|
|
|
|
|
|
|
def test_LogMixin():
|
|
|
|
class Base(object):
|
|
|
|
pass
|
|
|
|
|
|
|
|
class A(LogMixin, Base):
|
|
|
|
pass
|
|
|
|
|
|
|
|
class B(A):
|
|
|
|
pass
|
|
|
|
|
|
|
|
a = A()
|
|
|
|
b = B()
|
|
|
|
|
2022-12-13 11:26:36 +00:00
|
|
|
assert hasattr(a, "log")
|
|
|
|
assert hasattr(b, "log")
|
2017-04-11 18:40:52 +01:00
|
|
|
assert isinstance(a.log, logging.Logger)
|
|
|
|
assert isinstance(b.log, logging.Logger)
|
|
|
|
assert a.log.name == "loggingTools_test.A"
|
|
|
|
assert b.log.name == "loggingTools_test.B"
|