in pkg/updater/gcs.go [278:451]
func convertResult(log logrus.FieldLogger, nameCfg nameConfig, id string, headers []string, result gcsResult, opt groupOptions) InflatedColumn {
cells := map[string][]Cell{}
var cellID string
if nameCfg.multiJob {
cellID = result.job + "/" + id
} else if opt.addCellID {
cellID = id
}
meta := result.finished.Metadata.Strings()
version := metadata.Version(result.started.Started, result.finished.Finished)
// Append each result into the column
for _, suite := range result.suites {
for _, r := range flattenResults(suite.Suites.Suites...) {
// "skipped" is the string that is always appended when the test is skipped without any reason in Ginkgo V2, e.g., "focus" is specified, and the test is skipped.
if r.Skipped != nil && r.Skipped.Value == "" && (r.Skipped.Message == "skipped" || r.Skipped.Message == "") {
continue
}
c := Cell{CellID: cellID}
if elapsed := r.Time; elapsed > 0 {
c.Metrics = setElapsed(c.Metrics, elapsed)
}
props := propertyMap(&r)
for metric, mean := range Means(props) {
if c.Metrics == nil {
c.Metrics = map[string]float64{}
}
c.Metrics[metric] = mean
}
const max = 140
if msg := r.Message(max); msg != "" {
c.Message = msg
}
switch {
case r.Errored != nil:
c.Result = statuspb.TestStatus_FAIL
if c.Message != "" {
c.Icon = "F"
}
case r.Failure != nil:
c.Result = statuspb.TestStatus_FAIL
if c.Message != "" {
c.Icon = "F"
}
case r.Skipped != nil:
c.Result = statuspb.TestStatus_PASS_WITH_SKIPS
c.Icon = "S"
default:
c.Result = statuspb.TestStatus_PASS
}
if override := CustomStatus(opt.rules, jUnitTestResult{&r}); override != nil {
c.Result = *override
}
if ignoreStatus(opt, c.Result) {
continue
}
for _, annotation := range opt.annotations {
_, ok := props[annotation.GetPropertyName()]
if !ok {
continue
}
c.Icon = annotation.ShortText
break
}
if f, ok := c.Metrics[opt.metricKey]; ok {
c.Icon = strconv.FormatFloat(f, 'g', 4, 64)
}
if values, ok := props[opt.userKey]; ok && len(values) > 0 {
c.UserProperty = values[0]
}
name := nameCfg.render(result.job, r.Name, first(props), suite.Metadata, meta)
cells[name] = append(cells[name], c)
}
}
overall := overallCell(result)
if overall.Result == statuspb.TestStatus_FAIL && overall.Message == "" { // Ensure failing build has a failing cell and/or overall message
var found bool
for _, namedCells := range cells {
for _, c := range namedCells {
if c.Result == statuspb.TestStatus_FAIL {
found = true // Failing test, huzzah!
break
}
}
if found {
break
}
}
if !found { // Nope, add the F icon and an explanatory Message
overall.Icon = "F"
overall.Message = "Build failed outside of test results"
}
}
injectedCells := map[string]Cell{
overallRow: overall,
}
if opt.analyzeProwJob {
if pic := podInfoCell(result); pic.Message != gcs.MissingPodInfo || overall.Result != statuspb.TestStatus_RUNNING {
injectedCells[podInfoRow] = pic
}
}
for name, c := range injectedCells {
c.CellID = cellID
jobName := result.job + "." + name
cells[jobName] = append([]Cell{c}, cells[jobName]...)
if nameCfg.multiJob {
cells[name] = append([]Cell{c}, cells[name]...)
}
}
buildID := id
if opt.buildKey != "" {
metadata := result.finished.Metadata.Strings()
if metadata != nil {
buildID = metadata[opt.buildKey]
}
if buildID == "" {
log.WithFields(logrus.Fields{
"metadata": result.finished.Metadata.Strings(),
"overrideBuildKey": opt.buildKey,
}).Warning("No override build ID found in metadata.")
}
}
out := InflatedColumn{
Column: &statepb.Column{
Build: buildID,
Started: float64(result.started.Timestamp * 1000),
Hint: id,
},
Cells: map[string]Cell{},
}
for name, cells := range cells {
switch {
case opt.merge:
out.Cells[name] = MergeCells(true, cells...)
default:
for n, c := range SplitCells(name, cells...) {
out.Cells[n] = c
}
}
}
for _, h := range headers {
val, ok := meta[h]
if !ok && h == "Commit" && version != metadata.Missing {
val = version
} else if !ok && overall.Result != statuspb.TestStatus_RUNNING {
val = "missing"
}
out.Column.Extra = append(out.Column.Extra, val)
}
emails, found := result.finished.Finished.Metadata.MultiString(EmailListKey)
if len(emails) == 0 && found {
log.Error("failed to extract dynamic email list, the list is empty or cannot convert to []string")
}
out.Column.EmailAddresses = emails
return out
}