forked from Delgan/loguru
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtest_add_option_catch.py
143 lines (102 loc) · 3.63 KB
/
test_add_option_catch.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
import re
import sys
import time
import pytest
from loguru import logger
from .conftest import default_threading_excepthook
def broken_sink(m):
raise Exception("Error!")
def test_catch_is_true(capsys):
logger.add(broken_sink, catch=True)
logger.debug("Fail")
out, err = capsys.readouterr()
assert out == ""
assert err != ""
def test_catch_is_false(capsys):
logger.add(broken_sink, catch=False)
with pytest.raises(Exception):
logger.debug("Fail")
out, err = capsys.readouterr()
assert out == err == ""
def test_no_sys_stderr(capsys, monkeypatch):
monkeypatch.setattr(sys, "stderr", None)
logger.add(broken_sink, catch=True)
logger.debug("a")
out, err = capsys.readouterr()
assert out == err == ""
def test_broken_sys_stderr(capsys, monkeypatch):
def broken_write(*args, **kwargs):
raise OSError
monkeypatch.setattr(sys.stderr, "write", broken_write)
logger.add(broken_sink, catch=True)
logger.debug("a")
out, err = capsys.readouterr()
assert out == err == ""
def test_encoding_error(capsys):
def sink(m):
raise UnicodeEncodeError("utf8", "", 10, 11, "too bad")
logger.add(sink, catch=True)
logger.debug("test")
out, err = capsys.readouterr()
lines = err.strip().splitlines()
assert out == ""
assert lines[0] == "--- Logging error in Loguru Handler #0 ---"
assert lines[1].startswith("Record was: {")
assert lines[1].endswith("}")
assert lines[-2].startswith("UnicodeEncodeError:")
assert lines[-1] == "--- End of logging error ---"
def test_unprintable_record(writer, capsys):
class Unprintable:
def __repr__(self):
raise ValueError("Failed")
logger.add(writer, format="{message} {extra[unprintable]}", catch=True)
logger.bind(unprintable=1).debug("a")
logger.bind(unprintable=Unprintable()).debug("b")
logger.bind(unprintable=2).debug("c")
out, err = capsys.readouterr()
lines = err.strip().splitlines()
assert writer.read() == "a 1\nc 2\n"
assert out == ""
assert lines[0] == "--- Logging error in Loguru Handler #0 ---"
assert lines[1] == "Record was: /!\\ Unprintable record /!\\"
assert lines[-2] == "ValueError: Failed"
assert lines[-1] == "--- End of logging error ---"
@pytest.mark.parametrize("enqueue", [False, True])
def test_broken_sink_message(capsys, enqueue):
logger.add(broken_sink, catch=True, enqueue=enqueue)
logger.debug("Oops")
time.sleep(0.1)
out, err = capsys.readouterr()
lines = err.strip().splitlines()
assert out == ""
assert lines[0] == "--- Logging error in Loguru Handler #0 ---"
assert re.match(r"Record was: \{.*Oops.*\}", lines[1])
assert lines[-2].startswith("Exception: Error!")
assert lines[-1] == "--- End of logging error ---"
@pytest.mark.parametrize("enqueue", [False, True])
def test_broken_sink_caught_keep_working(enqueue):
output = ""
def half_broken_sink(m):
nonlocal output
if m.startswith("NOK"):
raise ValueError("Broken!")
else:
output += m
logger.add(half_broken_sink, format="{message}", enqueue=enqueue, catch=True)
logger.info("A")
logger.info("NOK")
logger.info("B")
time.sleep(0.1)
assert output == "A\nB\n"
def test_broken_sink_not_caught_enqueue():
called = 0
def broken_sink(m):
nonlocal called
called += 1
raise ValueError("Nop")
logger.add(broken_sink, format="{message}", enqueue=True, catch=False)
with default_threading_excepthook():
logger.info("A")
logger.info("B")
time.sleep(0.1)
assert called == 1