func parseGrid()

in pkg/summarizer/flakiness.go [86:178]


func parseGrid(grid *statepb.Grid, startTime int, endTime int) ([]*common.GridMetrics, map[string][]analyzers.StatusCategory) {
	// Get the relevant data for flakiness from each Grid (which represents
	// a dashboard tab) as a list of GridMetrics structs

	// TODO (itsazhuhere@): consider refactoring/using summary.go's gridMetrics function
	// as it does very similar data collection.

	// Multiply by 1000 because currently Column.Started is in milliseconds; this is used
	// for comparisons later. startTime and endTime will be used in a Timestamp later that
	// requires seconds, so we would like to impact that at little as possible.
	startTime *= 1000
	endTime *= 1000

	// We create maps because result.Map returns a map where we can access each result
	// through the test name, and at each instance we can increment our types.Result
	// using the same key. At the end we can filter out those types.Result that had
	// 0 of all counts.
	gridMetricsMap := make(map[string]*common.GridMetrics, 0)
	gridRows := make(map[string]*statepb.Row)

	// For each filtered test, status of non-infra-failure tests
	rowStatuses := make(map[string][]analyzers.StatusCategory)

	for i, row := range grid.Rows {
		gridRows[row.Name] = grid.Rows[i]
		gridMetricsMap[row.Name] = common.NewGridMetrics(row.Name)
		rowStatuses[row.Name] = []analyzers.StatusCategory{}
	}

	// result.Map is written in a way that assumes each test/row name is unique
	rowResults := result.Map(grid.Rows)
	failingColumns := failingColumns(len(grid.Columns), grid.Rows)

	for key, f := range rowResults {
		if !isValidTestName(key) {
			continue
		}
		rowToMessageIndex := 0
		i := -1
		for {
			nextRowResult, more := f()
			if !more {
				break
			}
			i++
			if i >= len(grid.Columns) {
				break
			}
			rowResult := result.Coalesce(nextRowResult, result.ShowRunning)

			// We still need to increment rowToMessageIndex even if we want to skip counting
			// this column.
			if !isWithinTimeFrame(grid.Columns[i], startTime, endTime) {
				switch rowResult {
				case statuspb.TestStatus_NO_RESULT:
					// Ignore NO_RESULT (e.g. blank cell)
				default:
					rowToMessageIndex++
				}
				continue
			}
			switch rowResult {
			case statuspb.TestStatus_NO_RESULT:
				continue
			case statuspb.TestStatus_FAIL:
				message := gridRows[key].Messages[rowToMessageIndex]
				if isInfraFailure(message) {
					gridMetricsMap[key].FailedInfraCount++
					gridMetricsMap[key].InfraFailures[message]++
				} else {
					gridMetricsMap[key].Failed++
					if !failingColumns[i] {
						rowStatuses[key] = append(rowStatuses[key], analyzers.StatusFail)
					}
				}
			case statuspb.TestStatus_PASS:
				gridMetricsMap[key].Passed++
				rowStatuses[key] = append(rowStatuses[key], analyzers.StatusPass)
			case statuspb.TestStatus_FLAKY:
				rowStatuses[key] = append(rowStatuses[key], analyzers.StatusFlaky)
				getValueOfFlakyMetric(gridMetricsMap[key])
			}
			rowToMessageIndex++
		}
	}
	gridMetrics := make([]*common.GridMetrics, 0)
	for _, metric := range gridMetricsMap {
		if metric.Failed > 0 || metric.Passed > 0 || metric.FlakyCount > 0 {
			gridMetrics = append(gridMetrics, metric)
		}
	}
	return gridMetrics, rowStatuses
}