3434 reraise = True ,
3535)
3636@beartype
37- def wait_for_health_check (container : Container ) -> None :
38- """Wait for a container to pass its health check ."""
37+ def _poll_health_check (container : Container ) -> None :
38+ """Poll a container until it reports a healthy status ."""
3939 container .reload ()
4040 health_status = container .attrs ["State" ]["Health" ]["Status" ]
4141 # In theory this might not be hit by coverage.
@@ -47,6 +47,35 @@ def wait_for_health_check(container: Container) -> None:
4747 raise ValueError (error_message )
4848
4949
50+ @beartype
51+ def wait_for_health_check (container : Container ) -> None :
52+ """Wait for a container to pass its health check.
53+
54+ On failure, augment the error with the container's logs and the
55+ Docker healthcheck probe history so CI failures are diagnosable.
56+ """
57+ try :
58+ _poll_health_check (container = container )
59+ except ValueError as exc : # pragma: no cover
60+ container .reload ()
61+ logs = container .logs ().decode (errors = "replace" )
62+ health_log = container .attrs ["State" ]["Health" ].get ("Log" , [])
63+ probes = "\n " .join (
64+ f" exit={ entry .get ('ExitCode' )!r} "
65+ f"start={ entry .get ('Start' )!r} end={ entry .get ('End' )!r} \n "
66+ f" output={ entry .get ('Output' )!r} "
67+ for entry in health_log
68+ )
69+ error_message = (
70+ f"{ exc } \n "
71+ f"--- container logs ({ container .name } ) ---\n "
72+ f"{ logs } \n "
73+ f"--- healthcheck probes ({ container .name } ) ---\n "
74+ f"{ probes } "
75+ )
76+ raise ValueError (error_message ) from exc
77+
78+
5079@pytest .fixture (name = "custom_bridge_network" )
5180def fixture_custom_bridge_network () -> Iterator [Network ]:
5281 """Yield a custom bridge network which containers can connect to.
0 commit comments