diff --git a/acceptance/bundle/resources/model_serving_endpoints/basic/out.first-requests.direct.json b/acceptance/bundle/resources/model_serving_endpoints/basic/out.first-requests.direct.json deleted file mode 100644 index 1c0964aa6ec..00000000000 --- a/acceptance/bundle/resources/model_serving_endpoints/basic/out.first-requests.direct.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "method": "POST", - "path": "/api/2.0/serving-endpoints", - "body": { - "name": "[ENDPOINT_NAME_1]" - } -} -{ - "method": "PUT", - "path": "/api/2.0/permissions/serving-endpoints/[ENDPOINT_ID_1]", - "body": { - "access_control_list": [ - { - "permission_level": "CAN_VIEW", - "user_name": "deco-test-user@databricks.com" - }, - { - "permission_level": "CAN_MANAGE", - "service_principal_name": "[USERNAME]" - } - ] - } -} diff --git a/acceptance/bundle/resources/model_serving_endpoints/basic/out.first-requests.direct.txt b/acceptance/bundle/resources/model_serving_endpoints/basic/out.first-requests.direct.txt new file mode 100644 index 00000000000..ff4ff00fb8e --- /dev/null +++ b/acceptance/bundle/resources/model_serving_endpoints/basic/out.first-requests.direct.txt @@ -0,0 +1,9 @@ +json[0].method = "POST"; +json[0].path = "/api/2.0/serving-endpoints"; +json[0].body.name = "[ENDPOINT_NAME_1]"; +json[1].method = "PUT"; +json[1].path = "/api/2.0/permissions/serving-endpoints/[ENDPOINT_ID_1]"; +json[1].body.access_control_list[0].permission_level = "CAN_MANAGE"; +json[1].body.access_control_list[0].service_principal_name = "[USERNAME]"; +json[1].body.access_control_list[1].permission_level = "CAN_VIEW"; +json[1].body.access_control_list[1].user_name = "deco-test-user@databricks.com"; diff --git a/acceptance/bundle/resources/model_serving_endpoints/basic/out.first-requests.terraform.json b/acceptance/bundle/resources/model_serving_endpoints/basic/out.first-requests.terraform.json deleted file mode 100644 index d66fe66a2e6..00000000000 --- a/acceptance/bundle/resources/model_serving_endpoints/basic/out.first-requests.terraform.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "method": "POST", - "path": "/api/2.0/serving-endpoints", - "body": { - "name": "[ENDPOINT_NAME_1]" - } -} -{ - "method": "PUT", - "path": "/api/2.0/permissions/serving-endpoints/[ENDPOINT_ID_1]", - "body": { - "access_control_list": [ - { - "permission_level": "CAN_MANAGE", - "service_principal_name": "[USERNAME]" - }, - { - "permission_level": "CAN_VIEW", - "user_name": "deco-test-user@databricks.com" - } - ] - } -} diff --git a/acceptance/bundle/resources/model_serving_endpoints/basic/out.first-requests.terraform.txt b/acceptance/bundle/resources/model_serving_endpoints/basic/out.first-requests.terraform.txt new file mode 100644 index 00000000000..ff4ff00fb8e --- /dev/null +++ b/acceptance/bundle/resources/model_serving_endpoints/basic/out.first-requests.terraform.txt @@ -0,0 +1,9 @@ +json[0].method = "POST"; +json[0].path = "/api/2.0/serving-endpoints"; +json[0].body.name = "[ENDPOINT_NAME_1]"; +json[1].method = "PUT"; +json[1].path = "/api/2.0/permissions/serving-endpoints/[ENDPOINT_ID_1]"; +json[1].body.access_control_list[0].permission_level = "CAN_MANAGE"; +json[1].body.access_control_list[0].service_principal_name = "[USERNAME]"; +json[1].body.access_control_list[1].permission_level = "CAN_VIEW"; +json[1].body.access_control_list[1].user_name = "deco-test-user@databricks.com"; diff --git a/acceptance/bundle/resources/model_serving_endpoints/basic/out.second-requests.direct.json b/acceptance/bundle/resources/model_serving_endpoints/basic/out.second-requests.direct.json deleted file mode 100644 index a392327a811..00000000000 --- a/acceptance/bundle/resources/model_serving_endpoints/basic/out.second-requests.direct.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "method": "DELETE", - "path": "/api/2.0/serving-endpoints/[ENDPOINT_NAME_1]" -} -{ - "method": "POST", - "path": "/api/2.0/serving-endpoints", - "body": { - "name": "[ENDPOINT_NAME_2]" - } -} -{ - "method": "PUT", - "path": "/api/2.0/permissions/serving-endpoints/[ENDPOINT_ID_2]", - "body": { - "access_control_list": [ - { - "permission_level": "CAN_VIEW", - "user_name": "deco-test-user@databricks.com" - }, - { - "permission_level": "CAN_MANAGE", - "service_principal_name": "[USERNAME]" - } - ] - } -} diff --git a/acceptance/bundle/resources/model_serving_endpoints/basic/out.second-requests.direct.txt b/acceptance/bundle/resources/model_serving_endpoints/basic/out.second-requests.direct.txt new file mode 100644 index 00000000000..8f5318593a8 --- /dev/null +++ b/acceptance/bundle/resources/model_serving_endpoints/basic/out.second-requests.direct.txt @@ -0,0 +1,11 @@ +json[0].method = "DELETE"; +json[0].path = "/api/2.0/serving-endpoints/[ENDPOINT_NAME_1]"; +json[1].method = "POST"; +json[1].path = "/api/2.0/serving-endpoints"; +json[1].body.name = "[ENDPOINT_NAME_2]"; +json[2].method = "PUT"; +json[2].path = "/api/2.0/permissions/serving-endpoints/[ENDPOINT_ID_2]"; +json[2].body.access_control_list[0].permission_level = "CAN_MANAGE"; +json[2].body.access_control_list[0].service_principal_name = "[USERNAME]"; +json[2].body.access_control_list[1].permission_level = "CAN_VIEW"; +json[2].body.access_control_list[1].user_name = "deco-test-user@databricks.com"; diff --git a/acceptance/bundle/resources/model_serving_endpoints/basic/out.second-requests.terraform.json b/acceptance/bundle/resources/model_serving_endpoints/basic/out.second-requests.terraform.json deleted file mode 100644 index 8a2028f4504..00000000000 --- a/acceptance/bundle/resources/model_serving_endpoints/basic/out.second-requests.terraform.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "method": "PUT", - "path": "/api/2.0/permissions/serving-endpoints/[ENDPOINT_ID_1]", - "body": { - "access_control_list": [ - { - "permission_level": "CAN_MANAGE", - "user_name": "[USERNAME]" - } - ] - } -} -{ - "method": "DELETE", - "path": "/api/2.0/serving-endpoints/[ENDPOINT_NAME_1]" -} -{ - "method": "POST", - "path": "/api/2.0/serving-endpoints", - "body": { - "name": "[ENDPOINT_NAME_2]" - } -} -{ - "method": "PUT", - "path": "/api/2.0/permissions/serving-endpoints/[ENDPOINT_ID_2]", - "body": { - "access_control_list": [ - { - "permission_level": "CAN_MANAGE", - "service_principal_name": "[USERNAME]" - }, - { - "permission_level": "CAN_VIEW", - "user_name": "deco-test-user@databricks.com" - } - ] - } -} diff --git a/acceptance/bundle/resources/model_serving_endpoints/basic/out.second-requests.terraform.txt b/acceptance/bundle/resources/model_serving_endpoints/basic/out.second-requests.terraform.txt new file mode 100644 index 00000000000..aba548c4913 --- /dev/null +++ b/acceptance/bundle/resources/model_serving_endpoints/basic/out.second-requests.terraform.txt @@ -0,0 +1,15 @@ +json[0].method = "PUT"; +json[0].path = "/api/2.0/permissions/serving-endpoints/[ENDPOINT_ID_1]"; +json[0].body.access_control_list[0].permission_level = "CAN_MANAGE"; +json[0].body.access_control_list[0].user_name = "[USERNAME]"; +json[1].method = "DELETE"; +json[1].path = "/api/2.0/serving-endpoints/[ENDPOINT_NAME_1]"; +json[2].method = "POST"; +json[2].path = "/api/2.0/serving-endpoints"; +json[2].body.name = "[ENDPOINT_NAME_2]"; +json[3].method = "PUT"; +json[3].path = "/api/2.0/permissions/serving-endpoints/[ENDPOINT_ID_2]"; +json[3].body.access_control_list[0].permission_level = "CAN_MANAGE"; +json[3].body.access_control_list[0].service_principal_name = "[USERNAME]"; +json[3].body.access_control_list[1].permission_level = "CAN_VIEW"; +json[3].body.access_control_list[1].user_name = "deco-test-user@databricks.com"; diff --git a/acceptance/bundle/resources/model_serving_endpoints/basic/out.test.toml b/acceptance/bundle/resources/model_serving_endpoints/basic/out.test.toml index 2d812727e32..e849ec85ace 100644 --- a/acceptance/bundle/resources/model_serving_endpoints/basic/out.test.toml +++ b/acceptance/bundle/resources/model_serving_endpoints/basic/out.test.toml @@ -1,4 +1,4 @@ -Local = false +Local = true Cloud = true RequiresUnityCatalog = true EnvMatrix.DATABRICKS_BUNDLE_ENGINE = ["terraform", "direct"] diff --git a/acceptance/bundle/resources/model_serving_endpoints/basic/output.txt b/acceptance/bundle/resources/model_serving_endpoints/basic/output.txt index 7b3b010eedd..0455fad681a 100644 --- a/acceptance/bundle/resources/model_serving_endpoints/basic/output.txt +++ b/acceptance/bundle/resources/model_serving_endpoints/basic/output.txt @@ -7,8 +7,6 @@ Deploying resources... Updating deployment state... Deployment complete! ->>> print_requests.py //serving-endpoints - === Print the GET endpoint details { "name": "[ENDPOINT_NAME_1]", @@ -23,8 +21,6 @@ Deploying resources... Updating deployment state... Deployment complete! ->>> print_requests.py //serving-endpoints - === Print the GET endpoint details { "name": "[ENDPOINT_NAME_2]", diff --git a/acceptance/bundle/resources/model_serving_endpoints/basic/script b/acceptance/bundle/resources/model_serving_endpoints/basic/script index c06b058d59f..3ff3f64ab28 100755 --- a/acceptance/bundle/resources/model_serving_endpoints/basic/script +++ b/acceptance/bundle/resources/model_serving_endpoints/basic/script @@ -10,7 +10,10 @@ trap cleanup EXIT trace $CLI bundle plan -o json > out.first-plan.$DATABRICKS_BUNDLE_ENGINE.json trace $CLI bundle deploy -trace print_requests.py //serving-endpoints > out.first-requests.$DATABRICKS_BUNDLE_ENGINE.json +# Sort access_control_list: the terraform engine stores it as a set whose order +# depends on the (unmasked) principal value, so it differs between the local fake +# SP and the real cloud SP. Sorting makes the recorded request stable across both. +print_requests.py //serving-endpoints | gron.py --sort-arrays access_control_list > out.first-requests.$DATABRICKS_BUNDLE_ENGINE.txt echo "$ENDPOINT_NAME:ENDPOINT_NAME_1" >> ACC_REPLS @@ -26,7 +29,7 @@ export ENDPOINT_NAME="test-endpoint-$UNIQUE_NAME-2" envsubst < databricks.yml.tmpl > databricks.yml trace $CLI bundle plan -o json > out.second-plan.$DATABRICKS_BUNDLE_ENGINE.json trace $CLI bundle deploy -trace print_requests.py //serving-endpoints > out.second-requests.$DATABRICKS_BUNDLE_ENGINE.json +print_requests.py //serving-endpoints | gron.py --sort-arrays access_control_list > out.second-requests.$DATABRICKS_BUNDLE_ENGINE.txt echo "$ENDPOINT_NAME:ENDPOINT_NAME_2" >> ACC_REPLS diff --git a/acceptance/bundle/resources/model_serving_endpoints/basic/test.toml b/acceptance/bundle/resources/model_serving_endpoints/basic/test.toml index 2aa692e7f24..28dbed8ca57 100644 --- a/acceptance/bundle/resources/model_serving_endpoints/basic/test.toml +++ b/acceptance/bundle/resources/model_serving_endpoints/basic/test.toml @@ -1,7 +1,12 @@ -Local = false +Local = true Cloud = true RecordRequests = true RequiresUnityCatalog = true +# Cloud goldens were recorded under a service principal, so the deployer's +# auto-added CAN_MANAGE ACL serializes as service_principal_name. Make the +# local fake report the deployer as a service principal to match. +IsServicePrincipal = true + [EnvMatrix] DATABRICKS_BUNDLE_ENGINE = ["terraform", "direct"] diff --git a/acceptance/bundle/resources/model_serving_endpoints/recreate/catalog-name/out.second-plan.direct.json b/acceptance/bundle/resources/model_serving_endpoints/recreate/catalog-name/out.second-plan.direct.json index 1c9610dd2fa..2af8d4d7416 100644 --- a/acceptance/bundle/resources/model_serving_endpoints/recreate/catalog-name/out.second-plan.direct.json +++ b/acceptance/bundle/resources/model_serving_endpoints/recreate/catalog-name/out.second-plan.direct.json @@ -53,8 +53,11 @@ } ] }, + "creation_timestamp": [UNIX_TIME_MILLIS][0], "creator": "[USERNAME]", + "description": "", "id": "[UUID]", + "last_updated_timestamp": [UNIX_TIME_MILLIS][0], "name": "[ORIGINAL_ENDPOINT_ID]", "permission_level": "CAN_MANAGE", "route_optimized": false, @@ -73,6 +76,11 @@ "new": "other_catalog", "remote": "main" }, + "description": { + "action": "skip", + "reason": "empty", + "remote": "" + }, "route_optimized": { "action": "skip", "reason": "empty", diff --git a/acceptance/bundle/resources/model_serving_endpoints/recreate/name-change/out.second-plan.direct.json b/acceptance/bundle/resources/model_serving_endpoints/recreate/name-change/out.second-plan.direct.json index 4826a8a87bf..71fe34b4591 100644 --- a/acceptance/bundle/resources/model_serving_endpoints/recreate/name-change/out.second-plan.direct.json +++ b/acceptance/bundle/resources/model_serving_endpoints/recreate/name-change/out.second-plan.direct.json @@ -43,8 +43,11 @@ } ] }, + "creation_timestamp": [UNIX_TIME_MILLIS][0], "creator": "[USERNAME]", + "description": "", "id": "[UUID]", + "last_updated_timestamp": [UNIX_TIME_MILLIS][0], "name": "[ORIGINAL_ENDPOINT_ID]", "permission_level": "CAN_MANAGE", "route_optimized": false, @@ -56,6 +59,11 @@ "endpoint_id": "[UUID]" }, "changes": { + "description": { + "action": "skip", + "reason": "empty", + "remote": "" + }, "name": { "action": "recreate", "reason": "id_field", diff --git a/acceptance/bundle/resources/model_serving_endpoints/recreate/route-optimized/out.second-plan.direct.json b/acceptance/bundle/resources/model_serving_endpoints/recreate/route-optimized/out.second-plan.direct.json index 5379c464648..fdf9dc54d3b 100644 --- a/acceptance/bundle/resources/model_serving_endpoints/recreate/route-optimized/out.second-plan.direct.json +++ b/acceptance/bundle/resources/model_serving_endpoints/recreate/route-optimized/out.second-plan.direct.json @@ -36,8 +36,11 @@ } ] }, + "creation_timestamp": [UNIX_TIME_MILLIS][0], "creator": "[USERNAME]", + "description": "", "id": "[UUID]", + "last_updated_timestamp": [UNIX_TIME_MILLIS][0], "name": "[ORIGINAL_ENDPOINT_ID]", "permission_level": "CAN_MANAGE", "route_optimized": false, @@ -49,6 +52,11 @@ "endpoint_id": "[UUID]" }, "changes": { + "description": { + "action": "skip", + "reason": "empty", + "remote": "" + }, "route_optimized": { "action": "recreate", "reason": "immutable", diff --git a/acceptance/bundle/resources/model_serving_endpoints/recreate/route-optimized/output.txt b/acceptance/bundle/resources/model_serving_endpoints/recreate/route-optimized/output.txt index 2f784d9f37d..d9ede211b2b 100644 --- a/acceptance/bundle/resources/model_serving_endpoints/recreate/route-optimized/output.txt +++ b/acceptance/bundle/resources/model_serving_endpoints/recreate/route-optimized/output.txt @@ -57,8 +57,11 @@ Deployment complete! } ] }, + "creation_timestamp": [UNIX_TIME_MILLIS][0], "creator": "[USERNAME]", + "description": "", "id": "[UUID]", + "last_updated_timestamp": [UNIX_TIME_MILLIS][0], "name": "[ORIGINAL_ENDPOINT_ID]", "permission_level": "CAN_MANAGE", "route_optimized": true, diff --git a/acceptance/bundle/resources/model_serving_endpoints/recreate/schema-name/out.second-plan.direct.json b/acceptance/bundle/resources/model_serving_endpoints/recreate/schema-name/out.second-plan.direct.json index 996ec9a09cb..367d2028d50 100644 --- a/acceptance/bundle/resources/model_serving_endpoints/recreate/schema-name/out.second-plan.direct.json +++ b/acceptance/bundle/resources/model_serving_endpoints/recreate/schema-name/out.second-plan.direct.json @@ -53,8 +53,11 @@ } ] }, + "creation_timestamp": [UNIX_TIME_MILLIS][0], "creator": "[USERNAME]", + "description": "", "id": "[UUID]", + "last_updated_timestamp": [UNIX_TIME_MILLIS][0], "name": "[ORIGINAL_ENDPOINT_ID]", "permission_level": "CAN_MANAGE", "route_optimized": false, @@ -73,6 +76,11 @@ "new": "other_schema", "remote": "default" }, + "description": { + "action": "skip", + "reason": "empty", + "remote": "" + }, "route_optimized": { "action": "skip", "reason": "empty", diff --git a/acceptance/bundle/resources/model_serving_endpoints/recreate/table-prefix/out.second-plan.direct.json b/acceptance/bundle/resources/model_serving_endpoints/recreate/table-prefix/out.second-plan.direct.json index c57e2ac8bb8..eb0db4dd581 100644 --- a/acceptance/bundle/resources/model_serving_endpoints/recreate/table-prefix/out.second-plan.direct.json +++ b/acceptance/bundle/resources/model_serving_endpoints/recreate/table-prefix/out.second-plan.direct.json @@ -53,8 +53,11 @@ } ] }, + "creation_timestamp": [UNIX_TIME_MILLIS][0], "creator": "[USERNAME]", + "description": "", "id": "[UUID]", + "last_updated_timestamp": [UNIX_TIME_MILLIS][0], "name": "[ORIGINAL_ENDPOINT_ID]", "permission_level": "CAN_MANAGE", "route_optimized": false, @@ -73,6 +76,11 @@ "new": "other_table", "remote": "my_table" }, + "description": { + "action": "skip", + "reason": "empty", + "remote": "" + }, "route_optimized": { "action": "skip", "reason": "empty", diff --git a/acceptance/bundle/resources/model_serving_endpoints/update/ai-gateway/out.plan.direct.json b/acceptance/bundle/resources/model_serving_endpoints/update/ai-gateway/out.plan.direct.json index b9228ef8c78..a2aa883123f 100644 --- a/acceptance/bundle/resources/model_serving_endpoints/update/ai-gateway/out.plan.direct.json +++ b/acceptance/bundle/resources/model_serving_endpoints/update/ai-gateway/out.plan.direct.json @@ -53,8 +53,11 @@ } ] }, + "creation_timestamp": [UNIX_TIME_MILLIS][0], "creator": "[USERNAME]", + "description": "", "id": "[UUID]", + "last_updated_timestamp": [UNIX_TIME_MILLIS][0], "name": "[ENDPOINT_ID]", "permission_level": "CAN_MANAGE", "route_optimized": false, @@ -72,6 +75,11 @@ "new": "second-inference-catalog", "remote": "first-inference-catalog" }, + "description": { + "action": "skip", + "reason": "empty", + "remote": "" + }, "route_optimized": { "action": "skip", "reason": "empty", diff --git a/acceptance/bundle/resources/model_serving_endpoints/update/both_gateway_and_tags/out.plan.direct.json b/acceptance/bundle/resources/model_serving_endpoints/update/both_gateway_and_tags/out.plan.direct.json index 6dd458695a2..482f463aa99 100644 --- a/acceptance/bundle/resources/model_serving_endpoints/update/both_gateway_and_tags/out.plan.direct.json +++ b/acceptance/bundle/resources/model_serving_endpoints/update/both_gateway_and_tags/out.plan.direct.json @@ -59,8 +59,11 @@ } ] }, + "creation_timestamp": [UNIX_TIME_MILLIS][0], "creator": "[USERNAME]", + "description": "", "id": "[UUID]", + "last_updated_timestamp": [UNIX_TIME_MILLIS][0], "name": "[ENDPOINT_ID]", "permission_level": "CAN_MANAGE", "route_optimized": false, @@ -84,6 +87,11 @@ "new": "second-inference-catalog", "remote": "first-inference-catalog" }, + "description": { + "action": "skip", + "reason": "empty", + "remote": "" + }, "route_optimized": { "action": "skip", "reason": "empty", diff --git a/acceptance/bundle/resources/model_serving_endpoints/update/config/out.plan.direct.json b/acceptance/bundle/resources/model_serving_endpoints/update/config/out.plan.direct.json index 7b82abf6da8..4a34e191777 100644 --- a/acceptance/bundle/resources/model_serving_endpoints/update/config/out.plan.direct.json +++ b/acceptance/bundle/resources/model_serving_endpoints/update/config/out.plan.direct.json @@ -43,8 +43,11 @@ } ] }, + "creation_timestamp": [UNIX_TIME_MILLIS][0], "creator": "[USERNAME]", + "description": "", "id": "[UUID]", + "last_updated_timestamp": [UNIX_TIME_MILLIS][0], "name": "[ENDPOINT_ID]", "permission_level": "CAN_MANAGE", "route_optimized": false, @@ -62,6 +65,11 @@ "new": "gpt-5o-mini", "remote": "gpt-4o-mini" }, + "description": { + "action": "skip", + "reason": "empty", + "remote": "" + }, "route_optimized": { "action": "skip", "reason": "empty", diff --git a/acceptance/bundle/resources/model_serving_endpoints/update/email-notifications/out.plan.direct.json b/acceptance/bundle/resources/model_serving_endpoints/update/email-notifications/out.plan.direct.json index 26087d47805..e43b533ebd9 100644 --- a/acceptance/bundle/resources/model_serving_endpoints/update/email-notifications/out.plan.direct.json +++ b/acceptance/bundle/resources/model_serving_endpoints/update/email-notifications/out.plan.direct.json @@ -48,13 +48,16 @@ } ] }, + "creation_timestamp": [UNIX_TIME_MILLIS][0], "creator": "[USERNAME]", + "description": "", "email_notifications": { "on_update_success": [ "user1@example.com" ] }, "id": "[UUID]", + "last_updated_timestamp": [UNIX_TIME_MILLIS][0], "name": "[ENDPOINT_ID]", "permission_level": "CAN_MANAGE", "route_optimized": false, @@ -66,6 +69,11 @@ "endpoint_id": "[UUID]" }, "changes": { + "description": { + "action": "skip", + "reason": "empty", + "remote": "" + }, "email_notifications.on_update_success[0]": { "action": "update", "old": "user1@example.com", diff --git a/acceptance/bundle/resources/model_serving_endpoints/update/tags/out.plan.direct.json b/acceptance/bundle/resources/model_serving_endpoints/update/tags/out.plan.direct.json index 75bcde8e90f..f616085b3e4 100644 --- a/acceptance/bundle/resources/model_serving_endpoints/update/tags/out.plan.direct.json +++ b/acceptance/bundle/resources/model_serving_endpoints/update/tags/out.plan.direct.json @@ -49,8 +49,11 @@ } ] }, + "creation_timestamp": [UNIX_TIME_MILLIS][0], "creator": "[USERNAME]", + "description": "", "id": "[UUID]", + "last_updated_timestamp": [UNIX_TIME_MILLIS][0], "name": "[ENDPOINT_ID]", "permission_level": "CAN_MANAGE", "route_optimized": false, @@ -68,6 +71,11 @@ "endpoint_id": "[UUID]" }, "changes": { + "description": { + "action": "skip", + "reason": "empty", + "remote": "" + }, "route_optimized": { "action": "skip", "reason": "empty", diff --git a/libs/testserver/serving_endpoints.go b/libs/testserver/serving_endpoints.go index 8a7ff891b50..7706b376815 100644 --- a/libs/testserver/serving_endpoints.go +++ b/libs/testserver/serving_endpoints.go @@ -110,23 +110,28 @@ func (s *FakeWorkspace) ServingEndpointCreate(req Request) Response { } } + now := nowMilli() endpoint := serving.ServingEndpointDetailed{ - AiGateway: createReq.AiGateway, - BudgetPolicyId: createReq.BudgetPolicyId, - Config: config, - Creator: s.CurrentUser().UserName, - Description: createReq.Description, - EmailNotifications: createReq.EmailNotifications, - Id: nextUUID(), - Name: createReq.Name, - PermissionLevel: serving.ServingEndpointDetailedPermissionLevelCanManage, - RouteOptimized: createReq.RouteOptimized, - Tags: createReq.Tags, + AiGateway: createReq.AiGateway, + BudgetPolicyId: createReq.BudgetPolicyId, + Config: config, + CreationTimestamp: now, + Creator: s.CurrentUser().UserName, + Description: createReq.Description, + EmailNotifications: createReq.EmailNotifications, + Id: nextUUID(), + LastUpdatedTimestamp: now, + Name: createReq.Name, + PermissionLevel: serving.ServingEndpointDetailedPermissionLevelCanManage, + RouteOptimized: createReq.RouteOptimized, + Tags: createReq.Tags, State: &serving.EndpointState{ ConfigUpdate: serving.EndpointStateConfigUpdateNotUpdating, Ready: serving.EndpointStateReadyNotReady, }, - ForceSendFields: append(createReq.ForceSendFields, "PermissionLevel", "RouteOptimized"), + // Force-send Description so an empty value serializes as "", matching the + // real backend which always echoes the field back on GET. + ForceSendFields: append(createReq.ForceSendFields, "PermissionLevel", "RouteOptimized", "Description"), } s.ServingEndpoints[createReq.Name] = endpoint @@ -180,6 +185,7 @@ func (s *FakeWorkspace) ServingEndpointUpdate(req Request, name string) Response } endpoint.Config = config + endpoint.LastUpdatedTimestamp = nowMilli() endpoint.State = &serving.EndpointState{ ConfigUpdate: serving.EndpointStateConfigUpdateNotUpdating, Ready: serving.EndpointStateReadyNotReady,