TF CFT: add TestCaseMetadata to each test results.

BUG=b:398093695
TEST=Unit+CQ

Change-Id: I0cc76a9e4a1a69cec93165b531131b100ba1df9c
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/dev-util/+/6332229
Tested-by: Alex Bergman <abergman@google.com>
Reviewed-by: Allen Xie <zhihuixie@google.com>
Commit-Queue: Alex Bergman <abergman@google.com>
diff --git a/src/go.chromium.org/chromiumos/test/execution/cmd/cros-test/internal/driver/tradefed_common.go b/src/go.chromium.org/chromiumos/test/execution/cmd/cros-test/internal/driver/tradefed_common.go
index 7e19e99..b389e07 100644
--- a/src/go.chromium.org/chromiumos/test/execution/cmd/cros-test/internal/driver/tradefed_common.go
+++ b/src/go.chromium.org/chromiumos/test/execution/cmd/cros-test/internal/driver/tradefed_common.go
@@ -208,3 +208,13 @@
 
 	return cmd
 }
+
+func extractTestCaseName(testName string) string {
+	testCaseName := testName
+	if strings.HasPrefix(testCaseName, tfprefix) {
+		testCaseName = strings.TrimPrefix(testCaseName, tfprefix)
+		// Also trimming the suite name.
+		testCaseName = strings.TrimLeft(testCaseName, ".")
+	}
+	return testCaseName
+}
diff --git a/src/go.chromium.org/chromiumos/test/execution/cmd/cros-test/internal/driver/tradefed_results.go b/src/go.chromium.org/chromiumos/test/execution/cmd/cros-test/internal/driver/tradefed_results.go
index 35f400d..c8d451b 100644
--- a/src/go.chromium.org/chromiumos/test/execution/cmd/cros-test/internal/driver/tradefed_results.go
+++ b/src/go.chromium.org/chromiumos/test/execution/cmd/cros-test/internal/driver/tradefed_results.go
@@ -578,5 +578,13 @@
 		tcResult.Errors = []*api.TestCaseResult_Error{testError}
 	}
 
+	tcResult.TestCaseMetadata = &api.TestCaseMetadata{
+		TestCase: &api.TestCase{
+			Id:   tcResult.TestCaseId,
+			Name: extractTestCaseName(tcResult.TestCaseId.Value),
+		},
+		TestCaseExec: &api.TestCaseExec{TestHarness: tcResult.TestHarness},
+	}
+
 	return tcResult
 }
diff --git a/src/go.chromium.org/chromiumos/test/execution/cmd/cros-test/internal/driver/tradefed_results_test.go b/src/go.chromium.org/chromiumos/test/execution/cmd/cros-test/internal/driver/tradefed_results_test.go
index bf3992a..1a58451 100644
--- a/src/go.chromium.org/chromiumos/test/execution/cmd/cros-test/internal/driver/tradefed_results_test.go
+++ b/src/go.chromium.org/chromiumos/test/execution/cmd/cros-test/internal/driver/tradefed_results_test.go
@@ -9,6 +9,7 @@
 	"io"
 	"log"
 	"os"
+	"strings"
 	"testing"
 	"time"
 
@@ -109,51 +110,73 @@
 	duration := &durationpb.Duration{Seconds: int64(2254 / 1000 / numOfTests)}
 	testTags := []*api.TestCase_Tag{&api.TestCase_Tag{Value: "abi:x86_64"}}
 	testHarness := &api.TestHarness{TestHarnessType: &api.TestHarness_Tradefed_{Tradefed: &api.TestHarness_Tradefed{}}}
