diff --git a/README.md b/README.md
index 960aed80..1a75cd26 100644
--- a/README.md
+++ b/README.md
@@ -200,8 +200,8 @@ Sample skips:
| update time | Field update_time should be updated when the resource is updated. | Generated only if all are true:
- has Create method
- Create method does not return long-running operation
- has Update method
- Update method does not return long-running operation
- has field 'update_time'
|
| persisted | The updated resource should be persisted and reachable with Get. | Generated only if all are true: - has Update method
- Update method does not return long-running operation
- has Get method
|
| preserve create_time | The field create_time should be preserved when a '\*'-update mask is used. | Generated only if all are true: - has Update method
- Update method does not return long-running operation
- has field 'create_time'
- resource has any required fields
|
-| etag mismatch | Method should fail with Aborted if the supplied etag doesnt match the current etag value. | Generated only if all are true: - has Update method
- request has etag field
- has field 'etag'
|
-| etag updated | Field etag should have a new value when the resource is successfully updated. | Generated only if all are true: - has Update method
- request has etag field
- has field 'etag'
|
+| etag mismatch | Method should fail with Aborted if the supplied etag doesnt match the current etag value. | Generated only if all are true: - has Update method
- has field 'etag'
|
+| etag updated | Field etag should have a new value when the resource is successfully updated. | Generated only if all are true: - has Update method
- has field 'etag'
|
| not found | Method should fail with NotFound if the resource does not exist. | Generated only if all are true: |
| invalid update mask | The method should fail with InvalidArgument if the update_mask is invalid. | Generated only if all are true: - has Update method
- Update method has update_mask
|
| required fields | Method should fail with InvalidArgument if any required field is missing when called with '\*' update_mask. | Generated only if all are true: - has Update method
- resource has any required fields
|
diff --git a/internal/aiptest/update/etag.go b/internal/aiptest/update/etag.go
index a0fef711..aba2e094 100644
--- a/internal/aiptest/update/etag.go
+++ b/internal/aiptest/update/etag.go
@@ -18,7 +18,6 @@ var etagMismatch = suite.Test{
},
OnlyIf: suite.OnlyIfs(
onlyif.HasMethod(aipreflect.MethodTypeUpdate),
- onlyif.HasRequestEtag(aipreflect.MethodTypeUpdate),
onlyif.HasField("etag"),
),
Generate: func(f *protogen.GeneratedFile, scope suite.Scope) error {
@@ -32,8 +31,10 @@ var etagMismatch = suite.Test{
util.MethodUpdate{
Resource: scope.Resource,
Method: updateMethod,
- Msg: "created",
+ Parent: "parent",
+ Name: "created.Name",
Etag: util.EtagLiteral("99999"),
+ EtagTest: true,
}.Generate(f, "_", "err", ":=")
f.P(ident.AssertEqual, "(t, ", ident.Codes(codes.Aborted), ",", ident.StatusCode, "(err), err)")
return nil
@@ -48,7 +49,6 @@ var etagUpdated = suite.Test{
},
OnlyIf: suite.OnlyIfs(
onlyif.HasMethod(aipreflect.MethodTypeUpdate),
- onlyif.HasRequestEtag(aipreflect.MethodTypeUpdate),
onlyif.HasField("etag"),
),
Generate: func(f *protogen.GeneratedFile, scope suite.Scope) error {
@@ -65,9 +65,16 @@ var etagUpdated = suite.Test{
Parent: "parent",
Name: "created.Name",
Etag: "created.Etag",
+ EtagTest: true,
}.Generate(f, "updated", "err", ":=")
f.P(ident.AssertNilError, "(t, err)")
- f.P(ident.AssertCheck, "(t, updated.Etag != created.Etag)")
+
+ if !util.ReturnsLRO(updateMethod.Desc) {
+ // only assert etag is different if the resource is returned.
+ f.P(ident.AssertCheck, "(t, updated.Etag != created.Etag)")
+ } else {
+ f.P("_ = updated") // prevent unused error.
+ }
return nil
},
}
diff --git a/internal/util/method.go b/internal/util/method.go
index 6362b042..7da1ad11 100644
--- a/internal/util/method.go
+++ b/internal/util/method.go
@@ -95,6 +95,7 @@ type MethodUpdate struct {
Msg string
UpdateMask []string
Etag string
+ EtagTest bool
}
func (m MethodUpdate) Generate(f *protogen.GeneratedFile, response, err, assign string) {
@@ -111,6 +112,14 @@ func (m MethodUpdate) Generate(f *protogen.GeneratedFile, response, err, assign
}
f.P("msg.Name = ", m.Name)
}
+ if m.EtagTest && !HasEtagField(m.Method.Input.Desc) && HasEtagField(m.Method.Output.Desc) {
+ // Request object does not have an etag field, but the resource has.
+ if m.Etag != "" {
+ f.P("msg.Etag = ", m.Etag)
+ } else {
+ f.P(`msg.Etag = created.Etag // assign etag from the created resource`)
+ }
+ }
f.P(response, ", ", err, " ", assign, " fx.Service().", m.Method.GoName, "(fx.Context(), &", m.Method.Input.GoIdent, "{") //nolint:lll
if m.Msg != "" {
f.P(upper, ":", m.Msg, ",")
diff --git a/proto/gen/einride/example/freight/v1/freight_service_aiptest.pb.go b/proto/gen/einride/example/freight/v1/freight_service_aiptest.pb.go
index 84cee541..e834755c 100644
--- a/proto/gen/einride/example/freight/v1/freight_service_aiptest.pb.go
+++ b/proto/gen/einride/example/freight/v1/freight_service_aiptest.pb.go
@@ -471,6 +471,33 @@ func (fx *FreightServiceShipperTestSuiteConfig) testUpdate(t *testing.T) {
assert.DeepEqual(t, originalCreateTime, updated.CreateTime, protocmp.Transform())
})
+ // Method should fail with Aborted if the supplied etag doesnt match the current etag value.
+ t.Run("etag mismatch", func(t *testing.T) {
+ fx.maybeSkip(t)
+ created := fx.create(t)
+ msg := fx.Update()
+ msg.Name = created.Name
+ msg.Etag = `"99999"`
+ _, err := fx.Service().UpdateShipper(fx.Context(), &UpdateShipperRequest{
+ Shipper: msg,
+ })
+ assert.Equal(t, codes.Aborted, status.Code(err), err)
+ })
+
+ // Field etag should have a new value when the resource is successfully updated.
+ t.Run("etag updated", func(t *testing.T) {
+ fx.maybeSkip(t)
+ created := fx.create(t)
+ msg := fx.Update()
+ msg.Name = created.Name
+ msg.Etag = created.Etag
+ updated, err := fx.Service().UpdateShipper(fx.Context(), &UpdateShipperRequest{
+ Shipper: msg,
+ })
+ assert.NilError(t, err)
+ assert.Check(t, updated.Etag != created.Etag)
+ })
+
created := fx.create(t)
// Method should fail with NotFound if the resource does not exist.
t.Run("not found", func(t *testing.T) {
@@ -1288,6 +1315,35 @@ func (fx *FreightServiceSiteTestSuiteConfig) testUpdate(t *testing.T) {
assert.DeepEqual(t, originalCreateTime, updated.CreateTime, protocmp.Transform())
})
+ // Method should fail with Aborted if the supplied etag doesnt match the current etag value.
+ t.Run("etag mismatch", func(t *testing.T) {
+ fx.maybeSkip(t)
+ parent := fx.nextParent(t, false)
+ created := fx.create(t, parent)
+ msg := fx.Update(parent)
+ msg.Name = created.Name
+ msg.Etag = `"99999"`
+ _, err := fx.Service().UpdateSite(fx.Context(), &UpdateSiteRequest{
+ Site: msg,
+ })
+ assert.Equal(t, codes.Aborted, status.Code(err), err)
+ })
+
+ // Field etag should have a new value when the resource is successfully updated.
+ t.Run("etag updated", func(t *testing.T) {
+ fx.maybeSkip(t)
+ parent := fx.nextParent(t, false)
+ created := fx.create(t, parent)
+ msg := fx.Update(parent)
+ msg.Name = created.Name
+ msg.Etag = created.Etag
+ updated, err := fx.Service().UpdateSite(fx.Context(), &UpdateSiteRequest{
+ Site: msg,
+ })
+ assert.NilError(t, err)
+ assert.Check(t, updated.Etag != created.Etag)
+ })
+
parent := fx.nextParent(t, false)
created := fx.create(t, parent)
// Method should fail with NotFound if the resource does not exist.
diff --git a/proto/gen/googleapis/aiplatform/apiv1/aiplatformpb/dataset_service_aiptest.pb.go b/proto/gen/googleapis/aiplatform/apiv1/aiplatformpb/dataset_service_aiptest.pb.go
index f9eca08c..efac94ce 100644
--- a/proto/gen/googleapis/aiplatform/apiv1/aiplatformpb/dataset_service_aiptest.pb.go
+++ b/proto/gen/googleapis/aiplatform/apiv1/aiplatformpb/dataset_service_aiptest.pb.go
@@ -918,6 +918,35 @@ func (fx *DatasetServiceDatasetTestSuiteConfig) testUpdate(t *testing.T) {
assert.DeepEqual(t, originalCreateTime, updated.CreateTime, protocmp.Transform())
})
+ // Method should fail with Aborted if the supplied etag doesnt match the current etag value.
+ t.Run("etag mismatch", func(t *testing.T) {
+ fx.maybeSkip(t)
+ parent := fx.nextParent(t, false)
+ created := fx.create(t, parent)
+ msg := fx.Update(parent)
+ msg.Name = created.Name
+ msg.Etag = `"99999"`
+ _, err := fx.Service().UpdateDataset(fx.Context(), &UpdateDatasetRequest{
+ Dataset: msg,
+ })
+ assert.Equal(t, codes.Aborted, status.Code(err), err)
+ })
+
+ // Field etag should have a new value when the resource is successfully updated.
+ t.Run("etag updated", func(t *testing.T) {
+ fx.maybeSkip(t)
+ parent := fx.nextParent(t, false)
+ created := fx.create(t, parent)
+ msg := fx.Update(parent)
+ msg.Name = created.Name
+ msg.Etag = created.Etag
+ updated, err := fx.Service().UpdateDataset(fx.Context(), &UpdateDatasetRequest{
+ Dataset: msg,
+ })
+ assert.NilError(t, err)
+ assert.Check(t, updated.Etag != created.Etag)
+ })
+
parent := fx.nextParent(t, false)
created := fx.create(t, parent)
// Method should fail with NotFound if the resource does not exist.
diff --git a/proto/gen/googleapis/aiplatform/apiv1/aiplatformpb/endpoint_service_aiptest.pb.go b/proto/gen/googleapis/aiplatform/apiv1/aiplatformpb/endpoint_service_aiptest.pb.go
index be9f9a70..90347b73 100644
--- a/proto/gen/googleapis/aiplatform/apiv1/aiplatformpb/endpoint_service_aiptest.pb.go
+++ b/proto/gen/googleapis/aiplatform/apiv1/aiplatformpb/endpoint_service_aiptest.pb.go
@@ -305,6 +305,35 @@ func (fx *EndpointServiceEndpointTestSuiteConfig) testUpdate(t *testing.T) {
assert.DeepEqual(t, originalCreateTime, updated.CreateTime, protocmp.Transform())
})
+ // Method should fail with Aborted if the supplied etag doesnt match the current etag value.
+ t.Run("etag mismatch", func(t *testing.T) {
+ fx.maybeSkip(t)
+ parent := fx.nextParent(t, false)
+ created := fx.create(t, parent)
+ msg := fx.Update(parent)
+ msg.Name = created.Name
+ msg.Etag = `"99999"`
+ _, err := fx.Service().UpdateEndpoint(fx.Context(), &UpdateEndpointRequest{
+ Endpoint: msg,
+ })
+ assert.Equal(t, codes.Aborted, status.Code(err), err)
+ })
+
+ // Field etag should have a new value when the resource is successfully updated.
+ t.Run("etag updated", func(t *testing.T) {
+ fx.maybeSkip(t)
+ parent := fx.nextParent(t, false)
+ created := fx.create(t, parent)
+ msg := fx.Update(parent)
+ msg.Name = created.Name
+ msg.Etag = created.Etag
+ updated, err := fx.Service().UpdateEndpoint(fx.Context(), &UpdateEndpointRequest{
+ Endpoint: msg,
+ })
+ assert.NilError(t, err)
+ assert.Check(t, updated.Etag != created.Etag)
+ })
+
parent := fx.nextParent(t, false)
created := fx.create(t, parent)
// Method should fail with NotFound if the resource does not exist.
diff --git a/proto/gen/googleapis/aiplatform/apiv1/aiplatformpb/feature_online_store_admin_service_aiptest.pb.go b/proto/gen/googleapis/aiplatform/apiv1/aiplatformpb/feature_online_store_admin_service_aiptest.pb.go
index 401980bd..043c6ac7 100644
--- a/proto/gen/googleapis/aiplatform/apiv1/aiplatformpb/feature_online_store_admin_service_aiptest.pb.go
+++ b/proto/gen/googleapis/aiplatform/apiv1/aiplatformpb/feature_online_store_admin_service_aiptest.pb.go
@@ -304,6 +304,33 @@ func (fx *FeatureOnlineStoreAdminServiceFeatureOnlineStoreTestSuiteConfig) testU
assert.Equal(t, codes.InvalidArgument, status.Code(err), err)
})
+ // Method should fail with Aborted if the supplied etag doesnt match the current etag value.
+ t.Run("etag mismatch", func(t *testing.T) {
+ fx.maybeSkip(t)
+ parent := fx.nextParent(t, false)
+ created := fx.create(t, parent)
+ msg := fx.Update(parent)
+ msg.Name = created.Name
+ _, err := fx.Service().UpdateFeatureOnlineStore(fx.Context(), &UpdateFeatureOnlineStoreRequest{
+ FeatureOnlineStore: msg,
+ })
+ assert.Equal(t, codes.Aborted, status.Code(err), err)
+ })
+
+ // Field etag should have a new value when the resource is successfully updated.
+ t.Run("etag updated", func(t *testing.T) {
+ fx.maybeSkip(t)
+ parent := fx.nextParent(t, false)
+ created := fx.create(t, parent)
+ msg := fx.Update(parent)
+ msg.Name = created.Name
+ updated, err := fx.Service().UpdateFeatureOnlineStore(fx.Context(), &UpdateFeatureOnlineStoreRequest{
+ FeatureOnlineStore: msg,
+ })
+ assert.NilError(t, err)
+ _ = updated
+ })
+
parent := fx.nextParent(t, false)
created := fx.create(t, parent)
// Method should fail with NotFound if the resource does not exist.
@@ -830,6 +857,33 @@ func (fx *FeatureOnlineStoreAdminServiceFeatureViewTestSuiteConfig) testUpdate(t
assert.Equal(t, codes.InvalidArgument, status.Code(err), err)
})
+ // Method should fail with Aborted if the supplied etag doesnt match the current etag value.
+ t.Run("etag mismatch", func(t *testing.T) {
+ fx.maybeSkip(t)
+ parent := fx.nextParent(t, false)
+ created := fx.create(t, parent)
+ msg := fx.Update(parent)
+ msg.Name = created.Name
+ _, err := fx.Service().UpdateFeatureView(fx.Context(), &UpdateFeatureViewRequest{
+ FeatureView: msg,
+ })
+ assert.Equal(t, codes.Aborted, status.Code(err), err)
+ })
+
+ // Field etag should have a new value when the resource is successfully updated.
+ t.Run("etag updated", func(t *testing.T) {
+ fx.maybeSkip(t)
+ parent := fx.nextParent(t, false)
+ created := fx.create(t, parent)
+ msg := fx.Update(parent)
+ msg.Name = created.Name
+ updated, err := fx.Service().UpdateFeatureView(fx.Context(), &UpdateFeatureViewRequest{
+ FeatureView: msg,
+ })
+ assert.NilError(t, err)
+ _ = updated
+ })
+
parent := fx.nextParent(t, false)
created := fx.create(t, parent)
// Method should fail with NotFound if the resource does not exist.
diff --git a/proto/gen/googleapis/aiplatform/apiv1/aiplatformpb/feature_registry_service_aiptest.pb.go b/proto/gen/googleapis/aiplatform/apiv1/aiplatformpb/feature_registry_service_aiptest.pb.go
index 783d5d69..404539b3 100644
--- a/proto/gen/googleapis/aiplatform/apiv1/aiplatformpb/feature_registry_service_aiptest.pb.go
+++ b/proto/gen/googleapis/aiplatform/apiv1/aiplatformpb/feature_registry_service_aiptest.pb.go
@@ -237,6 +237,33 @@ func (fx *FeatureRegistryServiceFeatureTestSuiteConfig) testUpdate(t *testing.T)
assert.Equal(t, codes.InvalidArgument, status.Code(err), err)
})
+ // Method should fail with Aborted if the supplied etag doesnt match the current etag value.
+ t.Run("etag mismatch", func(t *testing.T) {
+ fx.maybeSkip(t)
+ parent := fx.nextParent(t, false)
+ created := fx.create(t, parent)
+ msg := fx.Update(parent)
+ msg.Name = created.Name
+ _, err := fx.Service().UpdateFeature(fx.Context(), &UpdateFeatureRequest{
+ Feature: msg,
+ })
+ assert.Equal(t, codes.Aborted, status.Code(err), err)
+ })
+
+ // Field etag should have a new value when the resource is successfully updated.
+ t.Run("etag updated", func(t *testing.T) {
+ fx.maybeSkip(t)
+ parent := fx.nextParent(t, false)
+ created := fx.create(t, parent)
+ msg := fx.Update(parent)
+ msg.Name = created.Name
+ updated, err := fx.Service().UpdateFeature(fx.Context(), &UpdateFeatureRequest{
+ Feature: msg,
+ })
+ assert.NilError(t, err)
+ _ = updated
+ })
+
parent := fx.nextParent(t, false)
created := fx.create(t, parent)
// Method should fail with NotFound if the resource does not exist.
@@ -708,6 +735,33 @@ func (fx *FeatureRegistryServiceFeatureGroupTestSuiteConfig) testUpdate(t *testi
assert.Equal(t, codes.InvalidArgument, status.Code(err), err)
})
+ // Method should fail with Aborted if the supplied etag doesnt match the current etag value.
+ t.Run("etag mismatch", func(t *testing.T) {
+ fx.maybeSkip(t)
+ parent := fx.nextParent(t, false)
+ created := fx.create(t, parent)
+ msg := fx.Update(parent)
+ msg.Name = created.Name
+ _, err := fx.Service().UpdateFeatureGroup(fx.Context(), &UpdateFeatureGroupRequest{
+ FeatureGroup: msg,
+ })
+ assert.Equal(t, codes.Aborted, status.Code(err), err)
+ })
+
+ // Field etag should have a new value when the resource is successfully updated.
+ t.Run("etag updated", func(t *testing.T) {
+ fx.maybeSkip(t)
+ parent := fx.nextParent(t, false)
+ created := fx.create(t, parent)
+ msg := fx.Update(parent)
+ msg.Name = created.Name
+ updated, err := fx.Service().UpdateFeatureGroup(fx.Context(), &UpdateFeatureGroupRequest{
+ FeatureGroup: msg,
+ })
+ assert.NilError(t, err)
+ _ = updated
+ })
+
parent := fx.nextParent(t, false)
created := fx.create(t, parent)
// Method should fail with NotFound if the resource does not exist.
diff --git a/proto/gen/googleapis/aiplatform/apiv1/aiplatformpb/featurestore_service_aiptest.pb.go b/proto/gen/googleapis/aiplatform/apiv1/aiplatformpb/featurestore_service_aiptest.pb.go
index 7709b620..d68deb57 100644
--- a/proto/gen/googleapis/aiplatform/apiv1/aiplatformpb/featurestore_service_aiptest.pb.go
+++ b/proto/gen/googleapis/aiplatform/apiv1/aiplatformpb/featurestore_service_aiptest.pb.go
@@ -266,6 +266,35 @@ func (fx *FeaturestoreServiceEntityTypeTestSuiteConfig) testUpdate(t *testing.T)
assert.DeepEqual(t, updated, persisted, protocmp.Transform())
})
+ // Method should fail with Aborted if the supplied etag doesnt match the current etag value.
+ t.Run("etag mismatch", func(t *testing.T) {
+ fx.maybeSkip(t)
+ parent := fx.nextParent(t, false)
+ created := fx.create(t, parent)
+ msg := fx.Update(parent)
+ msg.Name = created.Name
+ msg.Etag = `"99999"`
+ _, err := fx.Service().UpdateEntityType(fx.Context(), &UpdateEntityTypeRequest{
+ EntityType: msg,
+ })
+ assert.Equal(t, codes.Aborted, status.Code(err), err)
+ })
+
+ // Field etag should have a new value when the resource is successfully updated.
+ t.Run("etag updated", func(t *testing.T) {
+ fx.maybeSkip(t)
+ parent := fx.nextParent(t, false)
+ created := fx.create(t, parent)
+ msg := fx.Update(parent)
+ msg.Name = created.Name
+ msg.Etag = created.Etag
+ updated, err := fx.Service().UpdateEntityType(fx.Context(), &UpdateEntityTypeRequest{
+ EntityType: msg,
+ })
+ assert.NilError(t, err)
+ assert.Check(t, updated.Etag != created.Etag)
+ })
+
parent := fx.nextParent(t, false)
created := fx.create(t, parent)
// Method should fail with NotFound if the resource does not exist.
@@ -705,6 +734,35 @@ func (fx *FeaturestoreServiceFeatureTestSuiteConfig) testUpdate(t *testing.T) {
assert.DeepEqual(t, updated, persisted, protocmp.Transform())
})
+ // Method should fail with Aborted if the supplied etag doesnt match the current etag value.
+ t.Run("etag mismatch", func(t *testing.T) {
+ fx.maybeSkip(t)
+ parent := fx.nextParent(t, false)
+ created := fx.create(t, parent)
+ msg := fx.Update(parent)
+ msg.Name = created.Name
+ msg.Etag = `"99999"`
+ _, err := fx.Service().UpdateFeature(fx.Context(), &UpdateFeatureRequest{
+ Feature: msg,
+ })
+ assert.Equal(t, codes.Aborted, status.Code(err), err)
+ })
+
+ // Field etag should have a new value when the resource is successfully updated.
+ t.Run("etag updated", func(t *testing.T) {
+ fx.maybeSkip(t)
+ parent := fx.nextParent(t, false)
+ created := fx.create(t, parent)
+ msg := fx.Update(parent)
+ msg.Name = created.Name
+ msg.Etag = created.Etag
+ updated, err := fx.Service().UpdateFeature(fx.Context(), &UpdateFeatureRequest{
+ Feature: msg,
+ })
+ assert.NilError(t, err)
+ assert.Check(t, updated.Etag != created.Etag)
+ })
+
parent := fx.nextParent(t, false)
created := fx.create(t, parent)
// Method should fail with NotFound if the resource does not exist.
@@ -1152,6 +1210,33 @@ func (fx *FeaturestoreServiceFeaturestoreTestSuiteConfig) testUpdate(t *testing.
assert.Equal(t, codes.InvalidArgument, status.Code(err), err)
})
+ // Method should fail with Aborted if the supplied etag doesnt match the current etag value.
+ t.Run("etag mismatch", func(t *testing.T) {
+ fx.maybeSkip(t)
+ parent := fx.nextParent(t, false)
+ created := fx.create(t, parent)
+ msg := fx.Update(parent)
+ msg.Name = created.Name
+ _, err := fx.Service().UpdateFeaturestore(fx.Context(), &UpdateFeaturestoreRequest{
+ Featurestore: msg,
+ })
+ assert.Equal(t, codes.Aborted, status.Code(err), err)
+ })
+
+ // Field etag should have a new value when the resource is successfully updated.
+ t.Run("etag updated", func(t *testing.T) {
+ fx.maybeSkip(t)
+ parent := fx.nextParent(t, false)
+ created := fx.create(t, parent)
+ msg := fx.Update(parent)
+ msg.Name = created.Name
+ updated, err := fx.Service().UpdateFeaturestore(fx.Context(), &UpdateFeaturestoreRequest{
+ Featurestore: msg,
+ })
+ assert.NilError(t, err)
+ _ = updated
+ })
+
parent := fx.nextParent(t, false)
created := fx.create(t, parent)
// Method should fail with NotFound if the resource does not exist.
diff --git a/proto/gen/googleapis/aiplatform/apiv1/aiplatformpb/index_endpoint_service_aiptest.pb.go b/proto/gen/googleapis/aiplatform/apiv1/aiplatformpb/index_endpoint_service_aiptest.pb.go
index 4e76116a..05ac57e9 100644
--- a/proto/gen/googleapis/aiplatform/apiv1/aiplatformpb/index_endpoint_service_aiptest.pb.go
+++ b/proto/gen/googleapis/aiplatform/apiv1/aiplatformpb/index_endpoint_service_aiptest.pb.go
@@ -284,6 +284,35 @@ func (fx *IndexEndpointServiceIndexEndpointTestSuiteConfig) testUpdate(t *testin
assert.DeepEqual(t, originalCreateTime, updated.CreateTime, protocmp.Transform())
})
+ // Method should fail with Aborted if the supplied etag doesnt match the current etag value.
+ t.Run("etag mismatch", func(t *testing.T) {
+ fx.maybeSkip(t)
+ parent := fx.nextParent(t, false)
+ created := fx.create(t, parent)
+ msg := fx.Update(parent)
+ msg.Name = created.Name
+ msg.Etag = `"99999"`
+ _, err := fx.Service().UpdateIndexEndpoint(fx.Context(), &UpdateIndexEndpointRequest{
+ IndexEndpoint: msg,
+ })
+ assert.Equal(t, codes.Aborted, status.Code(err), err)
+ })
+
+ // Field etag should have a new value when the resource is successfully updated.
+ t.Run("etag updated", func(t *testing.T) {
+ fx.maybeSkip(t)
+ parent := fx.nextParent(t, false)
+ created := fx.create(t, parent)
+ msg := fx.Update(parent)
+ msg.Name = created.Name
+ msg.Etag = created.Etag
+ updated, err := fx.Service().UpdateIndexEndpoint(fx.Context(), &UpdateIndexEndpointRequest{
+ IndexEndpoint: msg,
+ })
+ assert.NilError(t, err)
+ assert.Check(t, updated.Etag != created.Etag)
+ })
+
parent := fx.nextParent(t, false)
created := fx.create(t, parent)
// Method should fail with NotFound if the resource does not exist.
diff --git a/proto/gen/googleapis/aiplatform/apiv1/aiplatformpb/index_service_aiptest.pb.go b/proto/gen/googleapis/aiplatform/apiv1/aiplatformpb/index_service_aiptest.pb.go
index b10b208f..a211b176 100644
--- a/proto/gen/googleapis/aiplatform/apiv1/aiplatformpb/index_service_aiptest.pb.go
+++ b/proto/gen/googleapis/aiplatform/apiv1/aiplatformpb/index_service_aiptest.pb.go
@@ -234,6 +234,33 @@ func (fx *IndexServiceIndexTestSuiteConfig) testUpdate(t *testing.T) {
assert.Equal(t, codes.InvalidArgument, status.Code(err), err)
})
+ // Method should fail with Aborted if the supplied etag doesnt match the current etag value.
+ t.Run("etag mismatch", func(t *testing.T) {
+ fx.maybeSkip(t)
+ parent := fx.nextParent(t, false)
+ created := fx.create(t, parent)
+ msg := fx.Update(parent)
+ msg.Name = created.Name
+ _, err := fx.Service().UpdateIndex(fx.Context(), &UpdateIndexRequest{
+ Index: msg,
+ })
+ assert.Equal(t, codes.Aborted, status.Code(err), err)
+ })
+
+ // Field etag should have a new value when the resource is successfully updated.
+ t.Run("etag updated", func(t *testing.T) {
+ fx.maybeSkip(t)
+ parent := fx.nextParent(t, false)
+ created := fx.create(t, parent)
+ msg := fx.Update(parent)
+ msg.Name = created.Name
+ updated, err := fx.Service().UpdateIndex(fx.Context(), &UpdateIndexRequest{
+ Index: msg,
+ })
+ assert.NilError(t, err)
+ _ = updated
+ })
+
parent := fx.nextParent(t, false)
created := fx.create(t, parent)
// Method should fail with NotFound if the resource does not exist.
diff --git a/proto/gen/googleapis/aiplatform/apiv1/aiplatformpb/metadata_service_aiptest.pb.go b/proto/gen/googleapis/aiplatform/apiv1/aiplatformpb/metadata_service_aiptest.pb.go
index db74a01a..66e3a670 100644
--- a/proto/gen/googleapis/aiplatform/apiv1/aiplatformpb/metadata_service_aiptest.pb.go
+++ b/proto/gen/googleapis/aiplatform/apiv1/aiplatformpb/metadata_service_aiptest.pb.go
@@ -374,6 +374,35 @@ func (fx *MetadataServiceArtifactTestSuiteConfig) testUpdate(t *testing.T) {
assert.DeepEqual(t, updated, persisted, protocmp.Transform())
})
+ // Method should fail with Aborted if the supplied etag doesnt match the current etag value.
+ t.Run("etag mismatch", func(t *testing.T) {
+ fx.maybeSkip(t)
+ parent := fx.nextParent(t, false)
+ created := fx.create(t, parent)
+ msg := fx.Update(parent)
+ msg.Name = created.Name
+ msg.Etag = `"99999"`
+ _, err := fx.Service().UpdateArtifact(fx.Context(), &UpdateArtifactRequest{
+ Artifact: msg,
+ })
+ assert.Equal(t, codes.Aborted, status.Code(err), err)
+ })
+
+ // Field etag should have a new value when the resource is successfully updated.
+ t.Run("etag updated", func(t *testing.T) {
+ fx.maybeSkip(t)
+ parent := fx.nextParent(t, false)
+ created := fx.create(t, parent)
+ msg := fx.Update(parent)
+ msg.Name = created.Name
+ msg.Etag = created.Etag
+ updated, err := fx.Service().UpdateArtifact(fx.Context(), &UpdateArtifactRequest{
+ Artifact: msg,
+ })
+ assert.NilError(t, err)
+ assert.Check(t, updated.Etag != created.Etag)
+ })
+
parent := fx.nextParent(t, false)
created := fx.create(t, parent)
// Method should fail with NotFound if the resource does not exist.
@@ -869,6 +898,35 @@ func (fx *MetadataServiceContextTestSuiteConfig) testUpdate(t *testing.T) {
assert.DeepEqual(t, updated, persisted, protocmp.Transform())
})
+ // Method should fail with Aborted if the supplied etag doesnt match the current etag value.
+ t.Run("etag mismatch", func(t *testing.T) {
+ fx.maybeSkip(t)
+ parent := fx.nextParent(t, false)
+ created := fx.create(t, parent)
+ msg := fx.Update(parent)
+ msg.Name = created.Name
+ msg.Etag = `"99999"`
+ _, err := fx.Service().UpdateContext(fx.Context(), &UpdateContextRequest{
+ Context: msg,
+ })
+ assert.Equal(t, codes.Aborted, status.Code(err), err)
+ })
+
+ // Field etag should have a new value when the resource is successfully updated.
+ t.Run("etag updated", func(t *testing.T) {
+ fx.maybeSkip(t)
+ parent := fx.nextParent(t, false)
+ created := fx.create(t, parent)
+ msg := fx.Update(parent)
+ msg.Name = created.Name
+ msg.Etag = created.Etag
+ updated, err := fx.Service().UpdateContext(fx.Context(), &UpdateContextRequest{
+ Context: msg,
+ })
+ assert.NilError(t, err)
+ assert.Check(t, updated.Etag != created.Etag)
+ })
+
parent := fx.nextParent(t, false)
created := fx.create(t, parent)
// Method should fail with NotFound if the resource does not exist.
@@ -1364,6 +1422,35 @@ func (fx *MetadataServiceExecutionTestSuiteConfig) testUpdate(t *testing.T) {
assert.DeepEqual(t, updated, persisted, protocmp.Transform())
})
+ // Method should fail with Aborted if the supplied etag doesnt match the current etag value.
+ t.Run("etag mismatch", func(t *testing.T) {
+ fx.maybeSkip(t)
+ parent := fx.nextParent(t, false)
+ created := fx.create(t, parent)
+ msg := fx.Update(parent)
+ msg.Name = created.Name
+ msg.Etag = `"99999"`
+ _, err := fx.Service().UpdateExecution(fx.Context(), &UpdateExecutionRequest{
+ Execution: msg,
+ })
+ assert.Equal(t, codes.Aborted, status.Code(err), err)
+ })
+
+ // Field etag should have a new value when the resource is successfully updated.
+ t.Run("etag updated", func(t *testing.T) {
+ fx.maybeSkip(t)
+ parent := fx.nextParent(t, false)
+ created := fx.create(t, parent)
+ msg := fx.Update(parent)
+ msg.Name = created.Name
+ msg.Etag = created.Etag
+ updated, err := fx.Service().UpdateExecution(fx.Context(), &UpdateExecutionRequest{
+ Execution: msg,
+ })
+ assert.NilError(t, err)
+ assert.Check(t, updated.Etag != created.Etag)
+ })
+
parent := fx.nextParent(t, false)
created := fx.create(t, parent)
// Method should fail with NotFound if the resource does not exist.
diff --git a/proto/gen/googleapis/aiplatform/apiv1/aiplatformpb/model_service_aiptest.pb.go b/proto/gen/googleapis/aiplatform/apiv1/aiplatformpb/model_service_aiptest.pb.go
index a2a86db0..cde74141 100644
--- a/proto/gen/googleapis/aiplatform/apiv1/aiplatformpb/model_service_aiptest.pb.go
+++ b/proto/gen/googleapis/aiplatform/apiv1/aiplatformpb/model_service_aiptest.pb.go
@@ -262,6 +262,35 @@ func (fx *ModelServiceModelTestSuiteConfig) testUpdate(t *testing.T) {
assert.DeepEqual(t, originalCreateTime, updated.CreateTime, protocmp.Transform())
})
+ // Method should fail with Aborted if the supplied etag doesnt match the current etag value.
+ t.Run("etag mismatch", func(t *testing.T) {
+ fx.maybeSkip(t)
+ parent := fx.nextParent(t, false)
+ created := fx.create(t, parent)
+ msg := fx.Update(parent)
+ msg.Name = created.Name
+ msg.Etag = `"99999"`
+ _, err := fx.Service().UpdateModel(fx.Context(), &UpdateModelRequest{
+ Model: msg,
+ })
+ assert.Equal(t, codes.Aborted, status.Code(err), err)
+ })
+
+ // Field etag should have a new value when the resource is successfully updated.
+ t.Run("etag updated", func(t *testing.T) {
+ fx.maybeSkip(t)
+ parent := fx.nextParent(t, false)
+ created := fx.create(t, parent)
+ msg := fx.Update(parent)
+ msg.Name = created.Name
+ msg.Etag = created.Etag
+ updated, err := fx.Service().UpdateModel(fx.Context(), &UpdateModelRequest{
+ Model: msg,
+ })
+ assert.NilError(t, err)
+ assert.Check(t, updated.Etag != created.Etag)
+ })
+
parent := fx.nextParent(t, false)
created := fx.create(t, parent)
// Method should fail with NotFound if the resource does not exist.
diff --git a/proto/gen/googleapis/aiplatform/apiv1/aiplatformpb/tensorboard_service_aiptest.pb.go b/proto/gen/googleapis/aiplatform/apiv1/aiplatformpb/tensorboard_service_aiptest.pb.go
index 15157459..dde1bbe6 100644
--- a/proto/gen/googleapis/aiplatform/apiv1/aiplatformpb/tensorboard_service_aiptest.pb.go
+++ b/proto/gen/googleapis/aiplatform/apiv1/aiplatformpb/tensorboard_service_aiptest.pb.go
@@ -316,6 +316,33 @@ func (fx *TensorboardServiceTensorboardTestSuiteConfig) testUpdate(t *testing.T)
assert.Equal(t, codes.InvalidArgument, status.Code(err), err)
})
+ // Method should fail with Aborted if the supplied etag doesnt match the current etag value.
+ t.Run("etag mismatch", func(t *testing.T) {
+ fx.maybeSkip(t)
+ parent := fx.nextParent(t, false)
+ created := fx.create(t, parent)
+ msg := fx.Update(parent)
+ msg.Name = created.Name
+ _, err := fx.Service().UpdateTensorboard(fx.Context(), &UpdateTensorboardRequest{
+ Tensorboard: msg,
+ })
+ assert.Equal(t, codes.Aborted, status.Code(err), err)
+ })
+
+ // Field etag should have a new value when the resource is successfully updated.
+ t.Run("etag updated", func(t *testing.T) {
+ fx.maybeSkip(t)
+ parent := fx.nextParent(t, false)
+ created := fx.create(t, parent)
+ msg := fx.Update(parent)
+ msg.Name = created.Name
+ updated, err := fx.Service().UpdateTensorboard(fx.Context(), &UpdateTensorboardRequest{
+ Tensorboard: msg,
+ })
+ assert.NilError(t, err)
+ _ = updated
+ })
+
parent := fx.nextParent(t, false)
created := fx.create(t, parent)
// Method should fail with NotFound if the resource does not exist.
@@ -839,6 +866,35 @@ func (fx *TensorboardServiceTensorboardExperimentTestSuiteConfig) testUpdate(t *
assert.DeepEqual(t, updated, persisted, protocmp.Transform())
})
+ // Method should fail with Aborted if the supplied etag doesnt match the current etag value.
+ t.Run("etag mismatch", func(t *testing.T) {
+ fx.maybeSkip(t)
+ parent := fx.nextParent(t, false)
+ created := fx.create(t, parent)
+ msg := fx.Update(parent)
+ msg.Name = created.Name
+ msg.Etag = `"99999"`
+ _, err := fx.Service().UpdateTensorboardExperiment(fx.Context(), &UpdateTensorboardExperimentRequest{
+ TensorboardExperiment: msg,
+ })
+ assert.Equal(t, codes.Aborted, status.Code(err), err)
+ })
+
+ // Field etag should have a new value when the resource is successfully updated.
+ t.Run("etag updated", func(t *testing.T) {
+ fx.maybeSkip(t)
+ parent := fx.nextParent(t, false)
+ created := fx.create(t, parent)
+ msg := fx.Update(parent)
+ msg.Name = created.Name
+ msg.Etag = created.Etag
+ updated, err := fx.Service().UpdateTensorboardExperiment(fx.Context(), &UpdateTensorboardExperimentRequest{
+ TensorboardExperiment: msg,
+ })
+ assert.NilError(t, err)
+ assert.Check(t, updated.Etag != created.Etag)
+ })
+
parent := fx.nextParent(t, false)
created := fx.create(t, parent)
// Method should fail with NotFound if the resource does not exist.
@@ -1362,6 +1418,35 @@ func (fx *TensorboardServiceTensorboardRunTestSuiteConfig) testUpdate(t *testing
assert.DeepEqual(t, originalCreateTime, updated.CreateTime, protocmp.Transform())
})
+ // Method should fail with Aborted if the supplied etag doesnt match the current etag value.
+ t.Run("etag mismatch", func(t *testing.T) {
+ fx.maybeSkip(t)
+ parent := fx.nextParent(t, false)
+ created := fx.create(t, parent)
+ msg := fx.Update(parent)
+ msg.Name = created.Name
+ msg.Etag = `"99999"`
+ _, err := fx.Service().UpdateTensorboardRun(fx.Context(), &UpdateTensorboardRunRequest{
+ TensorboardRun: msg,
+ })
+ assert.Equal(t, codes.Aborted, status.Code(err), err)
+ })
+
+ // Field etag should have a new value when the resource is successfully updated.
+ t.Run("etag updated", func(t *testing.T) {
+ fx.maybeSkip(t)
+ parent := fx.nextParent(t, false)
+ created := fx.create(t, parent)
+ msg := fx.Update(parent)
+ msg.Name = created.Name
+ msg.Etag = created.Etag
+ updated, err := fx.Service().UpdateTensorboardRun(fx.Context(), &UpdateTensorboardRunRequest{
+ TensorboardRun: msg,
+ })
+ assert.NilError(t, err)
+ assert.Check(t, updated.Etag != created.Etag)
+ })
+
parent := fx.nextParent(t, false)
created := fx.create(t, parent)
// Method should fail with NotFound if the resource does not exist.
@@ -1926,6 +2011,35 @@ func (fx *TensorboardServiceTensorboardTimeSeriesTestSuiteConfig) testUpdate(t *
assert.DeepEqual(t, originalCreateTime, updated.CreateTime, protocmp.Transform())
})
+ // Method should fail with Aborted if the supplied etag doesnt match the current etag value.
+ t.Run("etag mismatch", func(t *testing.T) {
+ fx.maybeSkip(t)
+ parent := fx.nextParent(t, false)
+ created := fx.create(t, parent)
+ msg := fx.Update(parent)
+ msg.Name = created.Name
+ msg.Etag = `"99999"`
+ _, err := fx.Service().UpdateTensorboardTimeSeries(fx.Context(), &UpdateTensorboardTimeSeriesRequest{
+ TensorboardTimeSeries: msg,
+ })
+ assert.Equal(t, codes.Aborted, status.Code(err), err)
+ })
+
+ // Field etag should have a new value when the resource is successfully updated.
+ t.Run("etag updated", func(t *testing.T) {
+ fx.maybeSkip(t)
+ parent := fx.nextParent(t, false)
+ created := fx.create(t, parent)
+ msg := fx.Update(parent)
+ msg.Name = created.Name
+ msg.Etag = created.Etag
+ updated, err := fx.Service().UpdateTensorboardTimeSeries(fx.Context(), &UpdateTensorboardTimeSeriesRequest{
+ TensorboardTimeSeries: msg,
+ })
+ assert.NilError(t, err)
+ assert.Check(t, updated.Etag != created.Etag)
+ })
+
parent := fx.nextParent(t, false)
created := fx.create(t, parent)
// Method should fail with NotFound if the resource does not exist.
diff --git a/proto/gen/googleapis/spanner/admin/instance/apiv1/instancepb/spanner_instance_admin_aiptest.pb.go b/proto/gen/googleapis/spanner/admin/instance/apiv1/instancepb/spanner_instance_admin_aiptest.pb.go
index 3beb8095..3c3b3620 100644
--- a/proto/gen/googleapis/spanner/admin/instance/apiv1/instancepb/spanner_instance_admin_aiptest.pb.go
+++ b/proto/gen/googleapis/spanner/admin/instance/apiv1/instancepb/spanner_instance_admin_aiptest.pb.go
@@ -909,6 +909,33 @@ func (fx *InstanceAdminInstanceConfigTestSuiteConfig) testUpdate(t *testing.T) {
assert.Equal(t, codes.InvalidArgument, status.Code(err), err)
})
+ // Method should fail with Aborted if the supplied etag doesnt match the current etag value.
+ t.Run("etag mismatch", func(t *testing.T) {
+ fx.maybeSkip(t)
+ parent := fx.nextParent(t, false)
+ created := fx.create(t, parent)
+ msg := fx.Update(parent)
+ msg.Name = created.Name
+ _, err := fx.Service().UpdateInstanceConfig(fx.Context(), &UpdateInstanceConfigRequest{
+ InstanceConfig: msg,
+ })
+ assert.Equal(t, codes.Aborted, status.Code(err), err)
+ })
+
+ // Field etag should have a new value when the resource is successfully updated.
+ t.Run("etag updated", func(t *testing.T) {
+ fx.maybeSkip(t)
+ parent := fx.nextParent(t, false)
+ created := fx.create(t, parent)
+ msg := fx.Update(parent)
+ msg.Name = created.Name
+ updated, err := fx.Service().UpdateInstanceConfig(fx.Context(), &UpdateInstanceConfigRequest{
+ InstanceConfig: msg,
+ })
+ assert.NilError(t, err)
+ _ = updated
+ })
+
parent := fx.nextParent(t, false)
created := fx.create(t, parent)
// Method should fail with NotFound if the resource does not exist.
@@ -1405,6 +1432,33 @@ func (fx *InstanceAdminInstancePartitionTestSuiteConfig) testUpdate(t *testing.T
assert.Equal(t, codes.InvalidArgument, status.Code(err), err)
})
+ // Method should fail with Aborted if the supplied etag doesnt match the current etag value.
+ t.Run("etag mismatch", func(t *testing.T) {
+ fx.maybeSkip(t)
+ parent := fx.nextParent(t, false)
+ created := fx.create(t, parent)
+ msg := fx.Update(parent)
+ msg.Name = created.Name
+ _, err := fx.Service().UpdateInstancePartition(fx.Context(), &UpdateInstancePartitionRequest{
+ InstancePartition: msg,
+ })
+ assert.Equal(t, codes.Aborted, status.Code(err), err)
+ })
+
+ // Field etag should have a new value when the resource is successfully updated.
+ t.Run("etag updated", func(t *testing.T) {
+ fx.maybeSkip(t)
+ parent := fx.nextParent(t, false)
+ created := fx.create(t, parent)
+ msg := fx.Update(parent)
+ msg.Name = created.Name
+ updated, err := fx.Service().UpdateInstancePartition(fx.Context(), &UpdateInstancePartitionRequest{
+ InstancePartition: msg,
+ })
+ assert.NilError(t, err)
+ _ = updated
+ })
+
parent := fx.nextParent(t, false)
created := fx.create(t, parent)
// Method should fail with NotFound if the resource does not exist.