Skip to content

Commit a3c0bae

Browse files
committed
tests(maas): gateway, policies added, and maas controller are enabled for tests
1 parent 5ac0a40 commit a3c0bae

2 files changed

Lines changed: 193 additions & 352 deletions

File tree

tests/model_serving/model_server/maas_billing/conftest.py

Lines changed: 65 additions & 143 deletions
Original file line numberDiff line numberDiff line change
@@ -28,18 +28,20 @@
2828
from utilities.general import wait_for_oauth_openshift_deployment
2929
from ocp_resources.secret import Secret
3030
from tests.model_serving.model_server.maas_billing.utils import get_total_tokens
31+
from utilities.infra import get_data_science_cluster
3132
from tests.model_serving.model_server.maas_billing.utils import (
3233
detect_scheme_via_llmisvc,
3334
host_from_ingress_domain,
3435
mint_token,
35-
llmis_name,
3636
patch_llmisvc_with_maas_router,
3737
create_maas_group,
3838
build_maas_headers,
3939
get_maas_models_response,
4040
verify_chat_completions,
4141
maas_gateway_rate_limits_patched,
4242
ensure_maas_gateway_and_policies,
43+
detect_maas_control_plane_namespace,
44+
get_tier_mapping_configmap,
4345
)
4446

4547
LOGGER = get_logger(name=__name__)
@@ -82,6 +84,7 @@ def minted_token(request_session_http, base_url: str, current_client_token: str)
8284
def base_url(maas_scheme: str, maas_host: str) -> str:
8385
return f"{maas_scheme}://{maas_host}/maas-api"
8486

