go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/config_service/internal/retention/retention_test.go (about)

     1  // Copyright 2023 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 retention
    16  
    17  import (
    18  	"testing"
    19  	"time"
    20  
    21  	"github.com/golang/mock/gomock"
    22  
    23  	"go.chromium.org/luci/common/clock"
    24  	"go.chromium.org/luci/common/clock/testclock"
    25  	"go.chromium.org/luci/common/gcloud/gs"
    26  	"go.chromium.org/luci/config"
    27  	"go.chromium.org/luci/gae/service/datastore"
    28  
    29  	"go.chromium.org/luci/config_service/internal/clients"
    30  	"go.chromium.org/luci/config_service/internal/model"
    31  	"go.chromium.org/luci/config_service/testutil"
    32  
    33  	. "github.com/smartystreets/goconvey/convey"
    34  )
    35  
    36  func TestRetention(t *testing.T) {
    37  	t.Parallel()
    38  
    39  	Convey("DeleteStaleConfigs", t, func() {
    40  		ctx := testutil.SetupContext()
    41  		ctl := gomock.NewController(t)
    42  		mockGsClient := clients.NewMockGsClient(ctl)
    43  		ctx = clients.WithGsClient(ctx, mockGsClient)
    44  
    45  		cfgset := &model.ConfigSet{
    46  			ID:             config.MustProjectSet("foo"),
    47  			LatestRevision: model.RevisionInfo{ID: "latest"},
    48  		}
    49  		now := clock.Get(ctx).(testclock.TestClock).Now()
    50  		latestCfg := &model.File{
    51  			Path:       "config.cfg",
    52  			Revision:   datastore.MakeKey(ctx, model.ConfigSetKind, "projects/foo", model.RevisionKind, "latest"),
    53  			CreateTime: now,
    54  			GcsURI:     gs.MakePath("bucket", "latestCfg_sha256"),
    55  		}
    56  		oldCfg1 := &model.File{
    57  			Path:       "config.cfg",
    58  			Revision:   datastore.MakeKey(ctx, model.ConfigSetKind, "projects/foo", model.RevisionKind, "old1"),
    59  			CreateTime: now.Add(-configRetention - 1*time.Minute),
    60  			GcsURI:     gs.MakePath("bucket", "oldCfg1_sha256"),
    61  		}
    62  		oldCfg2 := &model.File{
    63  			Path:       "config.cfg",
    64  			Revision:   datastore.MakeKey(ctx, model.ConfigSetKind, "projects/foo", model.RevisionKind, "old2"),
    65  			CreateTime: now.Add(-configRetention - 2*time.Minute),
    66  			GcsURI:     gs.MakePath("bucket", "oldCfg2_sha256"),
    67  		}
    68  
    69  		anotherCfgset := &model.ConfigSet{
    70  			ID:             config.MustProjectSet("bar"),
    71  			LatestRevision: model.RevisionInfo{ID: "latest"},
    72  		}
    73  		barCfg := &model.File{
    74  			Path:       "config.cfg",
    75  			Revision:   datastore.MakeKey(ctx, model.ConfigSetKind, "projects/bar", model.RevisionKind, "latest"),
    76  			CreateTime: now,
    77  			GcsURI:     gs.MakePath("bucket", "oldCfg2_sha256"),
    78  		}
    79  
    80  		mockGsClient.EXPECT().Delete(gomock.Any(), gomock.Eq("bucket"), gomock.Eq("oldCfg1_sha256")).Return(nil)
    81  		// Don't expect oldCfg2's Gcs file to be deleted as it's referred by another in use File entity.
    82  		mockGsClient.EXPECT().Delete(gomock.Any(), gomock.Eq("bucket"), gomock.Eq("oldCfg2_sha256")).Times(0)
    83  		So(datastore.Put(ctx, cfgset, latestCfg, oldCfg1, oldCfg2, anotherCfgset, barCfg), ShouldBeNil)
    84  
    85  		So(DeleteStaleConfigs(ctx), ShouldBeNil)
    86  		exists, err := datastore.Exists(ctx, cfgset, latestCfg, oldCfg1, oldCfg2, anotherCfgset, barCfg)
    87  		So(err, ShouldBeNil)
    88  		So(exists.Get(0), ShouldBeTrue)  // cfgset
    89  		So(exists.Get(1), ShouldBeTrue)  // latestCfg
    90  		So(exists.Get(2), ShouldBeFalse) // oldCfg1
    91  		So(exists.Get(3), ShouldBeFalse) // oldCfg2
    92  		So(exists.Get(4), ShouldBeTrue)  // anotherCfgset
    93  		So(exists.Get(5), ShouldBeTrue)  // barCfg
    94  	})
    95  }