Add error string to JSON test result output

Useful for third-party bogo users.

Change-Id: I8f456c714ca689bed8b6a44e4adb5f9103b994c7
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/68747
Commit-Queue: Roland Shoemaker <bracewell@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
diff --git a/ssl/test/runner/runner.go b/ssl/test/runner/runner.go
index b08e1bf..37a36fb 100644
--- a/ssl/test/runner/runner.go
+++ b/ssl/test/runner/runner.go
@@ -20364,19 +20364,19 @@
 					if *allowUnimplemented {
 						testOutput.AddSkip(msg.test.name)
 					} else {
-						testOutput.AddResult(msg.test.name, "SKIP")
+						testOutput.AddResult(msg.test.name, "SKIP", nil)
 					}
 				} else {
 					fmt.Printf("FAILED (%s)\n%s\n", msg.test.name, msg.err)
 					failed++
-					testOutput.AddResult(msg.test.name, "FAIL")
+					testOutput.AddResult(msg.test.name, "FAIL", msg.err)
 				}
 			} else {
 				if *pipe {
 					// Print each test instead of a status line.
 					fmt.Printf("PASSED (%s)\n", msg.test.name)
 				}
-				testOutput.AddResult(msg.test.name, "PASS")
+				testOutput.AddResult(msg.test.name, "PASS", nil)
 			}
 		}
 
diff --git a/util/all_tests.go b/util/all_tests.go
index dad4d4a..09c98b9 100644
--- a/util/all_tests.go
+++ b/util/all_tests.go
@@ -398,15 +398,15 @@
 			fmt.Printf("%s\n", test.longName())
 			fmt.Printf("%s failed to complete: %s\n", args[0], testResult.Error)
 			failed = append(failed, test)
-			testOutput.AddResult(test.longName(), "CRASH")
+			testOutput.AddResult(test.longName(), "CRASH", testResult.Error)
 		} else if !testResult.Passed {
 			fmt.Printf("%s\n", test.longName())
 			fmt.Printf("%s failed to print PASS on the last line.\n", args[0])
 			failed = append(failed, test)
-			testOutput.AddResult(test.longName(), "FAIL")
+			testOutput.AddResult(test.longName(), "FAIL", nil)
 		} else {
 			fmt.Printf("%s\n", test.shortName())
-			testOutput.AddResult(test.longName(), "PASS")
+			testOutput.AddResult(test.longName(), "PASS", nil)
 		}
 	}
 
diff --git a/util/testresult/testresult.go b/util/testresult/testresult.go
index b353ece..5b131ad 100644
--- a/util/testresult/testresult.go
+++ b/util/testresult/testresult.go
@@ -43,27 +43,31 @@
 	}
 }
 
-func (t *Results) addResult(name, result, expected string) {
+func (t *Results) addResult(name, result, expected string, err error) {
 	if _, found := t.Tests[name]; found {
 		panic(fmt.Sprintf("duplicate test name %q", name))
 	}
-	t.Tests[name] = Result{
+	r := Result{
 		Actual:       result,
 		Expected:     expected,
 		IsUnexpected: result != expected,
 	}
+	if err != nil {
+		r.Error = err.Error()
+	}
+	t.Tests[name] = r
 	t.NumFailuresByType[result]++
 }
 
 // AddResult records a test result with the given result string. The test is a
 // failure if the result is not "PASS".
-func (t *Results) AddResult(name, result string) {
-	t.addResult(name, result, "PASS")
+func (t *Results) AddResult(name, result string, err error) {
+	t.addResult(name, result, "PASS", err)
 }
 
 // AddSkip marks a test as being skipped. It is not considered a failure.
 func (t *Results) AddSkip(name string) {
-	t.addResult(name, "SKIP", "SKIP")
+	t.addResult(name, "SKIP", "SKIP", nil)
 }
 
 func (t *Results) HasUnexpectedResults() bool {
@@ -93,4 +97,7 @@
 	Actual       string `json:"actual"`
 	Expected     string `json:"expected"`
 	IsUnexpected bool   `json:"is_unexpected"`
+	// Error is not part of the Chromium test results schema, but is useful for
+	// BoGo output.
+	Error string `json:"error,omitempty"`
 }