+	testClass := "android.jvmti.cts.JvmtiHostTest1976"
+	testFullName := prefix + testClass
 
 	return []*api.TestCaseResult{
 		{
-			TestCaseId:  &api.TestCase_Id{Value: prefix + "android.jvmti.cts.JvmtiHostTest1976#testJvmti"},
+			TestCaseId:  &api.TestCase_Id{Value: prefix + testClass + "#testJvmti"},
 			Tags:        testTags,
 			TestHarness: testHarness,
 			Verdict:     &api.TestCaseResult_Pass_{Pass: &api.TestCaseResult_Pass{}},
 			StartTime:   startTime,
 			Duration:    duration,
+			TestCaseMetadata: &api.TestCaseMetadata{
+				TestCase:     &api.TestCase{Id: &api.TestCase_Id{Value: testFullName + "#testJvmti"}, Name: extractTestCaseName(testFullName + "#testJvmti")},
+				TestCaseExec: &api.TestCaseExec{TestHarness: testHarness},
+			},
 		},
 		{
-			TestCaseId:  &api.TestCase_Id{Value: prefix + "android.jvmti.cts.JvmtiHostTest1976#testAssumptionFail"},
+			TestCaseId:  &api.TestCase_Id{Value: prefix + testClass + "#testAssumptionFail"},
 			Tags:        testTags,
 			TestHarness: testHarness,
 			Verdict:     &api.TestCaseResult_Pass_{Pass: &api.TestCaseResult_Pass{}},
 			Errors:      []*api.TestCaseResult_Error{{Message: failureMessage}},
 			StartTime:   startTime,
 			Duration:    duration,
+			TestCaseMetadata: &api.TestCaseMetadata{
+				TestCase:     &api.TestCase{Id: &api.TestCase_Id{Value: testFullName + "#testAssumptionFail"}, Name: extractTestCaseName(testFullName + "#testAssumptionFail")},
+				TestCaseExec: &api.TestCaseExec{TestHarness: testHarness},
+			},
 		},
 		{
-			TestCaseId:  &api.TestCase_Id{Value: prefix + "android.jvmti.cts.JvmtiHostTest1976#testIncomplate"},
+			TestCaseId:  &api.TestCase_Id{Value: testFullName + "#testIncomplate"},
 			Tags:        testTags,
 			TestHarness: testHarness,
 			Verdict:     &api.TestCaseResult_Crash_{Crash: &api.TestCaseResult_Crash{}},
 			Errors:      []*api.TestCaseResult_Error{{Message: failureMessage}},
 			StartTime:   startTime,
 			Duration:    duration,
+			TestCaseMetadata: &api.TestCaseMetadata{
+				TestCase:     &api.TestCase{Id: &api.TestCase_Id{Value: testFullName + "#testIncomplate"}, Name: extractTestCaseName(testFullName + "#testIncomplate")},
+				TestCaseExec: &api.TestCaseExec{TestHarness: testHarness},
+			},
 		},
 		{
-			TestCaseId:  &api.TestCase_Id{Value: prefix + "android.jvmti.cts.JvmtiHostTest1976#testIgnored"},
+			TestCaseId:  &api.TestCase_Id{Value: testFullName + "#testIgnored"},
 			Tags:        testTags,
 			TestHarness: testHarness,
 			Verdict:     &api.TestCaseResult_Skip_{Skip: &api.TestCaseResult_Skip{}},
 			Errors:      []*api.TestCaseResult_Error{{Message: ""}},
 			StartTime:   startTime,
 			Duration:    duration,
+			TestCaseMetadata: &api.TestCaseMetadata{
+				TestCase:     &api.TestCase{Id: &api.TestCase_Id{Value: testFullName + "#testIgnored"}, Name: extractTestCaseName(testFullName + "#testIgnored")},
+				TestCaseExec: &api.TestCaseExec{TestHarness: testHarness},
+			},
 		},
 		{
-			TestCaseId:  &api.TestCase_Id{Value: prefix + "android.jvmti.cts.JvmtiHostTest1976#testUnknown"},
+			TestCaseId:  &api.TestCase_Id{Value: testFullName + "#testUnknown"},
 			Tags:        testTags,
 			TestHarness: testHarness,
 			Verdict:     &api.TestCaseResult_Fail_{Fail: &api.TestCaseResult_Fail{}},
 			Errors:      []*api.TestCaseResult_Error{{Message: ""}},
 			StartTime:   startTime,
 			Duration:    duration,
+			TestCaseMetadata: &api.TestCaseMetadata{
+				TestCase:     &api.TestCase{Id: &api.TestCase_Id{Value: testFullName + "#testUnknown"}, Name: extractTestCaseName(testFullName + "#testUnknown")},
+				TestCaseExec: &api.TestCaseExec{TestHarness: testHarness},
+			},
 		},
 		{
 			TestCaseId:  &api.TestCase_Id{Value: prefix + "android.mediav2.cts.CodecDecoderSurfaceTest#testFlushNative"},
@@ -163,6 +186,10 @@
 			Errors:      []*api.TestCaseResult_Error{{Message: failureMessage}},
 			StartTime:   startTime,
 			Duration:    duration,
+			TestCaseMetadata: &api.TestCaseMetadata{
+				TestCase:     &api.TestCase{Id: &api.TestCase_Id{Value: prefix + "android.mediav2.cts.CodecDecoderSurfaceTest#testFlushNative"}, Name: extractTestCaseName(prefix + "android.mediav2.cts.CodecDecoderSurfaceTest#testFlushNative")},
+				TestCaseExec: &api.TestCaseExec{TestHarness: testHarness},
+			},
 		},
 	}
 }
