go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/cv/internal/rpc/admin/delete_entities_test.go (about) 1 // Copyright 2024 The LUCI Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package admin 16 17 import ( 18 "testing" 19 20 "go.chromium.org/luci/gae/service/datastore" 21 "go.chromium.org/luci/server/auth" 22 "go.chromium.org/luci/server/auth/authtest" 23 "go.chromium.org/luci/server/dsmapper" 24 "go.chromium.org/luci/server/dsmapper/dsmapperpb" 25 "go.chromium.org/luci/server/tq/tqtesting" 26 27 "go.chromium.org/luci/cv/internal/cvtesting" 28 adminpb "go.chromium.org/luci/cv/internal/rpc/admin/api" 29 30 . "github.com/smartystreets/goconvey/convey" 31 ) 32 33 func TestDeleteEntities(t *testing.T) { 34 t.Parallel() 35 36 Convey("Delete entities", t, func() { 37 ct := cvtesting.Test{} 38 ctx, cancel := ct.SetUp(t) 39 defer cancel() 40 41 ent := &MockEntity{ 42 ID: "foo", 43 } 44 So(datastore.Put(ctx, ent), ShouldBeNil) 45 46 runJobAndEnsureSuccess := func() { 47 ctrl := &dsmapper.Controller{} 48 ctrl.Install(ct.TQDispatcher) 49 a := New(ct.TQDispatcher, ctrl, nil, nil, nil) 50 ctx = auth.WithState(ctx, &authtest.FakeState{ 51 Identity: "user:admin@example.com", 52 IdentityGroups: []string{allowGroup}, 53 }) 54 55 jobID, err := a.DSMLaunchJob(ctx, &adminpb.DSMLaunchJobRequest{Name: "delete-entities"}) 56 So(err, ShouldBeNil) 57 ct.TQ.Run(ctx, tqtesting.StopWhenDrained()) 58 jobInfo, err := a.DSMGetJob(ctx, jobID) 59 So(err, ShouldBeNil) 60 So(jobInfo.GetInfo().GetState(), ShouldEqual, dsmapperpb.State_SUCCESS) 61 } 62 63 Convey("can delete target entities", func() { 64 entities := []*MockEntity{ 65 {ID: "foo"}, 66 {ID: "bar"}, 67 {ID: "baz"}, 68 } 69 So(datastore.Put(ctx, entities), ShouldBeNil) 70 runJobAndEnsureSuccess() 71 res, err := datastore.Exists(ctx, entities) 72 So(err, ShouldBeNil) 73 So(res.List(0).Any(), ShouldBeFalse) 74 }) 75 76 Convey("can handle missing entity", func() { 77 entities := []*MockEntity{ 78 {ID: "foo"}, 79 {ID: "bar"}, 80 {ID: "baz"}, 81 } 82 So(datastore.Put(ctx, entities[0], entities[2]), ShouldBeNil) 83 runJobAndEnsureSuccess() 84 res, err := datastore.Exists(ctx, entities) 85 So(err, ShouldBeNil) 86 So(res.List(0).Any(), ShouldBeFalse) 87 }) 88 }) 89 } 90 91 type MockEntity struct { 92 // Kind must match the kind of `deleteEntityKind`. 93 _kind string `gae:"$kind,migration.VerifiedCQDRun"` 94 ID string `gae:"$id"` 95 }