github.com/GoogleCloudPlatform/testgrid@v0.0.174/pkg/summarizer/analyzers/baseanalyzer_test.go (about) 1 /* 2 Copyright 2020 The TestGrid Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package analyzers 18 19 import ( 20 "reflect" 21 "testing" 22 23 summarypb "github.com/GoogleCloudPlatform/testgrid/pb/summary" 24 "github.com/GoogleCloudPlatform/testgrid/pkg/summarizer/common" 25 "github.com/golang/protobuf/proto" 26 "github.com/golang/protobuf/ptypes/timestamp" 27 "github.com/google/go-cmp/cmp" 28 "google.golang.org/protobuf/testing/protocmp" 29 ) 30 31 func getTypicalGridMetricsArray() []*common.GridMetrics { 32 return []*common.GridMetrics{ 33 { 34 Name: "//test1 - [env1]", 35 Passed: 1, 36 Failed: 1, 37 FlakyCount: 1, 38 AverageFlakiness: 50.0, 39 FailedInfraCount: 1, 40 }, 41 } 42 } 43 44 func createTimestamp(time int) *timestamp.Timestamp { 45 timestamp := ×tamp.Timestamp{ 46 Seconds: int64(time), 47 } 48 return timestamp 49 } 50 51 func TestGetFlakinessBase(t *testing.T) { 52 cases := []struct { 53 name string 54 metrics []*common.GridMetrics 55 minRuns int 56 startDate int 57 endDate int 58 tab string 59 expected *summarypb.HealthinessInfo 60 }{ 61 { 62 name: "typical case returns expected healthiness", 63 metrics: getTypicalGridMetricsArray(), 64 minRuns: -1, 65 startDate: 0, 66 endDate: 2, 67 tab: "tab1", 68 expected: &summarypb.HealthinessInfo{ 69 Start: createTimestamp(0), 70 End: createTimestamp(2), 71 Tests: []*summarypb.TestInfo{ 72 { 73 DisplayName: "//test1 - [env1]", 74 TotalNonInfraRuns: 2, 75 TotalRunsWithInfra: 3, 76 PassedNonInfraRuns: 1, 77 FailedNonInfraRuns: 1, 78 FailedInfraRuns: 1, 79 Flakiness: 50, 80 }, 81 }, 82 AverageFlakiness: 50, 83 }, 84 }, 85 } 86 87 for _, tc := range cases { 88 t.Run(tc.name, func(t *testing.T) { 89 analyzer := BaseAnalyzer{} 90 actual := analyzer.GetFlakiness(tc.metrics, tc.minRuns, tc.startDate, tc.endDate, tc.tab) 91 if diff := cmp.Diff(tc.expected, actual, protocmp.Transform()); diff != "" { 92 t.Errorf("\nGetFlakiness produced unexpected diff (-want +got): %s", diff) 93 } 94 }) 95 } 96 } 97 98 func TestCreateHealthiness(t *testing.T) { 99 cases := []struct { 100 name string 101 startDate int 102 endDate int 103 testInfoList []*summarypb.TestInfo 104 expected *summarypb.HealthinessInfo 105 }{ 106 { 107 name: "typical inputs return correct Healthiness output", 108 startDate: 0, 109 endDate: 2, 110 testInfoList: []*summarypb.TestInfo{}, 111 expected: &summarypb.HealthinessInfo{ 112 Start: createTimestamp(0), 113 End: createTimestamp(2), 114 Tests: []*summarypb.TestInfo{}, 115 }, 116 }, 117 } 118 119 for _, tc := range cases { 120 t.Run(tc.name, func(t *testing.T) { 121 if actual := createHealthiness(tc.startDate, tc.endDate, tc.testInfoList); !reflect.DeepEqual(actual, tc.expected) { 122 t.Errorf("\nactual: %+v \n!= \nexpected: %+v", actual, tc.expected) 123 } 124 }) 125 } 126 } 127 128 func TestCalculateNaiveFlakiness(t *testing.T) { 129 cases := []struct { 130 name string 131 test *common.GridMetrics 132 minRuns int 133 expectedTestInfo *summarypb.TestInfo 134 expectedSuccess bool 135 }{ 136 { 137 name: "correctly filters GridMetrics with less than minRuns", 138 test: &common.GridMetrics{}, 139 minRuns: 1000, // arbitrarily large number so that it should get filtered 140 expectedTestInfo: &summarypb.TestInfo{}, 141 expectedSuccess: false, 142 }, 143 { 144 name: "typical GridMetrics returns correct TestInfo", 145 test: &common.GridMetrics{ 146 Passed: 3, 147 Failed: 2, 148 FlakyCount: 8, 149 AverageFlakiness: 50.0, 150 FailedInfraCount: 4, 151 }, 152 minRuns: -1, 153 expectedTestInfo: &summarypb.TestInfo{ 154 DisplayName: "", 155 Flakiness: 40.0, 156 TotalNonInfraRuns: 5, 157 TotalRunsWithInfra: 9, 158 PassedNonInfraRuns: 3, 159 FailedNonInfraRuns: 2, 160 FailedInfraRuns: 4, 161 }, 162 expectedSuccess: true, 163 }, 164 } 165 166 for _, tc := range cases { 167 t.Run(tc.name, func(t *testing.T) { 168 if actualTest, actualSuccess := calculateNaiveFlakiness(tc.test, tc.minRuns); !proto.Equal(actualTest, tc.expectedTestInfo) || tc.expectedSuccess != actualSuccess { 169 t.Errorf("\ntestInfo:\nactual: %v vs. expected: %v\nsuccess:\nactual: %v vs. expected: %v", actualTest, tc.expectedTestInfo, actualSuccess, tc.expectedSuccess) 170 } 171 }) 172 } 173 } 174 175 func TestIntToTimestamp(t *testing.T) { 176 cases := []struct { 177 name string 178 seconds int 179 expected *timestamp.Timestamp 180 }{ 181 { 182 name: "typical input returns correct timestamp", 183 seconds: 2, 184 expected: ×tamp.Timestamp{ 185 Seconds: int64(2), 186 }, 187 }, 188 } 189 190 for _, tc := range cases { 191 t.Run(tc.name, func(t *testing.T) { 192 if actual := intToTimestamp(tc.seconds); !proto.Equal(actual, tc.expected) { 193 t.Errorf("actual %+v != expected %+v", actual, tc.expected) 194 } 195 }) 196 } 197 }