@@ -174,40 +201,58 @@
 	duration := &durationpb.Duration{Seconds: int64(18 / numOfTests)}
 	testTags := []*api.TestCase_Tag{&api.TestCase_Tag{Value: "abi:x86_64"}}
 	testHarness := &api.TestHarness{TestHarnessType: &api.TestHarness_Tradefed_{Tradefed: &api.TestHarness_Tradefed{}}}
+	testClass := "com.android.chrome.desktop.integration.ChromeWindowTests"
+	testFullName := prefix + testClass
 
 	return []*api.TestCaseResult{
 		{
-			TestCaseId:  &api.TestCase_Id{Value: prefix + "com.android.chrome.desktop.integration.ChromeWindowTests#testSingleWindow"},
+			TestCaseId:  &api.TestCase_Id{Value: testFullName + "#testSingleWindow"},
 			Tags:        testTags,
 			TestHarness: testHarness,
 			Verdict:     &api.TestCaseResult_Pass_{Pass: &api.TestCaseResult_Pass{}},
 			StartTime:   startTime,
 			Duration:    duration,
+			TestCaseMetadata: &api.TestCaseMetadata{
+				TestCase:     &api.TestCase{Id: &api.TestCase_Id{Value: testFullName + "#testSingleWindow"}, Name: extractTestCaseName(testFullName + "#testSingleWindow")},
+				TestCaseExec: &api.TestCaseExec{TestHarness: testHarness},
+			},
 		},
 		{
-			TestCaseId:  &api.TestCase_Id{Value: prefix + "com.android.chrome.desktop.integration.ChromeWindowTests#testSingleWindow"},
+			TestCaseId:  &api.TestCase_Id{Value: testFullName + "#testSingleWindow"},
 			Tags:        testTags,
 			TestHarness: testHarness,
 			Verdict:     &api.TestCaseResult_Pass_{Pass: &api.TestCaseResult_Pass{}},
 			StartTime:   startTime,
 			Duration:    duration,
+			TestCaseMetadata: &api.TestCaseMetadata{
+				TestCase:     &api.TestCase{Id: &api.TestCase_Id{Value: testFullName + "#testSingleWindow"}, Name: extractTestCaseName(testFullName + "#testSingleWindow")},
+				TestCaseExec: &api.TestCaseExec{TestHarness: testHarness},
+			},
 		},
 		{
-			TestCaseId:  &api.TestCase_Id{Value: prefix + "com.android.chrome.desktop.integration.ChromeWindowTests#testMultiWindowsLimitFail"},
+			TestCaseId:  &api.TestCase_Id{Value: testFullName + "#testMultiWindowsLimitFail"},
 			Tags:        testTags,
 			TestHarness: testHarness,
 			Verdict:     &api.TestCaseResult_Fail_{Fail: &api.TestCaseResult_Fail{}},
 			Errors:      []*api.TestCaseResult_Error{{Message: "null: java.lang.AssertionError: windows expected: 5, found: 4"}},
 			StartTime:   startTime,
 			Duration:    duration,
+			TestCaseMetadata: &api.TestCaseMetadata{
+				TestCase:     &api.TestCase{Id: &api.TestCase_Id{Value: testFullName + "#testMultiWindowsLimitFail"}, Name: extractTestCaseName(testFullName + "#testMultiWindowsLimitFail")},
+				TestCaseExec: &api.TestCaseExec{TestHarness: testHarness},
+			},
 		},
 		{
-			TestCaseId:  &api.TestCase_Id{Value: prefix + "com.android.chrome.desktop.integration.ChromeWindowTests2#testMultiWindowsLimit2"},
+			TestCaseId:  &api.TestCase_Id{Value: testFullName + "2#testMultiWindowsLimit2"},
 			Tags:        []*api.TestCase_Tag{&api.TestCase_Tag{Value: "abi:arm64-v8a"}}, // Different test ABI that should override module ABI.
 			TestHarness: testHarness,
 			Verdict:     &api.TestCaseResult_Pass_{Pass: &api.TestCaseResult_Pass{}},
 			StartTime:   startTime,
 			Duration:    duration,
+			TestCaseMetadata: &api.TestCaseMetadata{
+				TestCase:     &api.TestCase{Id: &api.TestCase_Id{Value: testFullName + "2#testMultiWindowsLimit2"}, Name: extractTestCaseName(testFullName + "2#testMultiWindowsLimit2")},
+				TestCaseExec: &api.TestCaseExec{TestHarness: testHarness},
+			},
 		},
 	}
 }
