| // Copyright 2021 The Fuchsia Authors. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| package main |
| |
| import ( |
| "testing" |
| |
| buildbucketpb "go.chromium.org/luci/buildbucket/proto" |
| "go.fuchsia.dev/infra/cmd/autocorrelator/findings" |
| "google.golang.org/protobuf/types/known/structpb" |
| |
| "github.com/google/go-cmp/cmp" |
| ) |
| |
| func TestCheckTry(t *testing.T) { |
| t.Parallel() |
| |
| tests := []struct { |
| name string |
| builds []*buildbucketpb.Build |
| changeNum int64 |
| status buildbucketpb.Status |
| summaryMarkdown string |
| ignoreSkippedBuild bool |
| ignoreSkippedTests bool |
| ignoreFailedBuild bool |
| expected []*findings.SummarySimilarity |
| }{ |
| { |
| name: "many past builds", |
| builds: []*buildbucketpb.Build{ |
| { |
| Id: int64(999999), |
| Status: buildbucketpb.Status_SUCCESS, |
| SummaryMarkdown: "", |
| Input: &buildbucketpb.Build_Input{ |
| GerritChanges: []*buildbucketpb.GerritChange{ |
| { |
| Change: int64(111111), |
| }, |
| }, |
| }, |
| Output: &buildbucketpb.Build_Output{ |
| Properties: &structpb.Struct{ |
| Fields: map[string]*structpb.Value{}, |
| }, |
| }, |
| }, |
| { |
| Id: int64(999998), |
| Status: buildbucketpb.Status_FAILURE, |
| SummaryMarkdown: "ERROR", |
| Input: &buildbucketpb.Build_Input{ |
| GerritChanges: []*buildbucketpb.GerritChange{ |
| { |
| Change: int64(222222), |
| }, |
| }, |
| }, |
| Output: &buildbucketpb.Build_Output{ |
| Properties: &structpb.Struct{ |
| Fields: map[string]*structpb.Value{}, |
| }, |
| }, |
| }, |
| // This has an unaffected build graph, and should be ignored. |
| { |
| Id: int64(999997), |
| Status: buildbucketpb.Status_SUCCESS, |
| SummaryMarkdown: "", |
| Input: &buildbucketpb.Build_Input{ |
| GerritChanges: []*buildbucketpb.GerritChange{ |
| { |
| Change: int64(222222), |
| }, |
| }, |
| }, |
| Output: &buildbucketpb.Build_Output{ |
| Properties: &structpb.Struct{ |
| Fields: map[string]*structpb.Value{ |
| "skipped_because_unaffected": { |
| Kind: &structpb.Value_BoolValue{ |
| BoolValue: true, |
| }, |
| }, |
| }, |
| }, |
| }, |
| }, |
| // This has no affected tests, and should be ignored. |
| { |
| Id: int64(999996), |
| Status: buildbucketpb.Status_SUCCESS, |
| SummaryMarkdown: "", |
| Input: &buildbucketpb.Build_Input{ |
| GerritChanges: []*buildbucketpb.GerritChange{ |
| { |
| Change: int64(222222), |
| }, |
| }, |
| }, |
| Output: &buildbucketpb.Build_Output{ |
| Properties: &structpb.Struct{ |
| Fields: map[string]*structpb.Value{ |
| "affected_tests_no_work": { |
| Kind: &structpb.Value_BoolValue{ |
| BoolValue: true, |
| }, |
| }, |
| }, |
| }, |
| }, |
| }, |
| // This failed to build, and should be ignored. |
| { |
| Id: int64(999995), |
| Status: buildbucketpb.Status_SUCCESS, |
| SummaryMarkdown: "", |
| Input: &buildbucketpb.Build_Input{ |
| GerritChanges: []*buildbucketpb.GerritChange{ |
| { |
| Change: int64(222222), |
| }, |
| }, |
| }, |
| Output: &buildbucketpb.Build_Output{ |
| Properties: &structpb.Struct{ |
| Fields: map[string]*structpb.Value{ |
| "failed_to_build": { |
| Kind: &structpb.Value_BoolValue{ |
| BoolValue: true, |
| }, |
| }, |
| }, |
| }, |
| }, |
| }, |
| // This matches the input change number, and should be ignored. |
| { |
| Id: int64(999994), |
| Status: buildbucketpb.Status_FAILURE, |
| SummaryMarkdown: "ERROR", |
| Input: &buildbucketpb.Build_Input{ |
| GerritChanges: []*buildbucketpb.GerritChange{ |
| { |
| Change: int64(123456), |
| }, |
| }, |
| }, |
| Output: &buildbucketpb.Build_Output{ |
| Properties: &structpb.Struct{ |
| Fields: map[string]*structpb.Value{}, |
| }, |
| }, |
| }, |
| // This does not match the input status of FAILURE, and should |
| // be ignored. |
| { |
| Id: int64(999993), |
| Status: buildbucketpb.Status_INFRA_FAILURE, |
| SummaryMarkdown: "ERROR: checkout failed", |
| Input: &buildbucketpb.Build_Input{ |
| GerritChanges: []*buildbucketpb.GerritChange{ |
| { |
| Change: int64(333333), |
| }, |
| }, |
| }, |
| Output: &buildbucketpb.Build_Output{ |
| Properties: &structpb.Struct{ |
| Fields: map[string]*structpb.Value{}, |
| }, |
| }, |
| }, |
| // This has no output properties and should be ignored. |
| { |
| Id: int64(999992), |
| Status: buildbucketpb.Status_FAILURE, |
| SummaryMarkdown: "failed for unknown reasons", |
| Input: &buildbucketpb.Build_Input{ |
| GerritChanges: []*buildbucketpb.GerritChange{ |
| { |
| Change: int64(333333), |
| }, |
| }, |
| }, |
| Output: &buildbucketpb.Build_Output{ |
| Properties: nil, |
| }, |
| }, |
| // This is a CANCELED build which should be ignored. |
| { |
| Id: int64(999991), |
| Status: buildbucketpb.Status_CANCELED, |
| SummaryMarkdown: "canceled", |
| Input: &buildbucketpb.Build_Input{ |
| GerritChanges: []*buildbucketpb.GerritChange{ |
| { |
| Change: int64(333333), |
| }, |
| }, |
| }, |
| Output: &buildbucketpb.Build_Output{}, |
| }, |
| }, |
| status: buildbucketpb.Status_FAILURE, |
| changeNum: int64(123456), |
| summaryMarkdown: "ERROR", |
| ignoreSkippedBuild: true, |
| ignoreSkippedTests: true, |
| ignoreFailedBuild: true, |
| expected: []*findings.SummarySimilarity{ |
| { |
| Score: 0.0, |
| BuildId: "999999", |
| IsGreen: true, |
| }, |
| { |
| Score: 1.0, |
| BuildId: "999998", |
| IsGreen: false, |
| }, |
| }, |
| }, |
| { |
| name: "past build with no gerrit_changes", |
| builds: []*buildbucketpb.Build{ |
| { |
| Id: int64(999999), |
| Status: buildbucketpb.Status_SUCCESS, |
| SummaryMarkdown: "", |
| Input: &buildbucketpb.Build_Input{}, |
| Output: &buildbucketpb.Build_Output{ |
| Properties: &structpb.Struct{ |
| Fields: map[string]*structpb.Value{}, |
| }, |
| }, |
| }, |
| }, |
| status: buildbucketpb.Status_FAILURE, |
| changeNum: int64(123456), |
| summaryMarkdown: "ERROR", |
| ignoreSkippedBuild: true, |
| ignoreSkippedTests: true, |
| ignoreFailedBuild: true, |
| expected: nil, |
| }, |
| } |
| |
| for _, test := range tests { |
| t.Run(test.name, func(t *testing.T) { |
| comparator := mockComparator{} |
| ss := checkTry(test.builds, test.changeNum, test.status, test.summaryMarkdown, comparator, test.ignoreSkippedBuild, test.ignoreSkippedTests, test.ignoreFailedBuild, "", "") |
| if diff := cmp.Diff(test.expected, ss); diff != "" { |
| t.Fatalf("different (-want +got):\n%s", diff) |
| } |
| }) |
| } |
| } |