go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/buildbucket/appengine/internal/buildcron/retention_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 buildcron 16 17 import ( 18 "context" 19 "testing" 20 "time" 21 22 "go.chromium.org/luci/common/clock/testclock" 23 "go.chromium.org/luci/gae/impl/memory" 24 "go.chromium.org/luci/gae/service/datastore" 25 26 "go.chromium.org/luci/buildbucket/appengine/internal/buildid" 27 "go.chromium.org/luci/buildbucket/appengine/model" 28 pb "go.chromium.org/luci/buildbucket/proto" 29 30 . "github.com/smartystreets/goconvey/convey" 31 . "go.chromium.org/luci/common/testing/assertions" 32 ) 33 34 func TestDeleteOldBuilds(t *testing.T) { 35 t.Parallel() 36 37 Convey("DeleteOldBuilds", t, func() { 38 // now needs to be further fresh enough from buildid.beginningOfTheWorld 39 now := time.Date(2020, 01, 01, 0, 0, 0, 0, time.UTC) 40 41 ctx, _ := testclock.UseTime(memory.Use(context.Background()), now) 42 datastore.GetTestable(ctx).AutoIndex(true) 43 datastore.GetTestable(ctx).Consistent(true) 44 b := &model.Build{ 45 Proto: &pb.Build{ 46 Builder: &pb.BuilderID{ 47 Project: "project", 48 Bucket: "bucket", 49 Builder: "builder", 50 }, 51 Status: pb.Status_SUCCESS, 52 }, 53 } 54 setID := func(b *model.Build, t time.Time) { 55 b.ID = buildid.NewBuildIDs(ctx, t, 1)[0] 56 So(datastore.Put(ctx, b), ShouldBeNil) 57 So(datastore.Put(ctx, &model.BuildSteps{ 58 ID: 1, 59 Build: datastore.KeyForObj(ctx, b), 60 }), ShouldBeNil) 61 } 62 63 Convey("keeps builds", func() { 64 Convey("as old as BuildStorageDuration", func() { 65 setID(b, now.Add(-model.BuildStorageDuration)) 66 So(DeleteOldBuilds(ctx), ShouldBeNil) 67 So(datastore.Get(ctx, b), ShouldBeNil) 68 count, err := datastore.Count(ctx, datastore.NewQuery("")) 69 So(err, ShouldBeNil) 70 So(count, ShouldResemble, int64(2)) 71 }) 72 Convey("younger than BuildStorageDuration", func() { 73 setID(b, now.Add(-model.BuildStorageDuration+time.Minute)) 74 So(DeleteOldBuilds(ctx), ShouldBeNil) 75 count, err := datastore.Count(ctx, datastore.NewQuery("")) 76 So(err, ShouldBeNil) 77 So(count, ShouldResemble, int64(2)) 78 }) 79 }) 80 81 Convey("deletes builds older than BuildStorageDuration", func() { 82 setID(b, now.Add(-model.BuildStorageDuration-time.Minute)) 83 So(DeleteOldBuilds(ctx), ShouldBeNil) 84 So(datastore.Get(ctx, b), ShouldEqual, datastore.ErrNoSuchEntity) 85 count, err := datastore.Count(ctx, datastore.NewQuery("")) 86 So(err, ShouldBeNil) 87 So(count, ShouldResemble, int64(0)) 88 }) 89 90 Convey("removes many builds", func() { 91 bs := make([]model.Build, 234) 92 old := now.Add(-model.BuildStorageDuration - time.Minute) 93 for i := range bs { 94 bs[i] = *b 95 setID(&bs[i], old) 96 } 97 So(DeleteOldBuilds(ctx), ShouldBeNil) 98 count, err := datastore.Count(ctx, datastore.NewQuery("")) 99 So(err, ShouldBeNil) 100 So(count, ShouldResemble, int64(0)) 101 So(datastore.Get(ctx, bs), ShouldErrLike, 102 "datastore: no such entity (and 233 other errors)") 103 }) 104 }) 105 }