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 := &timestamp.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: &timestamp.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  }