Skip to content

Commit ffd88d7

Browse files
authored
Merge branch 'main' into cosign_binary
2 parents 0765191 + bbf4eab commit ffd88d7

File tree

16 files changed

+1278
-1060
lines changed

16 files changed

+1278
-1060
lines changed

.github/workflows/scripts/pr_workflow.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ def verify_allowed_user(self) -> bool:
109109
# check if the user is a member of opendatahub-tests-contributors
110110
membership = team.get_team_membership(member=self.user_login)
111111
LOGGER.info(f"User {self.user_login} is a member of the test contributor team. {membership}")
112-
return True # noqa: TRY300
112+
return True
113113
except UnknownObjectException:
114114
LOGGER.error(f"User {self.user_login} is not allowed for this action. Exiting.")
115115
return False

.pre-commit-config.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ repos:
3636
exclude: .*/__snapshots__/.*|.*-input\.json$|^semgrep\.yaml$
3737

3838
- repo: https://github.com/astral-sh/ruff-pre-commit
39-
rev: v0.15.5
39+
rev: v0.15.6
4040
hooks:
4141
- id: ruff
4242
- id: ruff-format
@@ -50,7 +50,7 @@ repos:
5050
# - id: renovate-config-validator
5151

5252
- repo: https://github.com/gitleaks/gitleaks
53-
rev: v8.30.0
53+
rev: v8.30.1
5454
hooks:
5555
- id: gitleaks
5656

tests/conftest.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ def registry_pull_secret(pytestconfig: Config) -> list[str]:
167167
try:
168168
for secret in registry_pull_secret:
169169
base64.b64decode(s=secret, validate=True)
170-
return registry_pull_secret # noqa: TRY300
170+
return registry_pull_secret
171171
except binascii.Error:
172172
raise ValueError("Registry pull secret is not a valid base64 encoded string")
173173

@@ -253,7 +253,7 @@ def modelcar_yaml_config(pytestconfig: pytest.Config) -> dict[str, Any] | None:
253253
modelcar_yaml = yaml.safe_load(file)
254254
if not isinstance(modelcar_yaml, dict):
255255
raise ValueError("modelcar.yaml should contain a dictionary.") # noqa: TRY004
256-
return modelcar_yaml # noqa: TRY300
256+
return modelcar_yaml
257257
except yaml.YAMLError as e:
258258
raise ValueError(f"Error parsing modelcar.yaml: {e}") from e
259259

tests/llama_stack/safety/conftest.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ def guardrails_orchestrator_ssl_cert(guardrails_orchestrator_route: Route):
4848
with open(filepath, "w") as f:
4949
f.write("\n".join(cert_lines))
5050

51-
return filepath # noqa: TRY300
51+
return filepath
5252

5353
except Exception as e: # noqa: BLE001
5454
raise RuntimeError(f"Could not get certificate from {hostname}: {e}")

tests/llama_stack/utils.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ def wait_for_llama_stack_client_ready(client: LlamaStackClient) -> bool:
9898
f"vector_stores:{len(vector_stores.data)} "
9999
f"files:{len(files.data)})"
100100
)
101-
return True # noqa: TRY300
101+
return True
102102

103103
except (APIConnectionError, InternalServerError) as error:
104104
LOGGER.debug(f"Llama Stack server not ready yet: {error}")

tests/model_registry/model_catalog/huggingface/utils.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ def get_huggingface_nested_attributes(obj, attr_path) -> Any:
5757
if not hasattr(current_obj, attr):
5858
return None
5959
current_obj = getattr(current_obj, attr)
60-
return current_obj # noqa: TRY300
60+
return current_obj
6161
except AttributeError as e:
6262
LOGGER.error(f"AttributeError getting '{attr_path}': {e}")
6363
return None

tests/model_registry/model_catalog/metadata/utils.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@ def get_metadata_from_catalog_pod(model_catalog_pod: Pod, model_name: str) -> di
294294
metadata_json = model_catalog_pod.execute(command=["cat", metadata_path], container=CATALOG_CONTAINER)
295295
metadata = json.loads(metadata_json)
296296
LOGGER.info(f"Successfully loaded metadata.json for model '{model_name}'")
297-
return metadata # noqa: TRY300
297+
return metadata
298298
except Exception as e:
299299
LOGGER.error(f"Failed to read metadata.json for model '{model_name}': {e}")
300300
raise

tests/model_registry/model_registry/conftest.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ def sa_token(service_account: ServiceAccount) -> str:
135135
raise ValueError("Retrieved token is empty after successful command execution.")
136136

137137
LOGGER.info(f"Successfully retrieved token for SA '{sa_name}'")
138-
return token # noqa: TRY300
138+
return token
139139

140140
except Exception as e: # Catch all exceptions from the try block
141141
error_type = type(e).__name__

