Skip to content

Commit 4dfbd32

Browse files
committed
task(RHOAIENG-33045): Centralised image logic + fixed tests
Signed-off-by: Pat O'Connor <[email protected]>
1 parent 561fd10 commit 4dfbd32

File tree

7 files changed

+72
-20
lines changed

7 files changed

+72
-20
lines changed

.github/workflows/e2e_tests.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ jobs:
5757
- name: Set up specific Python version
5858
uses: actions/setup-python@v5
5959
with:
60-
python-version: '3.11'
60+
python-version: '3.12'
6161
cache: 'pip' # caching pip dependencies
6262

6363
- name: Setup NVidia GPU environment for KinD
Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
11
RAY_VERSION = "2.47.1"
2-
'''
2+
"""
33
The below are used to define the default runtime image for the Ray Cluster.
44
* For python 3.11:ray:2.47.1-py311-cu121
55
* For python 3.12:ray:2.47.1-py312-cu121
6-
'''
6+
"""
77
CUDA_PY311_RUNTIME_IMAGE = "quay.io/modh/ray@sha256:6d076aeb38ab3c34a6a2ef0f58dc667089aa15826fa08a73273c629333e12f1e"
88
CUDA_PY312_RUNTIME_IMAGE = "quay.io/modh/ray@sha256:23860dfe2e47bb69709b3883b08fd1a4d836ce02eaf8d0afeeafe6986d0fc8fb"
9+
10+
# Centralized image selection
11+
SUPPORTED_PYTHON_VERSIONS = {
12+
"3.11": CUDA_PY311_RUNTIME_IMAGE,
13+
"3.12": CUDA_PY312_RUNTIME_IMAGE,
14+
}

src/codeflare_sdk/common/utils/unit_test_support.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import string
1616
import sys
1717
from codeflare_sdk.common.utils import constants
18+
from codeflare_sdk.common.utils.utils import get_ray_image_for_python_version
1819
from codeflare_sdk.ray.cluster.cluster import (
1920
Cluster,
2021
ClusterConfiguration,
@@ -69,7 +70,7 @@ def create_cluster_wrong_type():
6970
worker_extended_resource_requests={"nvidia.com/gpu": 7},
7071
appwrapper=True,
7172
image_pull_secrets=["unit-test-pull-secret"],
72-
image=constants.CUDA_RUNTIME_IMAGE,
73+
image=constants.CUDA_PY312_RUNTIME_IMAGE,
7374
write_to_file=True,
7475
labels={1: 1},
7576
)
@@ -294,8 +295,8 @@ def apply_template(yaml_file_path, variables):
294295

295296

296297
def get_expected_image():
297-
# TODO: Select image based on Python version
298-
return constants.CUDA_RUNTIME_IMAGE
298+
# Use centralized image selection logic (fallback to 3.12 for test consistency)
299+
return get_ray_image_for_python_version(warn_on_unsupported=True)
299300

300301

301302
def get_template_variables():
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# Copyright 2025 IBM, Red Hat
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
from codeflare_sdk.common.utils.constants import (
16+
SUPPORTED_PYTHON_VERSIONS,
17+
CUDA_PY312_RUNTIME_IMAGE,
18+
)
19+
20+
21+
def get_ray_image_for_python_version(python_version=None, warn_on_unsupported=True):
22+
"""
23+
Get the appropriate Ray image for a given Python version.
24+
If no version is provided, uses the current runtime Python version.
25+
This prevents us needing to hard code image versions for tests.
26+
27+
Args:
28+
python_version: Python version string (e.g. "3.11"). If None, detects current version.
29+
warn_on_unsupported: If True, warns and returns None for unsupported versions.
30+
If False, silently falls back to Python 3.12 image.
31+
"""
32+
if python_version is None:
33+
import sys
34+
35+
python_version = f"{sys.version_info.major}.{sys.version_info.minor}"
36+
37+
if python_version in SUPPORTED_PYTHON_VERSIONS:
38+
return SUPPORTED_PYTHON_VERSIONS[python_version]
39+
elif warn_on_unsupported:
40+
import warnings
41+
42+
warnings.warn(
43+
f"No default Ray image defined for {python_version}. Please provide your own image or use one of the following python versions: {', '.join(SUPPORTED_PYTHON_VERSIONS.keys())}."
44+
)
45+
return None
46+
else:
47+
return CUDA_PY312_RUNTIME_IMAGE

src/codeflare_sdk/ray/cluster/build_ray_cluster.py

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
from ...common.kubernetes_cluster import get_api_client, config_check
2222
from kubernetes.client.exceptions import ApiException
2323
from ...common.utils.constants import RAY_VERSION
24+
from ...common.utils.utils import get_ray_image_for_python_version
2425
import codeflare_sdk
2526
import os
2627

@@ -95,10 +96,8 @@
9596
),
9697
]
9798

98-
SUPPORTED_PYTHON_VERSIONS = {
99-
"3.11": constants.CUDA_PY311_RUNTIME_IMAGE,
100-
"3.12": constants.CUDA_PY312_RUNTIME_IMAGE,
101-
}
99+
# Use centralized mapping from constants (so that we only have to update constants.py)
100+
SUPPORTED_PYTHON_VERSIONS = constants.SUPPORTED_PYTHON_VERSIONS
102101

103102

104103
# RayCluster/AppWrapper builder function
@@ -273,16 +272,11 @@ def with_nb_annotations(annotations: dict):
273272
def update_image(image) -> str:
274273
"""
275274
The update_image() function automatically sets the image config parameter to a preset image based on Python version if not specified.
276-
If no Ray image exists for the given Python version a warning is produced.
275+
This now points to the centralized function in utils.py.
277276
"""
278277
if not image:
279-
python_version = f"{sys.version_info.major}.{sys.version_info.minor}"
280-
if python_version in SUPPORTED_PYTHON_VERSIONS:
281-
image = SUPPORTED_PYTHON_VERSIONS[python_version]
282-
else:
283-
warnings.warn(
284-
f"No default Ray image defined for {python_version}. Please provide your own image or use one of the following python versions: {', '.join(SUPPORTED_PYTHON_VERSIONS.keys())}."
285-
)
278+
# Pull the image based on the matching Python version (or output a warning if not supported)
279+
image = get_ray_image_for_python_version(warn_on_unsupported=True)
286280
return image
287281

288282

src/codeflare_sdk/ray/cluster/test_build_ray_cluster.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ def test_update_image_without_supported_python_version(mocker):
4343
"codeflare_sdk.ray.cluster.build_ray_cluster.SUPPORTED_PYTHON_VERSIONS",
4444
{
4545
"3.11": "ray-py3.11",
46+
"3.12": "ray-py3.12",
4647
},
4748
)
4849

@@ -60,7 +61,7 @@ def test_update_image_without_supported_python_version(mocker):
6061

6162
# Assert that the warning was called with the expected message
6263
warn_mock.assert_called_once_with(
63-
"No default Ray image defined for 3.8. Please provide your own image or use one of the following python versions: 3.11."
64+
"No default Ray image defined for 3.8. Please provide your own image or use one of the following python versions: 3.11, 3.12."
6465
)
6566

6667
# Assert that no image was set since the Python version is not supported

tests/e2e/support.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,10 @@ def get_ray_cluster(cluster_name, namespace):
2727

2828

2929
def get_ray_image():
30-
return os.getenv("RAY_IMAGE", constants.CUDA_RUNTIME_IMAGE)
30+
return os.getenv(
31+
"RAY_IMAGE",
32+
constants.get_ray_image_for_python_version(warn_on_unsupported=False),
33+
)
3134

3235

3336
def get_setup_env_variables(**kwargs):

0 commit comments

Comments
 (0)