Skip to content

Commit 9e471fb

Browse files
authored
test: target e2e tests to python 3.11 for max coverage (#1474)
* test: target e2e tests to python 3.12 for max coverage * ensure large udf tests are run without skip * remove pytest.mark.skip from one more test * adjust the expect warnings in the ingress settings and service account * fix mypy * remove version 1.x check to surface 2.0 future warning
1 parent 0ddee99 commit 9e471fb

File tree

4 files changed

+68
-48
lines changed

4 files changed

+68
-48
lines changed

bigframes/functions/_function_session.py

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@
4747
)
4848

4949
from bigframes import clients
50-
from bigframes import version as bigframes_version
5150
import bigframes.core.compile.ibis_types
5251
import bigframes.exceptions as bfe
5352
import bigframes.series as bf_series
@@ -458,16 +457,13 @@ def remote_function(
458457
msg = bfe.format_message(
459458
"You have not explicitly set a user-managed `cloud_function_service_account`. "
460459
"Using the default Compute Engine service account. "
461-
"To use Bigframes 2.0, please explicitly set `cloud_function_service_account` "
460+
"In BigFrames 2.0 onwards, you would have to explicitly set `cloud_function_service_account` "
462461
'either to a user-managed service account (preferred) or to `"default"` '
463-
"to use the Compute Engine service account (discouraged). "
462+
"to use the default Compute Engine service account (discouraged). "
464463
"See, https://cloud.google.com/functions/docs/securing/function-identity."
465464
)
466465

467-
if (
468-
bigframes_version.__version__.startswith("1.")
469-
and cloud_function_service_account is None
470-
):
466+
if cloud_function_service_account is None:
471467
warnings.warn(msg, stacklevel=2, category=FutureWarning)
472468

473469
if cloud_function_service_account == "default":

noxfile.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,12 @@
5959

6060
DEFAULT_PYTHON_VERSION = "3.10"
6161

62+
# Cloud Run Functions supports Python versions up to 3.12
63+
# https://cloud.google.com/run/docs/runtimes/python
64+
# Managed Python UDF is supported only in Python 3.11
65+
# Let's set the E2E tests version to 3.11 to cover most code paths.
66+
E2E_TEST_PYTHON_VERSION = "3.11"
67+
6268
UNIT_TEST_PYTHON_VERSIONS = ["3.9", "3.10", "3.11", "3.12", "3.13"]
6369
UNIT_TEST_STANDARD_DEPENDENCIES = [
6470
"mock",
@@ -418,7 +424,7 @@ def doctest(session: nox.sessions.Session):
418424
)
419425

420426

421-
@nox.session(python=SYSTEM_TEST_PYTHON_VERSIONS[-1])
427+
@nox.session(python=E2E_TEST_PYTHON_VERSION)
422428
def e2e(session: nox.sessions.Session):
423429
"""Run the large tests in system test suite."""
424430
run_system(

tests/system/large/functions/test_managed_function.py

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,6 @@
2525
bpd.options.experiments.udf = True
2626

2727

28-
@pytest.mark.skipif(
29-
get_python_version() not in bff_session._MANAGED_FUNC_PYTHON_VERSIONS,
30-
reason=f"Supported version: {bff_session._MANAGED_FUNC_PYTHON_VERSIONS}",
31-
)
3228
def test_managed_function_multiply_with_ibis(
3329
session,
3430
scalars_table_id,
@@ -80,10 +76,6 @@ def multiply(x, y):
8076
cleanup_function_assets(multiply, bigquery_client)
8177

8278

83-
@pytest.mark.skipif(
84-
get_python_version() not in bff_session._MANAGED_FUNC_PYTHON_VERSIONS,
85-
reason=f"Supported version: {bff_session._MANAGED_FUNC_PYTHON_VERSIONS}",
86-
)
8779
def test_managed_function_stringify_with_ibis(
8880
session,
8981
scalars_table_id,
@@ -132,10 +124,6 @@ def stringify(x):
132124
)
133125

134126

135-
@pytest.mark.skipif(
136-
get_python_version() not in bff_session._MANAGED_FUNC_PYTHON_VERSIONS,
137-
reason=f"Supported version: {bff_session._MANAGED_FUNC_PYTHON_VERSIONS}",
138-
)
139127
def test_managed_function_binop(session, scalars_dfs, dataset_id):
140128
try:
141129

tests/system/large/functions/test_remote_function.py

Lines changed: 58 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,11 @@
1717
import inspect
1818
import math # must keep this at top level to test udf referring global import
1919
import os.path
20+
import re
2021
import shutil
21-
import sys
2222
import tempfile
2323
import textwrap
24+
import typing
2425
import warnings
2526

2627
import google.api_core.exceptions
@@ -50,12 +51,6 @@
5051
_team_euler = "Team Euler"
5152

5253

53-
pytestmark = pytest.mark.skipif(
54-
sys.version_info >= (3, 13),
55-
reason="Runtime 'python313' is not supported yet. Skip for now.",
56-
)
57-
58-
5954
def make_uniq_udf(udf):
6055
"""Transform a udf to another with same behavior but a unique name.
6156
Use this to test remote functions with reuse=True, in which case parallel
@@ -1323,14 +1318,38 @@ def square_num(x):
13231318
)
13241319

13251320

1326-
def test_remote_function_warns_default_cloud_function_service_account():
1327-
project = "bigframes-dev-perf"
1328-
rf_session = bigframes.Session(context=bigframes.BigQueryOptions(project=project))
1329-
1330-
with pytest.warns(FutureWarning, match="You have not explicitly set a"):
1331-
rf_session.remote_function(
1332-
cloud_function_service_account=None, # Explicitly omit service account.
1333-
)
1321+
@pytest.mark.parametrize(
1322+
("remote_function_args"),
1323+
[
1324+
pytest.param(
1325+
{},
1326+
id="no-set",
1327+
),
1328+
pytest.param(
1329+
{"cloud_function_service_account": None},
1330+
id="set-none",
1331+
),
1332+
],
1333+
)
1334+
def test_remote_function_warns_default_cloud_function_service_account(
1335+
session, remote_function_args
1336+
):
1337+
with pytest.warns(FutureWarning) as record:
1338+
session.remote_function(**remote_function_args)
1339+
1340+
len(
1341+
[
1342+
warn
1343+
for warn in record
1344+
if re.search(
1345+
(
1346+
"You have not explicitly set a user-managed.*Using the default Compute Engine.*service account"
1347+
),
1348+
typing.cast(FutureWarning, warn.message).args[0],
1349+
re.DOTALL,
1350+
)
1351+
]
1352+
) == 1
13341353

13351354

13361355
@pytest.mark.flaky(retries=2, delay=120)
@@ -2319,36 +2338,40 @@ def generate_stats(row: pandas.Series) -> list[int]:
23192338

23202339

23212340
@pytest.mark.parametrize(
2322-
("ingress_settings_args", "effective_ingress_settings", "expected_warning"),
2341+
(
2342+
"ingress_settings_args",
2343+
"effective_ingress_settings",
2344+
"expect_default_ingress_setting_warning",
2345+
),
23232346
[
23242347
pytest.param(
23252348
{},
23262349
functions_v2.ServiceConfig.IngressSettings.ALLOW_ALL,
2327-
FutureWarning,
2350+
True,
23282351
id="no-set",
23292352
),
23302353
pytest.param(
23312354
{"cloud_function_ingress_settings": None},
23322355
functions_v2.ServiceConfig.IngressSettings.ALLOW_ALL,
2333-
FutureWarning,
2356+
True,
23342357
id="set-none",
23352358
),
23362359
pytest.param(
23372360
{"cloud_function_ingress_settings": "all"},
23382361
functions_v2.ServiceConfig.IngressSettings.ALLOW_ALL,
2339-
None,
2362+
False,
23402363
id="set-all",
23412364
),
23422365
pytest.param(
23432366
{"cloud_function_ingress_settings": "internal-only"},
23442367
functions_v2.ServiceConfig.IngressSettings.ALLOW_INTERNAL_ONLY,
2345-
None,
2368+
False,
23462369
id="set-internal-only",
23472370
),
23482371
pytest.param(
23492372
{"cloud_function_ingress_settings": "internal-and-gclb"},
23502373
functions_v2.ServiceConfig.IngressSettings.ALLOW_INTERNAL_AND_GCLB,
2351-
None,
2374+
False,
23522375
id="set-internal-and-gclb",
23532376
),
23542377
],
@@ -2359,11 +2382,11 @@ def test_remote_function_ingress_settings(
23592382
scalars_dfs,
23602383
ingress_settings_args,
23612384
effective_ingress_settings,
2362-
expected_warning,
2385+
expect_default_ingress_setting_warning,
23632386
):
23642387
try:
23652388
# Verify the function raises the expected security warning message.
2366-
with warnings.catch_warnings(record=True) as w:
2389+
with warnings.catch_warnings(record=True) as record:
23672390

23682391
def square(x: int) -> int:
23692392
return x * x
@@ -2372,11 +2395,18 @@ def square(x: int) -> int:
23722395
reuse=False, **ingress_settings_args
23732396
)(square)
23742397

2375-
if expected_warning is not None:
2376-
assert issubclass(w[0].category, FutureWarning)
2377-
assert "Consider using 'internal-only' for enhanced security." in str(
2378-
w[0].message
2379-
)
2398+
default_ingress_setting_warnings = [
2399+
warn
2400+
for warn in record
2401+
if isinstance(warn.message, FutureWarning)
2402+
and "`cloud_function_ingress_settings` are set to 'all' by default"
2403+
in warn.message.args[0]
2404+
and "will change to 'internal-only' for enhanced security in future"
2405+
in warn.message.args[0]
2406+
]
2407+
assert len(default_ingress_setting_warnings) == (
2408+
1 if expect_default_ingress_setting_warning else 0
2409+
)
23802410

23812411
# Assert that the GCF is created with the intended maximum timeout
23822412
gcf = session.cloudfunctionsclient.get_function(

0 commit comments

Comments
 (0)