@@ -549,3 +549,101 @@ def foo(x: int) -> int:
549
549
finally :
550
550
# Clean up the gcp assets created for the managed function.
551
551
cleanup_function_assets (foo , session .bqclient , ignore_failures = False )
552
+
553
+
554
+ def test_managed_function_options (session , dataset_id , scalars_dfs ):
555
+ try :
556
+
557
+ def multiply_five (x : int ) -> int :
558
+ return x * 5
559
+
560
+ mf_multiply_five = session .udf (
561
+ dataset = dataset_id ,
562
+ name = prefixer .create_prefix (),
563
+ max_batching_rows = 100 ,
564
+ container_cpu = 2 ,
565
+ container_memory = "2Gi" ,
566
+ )(multiply_five )
567
+
568
+ scalars_df , scalars_pandas_df = scalars_dfs
569
+
570
+ bf_int64_df = scalars_df ["int64_col" ]
571
+ bf_int64_df_filtered = bf_int64_df .dropna ()
572
+ bf_result = bf_int64_df_filtered .apply (mf_multiply_five ).to_pandas ()
573
+
574
+ pd_int64_df = scalars_pandas_df ["int64_col" ]
575
+ pd_int64_df_filtered = pd_int64_df .dropna ()
576
+ pd_result = pd_int64_df_filtered .apply (multiply_five )
577
+
578
+ pandas .testing .assert_series_equal (bf_result , pd_result , check_dtype = False )
579
+
580
+ # Make sure the read_gbq_function path works for this function.
581
+ multiply_five_ref = session .read_gbq_function (
582
+ function_name = mf_multiply_five .bigframes_bigquery_function , # type: ignore
583
+ )
584
+ assert mf_multiply_five .bigframes_bigquery_function == multiply_five_ref .bigframes_bigquery_function # type: ignore
585
+
586
+ bf_result = bf_int64_df_filtered .apply (multiply_five_ref ).to_pandas ()
587
+ pandas .testing .assert_series_equal (bf_result , pd_result , check_dtype = False )
588
+
589
+ # Retrieve the routine and validate its runtime configuration.
590
+ routine = session .bqclient .get_routine (
591
+ mf_multiply_five .bigframes_bigquery_function
592
+ )
593
+
594
+ # TODO(jialuo): Use the newly exposed class properties instead of
595
+ # accessing the hidden _properties after resolve of this issue:
596
+ # https://github.com/googleapis/python-bigquery/issues/2240.
597
+ assert routine ._properties ["externalRuntimeOptions" ]["maxBatchingRows" ] == "100"
598
+ assert routine ._properties ["externalRuntimeOptions" ]["containerCpu" ] == 2
599
+ assert routine ._properties ["externalRuntimeOptions" ]["containerMemory" ] == "2Gi"
600
+
601
+ finally :
602
+ # Clean up the gcp assets created for the managed function.
603
+ cleanup_function_assets (
604
+ mf_multiply_five , session .bqclient , ignore_failures = False
605
+ )
606
+
607
+
608
+ def test_managed_function_options_errors (session , dataset_id ):
609
+ def foo (x : int ) -> int :
610
+ return 0
611
+
612
+ with pytest .raises (
613
+ google .api_core .exceptions .BadRequest ,
614
+ # For CPU Value >= 1.0, the value must be one of [1, 2, ...].
615
+ match = "Invalid container_cpu function OPTIONS value" ,
616
+ ):
617
+ session .udf (
618
+ dataset = dataset_id ,
619
+ name = prefixer .create_prefix (),
620
+ max_batching_rows = 100 ,
621
+ container_cpu = 2.5 ,
622
+ container_memory = "2Gi" ,
623
+ )(foo )
624
+
625
+ with pytest .raises (
626
+ google .api_core .exceptions .BadRequest ,
627
+ # For less than 1.0 CPU, the value must be no less than 0.33.
628
+ match = "Invalid container_cpu function OPTIONS value" ,
629
+ ):
630
+ session .udf (
631
+ dataset = dataset_id ,
632
+ name = prefixer .create_prefix (),
633
+ max_batching_rows = 100 ,
634
+ container_cpu = 0.10 ,
635
+ container_memory = "512Mi" ,
636
+ )(foo )
637
+
638
+ with pytest .raises (
639
+ google .api_core .exceptions .BadRequest ,
640
+ # For 2.00 CPU, the memory must be in the range of [256Mi, 8Gi].
641
+ match = "Invalid container_memory function OPTIONS value" ,
642
+ ):
643
+ session .udf (
644
+ dataset = dataset_id ,
645
+ name = prefixer .create_prefix (),
646
+ max_batching_rows = 100 ,
647
+ container_cpu = 2 ,
648
+ container_memory = "64Mi" ,
649
+ )(foo )
0 commit comments