Skip to content

Commit bf221eb

Browse files
Update fallback tests for new fallback templating.
1 parent 33d9281 commit bf221eb

2 files changed

Lines changed: 43 additions & 41 deletions

File tree

src/labthings_fastapi/server/fallback.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,18 +31,18 @@
3131
class FallbackContext:
3232
"""A dataclass to provide the context of the server failing to load."""
3333

34-
error: BaseException | None
34+
error: BaseException | None = None
3535
"""The error caught when running uvicorn.run."""
3636

37-
server: ThingServer | None
37+
server: ThingServer | None = None
3838
"""The ThingServer that failed to start."""
3939

40-
config: ThingServerConfig | dict[str, Any] | None
40+
config: ThingServerConfig | dict[str, Any] | None = None
4141
"""The config used to set up the server.
4242
4343
This can be the ThingServerConfig, or the dict read from the JSON file."""
4444

45-
log_history: str | None
45+
log_history: str | None = None
4646
"""Any logging history to show."""
4747

4848

tests/test_fallback.py

Lines changed: 39 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,14 @@
66
"""
77

88
import re
9+
from html import unescape
910

1011
import pytest
1112
import uvicorn
1213

1314
from fastapi.testclient import TestClient
1415
import labthings_fastapi as lt
15-
from labthings_fastapi.server.fallback import app
16+
from labthings_fastapi.server.fallback import app, FallbackContext
1617
from labthings_fastapi.example_things import ThingThatCantStart
1718

1819
CONFIG_DICT = {
@@ -29,21 +30,20 @@
2930
@pytest.fixture(autouse=True)
3031
def reset_app_state():
3132
"""Reset the fallback app state before each fallback test."""
32-
app.labthings_config = None
33-
app.labthings_server = None
34-
app.labthings_error = None
35-
app.log_history = None
33+
app._context = None
3634

3735

3836
def test_fallback_redirect():
3937
"""Test that the redirect works."""
38+
# Need to set a context even if everything in it is empty.
39+
app.set_context(FallbackContext())
4040
with TestClient(app) as client:
4141
response = client.get("/")
4242
# No history as no redirect
4343
assert len(response.history) == 0
4444
html = response.text
45-
# test that something when wrong is shown
46-
assert "Something went wrong" in html
45+
# Check that the basic failure message is shown
46+
assert "The LabThings server failed during startup." in html
4747

4848
# Now try another url
4949
response = client.get("/foo/bar")
@@ -53,77 +53,80 @@ def test_fallback_redirect():
5353

5454
# Redirects to error page.
5555
html = response.text
56-
# test that something when wrong is shown
57-
assert "Something went wrong" in html
56+
# Check that the basic failure message is shown
57+
assert "The LabThings server failed during startup." in html
5858

5959

6060
def test_fallback_empty():
61+
# Need to set a context even if everything in it is empty.
62+
app.set_context(FallbackContext())
6163
with TestClient(app) as client:
6264
response = client.get("/")
6365
html = response.text
64-
# test that something when wrong is shown
65-
assert "Something went wrong" in html
66-
assert "No logging info available" in html
66+
# Check that the basic failure message is shown
67+
assert "The LabThings server failed during startup." in html
68+
assert "No logging information available." in html
6769

6870

6971
def test_fallback_with_config_dict():
7072
"""Check that fallback server prints a config dictionary as JSON."""
71-
app.labthings_config = CONFIG_DICT
73+
app.set_context(FallbackContext(config=CONFIG_DICT))
7274
with TestClient(app) as client:
7375
response = client.get("/")
7476
html = response.text
75-
assert "Something went wrong" in html
76-
assert "No logging info available" in html
77-
assert '"thing1": "labthings_fastapi.example_things:MyThing"' in html
78-
assert '"class": "labthings_fastapi.example_things:MyThing"' in html
77+
assert "The LabThings server failed during startup." in html
78+
assert "No logging information available." in html
79+
assert '"thing1": "labthings_fastapi.example_things:MyThing"' in unescape(html)
80+
assert '"class": "labthings_fastapi.example_things:MyThing"' in unescape(html)
7981

8082

8183
def test_fallback_with_config_obj():
8284
"""Check that fallback server prints the config object as JSON."""
8385
config = lt.ThingServerConfig.model_validate(CONFIG_DICT)
84-
app.labthings_config = config
86+
app.set_context(FallbackContext(config=config))
8587
with TestClient(app) as client:
8688
response = client.get("/")
8789
html = response.text
88-
assert "Something went wrong" in html
89-
assert "No logging info available" in html
90+
assert "The LabThings server failed during startup." in html
91+
assert "No logging information available." in html
9092
assert "thing1" in html
9193
assert "thing2" in html
9294
cls_regex = re.compile(r'"cls": "labthings_fastapi\.example_things\.MyThing"')
93-
assert len(cls_regex.findall(html)) == 2
95+
assert len(cls_regex.findall(unescape(html))) == 2
9496

9597

9698
def test_fallback_with_error():
97-
app.labthings_error = RuntimeError("Custom error message")
99+
app.set_context(FallbackContext(error=RuntimeError("Custom error message")))
98100
with TestClient(app) as client:
99101
response = client.get("/")
100102
html = response.text
101-
assert "Something went wrong" in html
102-
assert "No logging info available" in html
103+
assert "The LabThings server failed during startup." in html
104+
assert "No logging information available." in html
103105
assert "RuntimeError" in html
104106
assert "Custom error message" in html
105107

106108

107109
def test_fallback_with_server():
108110
config = lt.ThingServerConfig.model_validate(CONFIG_DICT)
109-
app.labthings_server = lt.ThingServer.from_config(config)
111+
server = lt.ThingServer.from_config(config)
112+
app.set_context(FallbackContext(server=server))
110113
with TestClient(app) as client:
111114
response = client.get("/")
112115
html = response.text
113-
assert "Something went wrong" in html
114-
assert "No logging info available" in html
116+
assert "The LabThings server failed during startup." in html
117+
assert "No logging information available." in html
115118
assert "thing1" in html
116119
assert "thing2" in html
117120

118121

119122
def test_fallback_with_log():
120-
app.log_history = "Fake log content"
123+
app.set_context(FallbackContext(log_history="Fake log content"))
121124
with TestClient(app) as client:
122125
response = client.get("/")
123126
html = response.text
124-
assert "Something went wrong" in html
125-
assert "No logging info available" not in html
126-
assert "<p>Logging info</p>" in html
127+
assert "The LabThings server failed during startup." in html
128+
assert "No logging information available." not in html
129+
assert "<h2>Logging</h2>" in html
127130
assert "Fake log content" in html
128131

129132

@@ -146,17 +149,16 @@ def test_actual_server_fallback():
146149
thing_error = server.startup_failure["exception"]
147150
assert isinstance(thing_error, RuntimeError)
148151

149-
app.labthings_server = server
150-
app.labthings_error = server_error
152+
app.set_context(FallbackContext(server=server, error=server_error))
151153
with TestClient(app) as client:
152154
response = client.get("/")
153155
html = response.text
154-
assert "Something went wrong" in html
156+
assert "The LabThings server failed during startup." in html
155157
# Shouldn't be displaying the meaningless SystemExit
156158
assert "SystemExit" not in html
157159

158160
# The message from when the Thing errored should be displayed
159-
assert str(thing_error) in html
161+
assert str(thing_error) in unescape(html)
160162
# With the traceback
161-
assert 'labthings_fastapi/example_things/__init__.py", line' in html
162-
assert f'RuntimeError("{thing_error}")' in html
163+
assert 'labthings_fastapi/example_things/__init__.py", line' in unescape(html)
164+
assert f'RuntimeError("{thing_error}")' in unescape(html)

0 commit comments

Comments
 (0)