tests/model_serving/maas_billing/maas_subscription/conftest.py

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -556,3 +556,67 @@ def premium_system_authenticated_access(
556556
if extra_auth_policy.exists:
557557
LOGGER.info(f"Fixture teardown: ensuring AuthPolicy {extra_auth_policy.name} is removed")
558558
extra_auth_policy.clean_up(wait=True)
559+
560+
561+
@pytest.fixture(scope="function")
562+
def second_free_subscription(
563+
admin_client: DynamicClient,
564+
maas_free_group: str,
565+
maas_model_tinyllama_free: MaaSModelRef,
566+
maas_subscription_tinyllama_free: MaaSSubscription,
567+
) -> Generator[MaaSSubscription, Any, Any]:
568+
"""
569+
Creates a second subscription for maas_free_group on the free model.
570+
Used to simulate an ambiguous subscription selection (two qualifying subscriptions,
571+
no x-maas-subscription header).
572+
"""
573+
with create_maas_subscription(
574+
admin_client=admin_client,
575+
subscription_namespace=maas_subscription_tinyllama_free.namespace,
576+
subscription_name="e2e-second-free-subscription",
577+
owner_group_name=maas_free_group,
578+
model_name=maas_model_tinyllama_free.name,
579+
model_namespace=maas_model_tinyllama_free.namespace,
580+
tokens_per_minute=500,
581+
window="1m",
582+
priority=5,
583+
teardown=True,
584+
wait_for_resource=True,
585+
) as second_subscription:
586+
second_subscription.wait_for_condition(condition="Ready", status="True", timeout=300)
587+
LOGGER.info(
588+
f"Created second free subscription {second_subscription.name} for model {maas_model_tinyllama_free.name}"
589+
)
590+
yield second_subscription
591+
592+
593+
@pytest.fixture(scope="function")
594+
def free_actor_premium_subscription(
595+
admin_client: DynamicClient,
596+
maas_model_tinyllama_premium: MaaSModelRef,
597+
maas_subscription_tinyllama_premium: MaaSSubscription,
598+
) -> Generator[MaaSSubscription, Any, Any]:
599+
"""
600+
Creates a subscription for system:authenticated on the premium model.
601+
Used to verify that having a subscription alone is not sufficient —
602+
the actor must also be listed in the model's MaaSAuthPolicy.
603+
"""
604+
with create_maas_subscription(
605+
admin_client=admin_client,
606+
subscription_namespace=maas_subscription_tinyllama_premium.namespace,
607+
subscription_name="e2e-free-actor-premium-sub",
608+
owner_group_name="system:authenticated",
609+
model_name=maas_model_tinyllama_premium.name,
610+
model_namespace=maas_model_tinyllama_premium.namespace,
611+
tokens_per_minute=100,
612+
window="1m",
613+
priority=0,
614+
teardown=True,
615+
wait_for_resource=True,
616+
) as sub_for_free_actor:
617+
sub_for_free_actor.wait_for_condition(condition="Ready", status="True", timeout=300)
618+
LOGGER.info(
619+
f"Created subscription {sub_for_free_actor.name} for system:authenticated "
620+
f"on premium model {maas_model_tinyllama_premium.name}"
621+
)
622+
yield sub_for_free_actor
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
from __future__ import annotations
2+
3+
import pytest
4+
import requests
5+
from ocp_resources.maas_subscription import MaaSSubscription
6+
from simple_logger.logger import get_logger
7+
8+
from tests.model_serving.maas_billing.maas_subscription.utils import (
9+
chat_payload_for_url,
10+
poll_expected_status,
11+
)
12+
13+
LOGGER = get_logger(name=__name__)
14+
15+
16+
@pytest.mark.usefixtures(
17+
"maas_unprivileged_model_namespace",
18+
"maas_subscription_controller_enabled_latest",
19+
"maas_gateway_api",
20+
"maas_api_gateway_reachable",
21+
"maas_inference_service_tinyllama_free",
22+
"maas_model_tinyllama_free",
23+
"maas_auth_policy_tinyllama_free",
24+
"maas_subscription_tinyllama_free",
25+
)
26+
class TestMultipleSubscriptionsNoHeader:
27+
"""
28+
Validates that a token qualifying for multiple subscriptions on the same model
29+
is denied when no x-maas-subscription header is provided to disambiguate.
30+
"""
31+
32+
@pytest.mark.tier1
33+
@pytest.mark.parametrize("ocp_token_for_actor", [{"type": "free"}], indirect=True)
34+
def test_multiple_matching_subscriptions_no_header_gets_403(
35+
self,
36+
request_session_http: requests.Session,
37+
model_url_tinyllama_free: str,
38+
maas_headers_for_actor_api_key: dict[str, str],
39+
second_free_subscription: MaaSSubscription,
40+
) -> None:
41+
"""
42+
Verify that a token qualifying for multiple subscriptions receives 403
43+
when no x-maas-subscription header is provided.
44+
45+
Given two subscriptions for the same model that the free actor qualifies for,
46+
when the actor sends a request without the x-maas-subscription header,
47+
then the request should be denied with 403 because the subscription
48+
selection is ambiguous.
49+
"""
50+
LOGGER.info(
51+
f"Testing: free actor has two subscriptions including '{second_free_subscription.name}' "
52+
f"with no x-maas-subscription header — expecting 403"
53+
)
54+
55+
payload = chat_payload_for_url(model_url=model_url_tinyllama_free)
56+
57+
response = poll_expected_status(
58+
request_session_http=request_session_http,
59+
model_url=model_url_tinyllama_free,
60+
headers=maas_headers_for_actor_api_key,
61+
payload=payload,
62+
expected_statuses={403},
63+
)
64+
65+
assert response.status_code == 403, (
66+
f"Expected 403 when multiple subscriptions exist and no header is provided, "
67+
f"got {response.status_code}: {(response.text or '')[:200]}"
68+
)

0 commit comments

Comments
 (0)