11# AI Disclaimer: Google Gemini 2.5 pro has been used to generate a majority of this code, with human review and editing.
22import pytest
3- from typing import Self
3+ from typing import Any , Self
44from simple_logger .logger import get_logger
55from model_registry import ModelRegistry as ModelRegistryClient
66from tests .model_registry .rbac .utils import build_mr_client_args
77from utilities .infra import create_inference_token
8- from mr_openapi .exceptions import ForbiddenException
8+ from mr_openapi .exceptions import ForbiddenException , UnauthorizedException
99from ocp_resources .service_account import ServiceAccount
10+ from timeout_sampler import TimeoutSampler , retry
1011
1112LOGGER = get_logger (name = __name__ )
1213
@@ -44,12 +45,11 @@ def test_service_account_access_denied(
4445 )
4546 LOGGER .debug (f"Attempting client connection with args: { client_args } " )
4647
47- # Expect an exception related to HTTP 403
48- with pytest . raises ( ForbiddenException ) as exc_info :
49- _ = ModelRegistryClient ( ** client_args )
48+ # Retry for up to 2 minutes if we get UnauthorizedException (401) during kube-rbac-proxy initialization
49+ # Expect ForbiddenException (403) once kube-rbac-proxy is fully initialized
50+ http_error = _try_connection_expect_forbidden ( client_args = client_args )
5051
5152 # Verify the status code from the caught exception
52- http_error = exc_info .value
5353 assert http_error .body is not None , "HTTPError should have a response object"
5454 LOGGER .info (f"Received expected HTTP error: Status Code { http_error .status } " )
5555 assert http_error .status == 403 , f"Expected HTTP 403 Forbidden, but got { http_error .status } "
@@ -69,21 +69,44 @@ def test_service_account_access_granted(
6969 LOGGER .info (f"Targeting Model Registry REST endpoint: { model_registry_instance_rest_endpoint [0 ]} " )
7070 LOGGER .info ("Applied RBAC Role/Binding via fixtures. Expecting access GRANT." )
7171
72- # Create a fresh token to bypass OAuth proxy cache from previous test
72+ # Create a fresh token to bypass kube-rbac- proxy cache from previous test
7373 fresh_token = create_inference_token (model_service_account = service_account )
74+ client_args = build_mr_client_args (
75+ rest_endpoint = model_registry_instance_rest_endpoint [0 ], token = fresh_token , author = "rbac-test-granted"
76+ )
77+ LOGGER .debug (f"Attempting client connection with args: { client_args } " )
78+
79+ # Retry for up to 2 minutes to allow RBAC propagation
80+ # Accept UnauthorizedException (401) as a transient error during RBAC propagation
81+ sampler = TimeoutSampler (
82+ wait_timeout = 120 ,
83+ sleep = 5 ,
84+ func = lambda : ModelRegistryClient (** client_args ),
85+ exceptions_dict = {UnauthorizedException : []},
86+ )
7487
7588 try :
76- client_args = build_mr_client_args (
77- rest_endpoint = model_registry_instance_rest_endpoint [0 ], token = fresh_token , author = "rbac-test-granted"
78- )
79- LOGGER .debug (f"Attempting client connection with args: { client_args } " )
80- mr_client_success = ModelRegistryClient (** client_args )
89+ # Get the first successful result
90+ mr_client_success = next (iter (sampler ))
8191 assert mr_client_success is not None , "Client initialization failed after granting permissions"
8292 LOGGER .info ("Client instantiated successfully after granting permissions." )
83-
8493 except Exception as e :
85- # If we get an exception here, it's unexpected, especially 403
86- LOGGER .error (f"Received unexpected general error after granting access: { e } " , exc_info = True )
94+ LOGGER .error (f"Failed to access Model Registry after granting permissions: { e } " , exc_info = True )
8795 raise
8896
8997 LOGGER .info ("--- RBAC Test Completed Successfully ---" )
98+
99+
100+ @retry (wait_timeout = 120 , sleep = 5 , exceptions_dict = {UnauthorizedException : []})
101+ def _try_connection_expect_forbidden (client_args : dict [str , Any ]) -> ForbiddenException :
102+ """
103+ Attempts to create a ModelRegistryClient and expects ForbiddenException.
104+ Retries on UnauthorizedException (401) during kube-rbac-proxy initialization.
105+ Returns the ForbiddenException when received.
106+ """
107+ try :
108+ ModelRegistryClient (** client_args )
109+ raise AssertionError ("Expected ForbiddenException but client connection succeeded" )
110+ except ForbiddenException as e :
111+ # This is what we want - 403 Forbidden
112+ return e
0 commit comments