KeycloakContainer image
Hi! I was trying to change from jboss/keycloak image to quay.io/keycloak/keycloak:latest because the jboss repo is not longer supported. However, I don't know why, I'm getting TimeoutException during port mapping for container.
Here I have the logs:
============================= test session starts ==============================
collecting ... collected 1 item
run-last-failure: rerun previous 1 failure
test_security_controller.py::TestSecurityController::test_auth_token FAILED [100%]Pulling image quay.io/keycloak/keycloak:latest
Container started: 4f0e9d085c71
Waiting to be ready...
Waiting to be ready...
Waiting to be ready...
eees_eas_discovery/test/test_security_controller.py:8 (TestSecurityController.test_auth_token)
self = <eees_eas_discovery.test.test_security_controller.TestSecurityController testMethod=test_auth_token>
def test_auth_token(self):
keycloak_container = KeycloakContainer()
> with KeycloakContainer(image='quay.io/keycloak/keycloak:latest') as kc:
test_security_controller.py:12:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
../../venv/lib/python3.8/site-packages/testcontainers/core/container.py:71: in __enter__
return self.start()
../../venv/lib/python3.8/site-packages/testcontainers/keycloak.py:61: in start
self._connect()
../../venv/lib/python3.8/site-packages/testcontainers/core/waiting_utils.py:49: in wrapper
return wrapped(*args, **kwargs)
../../venv/lib/python3.8/site-packages/testcontainers/keycloak.py:54: in _connect
url = self.get_url()
../../venv/lib/python3.8/site-packages/testcontainers/keycloak.py:49: in get_url
port = self.get_exposed_port(self.port_to_expose)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
wrapped = <bound method DockerContainer.get_exposed_port of <testcontainers.keycloak.KeycloakContainer object at 0x7fe0ae54a310>>
instance = <testcontainers.keycloak.KeycloakContainer object at 0x7fe0ae54a310>
args = (8080,), kwargs = {}
@wrapt.decorator
def wrapper(wrapped, instance, args, kwargs):
exception = None
logger.info("Waiting to be ready...")
for attempt_no in range(config.MAX_TRIES):
try:
return wrapped(*args, **kwargs)
except transient_exceptions as e:
logger.debug(f"Connection attempt '{attempt_no + 1}' of '{config.MAX_TRIES + 1}' "
f"failed: {traceback.format_exc()}")
time.sleep(config.SLEEP_TIME)
exception = e
> raise TimeoutException(
f'Wait time ({config.MAX_TRIES * config.SLEEP_TIME}s) exceeded for {wrapped.__name__}'
f'(args: {args}, kwargs {kwargs}). Exception: {exception}'
)
E testcontainers.core.exceptions.TimeoutException: Wait time (120s) exceeded for get_exposed_port(args: (8080,), kwargs {}). Exception: port mapping for container 4f0e9d085c712ddc2edd35cd34c9e88cf93e30c7555a46a7569f61d3ae4ae3b6 and port 8080 is not available
../../venv/lib/python3.8/site-packages/testcontainers/core/waiting_utils.py:55: TimeoutException
This is my tests:
def test_auth_token(self):
with KeycloakContainer(image='quay.io/keycloak/keycloak:latest') as kc:
keycloak = kc.get_client()
...
Do you have the full code for the test handy? It looks like there is a kc and also a keycloak_container variable in the traceback (see below).
def test_auth_token(self): keycloak_container = KeycloakContainer() # Here. > with KeycloakContainer(image='quay.io/keycloak/keycloak:latest') as kc: # Here.
Hi, yeah, I did't realize that I had two KeycloakContainer objects. I tried again with only kc but the output it's the same.
def test_auth_token(self):
with KeycloakContainer(image='quay.io/keycloak/keycloak:latest') as kc:
keycloak = kc.get_client()
realm = json.load(open('./realm.json'))
keycloak.import_realm(realm)
token = keycloak.get_token()
validation = function_to_test(token)
self.assertNotEqual(validation, None)
Output:
Pulling image quay.io/keycloak/keycloak:latest
Container started: 15fab070147c
Waiting to be ready...
Waiting to be ready...
Waiting to be ready...
Waiting to be ready...
def test_auth_token(self):
> with KeycloakContainer(image='quay.io/keycloak/keycloak:latest') as kc:
test_security_controller.py:14:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
../../venv/lib/python3.8/site-packages/testcontainers/core/container.py:71: in __enter__
return self.start()
../../venv/lib/python3.8/site-packages/testcontainers/keycloak.py:61: in start
self._connect()
../../venv/lib/python3.8/site-packages/testcontainers/core/waiting_utils.py:49: in wrapper
return wrapped(*args, **kwargs)
../../venv/lib/python3.8/site-packages/testcontainers/keycloak.py:54: in _connect
url = self.get_url()
../../venv/lib/python3.8/site-packages/testcontainers/keycloak.py:49: in get_url
port = self.get_exposed_port(self.port_to_expose)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
wrapped = <bound method DockerContainer.get_exposed_port of <testcontainers.keycloak.KeycloakContainer object at 0x7ff18f50b820>>
instance = <testcontainers.keycloak.KeycloakContainer object at 0x7ff18f50b820>
args = (8082,), kwargs = {}
@wrapt.decorator
def wrapper(wrapped, instance, args, kwargs):
exception = None
logger.info("Waiting to be ready...")
for attempt_no in range(config.MAX_TRIES):
try:
return wrapped(*args, **kwargs)
except transient_exceptions as e:
logger.debug(f"Connection attempt '{attempt_no + 1}' of '{config.MAX_TRIES + 1}' "
f"failed: {traceback.format_exc()}")
time.sleep(config.SLEEP_TIME)
exception = e
> raise TimeoutException(
f'Wait time ({config.MAX_TRIES * config.SLEEP_TIME}s) exceeded for {wrapped.__name__}'
f'(args: {args}, kwargs {kwargs}). Exception: {exception}'
)
E testcontainers.core.exceptions.TimeoutException: Wait time (120s) exceeded for get_exposed_port(args: (8082,), kwargs {}). Exception: port mapping for container 15fab070147c6a01d5f44b18791aecf3e040929e867898283501562b48d182cc and port 8082 is not available
../../venv/lib/python3.8/site-packages/testcontainers/core/waiting_utils.py:55: TimeoutException
Would you be up for sending a PR with the failing test? Then we can ensure any changes we introduce address the problem you've encountered?
Hi! Just wanted to add my 2 cents here since I'm looking at the library as an interesting alternative to sidecars in the pipeline as we need integration testing to test an update in the infrastructure.
I haven't tested yet but I have a hunch this is happening because since versions 17 (which I believe is the latest in jboss repo) the /auth endpoint which is used for health checking either no longer exists or lost it's purpose as a health check.
Instead, by lookin at here, we can see how to enable the new health check endpoint and how to access it. Hope I was helpful :P
Hi! Just wanted to add my 2 cents here since I'm looking at the library as an interesting alternative to sidecars in the pipeline as we need integration testing to test an update in the infrastructure.
I haven't tested yet but I have a hunch this is happening because since versions 17 (which I believe is the latest in jboss repo) the
/authendpoint which is used for health checking either no longer exists or lost it's purpose as a health check.Instead, by lookin at here, we can see how to enable the new health check endpoint and how to access it. Hope I was helpful :P
I can confirm this. Using a bitnami/keycloak version 20 image the following error is thrown:
testcontainers.core.exceptions.TimeoutException: Wait time (120s) exceeded for _connect(args: (), kwargs {}). Exception: ('Connection aborted.', RemoteDisconnected('...
whereas using a jboss version my same test will pass.
This issue is already solved by #480. The solution was to update the health probes to the new versions of Keyclock that is presented in Quay.io repository. I believe this issues can be closed @tillahoffmann
Thank you for the update @matheusvnm. Closing this one as #480 seems to have done the trick.