17
17
import inspect
18
18
import math # must keep this at top level to test udf referring global import
19
19
import os .path
20
+ import re
20
21
import shutil
21
- import sys
22
22
import tempfile
23
23
import textwrap
24
+ import typing
24
25
import warnings
25
26
26
27
import google .api_core .exceptions
50
51
_team_euler = "Team Euler"
51
52
52
53
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
-
59
54
def make_uniq_udf (udf ):
60
55
"""Transform a udf to another with same behavior but a unique name.
61
56
Use this to test remote functions with reuse=True, in which case parallel
@@ -1323,14 +1318,38 @@ def square_num(x):
1323
1318
)
1324
1319
1325
1320
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
1334
1353
1335
1354
1336
1355
@pytest .mark .flaky (retries = 2 , delay = 120 )
@@ -2319,36 +2338,40 @@ def generate_stats(row: pandas.Series) -> list[int]:
2319
2338
2320
2339
2321
2340
@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
+ ),
2323
2346
[
2324
2347
pytest .param (
2325
2348
{},
2326
2349
functions_v2 .ServiceConfig .IngressSettings .ALLOW_ALL ,
2327
- FutureWarning ,
2350
+ True ,
2328
2351
id = "no-set" ,
2329
2352
),
2330
2353
pytest .param (
2331
2354
{"cloud_function_ingress_settings" : None },
2332
2355
functions_v2 .ServiceConfig .IngressSettings .ALLOW_ALL ,
2333
- FutureWarning ,
2356
+ True ,
2334
2357
id = "set-none" ,
2335
2358
),
2336
2359
pytest .param (
2337
2360
{"cloud_function_ingress_settings" : "all" },
2338
2361
functions_v2 .ServiceConfig .IngressSettings .ALLOW_ALL ,
2339
- None ,
2362
+ False ,
2340
2363
id = "set-all" ,
2341
2364
),
2342
2365
pytest .param (
2343
2366
{"cloud_function_ingress_settings" : "internal-only" },
2344
2367
functions_v2 .ServiceConfig .IngressSettings .ALLOW_INTERNAL_ONLY ,
2345
- None ,
2368
+ False ,
2346
2369
id = "set-internal-only" ,
2347
2370
),
2348
2371
pytest .param (
2349
2372
{"cloud_function_ingress_settings" : "internal-and-gclb" },
2350
2373
functions_v2 .ServiceConfig .IngressSettings .ALLOW_INTERNAL_AND_GCLB ,
2351
- None ,
2374
+ False ,
2352
2375
id = "set-internal-and-gclb" ,
2353
2376
),
2354
2377
],
@@ -2359,11 +2382,11 @@ def test_remote_function_ingress_settings(
2359
2382
scalars_dfs ,
2360
2383
ingress_settings_args ,
2361
2384
effective_ingress_settings ,
2362
- expected_warning ,
2385
+ expect_default_ingress_setting_warning ,
2363
2386
):
2364
2387
try :
2365
2388
# 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 :
2367
2390
2368
2391
def square (x : int ) -> int :
2369
2392
return x * x
@@ -2372,11 +2395,18 @@ def square(x: int) -> int:
2372
2395
reuse = False , ** ingress_settings_args
2373
2396
)(square )
2374
2397
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
+ )
2380
2410
2381
2411
# Assert that the GCF is created with the intended maximum timeout
2382
2412
gcf = session .cloudfunctionsclient .get_function (
0 commit comments