go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/buildbucket/appengine/internal/buildercron/inactive_test.go (about) 1 // Copyright 2022 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 buildercron 16 17 import ( 18 "context" 19 "testing" 20 "time" 21 22 "go.chromium.org/luci/buildbucket/appengine/model" 23 "go.chromium.org/luci/common/clock/testclock" 24 "go.chromium.org/luci/gae/impl/memory" 25 "go.chromium.org/luci/gae/service/datastore" 26 27 pb "go.chromium.org/luci/buildbucket/proto" 28 29 . "github.com/smartystreets/goconvey/convey" 30 ) 31 32 func TestResetExpiredLeases(t *testing.T) { 33 t.Parallel() 34 35 Convey("RemoveInactiveBuilderStats", t, func() { 36 ctx := memory.Use(context.Background()) 37 now := testclock.TestTimeUTC 38 ctx, _ = testclock.UseTime(ctx, now) 39 datastore.GetTestable(ctx).AutoIndex(true) 40 datastore.GetTestable(ctx).Consistent(true) 41 42 Convey("works when the world is empty", func() { 43 So(RemoveInactiveBuilderStats(ctx), ShouldBeNil) 44 }) 45 46 builds := []*model.Build{ 47 { 48 ID: 1, 49 Proto: &pb.Build{ 50 Builder: &pb.BuilderID{ 51 Project: "prj", 52 Bucket: "bkt", 53 Builder: "bld", 54 }, 55 Status: pb.Status_SCHEDULED, 56 }, 57 }, 58 } 59 builder := &model.Builder{ 60 ID: "bld", 61 Parent: model.BucketKey(ctx, "prj", "bkt"), 62 ConfigHash: "deadbeef", 63 } 64 statExist := func() bool { 65 r, err := datastore.Exists(ctx, model.BuilderStatKey(ctx, "prj", "bkt", "bld")) 66 So(err, ShouldBeNil) 67 return r.Any() 68 } 69 70 var ( 71 fresh = now.Add(-1 * time.Hour) 72 old = now.Add(-1 * model.BuilderExpirationDuration) 73 ) 74 So(datastore.Put(ctx, builder), ShouldBeNil) 75 So(statExist(), ShouldBeFalse) 76 77 Convey("leaves Active Stats", func() { 78 So(model.UpdateBuilderStat(ctx, builds, fresh), ShouldBeNil) 79 So(RemoveInactiveBuilderStats(ctx), ShouldBeNil) 80 So(statExist(), ShouldBeTrue) 81 }) 82 83 Convey("removes BuilderStat for an inactive Builder", func() { 84 So(model.UpdateBuilderStat(ctx, builds, old), ShouldBeNil) 85 So(RemoveInactiveBuilderStats(ctx), ShouldBeNil) 86 So(statExist(), ShouldBeFalse) 87 }) 88 89 Convey("leaves young zombie BuilderStat", func() { 90 So(model.UpdateBuilderStat(ctx, builds, fresh), ShouldBeNil) 91 So(datastore.Delete(ctx, model.BuilderKey(ctx, "prj", "bkt", "bld")), ShouldBeNil) 92 So(RemoveInactiveBuilderStats(ctx), ShouldBeNil) 93 So(statExist(), ShouldBeTrue) 94 }) 95 96 Convey("removes old zombie BuilderStat", func() { 97 old := now.Add(-1 * model.BuilderStatZombieDuration) 98 So(model.UpdateBuilderStat(ctx, builds, old), ShouldBeNil) 99 So(datastore.Delete(ctx, model.BuilderKey(ctx, "prj", "bkt", "bld")), ShouldBeNil) 100 So(RemoveInactiveBuilderStats(ctx), ShouldBeNil) 101 So(statExist(), ShouldBeFalse) 102 }) 103 }) 104 }