87+
8588
@pytest.fixture(scope="class")
8689
def model_url(
8790
maas_scheme: str,
@@ -106,6 +109,7 @@ def maas_models(
106109
base_url: str,
107110
maas_headers: dict,
108111
maas_inference_service_tinyllama: LLMInferenceService,
112+
maas_gateway_and_policies,
109113
):
110114
resp = get_maas_models_response(
111115
session=request_session_http,
@@ -435,6 +439,9 @@ def maas_token_for_actor(
435439
request_session_http: requests.Session,
436440
base_url: str,
437441
ocp_token_for_actor: str,
442+
maas_control_plane_namespace: str,
443+
maas_controller_enabled_latest,
444+
maas_gateway_and_policies,
438445
) -> str:
439446
"""
440447
Mint a MaaS token once per actor (admin / free / premium) and reuse it
@@ -532,106 +539,13 @@ def exercise_rate_limiter(
532539
return status_codes_list
533540

534541

535-
# @pytest.fixture(scope="class")
536-
# def maas_inference_service_tinyllama(
537-
# admin_client: DynamicClient,
538-
# unprivileged_model_namespace: Namespace,
539-
# model_service_account: ServiceAccount,
540-
# ) -> Generator[LLMInferenceService, None, None]:
541-
# """
542-
# TinyLlama S3-backed LLMInferenceService wired through MaaS for tests.
543-
# """
544-
# with (
545-
# create_llmisvc(
546-
# client=admin_client,
547-
# name="llm-s3-tinyllama",
548-
# namespace=unprivileged_model_namespace.name,
549-
# storage_uri=ModelStorage.TINYLLAMA_S3,
550-
# container_image=ContainerImages.VLLM_CPU,
551-
# container_resources={
552-
# "limits": {"cpu": "2", "memory": "12Gi"},
553-
# "requests": {"cpu": "1", "memory": "8Gi"},
554-
# },
555-
# service_account=model_service_account.name,
556-
# wait=True,
557-
# timeout=Timeout.TIMEOUT_15MIN,
558-
# ) as llm_service,
559-
# patch_llmisvc_with_maas_router(llm_service=llm_service),
560-
# ):
561-
# llmd_instance = llm_service.instance
562-
# model_spec = llmd_instance.spec.model
563-
564-
# storage_uri = model_spec.uri
565-
# assert storage_uri == ModelStorage.TINYLLAMA_S3, (
566-
# f"Unexpected storage_uri on TinyLlama LLMInferenceService: {storage_uri}"
567-
# )
568-
569-
# status = llmd_instance.status
570-
# conditions = {condition.type: condition.status for condition in status.conditions}
571-
# assert conditions.get("Ready") == "True", f"TinyLlama LLMInferenceService not Ready, conditions={conditions}"
572-
573-
# LOGGER.info(
574-
# f"MaaS: TinyLlama S3 LLMInferenceService "
575-
# f"{llm_service.namespace}/{llm_service.name} "
576-
# f"is Ready with storage_uri={storage_uri}"
577-
# )
578-
579-
# yield llm_service
580-
581-
# LOGGER.info(
582-
# f"MaaS: TinyLlama S3 LLMInferenceService "
583-
# f"{llm_service.namespace}/{llm_service.name} "
584-
# f"will be deleted at teardown"
585-
# )
586-
587-
# @pytest.fixture(scope="class")
588-
# def maas_inference_service_tinyllama(
589-
# admin_client: DynamicClient,
590-
# unprivileged_model_namespace: Namespace,
591-
# model_service_account: ServiceAccount,
592-
# ) -> Generator[LLMInferenceService, None, None]:
593-
# """
594-
# TinyLlama S3-backed LLMInferenceService wired through MaaS for tests.
595-
# """
596-
# with create_llmisvc(
597-
# client=admin_client,
598-
# name="llm-s3-tinyllama",
599-
# namespace=unprivileged_model_namespace.name,
600-
# storage_uri=ModelStorage.TINYLLAMA_S3,
601-
# container_image=ContainerImages.VLLM_CPU,
602-
# container_resources={
603-
# "limits": {"cpu": "2", "memory": "12Gi"},
604-
# "requests": {"cpu": "1", "memory": "8Gi"},
605-
# },
606-
# service_account=model_service_account.name,
607-
# wait=False, # 🔴 IMPORTANT CHANGE
608-
# timeout=Timeout.TIMEOUT_15MIN,
609-
# ) as llm_service:
610-
611-
# # ✅ Patch IMMEDIATELY
612-
# with patch_llmisvc_with_maas_router(llm_service=llm_service):
613-
614-
# # Now wait for readiness AFTER patch
615-
# llm_service.wait_for_condition(
616-
# condition="Ready",
617-
# status="True",
618-
# timeout=Timeout.TIMEOUT_15MIN,
619-
# )
620-
621-
# # llm_service.refresh()
622-
623-
# LOGGER.info(
624-
# "MaaS: TinyLlama LLMI %s/%s Ready and patched",
625-
# llm_service.namespace,
626-
# llm_service.name,
627-
# )
628-
629-
# yield llm_service
630542
@pytest.fixture(scope="class")
631543
def maas_inference_service_tinyllama(
632544
admin_client: DynamicClient,
633545
unprivileged_model_namespace: Namespace,
634546
model_service_account: ServiceAccount,
547+
maas_control_plane_namespace: str,
548+
maas_gateway_and_policies,
635549
) -> Generator[LLMInferenceService, None, None]:
636550
"""
637551
TinyLlama S3-backed LLMInferenceService wired through MaaS for tests.
@@ -647,18 +561,15 @@ def maas_inference_service_tinyllama(
647561
"requests": {"cpu": "1", "memory": "8Gi"},
648562
},
649563
service_account=model_service_account.name,
650-
wait=False,
564+
wait=False,
651565
timeout=Timeout.TIMEOUT_15MIN,
652566
) as llm_service:
653-
654-
# Patch immediately so the controller creates HTTPRoute on MaaS gateway
655-
with patch_llmisvc_with_maas_router(llm_service=llm_service):
656-
567+
with patch_llmisvc_with_maas_router(
568+
llm_service=llm_service,
569+
):
657570
inst = llm_service.instance
658571
storage_uri = inst.spec.model.uri
659-
assert storage_uri == ModelStorage.TINYLLAMA_S3, (
660-
f"Unexpected storage_uri on TinyLlama LLMI: {storage_uri}"
661-
)
572+
assert storage_uri == ModelStorage.TINYLLAMA_S3, f"Unexpected storage_uri on TinyLlama LLMI: {storage_uri}"
662573

663574
llm_service.wait_for_condition(
664575
condition="Ready",
@@ -673,16 +584,14 @@ def maas_inference_service_tinyllama(
673584

674585
yield llm_service
675586

587+
676588
@pytest.fixture(scope="class")
677589
def maas_scheme(admin_client: DynamicClient, unprivileged_model_namespace: Namespace) -> str:
678590
return detect_scheme_via_llmisvc(
679591
client=admin_client,
680592
namespace=unprivileged_model_namespace.name,
681593
)
682594

683-
# @pytest.fixture(scope="class")
684-
# def maas_scheme() -> str:
685-
# return "https"
686595

687596
@pytest.fixture(scope="class")
688597
def maas_host(admin_client):
@@ -693,6 +602,7 @@ def maas_host(admin_client):
693602
def maas_gateway_rate_limits(
694603
admin_client: DynamicClient,
695604
maas_gateway_and_policies,
605+
maas_tier_mapping_cm,
696606
) -> Generator[None, None, None]:
697607
with maas_gateway_rate_limits_patched(
698608
admin_client=admin_client,
@@ -702,6 +612,7 @@ def maas_gateway_rate_limits(
702612
):
703613
yield
704614

615+
705616
@pytest.fixture(scope="session")
706617
def maas_gateway_api_hostname(admin_client: DynamicClient) -> str:
707618
return host_from_ingress_domain(client=admin_client)
@@ -711,7 +622,7 @@ def maas_gateway_api_hostname(admin_client: DynamicClient) -> str:
711622
def maas_gateway_and_policies(
712623
admin_client: DynamicClient,
713624
maas_gateway_api_hostname: str,
714-
# maas_controller_enabled,
625+
maas_controller_enabled_latest,
715626
) -> Generator[None, None, None]:
716627
"""
717628
Ensure MaaS Gateway + Kuadrant policies exist once per test session.
@@ -722,38 +633,49 @@ def maas_gateway_and_policies(
722633
):
723634
yield
724635

725-
# @pytest.fixture(scope="session")
726-
# def maas_controller_enabled(admin_client):
727-
# """
728-
# Enable MaaS controller via DataScienceCluster component toggle.
729-
# Fails fast if the MaaS DSC component key is not present.
730-
# """
731-
# data_science_cluster = DataScienceCluster(client=admin_client, name=DSC_NAME)
732-
# data_science_cluster.get()
733-
734-
# components_section = (data_science_cluster.instance.get("spec") or {}).get("components") or {}
735-
# if MAAS_DSC_COMPONENT_KEY not in components_section:
736-
# raise RuntimeError(
737-
# f"MaaS tests require DSC component '{MAAS_DSC_COMPONENT_KEY}', but it is missing. "
738-
# f"Available DSC components: {sorted(list(components_section.keys()))}"
739-
# )
740-
741-
# current_component_state = (
742-
# (components_section.get(MAAS_DSC_COMPONENT_KEY) or {}).get("managementState")
743-
# )
744-
# if current_component_state == "Managed":
745-
# wait_for_data_science_cluster_ready(data_science_cluster=data_science_cluster)
746-
# yield
747-
# return
748-
749-
# patch_body = {
750-
# "spec": {
751-
# "components": {
752-
# MAAS_DSC_COMPONENT_KEY: {"managementState": "Managed"},
753-
# }
754-
# }
755-
# }
756-
757-
# with ResourceEditor(patches={data_science_cluster: patch_body}):
758-
# wait_for_data_science_cluster_ready(data_science_cluster=data_science_cluster)
759-
# yield
636+
637+
@pytest.fixture(scope="session")
638+
def maas_controller_enabled_latest(admin_client: DynamicClient):
639+
dsc_resource = get_data_science_cluster(client=admin_client)
640+
dsc_resource.get()
641+
642+
original_components = dsc_resource.instance.spec.components
643+
644+
kserve = original_components.get("kserve") or {}
645+
maas = kserve.get("modelsAsService") or {}
646+
if (maas.get("managementState") or "Removed") == "Managed":
647+
dsc_resource.wait_for_condition(condition="ModelsAsServiceReady", status="True", timeout=Timeout.TIMEOUT_15MIN)
648+
yield dsc_resource
649+
return
650+
651+
component_patch = {"kserve": {"modelsAsService": {"managementState": "Managed"}}}
652+
653+
with ResourceEditor(patches={dsc_resource: {"spec": {"components": component_patch}}}):
654+
dsc_resource.wait_for_condition(condition="ModelsAsServiceReady", status="True", timeout=Timeout.TIMEOUT_15MIN)
655+
dsc_resource.wait_for_condition(condition="Ready", status="True", timeout=Timeout.TIMEOUT_15MIN)
656+
yield dsc_resource
657+
658+
659+
@pytest.fixture(scope="session")
660+
def maas_control_plane_namespace(admin_client: DynamicClient) -> str:
661+
return detect_maas_control_plane_namespace(admin_client=admin_client)
662+
663+
664+
@pytest.fixture(scope="session")
665+
def maas_tier_mapping_cm(
666+
admin_client: DynamicClient,
667+
maas_control_plane_namespace: str,
668+
):
669+
"""
670+
Ensure MaaS tier mapping ConfigMap is present and readable.
671+
"""
672+
config_map = get_tier_mapping_configmap(
673+
admin_client=admin_client,
674+
namespace=maas_control_plane_namespace,
675+
)
676+
677+
LOGGER.info(
678+
f"MaaS tier mapping ConfigMap detected: namespace={maas_control_plane_namespace}, name={config_map.name}"
679+
)
680+
681+
return config_map

0 commit comments

Comments
 (0)