tests: fix potential infinite wait in tests spinning up a container (#7153)

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
This commit is contained in:
Jens L 2023-10-12 13:57:29 +02:00 committed by GitHub
parent 6d1eef039e
commit abab635a01
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 37 additions and 52 deletions

View File

@ -17,8 +17,8 @@ TestCase.maxDiff = None
class PytestTestRunner(DiscoverRunner): # pragma: no cover
"""Runs pytest to discover and run tests."""
def __init__(self, verbosity=1, failfast=False, keepdb=False, **kwargs):
super().__init__(verbosity, failfast, keepdb, **kwargs)
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.args = []
if self.failfast:
@ -47,6 +47,7 @@ class PytestTestRunner(DiscoverRunner): # pragma: no cover
@classmethod
def add_arguments(cls, parser: ArgumentParser):
"""Add more pytest-specific arguments"""
DiscoverRunner.add_arguments(parser)
parser.add_argument(
"--randomly-seed",
type=int,
@ -55,9 +56,6 @@ class PytestTestRunner(DiscoverRunner): # pragma: no cover
"Default behaviour: use random.Random().getrandbits(32), so the seed is"
"different on each run.",
)
parser.add_argument(
"--keepdb", action="store_true", help="Preserves the test DB between runs."
)
def run_tests(self, test_labels, extra_tests=None, **kwargs):
"""Run pytest and return the exitcode.

View File

@ -49,13 +49,8 @@ class TestProviderOAuth2OIDC(SeleniumTestCase):
"OIDC_PROVIDER": f"{self.live_server_url}/application/o/{self.application_slug}/",
},
)
while True:
container.reload()
status = container.attrs.get("State", {}).get("Health", {}).get("Status")
if status == "healthy":
return container
self.logger.info("Container failed healthcheck")
sleep(1)
self.wait_for_container(container)
return container
@retry()
@apply_blueprint(

View File

@ -49,13 +49,8 @@ class TestProviderOAuth2OIDCImplicit(SeleniumTestCase):
"OIDC_PROVIDER": f"{self.live_server_url}/application/o/{self.application_slug}/",
},
)
while True:
container.reload()
status = container.attrs.get("State", {}).get("Health", {}).get("Status")
if status == "healthy":
return container
self.logger.info("Container failed healthcheck")
sleep(1)
self.wait_for_container(container)
return container
@retry()
@apply_blueprint(

View File

@ -48,13 +48,8 @@ class TestProviderSAML(SeleniumTestCase):
"SP_METADATA_URL": metadata_url,
},
)
while True:
container.reload()
status = container.attrs.get("State", {}).get("Health", {}).get("Status")
if status == "healthy":
return container
self.logger.info("Container failed healthcheck")
sleep(1)
self.wait_for_container(container)
return container
@retry()
@apply_blueprint(

View File

@ -43,7 +43,24 @@ def get_docker_tag() -> str:
return f"gh-{branch_name}"
class SeleniumTestCase(StaticLiveServerTestCase):
class DockerTestCase:
"""Mixin for dealing with containers"""
def wait_for_container(self, container: Container):
"""Check that container is health"""
attempt = 0
while True:
container.reload()
status = container.attrs.get("State", {}).get("Health", {}).get("Status")
if status == "healthy":
return container
sleep(1)
attempt += 1
if attempt >= 30:
self.failureException("Container failed to start")
class SeleniumTestCase(DockerTestCase, StaticLiveServerTestCase):
"""StaticLiveServerTestCase which automatically creates a Webdriver instance"""
container: Optional[Container] = None
@ -82,13 +99,8 @@ class SeleniumTestCase(StaticLiveServerTestCase):
state = container.attrs.get("State", {})
if "Health" not in state:
return container
while True:
container.reload()
status = container.attrs.get("State", {}).get("Health", {}).get("Status")
if status == "healthy":
return container
self.logger.info("Container failed healthcheck")
sleep(1)
self.wait_for_container(container)
return container
def output_container_logs(self, container: Optional[Container] = None):
"""Output the container logs to our STDOUT"""

View File

@ -1,7 +1,6 @@
"""outpost tests"""
from shutil import rmtree
from tempfile import mkdtemp
from time import sleep
import yaml
from channels.testing import ChannelsLiveServerTestCase
@ -20,10 +19,10 @@ from authentik.outposts.models import (
)
from authentik.outposts.tasks import outpost_connection_discovery
from authentik.providers.proxy.models import ProxyProvider
from tests.e2e.utils import get_docker_tag
from tests.e2e.utils import DockerTestCase, get_docker_tag
class OutpostDockerTests(ChannelsLiveServerTestCase):
class OutpostDockerTests(DockerTestCase, ChannelsLiveServerTestCase):
"""Test Docker Controllers"""
def _start_container(self, ssl_folder: str) -> Container:
@ -45,12 +44,8 @@ class OutpostDockerTests(ChannelsLiveServerTestCase):
}
},
)
while True:
container.reload()
status = container.attrs.get("State", {}).get("Health", {}).get("Status")
if status == "healthy":
return container
sleep(1)
self.wait_for_container(container)
return container
def setUp(self):
super().setUp()

View File

@ -1,7 +1,6 @@
"""outpost tests"""
from shutil import rmtree
from tempfile import mkdtemp
from time import sleep
import yaml
from channels.testing.live import ChannelsLiveServerTestCase
@ -20,10 +19,10 @@ from authentik.outposts.models import (
from authentik.outposts.tasks import outpost_connection_discovery
from authentik.providers.proxy.controllers.docker import DockerController
from authentik.providers.proxy.models import ProxyProvider
from tests.e2e.utils import get_docker_tag
from tests.e2e.utils import DockerTestCase, get_docker_tag
class TestProxyDocker(ChannelsLiveServerTestCase):
class TestProxyDocker(DockerTestCase, ChannelsLiveServerTestCase):
"""Test Docker Controllers"""
def _start_container(self, ssl_folder: str) -> Container:
@ -45,12 +44,8 @@ class TestProxyDocker(ChannelsLiveServerTestCase):
}
},
)
while True:
container.reload()
status = container.attrs.get("State", {}).get("Health", {}).get("Status")
if status == "healthy":
return container
sleep(1)
self.wait_for_container(container)
return container
def setUp(self):
super().setUp()