go.fuchsia.dev/infra@v0.0.0-20240507153436-9b593402251b/cmd/autogardener/culprit_test.go (about)

     1  // Copyright 2022 The Fuchsia Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style license that can be
     3  // found in the LICENSE file.
     4  
     5  package main
     6  
     7  import (
     8  	"math/rand"
     9  	"testing"
    10  
    11  	"github.com/google/go-cmp/cmp"
    12  	buildbucketpb "go.chromium.org/luci/buildbucket/proto"
    13  	resultpb "go.chromium.org/luci/resultdb/proto/v1"
    14  	"google.golang.org/protobuf/testing/protocmp"
    15  	"google.golang.org/protobuf/types/known/structpb"
    16  )
    17  
    18  func TestClusterFailureModes(t *testing.T) {
    19  	buildResults := []buildResult{
    20  		{
    21  			Build: failedBuild(),
    22  			FailedTests: []*resultpb.TestResult{
    23  				failedTest("foo", "foo failed"),
    24  			},
    25  		},
    26  		{
    27  			Build: failedBuild(),
    28  			FailedTests: []*resultpb.TestResult{
    29  				failedTest("foo", "foo failed"),
    30  			},
    31  		},
    32  		{
    33  			Build: failedBuild(),
    34  			FailedTests: []*resultpb.TestResult{
    35  				failedTest("bar", "bar failed"),
    36  			},
    37  		},
    38  		{
    39  			Build: failedBuild(),
    40  			FailedTests: []*resultpb.TestResult{
    41  				failedTest("quux", "quux failed"),
    42  			},
    43  		},
    44  	}
    45  
    46  	clusters := clusterFailureModes(buildResults)
    47  	want := map[failureSignature][]buildResult{
    48  		{
    49  			FailedTest:    "foo",
    50  			FailureReason: "foo failed",
    51  		}: buildResults[:2],
    52  	}
    53  	if diff := cmp.Diff(want, clusters, protocmp.Transform()); diff != "" {
    54  		t.Errorf("Got wrong clusters (-want +got):\n%s", diff)
    55  	}
    56  }
    57  
    58  func failedBuild() *buildbucketpb.Build {
    59  	return &buildbucketpb.Build{
    60  		Id:     rand.Int63(),
    61  		Status: buildbucketpb.Status_FAILURE,
    62  	}
    63  }
    64  
    65  func failedTest(testID, failureReason string) *resultpb.TestResult {
    66  	return &resultpb.TestResult{
    67  		TestId: testID,
    68  		FailureReason: &resultpb.FailureReason{
    69  			PrimaryErrorMessage: failureReason,
    70  		},
    71  	}
    72  }
    73  
    74  func TestIntegrationProjectName(t *testing.T) {
    75  	props, err := structpb.NewStruct(map[string]any{
    76  		"checkout_info": map[string]any{
    77  			"manifest_project": "foo",
    78  		},
    79  	})
    80  	if err != nil {
    81  		t.Fatal(err)
    82  	}
    83  	b := &buildbucketpb.Build{
    84  		Output: &buildbucketpb.Build_Output{Properties: props},
    85  	}
    86  	want := "foo"
    87  	got, err := integrationProjectName(b)
    88  	if err != nil {
    89  		t.Fatal(err)
    90  	}
    91  	if want != got {
    92  		t.Errorf("Wanted integration project name %q, got %q", want, got)
    93  	}
    94  }
    95  
    96  func TestIntegrationProjectName_Error(t *testing.T) {
    97  	props, err := structpb.NewStruct(map[string]any{
    98  		"checkout_info": map[string]any{},
    99  	})
   100  	if err != nil {
   101  		t.Fatal(err)
   102  	}
   103  	b := &buildbucketpb.Build{
   104  		Output: &buildbucketpb.Build_Output{Properties: props},
   105  	}
   106  	got, err := integrationProjectName(b)
   107  	if err == nil {
   108  		t.Fatalf("Expected an error, got %q", got)
   109  	}
   110  	want := "build 0 has no `checkout_info.manifest_project` property"
   111  	if err.Error() != want {
   112  		t.Errorf("Wanted error %q, got %q", want, err.Error())
   113  	}
   114  }