|
7 | 7 |
|
8 | 8 | import re |
9 | 9 |
|
| 10 | +import pytest |
| 11 | +import uvicorn |
| 12 | + |
10 | 13 | from fastapi.testclient import TestClient |
11 | 14 | import labthings_fastapi as lt |
12 | 15 | from labthings_fastapi.server.fallback import app |
| 16 | +from labthings_fastapi.example_things import ThingThatCantStart |
13 | 17 |
|
14 | 18 | CONFIG_DICT = { |
15 | 19 | "things": { |
|
22 | 26 | } |
23 | 27 |
|
24 | 28 |
|
| 29 | +@pytest.fixture(autouse=True) |
| 30 | +def reset_app_state(): |
| 31 | + """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 |
| 36 | + |
| 37 | + |
| 38 | +def test_fallback_redirect(): |
| 39 | + """Test that the redirect works.""" |
| 40 | + with TestClient(app) as client: |
| 41 | + response = client.get("/") |
| 42 | + # No history as no redirect |
| 43 | + assert len(response.history) == 0 |
| 44 | + html = response.text |
| 45 | + # test that something when wrong is shown |
| 46 | + assert "Something went wrong" in html |
| 47 | + |
| 48 | + # Now try another url |
| 49 | + response = client.get("/foo/bar") |
| 50 | + # redirected so there is a history item showing a 307 Temporary Redirect code. |
| 51 | + assert len(response.history) == 1 |
| 52 | + assert response.history[0].status_code == 307 |
| 53 | + |
| 54 | + # Redirects to error page. |
| 55 | + html = response.text |
| 56 | + # test that something when wrong is shown |
| 57 | + assert "Something went wrong" in html |
| 58 | + |
| 59 | + |
25 | 60 | def test_fallback_empty(): |
26 | 61 | with TestClient(app) as client: |
27 | 62 | response = client.get("/") |
@@ -90,3 +125,38 @@ def test_fallback_with_log(): |
90 | 125 | assert "No logging info available" not in html |
91 | 126 | assert "<p>Logging info</p>" in html |
92 | 127 | assert "Fake log content" in html |
| 128 | + |
| 129 | + |
| 130 | +def test_actual_server_fallback(): |
| 131 | + """Test that the the server configures its startup failure correctly. |
| 132 | +
|
| 133 | + This may want to become an integration test in the fullness of time. Though |
| 134 | + the integration test may want to actually let the cli really serve up the |
| 135 | + fallback. |
| 136 | + """ |
| 137 | + # ThingThatCantStart has an error in __enter__ |
| 138 | + server = lt.ThingServer({"bad_thing": ThingThatCantStart}) |
| 139 | + |
| 140 | + # Starting the server is a SystemExit |
| 141 | + with pytest.raises(SystemExit, match="3") as excinfo: |
| 142 | + uvicorn.run(server.app, port=5000) |
| 143 | + server_error = excinfo.value |
| 144 | + assert server.startup_failure is not None |
| 145 | + assert server.startup_failure["thing"] == "bad_thing" |
| 146 | + thing_error = server.startup_failure["exception"] |
| 147 | + assert isinstance(thing_error, RuntimeError) |
| 148 | + |
| 149 | + app.labthings_server = server |
| 150 | + app.labthings_error = server_error |
| 151 | + with TestClient(app) as client: |
| 152 | + response = client.get("/") |
| 153 | + html = response.text |
| 154 | + assert "Something went wrong" in html |
| 155 | + # Shouldn't be displaying the meaningless SystemExit |
| 156 | + assert "SystemExit" not in html |
| 157 | + |
| 158 | + # The message from when the Thing errored should be displayed |
| 159 | + assert str(thing_error) in html |
| 160 | + # With the traceback |
| 161 | + assert 'labthings_fastapi/example_things/__init__.py", line' in html |
| 162 | + assert f'RuntimeError("{thing_error}")' in html |
0 commit comments