go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/bisection/metrics/metrics_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 metrics
    16  
    17  import (
    18  	"context"
    19  	"testing"
    20  	"time"
    21  
    22  	. "github.com/smartystreets/goconvey/convey"
    23  	"go.chromium.org/luci/bisection/model"
    24  	pb "go.chromium.org/luci/bisection/proto/v1"
    25  	"go.chromium.org/luci/bisection/util/testutil"
    26  	buildbucketpb "go.chromium.org/luci/buildbucket/proto"
    27  	"go.chromium.org/luci/common/clock"
    28  	"go.chromium.org/luci/common/clock/testclock"
    29  	"go.chromium.org/luci/common/tsmon"
    30  	"go.chromium.org/luci/gae/impl/memory"
    31  	"go.chromium.org/luci/gae/service/datastore"
    32  )
    33  
    34  func TestCollectGlobalMetrics(t *testing.T) {
    35  	t.Parallel()
    36  	c := memory.Use(context.Background())
    37  	c, _ = tsmon.WithDummyInMemory(c)
    38  
    39  	Convey("running compile analyses", t, func() {
    40  		createRunningAnalysis(c, 123, "chromium", model.PlatformLinux)
    41  		createRunningAnalysis(c, 456, "chromeos", model.PlatformLinux)
    42  		createRunningAnalysis(c, 789, "chromium", model.PlatformLinux)
    43  		err := collectMetricsForRunningAnalyses(c)
    44  		So(err, ShouldBeNil)
    45  		So(runningAnalysesGauge.Get(c, "chromium", "compile"), ShouldEqual, 2)
    46  		So(runningAnalysesGauge.Get(c, "chromeos", "compile"), ShouldEqual, 1)
    47  
    48  		m, err := retrieveRunningAnalyses(c)
    49  		So(err, ShouldBeNil)
    50  		So(m, ShouldResemble, map[string]int{
    51  			"chromium": 2,
    52  			"chromeos": 1,
    53  		})
    54  	})
    55  
    56  	Convey("running test analyses", t, func() {
    57  		testutil.CreateTestFailureAnalysis(c, &testutil.TestFailureAnalysisCreationOption{
    58  			ID:        1000,
    59  			Project:   "chromium",
    60  			RunStatus: pb.AnalysisRunStatus_STARTED,
    61  		})
    62  		testutil.CreateTestFailureAnalysis(c, &testutil.TestFailureAnalysisCreationOption{
    63  			ID:        1001,
    64  			Project:   "chromium",
    65  			RunStatus: pb.AnalysisRunStatus_STARTED,
    66  		})
    67  		testutil.CreateTestFailureAnalysis(c, &testutil.TestFailureAnalysisCreationOption{
    68  			ID:        1002,
    69  			Project:   "chromeos",
    70  			RunStatus: pb.AnalysisRunStatus_STARTED,
    71  		})
    72  		testutil.CreateTestFailureAnalysis(c, &testutil.TestFailureAnalysisCreationOption{
    73  			ID:        1003,
    74  			Project:   "chromeos",
    75  			RunStatus: pb.AnalysisRunStatus_ENDED,
    76  		})
    77  		err := collectMetricsForRunningAnalyses(c)
    78  		So(err, ShouldBeNil)
    79  		So(runningAnalysesGauge.Get(c, "chromium", "test"), ShouldEqual, 2)
    80  		So(runningAnalysesGauge.Get(c, "chromeos", "test"), ShouldEqual, 1)
    81  
    82  		m, err := retrieveRunningAnalyses(c)
    83  		So(err, ShouldBeNil)
    84  		So(m, ShouldResemble, map[string]int{
    85  			"chromium": 2,
    86  			"chromeos": 1,
    87  		})
    88  	})
    89  
    90  	Convey("For running reruns", t, func() {
    91  		cl := testclock.New(testclock.TestTimeUTC)
    92  		c = clock.Set(c, cl)
    93  		testutil.UpdateIndices(c)
    94  
    95  		// Create a rerun for chromium
    96  		cfa1 := createRunningAnalysis(c, 123, "chromium", model.PlatformLinux)
    97  
    98  		rrBuild1 := &model.CompileRerunBuild{
    99  			LuciBuild: model.LuciBuild{
   100  				Status: buildbucketpb.Status_STATUS_UNSPECIFIED,
   101  			},
   102  		}
   103  		So(datastore.Put(c, rrBuild1), ShouldBeNil)
   104  		datastore.GetTestable(c).CatchupIndexes()
   105  
   106  		rerun1 := &model.SingleRerun{
   107  			Analysis:   datastore.KeyForObj(c, cfa1),
   108  			RerunBuild: datastore.KeyForObj(c, rrBuild1),
   109  			CreateTime: clock.Now(c).Add(-10 * time.Second),
   110  			Status:     pb.RerunStatus_RERUN_STATUS_IN_PROGRESS,
   111  		}
   112  		So(datastore.Put(c, rerun1), ShouldBeNil)
   113  		datastore.GetTestable(c).CatchupIndexes()
   114  
   115  		// Create another rerun for chromeos
   116  		cfa2 := createRunningAnalysis(c, 456, "chromeos", model.PlatformMac)
   117  
   118  		rrBuild2 := &model.CompileRerunBuild{
   119  			LuciBuild: model.LuciBuild{
   120  				Status: buildbucketpb.Status_STARTED,
   121  			},
   122  		}
   123  		So(datastore.Put(c, rrBuild2), ShouldBeNil)
   124  		datastore.GetTestable(c).CatchupIndexes()
   125  
   126  		rerun2 := &model.SingleRerun{
   127  			Analysis:   datastore.KeyForObj(c, cfa2),
   128  			RerunBuild: datastore.KeyForObj(c, rrBuild2),
   129  			CreateTime: clock.Now(c).Add(time.Minute),
   130  			Status:     pb.RerunStatus_RERUN_STATUS_IN_PROGRESS,
   131  		}
   132  		So(datastore.Put(c, rerun2), ShouldBeNil)
   133  		datastore.GetTestable(c).CatchupIndexes()
   134  
   135  		err := collectMetricsForRunningReruns(c)
   136  		So(err, ShouldBeNil)
   137  		So(runningRerunGauge.Get(c, "chromium", "pending", "linux", "compile"), ShouldEqual, 1)
   138  		So(runningRerunGauge.Get(c, "chromium", "running", "linux", "compile"), ShouldEqual, 0)
   139  		So(runningRerunGauge.Get(c, "chromeos", "pending", "mac", "compile"), ShouldEqual, 0)
   140  		So(runningRerunGauge.Get(c, "chromeos", "running", "mac", "compile"), ShouldEqual, 1)
   141  		dist := rerunAgeMetric.Get(c, "chromium", "pending", "linux", "compile")
   142  		So(dist.Count(), ShouldEqual, 1)
   143  		dist = rerunAgeMetric.Get(c, "chromeos", "running", "mac", "compile")
   144  		So(dist.Count(), ShouldEqual, 1)
   145  	})
   146  
   147  	Convey("running test reruns", t, func() {
   148  		cl := testclock.New(testclock.TestTimeUTC)
   149  		c = clock.Set(c, cl)
   150  		createRerun := func(ID int64, project, OS string, status buildbucketpb.Status) {
   151  			rerun := &model.TestSingleRerun{
   152  				ID:     ID,
   153  				Status: pb.RerunStatus_RERUN_STATUS_IN_PROGRESS,
   154  				LUCIBuild: model.LUCIBuild{
   155  					Project:    project,
   156  					Status:     status,
   157  					CreateTime: clock.Now(c).Add(-10 * time.Second),
   158  				},
   159  				Dimensions: &pb.Dimensions{Dimensions: []*pb.Dimension{{
   160  					Key:   "os",
   161  					Value: OS,
   162  				}}},
   163  			}
   164  			So(datastore.Put(c, rerun), ShouldBeNil)
   165  			datastore.GetTestable(c).CatchupIndexes()
   166  		}
   167  		createRerun(100, "chromium", "Ubuntu-22.04", buildbucketpb.Status_SCHEDULED)
   168  		createRerun(101, "chromium", "Ubuntu-22.04", buildbucketpb.Status_STARTED)
   169  		createRerun(102, "chromium", "Ubuntu-22.04", buildbucketpb.Status_STARTED)
   170  		createRerun(103, "chromium", "Mac-12", buildbucketpb.Status_STARTED)
   171  		createRerun(104, "chromeos", "Ubuntu-22.04", buildbucketpb.Status_STARTED)
   172  
   173  		err := collectMetricsForRunningTestReruns(c)
   174  		So(err, ShouldBeNil)
   175  		So(runningRerunGauge.Get(c, "chromium", "running", "linux", "test"), ShouldEqual, 2)
   176  		So(runningRerunGauge.Get(c, "chromium", "pending", "linux", "test"), ShouldEqual, 1)
   177  		So(runningRerunGauge.Get(c, "chromium", "running", "mac", "test"), ShouldEqual, 1)
   178  		So(runningRerunGauge.Get(c, "chromeos", "running", "linux", "test"), ShouldEqual, 1)
   179  		dist := rerunAgeMetric.Get(c, "chromium", "pending", "linux", "test")
   180  		So(dist.Count(), ShouldEqual, 1)
   181  		dist = rerunAgeMetric.Get(c, "chromeos", "running", "linux", "test")
   182  		So(dist.Count(), ShouldEqual, 1)
   183  	})
   184  }
   185  
   186  func createRunningAnalysis(c context.Context, id int64, proj string, platform model.Platform) *model.CompileFailureAnalysis {
   187  	fb := &model.LuciFailedBuild{
   188  		Id: id,
   189  		LuciBuild: model.LuciBuild{
   190  			Project: proj,
   191  		},
   192  		Platform: platform,
   193  	}
   194  	So(datastore.Put(c, fb), ShouldBeNil)
   195  	datastore.GetTestable(c).CatchupIndexes()
   196  
   197  	cf := testutil.CreateCompileFailure(c, fb)
   198  	cfa := &model.CompileFailureAnalysis{
   199  		Id:             id,
   200  		CompileFailure: datastore.KeyForObj(c, cf),
   201  		RunStatus:      pb.AnalysisRunStatus_STARTED,
   202  	}
   203  	So(datastore.Put(c, cfa), ShouldBeNil)
   204  	datastore.GetTestable(c).CatchupIndexes()
   205  	return cfa
   206  }