in pkg/updater/eval.go [163:254]
func evalProperties(rule *evalpb.Rule, testResult TestResult) *tspb.TestStatus {
for _, cmp := range rule.TestResultComparisons {
if cmp.Comparison == nil {
return nil
}
var scmp func(string, string) bool
var fcmp func(float64, float64) bool
sval := cmp.Comparison.GetStringValue()
fval := cmp.Comparison.GetNumericalValue()
switch cmp.Comparison.Op {
case evalpb.Comparison_OP_CONTAINS:
scmp = strContains
case evalpb.Comparison_OP_REGEX:
scmp = strReg
case evalpb.Comparison_OP_STARTS_WITH:
scmp = strStartsWith
case evalpb.Comparison_OP_EQ:
scmp = strEQ
fcmp = numEQ
case evalpb.Comparison_OP_NE:
scmp = strNE
fcmp = numNE
}
if p := cmp.GetPropertyKey(); p != "" {
if scmp == nil {
return nil
}
var good bool
props := testResult.Properties()
if props == nil {
return nil
}
for _, val := range props[p] {
if !scmp(val, sval) {
continue
}
good = true
break
}
if !good {
return nil
}
} else if f := cmp.GetTestResultField(); f != "" {
var getNum func() int
var getStr func() string
switch f {
case "name":
getStr = testResult.Name
case "error_count":
getNum = testResult.Errors
case "failure_count":
getNum = testResult.Failures
default: // TODO(fejta): drop or support other fields
return nil
}
switch {
case getNum != nil:
n := float64(getNum())
if !fcmp(n, fval) {
return nil
}
case getStr != nil:
if !scmp(getStr(), sval) {
return nil
}
}
} else if ef := cmp.GetTestResultErrorField(); ef != "" {
if scmp == nil {
return nil
}
if ef != "exception_type" {
return nil
}
var good bool
for _, got := range testResult.Exceptions() {
if scmp(got, sval) {
good = true
break
}
}
if !good {
return nil
}
} else {
return nil
}
}
want := rule.GetComputedStatus()
return &want
}