@@ -319,6 +364,10 @@
 		testHarness := &api.TestHarness{TestHarnessType: &api.TestHarness_Tradefed_{Tradefed: &api.TestHarness_Tradefed{}}}
 		wantStartTime := timestamppb.New(startTime)
 		wantDuration := &durationpb.Duration{Seconds: int64(duration.Seconds())}
+		wantTestCaseMetadata := &api.TestCaseMetadata{
+			TestCase:     &api.TestCase{Id: testCaseID, Name: strings.TrimPrefix(testName, "tradefed.")},
+			TestCaseExec: &api.TestCaseExec{TestHarness: testHarness},
+		}
 
 		for _, tc := range []struct {
 			name         string
@@ -333,12 +382,13 @@
 				errorMessage: "",
 				status:       "PASSED",
 				want: &api.TestCaseResult{
-					TestCaseId:  testCaseID,
-					Tags:        testTags,
-					TestHarness: testHarness,
-					Verdict:     &api.TestCaseResult_Pass_{Pass: &api.TestCaseResult_Pass{}},
-					StartTime:   wantStartTime,
-					Duration:    wantDuration,
+					TestCaseId:       testCaseID,
+					Tags:             testTags,
+					TestHarness:      testHarness,
+					Verdict:          &api.TestCaseResult_Pass_{Pass: &api.TestCaseResult_Pass{}},
+					StartTime:        wantStartTime,
+					Duration:         wantDuration,
+					TestCaseMetadata: wantTestCaseMetadata,
 				},
 			},
 			{
@@ -347,13 +397,14 @@
 				errorMessage: failureMessage,
 				status:       "ASSUMPTION_FAILURE",
 				want: &api.TestCaseResult{
-					TestCaseId:  testCaseID,
-					Tags:        testTags,
-					TestHarness: testHarness,
-					Verdict:     &api.TestCaseResult_Pass_{Pass: &api.TestCaseResult_Pass{}},
-					Errors:      []*api.TestCaseResult_Error{{Message: failureMessage}},
-					StartTime:   wantStartTime,
-					Duration:    wantDuration,
+					TestCaseId:       testCaseID,
+					Tags:             testTags,
+					TestHarness:      testHarness,
+					Verdict:          &api.TestCaseResult_Pass_{Pass: &api.TestCaseResult_Pass{}},
+					Errors:           []*api.TestCaseResult_Error{{Message: failureMessage}},
+					StartTime:        wantStartTime,
+					Duration:         wantDuration,
+					TestCaseMetadata: wantTestCaseMetadata,
 				},
 			},
 			{
@@ -362,13 +413,14 @@
 				errorMessage: failureMessage,
 				status:       "FAILED",
 				want: &api.TestCaseResult{
-					TestCaseId:  testCaseID,
-					Tags:        testTags,
-					TestHarness: testHarness,
-					Verdict:     &api.TestCaseResult_Fail_{Fail: &api.TestCaseResult_Fail{}},
-					Errors:      []*api.TestCaseResult_Error{{Message: failureMessage}},
-					StartTime:   wantStartTime,
-					Duration:    wantDuration,
+					TestCaseId:       testCaseID,
+					Tags:             testTags,
+					TestHarness:      testHarness,
+					Verdict:          &api.TestCaseResult_Fail_{Fail: &api.TestCaseResult_Fail{}},
+					Errors:           []*api.TestCaseResult_Error{{Message: failureMessage}},
+					StartTime:        wantStartTime,
+					Duration:         wantDuration,
+					TestCaseMetadata: wantTestCaseMetadata,
 				},
 			},
 			{
@@ -377,13 +429,14 @@
 				errorMessage: failureMessage,
 				status:       "INCOMPLETE",
 				want: &api.TestCaseResult{
-					TestCaseId:  testCaseID,
-					Tags:        testTags,
-					TestHarness: testHarness,
-					Verdict:     &api.TestCaseResult_Crash_{Crash: &api.TestCaseResult_Crash{}},
-					Errors:      []*api.TestCaseResult_Error{{Message: failureMessage}},
-					StartTime:   wantStartTime,
-					Duration:    wantDuration,
+					TestCaseId:       testCaseID,
+					Tags:             testTags,
+					TestHarness:      testHarness,
+					Verdict:          &api.TestCaseResult_Crash_{Crash: &api.TestCaseResult_Crash{}},
+					Errors:           []*api.TestCaseResult_Error{{Message: failureMessage}},
+					StartTime:        wantStartTime,
+					Duration:         wantDuration,
+					TestCaseMetadata: wantTestCaseMetadata,
 				},
 			},
 			{
@@ -392,13 +445,14 @@
 				errorMessage: failureMessage,
 				status:       "SKIPPED",
 				want: &api.TestCaseResult{
-					TestCaseId:  testCaseID,
-					Tags:        testTags,
-					TestHarness: testHarness,
-					Verdict:     &api.TestCaseResult_Skip_{Skip: &api.TestCaseResult_Skip{}},
-					Errors:      []*api.TestCaseResult_Error{{Message: failureMessage}},
-					StartTime:   wantStartTime,
-					Duration:    wantDuration,
+					TestCaseId:       testCaseID,
+					Tags:             testTags,
+					TestHarness:      testHarness,
+					Verdict:          &api.TestCaseResult_Skip_{Skip: &api.TestCaseResult_Skip{}},
+					Errors:           []*api.TestCaseResult_Error{{Message: failureMessage}},
+					StartTime:        wantStartTime,
+					Duration:         wantDuration,
+					TestCaseMetadata: wantTestCaseMetadata,
 				},
 			},
 			{
@@ -407,13 +461,14 @@
 				errorMessage: failureMessage,
 				status:       "IGNORED",
 				want: &api.TestCaseResult{
-					TestCaseId:  testCaseID,
-					Tags:        testTags,
-					TestHarness: testHarness,
-					Verdict:     &api.TestCaseResult_Skip_{Skip: &api.TestCaseResult_Skip{}},
-					Errors:      []*api.TestCaseResult_Error{{Message: failureMessage}},
-					StartTime:   wantStartTime,
-					Duration:    wantDuration,
+					TestCaseId:       testCaseID,
+					Tags:             testTags,
+					TestHarness:      testHarness,
+					Verdict:          &api.TestCaseResult_Skip_{Skip: &api.TestCaseResult_Skip{}},
+					Errors:           []*api.TestCaseResult_Error{{Message: failureMessage}},
+					StartTime:        wantStartTime,
+					Duration:         wantDuration,
+					TestCaseMetadata: wantTestCaseMetadata,
 				},
 			},
 		} {