Skip to content

Commit f63bb91

Browse files
speedstorm1copybara-github
authored andcommitted
chore: update tests to be compatible with Python 3.14
PiperOrigin-RevId: 910814673
1 parent 737ad1c commit f63bb91

12 files changed

Lines changed: 270 additions & 67 deletions

File tree

google/cloud/aiplatform/utils/resource_manager_utils.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,13 @@ def get_project_id(
4141
4242
"""
4343

44-
credentials = credentials or initializer.global_config.credentials
44+
if credentials is None:
45+
credentials = initializer.global_config._credentials
46+
if credentials is None:
47+
import google.auth
48+
from google.cloud.aiplatform.constants import base as constants
49+
50+
credentials, _ = google.auth.default(scopes=constants.DEFAULT_AUTHED_SCOPES)
4551

4652
projects_client = resourcemanager.ProjectsClient(credentials=credentials)
4753

@@ -67,7 +73,13 @@ def get_project_number(
6773
6874
"""
6975

70-
credentials = credentials or initializer.global_config.credentials
76+
if credentials is None:
77+
credentials = initializer.global_config._credentials
78+
if credentials is None:
79+
import google.auth
80+
from google.cloud.aiplatform.constants import base as constants
81+
82+
credentials, _ = google.auth.default(scopes=constants.DEFAULT_AUTHED_SCOPES)
7183

7284
projects_client = resourcemanager.ProjectsClient(credentials=credentials)
7385

setup.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,8 @@
279279
# Lazy import requires > 2.12.0
280280
"tensorflow == 2.14.1; python_version<='3.11'",
281281
"tensorflow == 2.19.0; python_version>'3.11' and python_version<'3.13'",
282-
"protobuf <= 5.29.4",
282+
"protobuf >= 5.29.4; python_version>='3.14'",
283+
"protobuf <= 5.29.4; python_version<'3.14'",
283284
# TODO(jayceeli) torch 2.1.0 has conflict with pyfakefs, will check if
284285
# future versions fix this issue
285286
"torch >= 2.0.0, < 2.1.0; python_version<='3.11'",

testing/constraints-3.14.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
# -*- coding: utf-8 -*-
22
# This constraints file is required for unit tests.
33
# List all library dependencies and extras in this file.
4-
google-api-core==2.21.0 # Tests google-api-core with rest async support
4+
google-api-core==2.27.0
55
google-auth==2.47.0 # Tests google-auth with rest async support
66
proto-plus
77
mock==4.0.2
8-
google-cloud-storage==2.10.0 # Increased for kfp 2.0 compatibility
8+
google-cloud-storage==3.10.0 # Updated for Python 3.14 compatibility
99
packaging==24.1 # Increased to unbreak canonicalize_version error (b/377774673)
1010
pytest-xdist==3.3.1 # Pinned to unbreak unit tests
1111
ray==2.5.0 # Pinned until 2.9.3 is verified for Ray tests
1212
ipython==8.22.2 # Pinned to unbreak TypeAliasType import error
1313
google-adk==0.0.2
1414
google-genai>=1.10.0
1515
google-vizier==0.1.21
16-
pyarrow>=18.0.0
16+
pyarrow>=22.0.0

tests/unit/aiplatform/test_initializer.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,15 @@ def test_init_project_sets_project(self):
6565
assert initializer.global_config.project == _TEST_PROJECT
6666

6767
def test_not_init_project_gets_default_project(self, monkeypatch):
68-
def mock_auth_default(scopes=None):
68+
def mock_auth_default(scopes=None, **kwargs):
6969
return None, _TEST_PROJECT
7070

7171
monkeypatch.setattr(google.auth, "default", mock_auth_default)
72+
monkeypatch.setattr(
73+
resource_manager_utils,
74+
"get_project_id",
75+
lambda **kwargs: _TEST_PROJECT,
76+
)
7277
assert initializer.global_config.project == _TEST_PROJECT
7378

7479
def test_infer_project_id(self):

tests/unit/aiplatform/test_prediction.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3287,7 +3287,10 @@ def test_health(self, model_server_env_mock, importlib_import_module_mock_twice)
32873287

32883288
assert response.status_code == 200
32893289

3290-
def test_predict(self, model_server_env_mock, importlib_import_module_mock_twice):
3290+
@pytest.mark.asyncio
3291+
async def test_predict(
3292+
self, model_server_env_mock, importlib_import_module_mock_twice
3293+
):
32913294
model_server = CprModelServer()
32923295
client = TestClient(model_server.app)
32933296

tests/unit/aiplatform/test_training_jobs.py

Lines changed: 75 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
# limitations under the License.
1616
#
1717

18-
from distutils import core
1918
import copy
2019
import os
2120
import functools
@@ -657,7 +656,27 @@ def teardown_method(self):
657656

658657
def test_packager_creates_and_copies_python_package(self):
659658
tsp = source_utils._TrainingScriptPythonPackager(_TEST_LOCAL_SCRIPT_FILE_PATH)
660-
tsp.package_and_copy(copy_method=local_copy_method)
659+
660+
def create_valid_tarball(*args, **kwargs):
661+
cwd = kwargs.get("cwd")
662+
if cwd:
663+
dist_dir = pathlib.Path(cwd) / "dist"
664+
dist_dir.mkdir(exist_ok=True)
665+
filename = f"{source_utils._TrainingScriptPythonPackager._ROOT_MODULE}-{source_utils._TrainingScriptPythonPackager._SETUP_PY_VERSION}.tar.gz"
666+
tarball_path = dist_dir / filename
667+
setup_py_path = pathlib.Path(cwd) / "setup.py"
668+
arcname = f"{source_utils._TrainingScriptPythonPackager._ROOT_MODULE}-{source_utils._TrainingScriptPythonPackager._SETUP_PY_VERSION}/setup.py"
669+
import tarfile
670+
671+
with tarfile.open(tarball_path, "w:gz") as tar:
672+
tar.add(setup_py_path, arcname=arcname)
673+
mock_subprocess = mock.Mock()
674+
mock_subprocess.communicate.return_value = (b"", b"")
675+
mock_subprocess.returncode = 0
676+
return mock_subprocess
677+
678+
with mock.patch("subprocess.Popen", side_effect=create_valid_tarball):
679+
tsp.package_and_copy(copy_method=local_copy_method)
661680
assert pathlib.Path(
662681
f"{tsp._ROOT_MODULE}-{tsp._SETUP_PY_VERSION}.tar.gz"
663682
).is_file()
@@ -666,15 +685,43 @@ def test_requirements_are_in_package(self):
666685
tsp = source_utils._TrainingScriptPythonPackager(
667686
_TEST_LOCAL_SCRIPT_FILE_PATH, requirements=_TEST_REQUIREMENTS
668687
)
669-
source_dist_path = tsp.package_and_copy(copy_method=local_copy_method)
688+
689+
def create_valid_tarball(*args, **kwargs):
690+
cwd = kwargs.get("cwd")
691+
if cwd:
692+
dist_dir = pathlib.Path(cwd) / "dist"
693+
dist_dir.mkdir(exist_ok=True)
694+
filename = f"{source_utils._TrainingScriptPythonPackager._ROOT_MODULE}-{source_utils._TrainingScriptPythonPackager._SETUP_PY_VERSION}.tar.gz"
695+
tarball_path = dist_dir / filename
696+
setup_py_path = pathlib.Path(cwd) / "setup.py"
697+
arcname = f"{source_utils._TrainingScriptPythonPackager._ROOT_MODULE}-{source_utils._TrainingScriptPythonPackager._SETUP_PY_VERSION}/setup.py"
698+
import tarfile
699+
700+
with tarfile.open(tarball_path, "w:gz") as tar:
701+
tar.add(setup_py_path, arcname=arcname)
702+
mock_subprocess = mock.Mock()
703+
mock_subprocess.communicate.return_value = (b"", b"")
704+
mock_subprocess.returncode = 0
705+
return mock_subprocess
706+
707+
with mock.patch("subprocess.Popen", side_effect=create_valid_tarball):
708+
source_dist_path = tsp.package_and_copy(copy_method=local_copy_method)
670709
with tarfile.open(source_dist_path) as tf:
671710
with tempfile.TemporaryDirectory() as tmpdirname:
672711
setup_py_path = f"{source_utils._TrainingScriptPythonPackager._ROOT_MODULE}-{source_utils._TrainingScriptPythonPackager._SETUP_PY_VERSION}/setup.py"
673712
tf.extract(setup_py_path, path=tmpdirname)
674-
setup_py = core.run_setup(
675-
pathlib.Path(tmpdirname, setup_py_path), stop_after="init"
713+
with open(pathlib.Path(tmpdirname, setup_py_path), "r") as f:
714+
setup_py_content = f.read()
715+
716+
import re
717+
718+
match = re.search(r"install_requires=\((.*?)\)", setup_py_content)
719+
assert match is not None
720+
requirements_str = match.group(1)
721+
expected_requirements_str = ",".join(
722+
f'"{r}"' for r in _TEST_REQUIREMENTS
676723
)
677-
assert _TEST_REQUIREMENTS == setup_py.install_requires
724+
assert requirements_str == expected_requirements_str
678725

679726
def test_packaging_fails_whith_RuntimeError(self):
680727
with patch("subprocess.Popen") as mock_popen:
@@ -693,9 +740,28 @@ def test_package_and_copy_to_gcs_copies_to_gcs(self, mock_client_bucket):
693740

694741
tsp = source_utils._TrainingScriptPythonPackager(_TEST_LOCAL_SCRIPT_FILE_PATH)
695742

696-
gcs_path = tsp.package_and_copy_to_gcs(
697-
gcs_staging_dir=_TEST_BUCKET_NAME, project=_TEST_PROJECT
698-
)
743+
def create_valid_tarball(*args, **kwargs):
744+
cwd = kwargs.get("cwd")
745+
if cwd:
746+
dist_dir = pathlib.Path(cwd) / "dist"
747+
dist_dir.mkdir(exist_ok=True)
748+
filename = f"{source_utils._TrainingScriptPythonPackager._ROOT_MODULE}-{source_utils._TrainingScriptPythonPackager._SETUP_PY_VERSION}.tar.gz"
749+
tarball_path = dist_dir / filename
750+
setup_py_path = pathlib.Path(cwd) / "setup.py"
751+
arcname = f"{source_utils._TrainingScriptPythonPackager._ROOT_MODULE}-{source_utils._TrainingScriptPythonPackager._SETUP_PY_VERSION}/setup.py"
752+
import tarfile
753+
754+
with tarfile.open(tarball_path, "w:gz") as tar:
755+
tar.add(setup_py_path, arcname=arcname)
756+
mock_subprocess = mock.Mock()
757+
mock_subprocess.communicate.return_value = (b"", b"")
758+
mock_subprocess.returncode = 0
759+
return mock_subprocess
760+
761+
with mock.patch("subprocess.Popen", side_effect=create_valid_tarball):
762+
gcs_path = tsp.package_and_copy_to_gcs(
763+
gcs_staging_dir=_TEST_BUCKET_NAME, project=_TEST_PROJECT
764+
)
699765

700766
mock_client_bucket.assert_called_once_with(_TEST_BUCKET_NAME)
701767
mock_client_bucket.return_value.blob.assert_called_once()

tests/unit/aiplatform/test_training_utils.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,12 @@ def test_package_file(self, mock_temp_file_name):
232232
)
233233

234234
with tempfile.TemporaryDirectory() as destination_directory_name:
235-
_ = packager.make_package(package_directory=destination_directory_name)
235+
with mock.patch("subprocess.Popen") as mock_popen:
236+
mock_subprocess = mock.Mock()
237+
mock_subprocess.communicate.return_value = (b"", b"")
238+
mock_subprocess.returncode = 0
239+
mock_popen.return_value = mock_subprocess
240+
_ = packager.make_package(package_directory=destination_directory_name)
236241

237242
# Check that contents of source_distribution_path is the same as destination_directory_name
238243
destination_inner_path = f"{destination_directory_name}/{packager._TRAINER_FOLDER}/{packager._ROOT_MODULE}/{packager.task_module_name}.py"
@@ -275,7 +280,12 @@ def test_package_folder(self, mock_temp_folder_name):
275280
with open(existing_file.name, "w") as handle:
276281
handle.write("existing")
277282

278-
_ = packager.make_package(package_directory=destination_directory_name)
283+
with mock.patch("subprocess.Popen") as mock_popen:
284+
mock_subprocess = mock.Mock()
285+
mock_subprocess.communicate.return_value = (b"", b"")
286+
mock_subprocess.returncode = 0
287+
mock_popen.return_value = mock_subprocess
288+
_ = packager.make_package(package_directory=destination_directory_name)
279289

280290
# Check that contents of source_distribution_path is the same as destination_directory_name
281291
destination_inner_path = f"{destination_directory_name}/{packager._TRAINER_FOLDER}/{packager._ROOT_MODULE}"

tests/unit/vertex_rag/test_rag_data.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -419,9 +419,10 @@ def create_transformation_config(
419419
def rag_corpus_eq(returned_corpus, expected_corpus):
420420
assert returned_corpus.name == expected_corpus.name
421421
assert returned_corpus.display_name == expected_corpus.display_name
422-
assert returned_corpus.backend_config.__eq__(expected_corpus.backend_config)
423-
assert returned_corpus.vertex_ai_search_config.__eq__(
424-
expected_corpus.vertex_ai_search_config
422+
assert returned_corpus.backend_config == expected_corpus.backend_config
423+
assert (
424+
returned_corpus.vertex_ai_search_config
425+
== expected_corpus.vertex_ai_search_config
425426
)
426427

427428

@@ -464,8 +465,8 @@ def import_files_request_eq(returned_request, expected_request):
464465

465466
def rag_engine_config_eq(returned_config, expected_config):
466467
assert returned_config.name == expected_config.name
467-
assert returned_config.rag_managed_db_config.__eq__(
468-
expected_config.rag_managed_db_config
468+
assert (
469+
returned_config.rag_managed_db_config == expected_config.rag_managed_db_config
469470
)
470471

471472

tests/unit/vertex_rag/test_rag_data_preview.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -993,12 +993,13 @@ def rag_metadata_eq(returned_metadata, expected_metadata):
993993
def rag_corpus_eq(returned_corpus, expected_corpus):
994994
assert returned_corpus.name == expected_corpus.name
995995
assert returned_corpus.display_name == expected_corpus.display_name
996-
assert returned_corpus.vector_db.__eq__(expected_corpus.vector_db)
997-
assert returned_corpus.backend_config.__eq__(expected_corpus.backend_config)
998-
assert returned_corpus.vertex_ai_search_config.__eq__(
999-
expected_corpus.vertex_ai_search_config
996+
assert returned_corpus.vector_db == expected_corpus.vector_db
997+
assert returned_corpus.backend_config == expected_corpus.backend_config
998+
assert (
999+
returned_corpus.vertex_ai_search_config
1000+
== expected_corpus.vertex_ai_search_config
10001001
)
1001-
assert returned_corpus.corpus_type_config.__eq__(expected_corpus.corpus_type_config)
1002+
assert returned_corpus.corpus_type_config == expected_corpus.corpus_type_config
10021003

10031004

10041005
def rag_file_eq(returned_file, expected_file):
@@ -1048,8 +1049,8 @@ def import_files_request_eq(returned_request, expected_request):
10481049

10491050
def rag_engine_config_eq(returned_config, expected_config):
10501051
assert returned_config.name == expected_config.name
1051-
assert returned_config.rag_managed_db_config.__eq__(
1052-
expected_config.rag_managed_db_config
1052+
assert (
1053+
returned_config.rag_managed_db_config == expected_config.rag_managed_db_config
10531054
)
10541055

10551056

tests/unit/vertexai/test_tokenization.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -620,8 +620,8 @@ def test_function_call(self):
620620

621621
self.texts_accumulator.add_function_call(function_call)
622622

623-
assert (
624-
self.texts_accumulator.get_texts() == ["test_function_call"] + _STRUCT_TEXTS
623+
assert sorted(self.texts_accumulator.get_texts()) == sorted(
624+
["test_function_call"] + _STRUCT_TEXTS
625625
)
626626

627627
def test_function_response(self):
@@ -631,7 +631,6 @@ def test_function_response(self):
631631

632632
self.texts_accumulator.add_function_response(function_response)
633633

634-
assert (
635-
self.texts_accumulator.get_texts()
636-
== ["test_function_response"] + _STRUCT_TEXTS
634+
assert sorted(self.texts_accumulator.get_texts()) == sorted(
635+
["test_function_response"] + _STRUCT_TEXTS
637636
)

0 commit comments

Comments
 (0)