Skip to content

Commit fbad976

Browse files
Add tests for error logs from actions
1 parent 51e37a4 commit fbad976

File tree

1 file changed

+56
-15
lines changed

1 file changed

+56
-15
lines changed

tests/test_action_logging.py

Lines changed: 56 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,32 +9,73 @@
99
from labthings_fastapi.actions.invocation_model import LogRecordModel
1010

1111

12-
class ThingOne(lt.Thing):
12+
class ThingThatLogsAndErrors(lt.Thing):
1313
LOG_MESSAGES = [
1414
"message 1",
1515
"message 2",
1616
]
1717

1818
@lt.thing_action
19-
def action_one(self, logger: lt.deps.InvocationLogger):
19+
def action_that_logs(self, logger: lt.deps.InvocationLogger):
2020
for m in self.LOG_MESSAGES:
2121
logger.info(m)
2222

23+
@lt.thing_action
24+
def action_with_unhandled_error(self, logger: lt.deps.InvocationLogger):
25+
raise RuntimeError("I was asked to raise this error.")
26+
27+
@lt.thing_action
28+
def action_with_invocation_error(self, logger: lt.deps.InvocationLogger):
29+
raise lt.exceptions.InvocationError("This is an error, but I handled it!")
30+
2331

2432
def test_invocation_logging(caplog):
25-
caplog.set_level(logging.INFO)
26-
server = lt.ThingServer()
27-
server.add_thing(ThingOne(), "/thing_one")
28-
with TestClient(server.app) as client:
29-
r = client.post("/thing_one/action_one")
30-
r.raise_for_status()
31-
invocation = poll_task(client, r.json())
32-
assert invocation["status"] == "completed"
33-
assert len(invocation["log"]) == len(ThingOne.LOG_MESSAGES)
34-
for expected, entry in zip(
35-
ThingOne.LOG_MESSAGES, invocation["log"], strict=True
36-
):
37-
assert entry["message"] == expected
33+
with caplog.at_level(logging.INFO, logger="labthings.action"):
34+
server = lt.ThingServer()
35+
server.add_thing(ThingThatLogsAndErrors(), "/log_and_error_thing")
36+
with TestClient(server.app) as client:
37+
r = client.post("/log_and_error_thing/action_that_logs")
38+
r.raise_for_status()
39+
invocation = poll_task(client, r.json())
40+
assert invocation["status"] == "completed"
41+
assert len(invocation["log"]) == len(ThingThatLogsAndErrors.LOG_MESSAGES)
42+
assert len(invocation["log"]) == len(caplog.records)
43+
for expected, entry in zip(
44+
ThingThatLogsAndErrors.LOG_MESSAGES, invocation["log"], strict=True
45+
):
46+
assert entry["message"] == expected
47+
48+
49+
def test_unhandled_error_logs(caplog):
50+
"""Check that a log with a traceback is raised if there is an unhandled error."""
51+
with caplog.at_level(logging.INFO, logger="labthings.action"):
52+
server = lt.ThingServer()
53+
server.add_thing(ThingThatLogsAndErrors(), "/log_and_error_thing")
54+
with TestClient(server.app) as client:
55+
r = client.post("/log_and_error_thing/action_with_unhandled_error")
56+
r.raise_for_status()
57+
invocation = poll_task(client, r.json())
58+
assert invocation["status"] == "error"
59+
assert len(invocation["log"]) == len(caplog.records) == 1
60+
assert caplog.records[0].levelname == "ERROR"
61+
# There is a traceback
62+
assert caplog.records[0].exc_info is not None
63+
64+
65+
def test_invocation_error_logs(caplog):
66+
"""Check that a log with a traceback is raised if there is an unhandled error."""
67+
with caplog.at_level(logging.INFO, logger="labthings.action"):
68+
server = lt.ThingServer()
69+
server.add_thing(ThingThatLogsAndErrors(), "/log_and_error_thing")
70+
with TestClient(server.app) as client:
71+
r = client.post("/log_and_error_thing/action_with_invocation_error")
72+
r.raise_for_status()
73+
invocation = poll_task(client, r.json())
74+
assert invocation["status"] == "error"
75+
assert len(invocation["log"]) == len(caplog.records) == 1
76+
assert caplog.records[0].levelname == "ERROR"
77+
# There is not a traceback
78+
assert caplog.records[0].exc_info is None
3879

3980

4081
def test_logrecordmodel():

0 commit comments

Comments
 (0)