blob: b3c4ef9651bfe9a6ce03131dc5801ef5df0820d8 [file] [log] [blame]
// Copyright 2024 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Package driver implements drivers to execute tests.
package driver
import (
"encoding/json"
"fmt"
"strings"
"time"
"go.chromium.org/chromiumos/config/go/test/api"
"google.golang.org/protobuf/types/known/durationpb"
"google.golang.org/protobuf/types/known/timestamppb"
)
// Unmarshal Json respresentation of SessionDetailResponse to golang struct
func toSessionResponse(jsonText string) (*sessionDetailResponse, error) {
var response *sessionDetailResponse
err := json.Unmarshal([]byte(jsonText), &response)
if err != nil {
return nil, fmt.Errorf("Failed to deserialize (%v): %v \n", jsonText, err)
}
return response, nil
}
// Helper function for creating a CFT TestCaseResult skeleton
func buildCommonTestCaseResult(test *api.TestCaseMetadata,
startTime time.Time,
duration time.Duration) *api.TestCaseResult {
tcResult := &api.TestCaseResult{}
tcResult.TestHarness = &api.TestHarness{TestHarnessType: &api.TestHarness_Mobly_{Mobly: &api.TestHarness_Mobly{}}}
if test != nil && test.TestCase != nil && test.TestCase.Id != nil {
tcResult.TestCaseId = test.TestCase.Id
}
tcResult.TestCaseMetadata = test
tcResult.StartTime = timestamppb.New(startTime)
tcResult.Duration = &durationpb.Duration{Seconds: int64(duration.Seconds())}
return tcResult
}
// Create CFT TestCaseResult based on verdict and reason.
func buildTestCaseResult(test *api.TestCaseMetadata,
startTime time.Time,
duration time.Duration,
verdict string,
reason string) *api.TestCaseResult {
tcResult := buildCommonTestCaseResult(test, startTime, duration)
switch verdict {
case "PASS":
tcResult.Verdict = &api.TestCaseResult_Pass_{Pass: &api.TestCaseResult_Pass{}}
case "FAIL":
tcResult.Verdict = &api.TestCaseResult_Fail_{Fail: &api.TestCaseResult_Fail{}}
case "CRASH":
tcResult.Verdict = &api.TestCaseResult_Crash_{Crash: &api.TestCaseResult_Crash{}}
case "ABORT":
tcResult.Verdict = &api.TestCaseResult_Abort_{Abort: &api.TestCaseResult_Abort{}}
case "SKIP":
tcResult.Verdict = &api.TestCaseResult_Skip_{Skip: &api.TestCaseResult_Skip{}}
case "NOT_RUN":
tcResult.Verdict = &api.TestCaseResult_NotRun_{NotRun: &api.TestCaseResult_NotRun{}}
default:
tcResult.Verdict = &api.TestCaseResult_Fail_{Fail: &api.TestCaseResult_Fail{}}
}
if reason != "" {
tcResult.Reason = reason
}
return tcResult
}
// Convert SessionDetailResponse in CFT TestCaseResult
func buildTestCaseResultFromSessionResponse(test *api.TestCaseMetadata,
startTime time.Time,
duration time.Duration,
response *sessionDetailResponse) *api.TestCaseResult {
tcResult := buildCommonTestCaseResult(test, startTime, duration)
if response != nil && response.SessionDetail != nil && response.SessionDetail.SessionSummary != nil {
switch result := response.SessionDetail.SessionSummary.Result; result {
case "PASS":
tcResult.Verdict = &api.TestCaseResult_Pass_{Pass: &api.TestCaseResult_Pass{}}
case "ABORT":
tcResult.Verdict = &api.TestCaseResult_Abort_{Abort: &api.TestCaseResult_Abort{}}
case "SKIP":
tcResult.Verdict = &api.TestCaseResult_Skip_{Skip: &api.TestCaseResult_Skip{}}
case "FAIL", "UNKNOWN", "INFRA_ERROR", "ALLOC_FAIL", "ALLOC_ERROR":
// we lump all these cases into "FAIL". There could be fine granularity control
// on fetching the errors from sessionDetailResponse as we learn more about those scenarios.
tcResult.Verdict = &api.TestCaseResult_Fail_{Fail: &api.TestCaseResult_Fail{}}
reasons := []string{}
reasons = append(reasons, fmt.Sprintf("Omnilab result: %v", result))
if response.SessionDetail != nil {
for _, jd := range response.SessionDetail.JobDetail {
if jd.JobSummary != nil {
for _, errMsg := range jd.JobSummary.Error {
reasons = append(reasons, errMsg)
}
}
}
}
tcResult.Reason = strings.Join(reasons, "\n")
case "TIMEOUT":
tcResult.Verdict = &api.TestCaseResult_Fail_{Fail: &api.TestCaseResult_Fail{}}
tcResult.Reason = "timeout during omnilab execution"
}
} else {
tcResult.Verdict = &api.TestCaseResult_Fail_{Fail: &api.TestCaseResult_Fail{}}
tcResult.Reason = "Omnilab result not available"
}
return tcResult
}