From 3ef7429ea45908ae438e38f47f1d2ee4ad76a9c4 Mon Sep 17 00:00:00 2001
From: euri10 <euri10@users.noreply.github.com>
Date: Mon, 31 May 2021 16:40:25 +0200
Subject: [PATCH] Coverage logging (#1057)

* Increased logging.py coverage 71>90

* Increased logging.py coverage 90>91, removed dead code ?

* Increased logging.py coverage

* Revert "Increased logging.py coverage 90>91, removed dead code ?"

This reverts commit fa605b83

* Avoid coverage on those, most likely untouchable since protocol will crash before on any status code not in range(100, 600)
---
 tests/middleware/test_logging.py | 32 ++++++++++++++++++++++++++++----
 uvicorn/logging.py               |  8 ++++----
 2 files changed, 32 insertions(+), 8 deletions(-)

diff --git a/tests/middleware/test_logging.py b/tests/middleware/test_logging.py
index 5c1bb58f94..0434b9f8b4 100644
--- a/tests/middleware/test_logging.py
+++ b/tests/middleware/test_logging.py
@@ -46,8 +46,9 @@ async def test_trace_logging(caplog):
 
 
 @pytest.mark.asyncio
-async def test_access_logging(caplog):
-    config = Config(app=app)
+@pytest.mark.parametrize("use_colors", [(True), (False), (None)])
+async def test_access_logging(use_colors, caplog):
+    config = Config(app=app, use_colors=use_colors)
     with caplog_for_logger(caplog, "uvicorn.access"):
         async with run_server(config):
             async with httpx.AsyncClient() as client:
@@ -63,8 +64,9 @@ async def test_access_logging(caplog):
 
 
 @pytest.mark.asyncio
-async def test_default_logging(caplog):
-    config = Config(app=app)
+@pytest.mark.parametrize("use_colors", [(True), (False)])
+async def test_default_logging(use_colors, caplog):
+    config = Config(app=app, use_colors=use_colors)
     with caplog_for_logger(caplog, "uvicorn.access"):
         async with run_server(config):
             async with httpx.AsyncClient() as client:
@@ -80,3 +82,25 @@ async def test_default_logging(caplog):
         assert "Uvicorn running on http://127.0.0.1:8000" in messages.pop(0)
         assert '"GET / HTTP/1.1" 204' in messages.pop(0)
         assert "Shutting down" in messages.pop(0)
+
+
+@pytest.mark.asyncio
+async def test_unknown_status_code(caplog):
+    async def app(scope, receive, send):
+        assert scope["type"] == "http"
+        await send({"type": "http.response.start", "status": 599, "headers": []})
+        await send({"type": "http.response.body", "body": b"", "more_body": False})
+
+    config = Config(app=app)
+    with caplog_for_logger(caplog, "uvicorn.access"):
+        async with run_server(config):
+            async with httpx.AsyncClient() as client:
+                response = await client.get("http://127.0.0.1:8000")
+
+        assert response.status_code == 599
+        messages = [
+            record.message
+            for record in caplog.records
+            if record.name == "uvicorn.access"
+        ]
+        assert '"GET / HTTP/1.1" 599' in messages.pop()
diff --git a/uvicorn/logging.py b/uvicorn/logging.py
index 8618f8754f..f22ed8d72e 100644
--- a/uvicorn/logging.py
+++ b/uvicorn/logging.py
@@ -44,13 +44,13 @@ def __init__(
 
     def color_level_name(self, level_name: str, level_no: int) -> str:
         def default(level_name: str) -> str:
-            return str(level_name)
+            return str(level_name)  # pragma: no cover
 
         func = self.level_name_colors.get(level_no, default)
         return func(level_name)
 
     def should_use_colors(self) -> bool:
-        return True
+        return True  # pragma: no cover
 
     def formatMessage(self, record: logging.LogRecord) -> str:
         recordcopy = copy(record)
@@ -67,7 +67,7 @@ def formatMessage(self, record: logging.LogRecord) -> str:
 
 class DefaultFormatter(ColourizedFormatter):
     def should_use_colors(self) -> bool:
-        return sys.stderr.isatty()
+        return sys.stderr.isatty()  # pragma: no cover
 
 
 class AccessFormatter(ColourizedFormatter):
@@ -88,7 +88,7 @@ def get_status_code(self, status_code: int) -> str:
         if self.use_colors:
 
             def default(code: int) -> str:
-                return status_and_phrase
+                return status_and_phrase  # pragma: no cover
 
             func = self.status_code_colours.get(status_code // 100, default)
             return func(status_and_phrase)