blob: 24035b495455b7c949ae1678c5a63e7874fe7126 [file] [log] [blame]
package buildbucket
import (
"context"
"strconv"
"testing"
"time"
"github.com/stretchr/testify/require"
buildbucketpb "go.chromium.org/luci/buildbucket/proto"
bb_mocks "go.skia.org/infra/go/buildbucket/mocks"
metrics_util "go.skia.org/infra/go/metrics2/testutils"
"go.skia.org/infra/go/testutils"
ts_mocks "go.skia.org/infra/task_scheduler/go/mocks"
"go.skia.org/infra/task_scheduler/go/types"
"google.golang.org/protobuf/types/known/timestamppb"
)
const (
fakeBuildbucketProject = "fake-project"
fakeBuildbucketBucket = "fake.bucket"
)
func TestDoMetrics(t *testing.T) {
ctx := context.Background()
tsDb := &ts_mocks.JobDB{}
defer tsDb.AssertExpectations(t)
bb2 := &bb_mocks.BuildBucketInterface{}
defer bb2.AssertExpectations(t)
// Set up mocks for buildbucket and task scheduler DB.
currentTime := time.Unix(1708706564, 0) // Arbitrary starting point.
const build1Age = 10 * time.Minute
const build2Age = 1 * time.Minute
const build1FinishLagTime = 5 * time.Minute
build1Created := currentTime.Add(-build1Age)
build2Created := currentTime.Add(-build2Age)
const job1Id = "job1"
job1Finished := currentTime.Add(-build1FinishLagTime)
build1 := &buildbucketpb.Build{
Id: 1,
CreateTime: timestamppb.New(build1Created),
Status: buildbucketpb.Status_STARTED,
Infra: &buildbucketpb.BuildInfra{
Backend: &buildbucketpb.BuildInfra_Backend{
Task: &buildbucketpb.Task{
Id: &buildbucketpb.TaskID{
Id: job1Id,
},
},
},
},
}
build2 := &buildbucketpb.Build{
Id: 2,
CreateTime: timestamppb.New(build2Created),
Status: buildbucketpb.Status_SCHEDULED,
}
job1 := &types.Job{
Id: job1Id,
Status: types.JOB_STATUS_SUCCESS,
Finished: job1Finished,
}
bb2.On("Search", testutils.AnyContext, &buildbucketpb.BuildPredicate{
Builder: &buildbucketpb.BuilderID{
Project: fakeBuildbucketProject,
Bucket: fakeBuildbucketBucket,
},
Status: buildbucketpb.Status_SCHEDULED,
}).Return([]*buildbucketpb.Build{build2}, nil)
bb2.On("Search", testutils.AnyContext, &buildbucketpb.BuildPredicate{
Builder: &buildbucketpb.BuilderID{
Project: fakeBuildbucketProject,
Bucket: fakeBuildbucketBucket,
},
Status: buildbucketpb.Status_STARTED,
}).Return([]*buildbucketpb.Build{build1}, nil)
tsDb.On("GetJobById", testutils.AnyContext, job1Id).Return(job1, nil)
// Run doMetrics.
metrics, err := doMetrics(ctx, tsDb, bb2, fakeBuildbucketProject, fakeBuildbucketBucket, currentTime)
require.NoError(t, err)
require.Len(t, metrics, 3)
// Retrieve the expected metrics and assert that they have the expected
// values.
tags1 := map[string]string{
"build_id": strconv.FormatInt(build1.Id, 10),
"build_state": build1.Status.String(),
"job_id": job1Id,
}
actualBuild1Age, err := strconv.ParseFloat(metrics_util.GetRecordedMetric(t, buildAgeMetric, tags1), 64)
require.NoError(t, err)
require.Equal(t, build1Age.Seconds(), actualBuild1Age)
tags2 := map[string]string{
"build_id": strconv.FormatInt(build2.Id, 10),
"build_state": build2.Status.String(),
"job_id": "",
}
actualBuild2Age, err := strconv.ParseFloat(metrics_util.GetRecordedMetric(t, buildAgeMetric, tags2), 64)
require.NoError(t, err)
require.Equal(t, int64(build2Age.Seconds()), int64(actualBuild2Age))
tags3 := map[string]string{
"build_id": strconv.FormatInt(build1.Id, 10),
"build_state": build1.Status.String(),
"job_id": job1Id,
"job_state": string(job1.Status),
}
actualBuild1FinishLag, err := strconv.ParseFloat(metrics_util.GetRecordedMetric(t, finishLagMetric, tags3), 64)
require.NoError(t, err)
require.Equal(t, int64(build1FinishLagTime.Seconds()), int64(actualBuild1FinishLag))
}