blob: d8e72ba106c6722dee8fcf8adcf51303c551aa2e [file] [log] [blame]
// Copyright 2022 The LUCI Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package aggrmetrics
import (
"context"
"fmt"
"testing"
bbpb "go.chromium.org/luci/buildbucket/proto"
bbutil "go.chromium.org/luci/buildbucket/protoutil"
"go.chromium.org/luci/hardcoded/chromeinfra"
cfgpb "go.chromium.org/luci/cv/api/config/v2"
"go.chromium.org/luci/cv/internal/configs/prjcfg/prjcfgtest"
"go.chromium.org/luci/cv/internal/cvtesting"
"go.chromium.org/luci/cv/internal/metrics"
"go.chromium.org/luci/cv/internal/tryjob"
. "github.com/smartystreets/goconvey/convey"
)
func TestBuilderPresenceAggregator(t *testing.T) {
t.Parallel()
Convey("builderPresenceAggregator works", t, func() {
ct := cvtesting.Test{}
ctx, cancel := ct.SetUp()
defer cancel()
const (
lProject = "test_proj"
configGroupName = "test_config_group"
bucketName = "test_bucket"
builderName = "test_builder"
)
tryjobDef := &tryjob.Definition{
Backend: &tryjob.Definition_Buildbucket_{
Buildbucket: &tryjob.Definition_Buildbucket{
Host: chromeinfra.BuildbucketHost,
Builder: &bbpb.BuilderID{
Project: lProject,
Bucket: bucketName,
Builder: builderName,
},
},
},
}
builder := &cfgpb.Verifiers_Tryjob_Builder{
Name: bbutil.FormatBuilderID(tryjobDef.GetBuildbucket().GetBuilder()),
}
config := &cfgpb.Config{
ConfigGroups: []*cfgpb.ConfigGroup{
{
Name: configGroupName,
Verifiers: &cfgpb.Verifiers{
Tryjob: &cfgpb.Verifiers_Tryjob{
Builders: []*cfgpb.Verifiers_Tryjob_Builder{
builder,
},
},
},
},
},
}
prjcfgtest.Create(ctx, lProject, config)
mustReport := func(active ...string) {
bpa := builderPresenceAggregator{env: ct.Env}
err := bpa.report(ctx, active)
So(err, ShouldBeNil)
}
Convey("Skip disabled project", func() {
prjcfgtest.Disable(ctx, lProject)
mustReport(lProject)
So(ct.TSMonStore.GetAll(ctx), ShouldBeEmpty)
})
Convey("Plain builder", func() {
mustReport(lProject)
tryjob.RunWithBuilderMetricsTarget(ctx, ct.Env, tryjobDef, func(ctx context.Context) {
So(ct.TSMonSentValue(ctx, metrics.Public.TryjobBuilderPresence, lProject, configGroupName, false, false, false), ShouldBeTrue)
})
})
Convey("Includable only builder", func() {
builder.IncludableOnly = true
prjcfgtest.Update(ctx, lProject, config)
mustReport(lProject)
tryjob.RunWithBuilderMetricsTarget(ctx, ct.Env, tryjobDef, func(ctx context.Context) {
So(ct.TSMonSentValue(ctx, metrics.Public.TryjobBuilderPresence, lProject, configGroupName, true, false, false), ShouldBeTrue)
})
})
Convey("With Location filter", func() {
builder.LocationFilters = append(builder.LocationFilters, &cfgpb.Verifiers_Tryjob_Builder_LocationFilter{
PathRegexp: `.*\.md`,
})
prjcfgtest.Update(ctx, lProject, config)
mustReport(lProject)
tryjob.RunWithBuilderMetricsTarget(ctx, ct.Env, tryjobDef, func(ctx context.Context) {
So(ct.TSMonSentValue(ctx, metrics.Public.TryjobBuilderPresence, lProject, configGroupName, false, true, false), ShouldBeTrue)
})
})
Convey("Experimental", func() {
builder.ExperimentPercentage = 99.9
prjcfgtest.Update(ctx, lProject, config)
mustReport(lProject)
tryjob.RunWithBuilderMetricsTarget(ctx, ct.Env, tryjobDef, func(ctx context.Context) {
So(ct.TSMonSentValue(ctx, metrics.Public.TryjobBuilderPresence, lProject, configGroupName, false, false, true), ShouldBeTrue)
})
})
Convey("Multiple projects, config groups, builders", func() {
var builderCount int
genBuilders := func(count int) []*cfgpb.Verifiers_Tryjob_Builder {
ret := make([]*cfgpb.Verifiers_Tryjob_Builder, count)
for i := 0; i < count; i++ {
ret[i] = &cfgpb.Verifiers_Tryjob_Builder{
Name: fmt.Sprintf("%s/test-bucket/builder-%04d", lProject, builderCount+i),
}
}
builderCount += count
return ret
}
prjcfgtest.Create(ctx, "prj-0", &cfgpb.Config{
ConfigGroups: []*cfgpb.ConfigGroup{
{
Name: "cg-0",
Verifiers: &cfgpb.Verifiers{
Tryjob: &cfgpb.Verifiers_Tryjob{
Builders: genBuilders(3),
},
},
},
{
Name: "cg-1",
Verifiers: &cfgpb.Verifiers{
Tryjob: &cfgpb.Verifiers_Tryjob{
Builders: genBuilders(7),
},
},
},
},
})
prjcfgtest.Create(ctx, "prj-1", &cfgpb.Config{
ConfigGroups: []*cfgpb.ConfigGroup{
{
Name: "cg-0",
Verifiers: &cfgpb.Verifiers{
Tryjob: &cfgpb.Verifiers_Tryjob{
Builders: genBuilders(37),
},
},
},
},
})
prjcfgtest.Create(ctx, "prj-2", &cfgpb.Config{
ConfigGroups: []*cfgpb.ConfigGroup{
{
Name: "cg-0",
Verifiers: &cfgpb.Verifiers{
Tryjob: &cfgpb.Verifiers_Tryjob{
Builders: genBuilders(29),
},
},
},
},
})
mustReport("prj-0", "prj-1", "prj-2")
So(ct.TSMonStore.GetAll(ctx), ShouldHaveLength, builderCount)
})
})
}