@@ -585,6 +585,12 @@ def register_operations(self) -> Dict[str, List[str]]:
585
585
"pydantic" : ["pydantic" ],
586
586
}
587
587
588
+ _TEST_BUILD_OPTIONS_INSTALLATION = _agent_engines ._BUILD_OPTIONS_INSTALLATION
589
+ _TEST_INSTALLATION_SUBDIR = _utils ._INSTALLATION_SUBDIR
590
+ _TEST_INSTALLATION_SCRIPT_PATH = (
591
+ f"{ _TEST_INSTALLATION_SUBDIR } /install_package.sh"
592
+ )
593
+
588
594
589
595
def _create_empty_fake_package (package_name : str ) -> str :
590
596
"""Creates a temporary directory structure representing an empty fake Python package.
@@ -1147,6 +1153,49 @@ def test_create_agent_engine_with_env_vars_list(
1147
1153
retry = _TEST_RETRY ,
1148
1154
)
1149
1155
1156
+ def test_create_agent_engine_with_build_options (
1157
+ self ,
1158
+ create_agent_engine_mock ,
1159
+ cloud_storage_create_bucket_mock ,
1160
+ tarfile_open_mock ,
1161
+ cloudpickle_dump_mock ,
1162
+ cloudpickle_load_mock ,
1163
+ importlib_metadata_version_mock ,
1164
+ get_agent_engine_mock ,
1165
+ get_gca_resource_mock ,
1166
+ ):
1167
+
1168
+ with mock .patch ("os.path.exists" , return_value = True ):
1169
+ agent_engines .create (
1170
+ self .test_agent ,
1171
+ display_name = _TEST_AGENT_ENGINE_DISPLAY_NAME ,
1172
+ extra_packages = [
1173
+ _TEST_INSTALLATION_SCRIPT_PATH ,
1174
+ ],
1175
+ build_options = {
1176
+ _TEST_BUILD_OPTIONS_INSTALLATION : [
1177
+ _TEST_INSTALLATION_SCRIPT_PATH
1178
+ ]
1179
+ },
1180
+ )
1181
+ test_spec = types .ReasoningEngineSpec (
1182
+ package_spec = _TEST_AGENT_ENGINE_PACKAGE_SPEC ,
1183
+ agent_framework = _agent_engines ._DEFAULT_AGENT_FRAMEWORK ,
1184
+ )
1185
+ test_spec .class_methods .append (_TEST_AGENT_ENGINE_QUERY_SCHEMA )
1186
+ create_agent_engine_mock .assert_called_with (
1187
+ parent = _TEST_PARENT ,
1188
+ reasoning_engine = types .ReasoningEngine (
1189
+ display_name = _TEST_AGENT_ENGINE_DISPLAY_NAME ,
1190
+ spec = test_spec ,
1191
+ ),
1192
+ )
1193
+
1194
+ get_agent_engine_mock .assert_called_with (
1195
+ name = _TEST_AGENT_ENGINE_RESOURCE_NAME ,
1196
+ retry = _TEST_RETRY ,
1197
+ )
1198
+
1150
1199
# pytest does not allow absl.testing.parameterized.named_parameters.
1151
1200
@pytest .mark .parametrize (
1152
1201
"test_case_name, test_engine_instance, expected_framework" ,
@@ -2795,8 +2844,8 @@ def test_update_agent_engine_with_no_updates(
2795
2844
ValueError ,
2796
2845
match = (
2797
2846
"At least one of `agent_engine`, `requirements`, "
2798
- "`extra_packages`, `display_name`, `description`, or `env_vars` "
2799
- "must be specified."
2847
+ "`extra_packages`, `display_name`, `description`, "
2848
+ "`env_vars`, or `build_options` must be specified."
2800
2849
),
2801
2850
):
2802
2851
test_agent_engine = _generate_agent_engine_to_update ()
@@ -3227,3 +3276,124 @@ def test_scan_with_explicit_ignore_modules(self):
3227
3276
"cloudpickle" : "3.0.0" ,
3228
3277
"pydantic" : "1.11.1" ,
3229
3278
}
3279
+
3280
+
3281
+ class TestValidateInstallationScripts :
3282
+ @parameterized .named_parameters (
3283
+ dict (
3284
+ testcase_name = "valid_script_in_subdir_and_extra_packages" ,
3285
+ script_paths = [f"{ _utils ._INSTALLATION_SUBDIR } /script.sh" ],
3286
+ extra_packages = [f"{ _utils ._INSTALLATION_SUBDIR } /script.sh" ],
3287
+ raises_error = False ,
3288
+ ),
3289
+ dict (
3290
+ testcase_name = "script_not_in_subdir" ,
3291
+ script_paths = ["script.sh" ],
3292
+ extra_packages = ["script.sh" ],
3293
+ raises_error = True ,
3294
+ error_message = (
3295
+ f"Required installation script 'script.sh' must be under"
3296
+ f" '{ _utils ._INSTALLATION_SUBDIR } '"
3297
+ ),
3298
+ ),
3299
+ dict (
3300
+ testcase_name = "script_not_in_extra_packages" ,
3301
+ script_paths = [f"{ _utils ._INSTALLATION_SUBDIR } /script.sh" ],
3302
+ extra_packages = [],
3303
+ raises_error = True ,
3304
+ error_message = (
3305
+ "Required installation script "
3306
+ f"'{ _utils ._INSTALLATION_SUBDIR } /script.sh'"
3307
+ " must be in extra_packages"
3308
+ ),
3309
+ ),
3310
+ dict (
3311
+ testcase_name = "extra_package_in_subdir_but_not_script" ,
3312
+ script_paths = [],
3313
+ extra_packages = [f"{ _utils ._INSTALLATION_SUBDIR } /script.sh" ],
3314
+ raises_error = True ,
3315
+ error_message = (
3316
+ f"Extra package '{ _utils ._INSTALLATION_SUBDIR } /script.sh' "
3317
+ "is in the installation scripts subdirectory, but is not "
3318
+ "specified as an installation script."
3319
+ ),
3320
+ ),
3321
+ dict (
3322
+ testcase_name = "multiple_valid_scripts" ,
3323
+ script_paths = [
3324
+ f"{ _utils ._INSTALLATION_SUBDIR } /script1.sh" ,
3325
+ f"{ _utils ._INSTALLATION_SUBDIR } /script2.sh" ,
3326
+ ],
3327
+ extra_packages = [
3328
+ f"{ _utils ._INSTALLATION_SUBDIR } /script1.sh" ,
3329
+ f"{ _utils ._INSTALLATION_SUBDIR } /script2.sh" ,
3330
+ ],
3331
+ raises_error = False ,
3332
+ ),
3333
+ dict (
3334
+ testcase_name = "one_valid_one_invalid_script_not_in_subdir" ,
3335
+ script_paths = [
3336
+ f"{ _utils ._INSTALLATION_SUBDIR } /script1.sh" ,
3337
+ "script2.sh" ,
3338
+ ],
3339
+ extra_packages = [
3340
+ f"{ _utils ._INSTALLATION_SUBDIR } /script1.sh" ,
3341
+ "script2.sh" ,
3342
+ ],
3343
+ raises_error = True ,
3344
+ error_message = (
3345
+ f"Required installation script 'script2.sh' must be under"
3346
+ f" '{ _utils ._INSTALLATION_SUBDIR } '"
3347
+ ),
3348
+ ),
3349
+ dict (
3350
+ testcase_name = "one_valid_one_invalid_script_not_in_extra_packages" ,
3351
+ script_paths = [
3352
+ f"{ _utils ._INSTALLATION_SUBDIR } /script1.sh" ,
3353
+ f"{ _utils ._INSTALLATION_SUBDIR } /script2.sh" ,
3354
+ ],
3355
+ extra_packages = [f"{ _utils ._INSTALLATION_SUBDIR } /script1.sh" ],
3356
+ raises_error = True ,
3357
+ error_message = (
3358
+ f"Required installation script"
3359
+ f" '{ _utils ._INSTALLATION_SUBDIR } /script2.sh' must be in"
3360
+ f" extra_packages"
3361
+ ),
3362
+ ),
3363
+ dict (
3364
+ testcase_name = "one_valid_one_invalid_extra_package_in_subdir" ,
3365
+ script_paths = [f"{ _utils ._INSTALLATION_SUBDIR } /script1.sh" ],
3366
+ extra_packages = [
3367
+ f"{ _utils ._INSTALLATION_SUBDIR } /script1.sh" ,
3368
+ f"{ _utils ._INSTALLATION_SUBDIR } /script2.sh" ,
3369
+ ],
3370
+ raises_error = True ,
3371
+ error_message = (
3372
+ f"Extra package '{ _utils ._INSTALLATION_SUBDIR } /script2.sh' "
3373
+ "is in the installation scripts subdirectory, but is not "
3374
+ "specified as an installation script."
3375
+ ),
3376
+ ),
3377
+ dict (
3378
+ testcase_name = "empty_script_paths_and_extra_packages" ,
3379
+ script_paths = [],
3380
+ extra_packages = [],
3381
+ raises_error = False ,
3382
+ ),
3383
+ )
3384
+ def test_validate_installation_scripts (
3385
+ self ,
3386
+ script_paths ,
3387
+ extra_packages ,
3388
+ raises_error ,
3389
+ error_message = None ,
3390
+ ):
3391
+ if raises_error :
3392
+ with pytest .raises (ValueError , match = error_message ):
3393
+ _utils .validate_installation_scripts_or_raise (
3394
+ script_paths = script_paths , extra_packages = extra_packages
3395
+ )
3396
+ else :
3397
+ _utils .validate_installation_scripts_or_raise (
3398
+ script_paths = script_paths , extra_packages = extra_packages
3399
+ )
0 commit comments