package common import ( "context" "encoding/json" "errors" "fmt" "fotff/tester" "fotff/utils" "os" "path/filepath" "strings" "github.com/sirupsen/logrus" ) const ( testResultPass = "pass" testCaseFlag = "--test-case" deviceFlag = "--device" resultPathFlag = "--result-path" resultFileFlag = "--result-file" ) // Tester is the common tester for most kinds of tests type Tester struct { Tool string `key:"tool"` Param string `key:"param"` ResultPath string `key:"result_path"` ResultFile string `key:"result_file"` } // TestResult is the structure of the test result json file type TestResult struct { TestCase string `json:"test_case"` Result string `json:"result"` } func NewTester() tester.Tester { t := &Tester{} utils.ParseFromConfigFile("common", t) return t } func (t *Tester) TaskName() string { return "common_tester" } func (t *Tester) Prepare(version string, device string, ctx context.Context) error { return nil } // DoTestTask run all test cases on the specified device func (t *Tester) DoTestTask(device string, ctx context.Context) ([]tester.Result, error) { args := strings.Split(t.Param, " ") if device != "" { args = append(args, []string{deviceFlag, device}...) } args = append(args, []string{resultPathFlag, t.ResultPath}...) args = append(args, []string{resultFileFlag, t.ResultFile}...) if err := utils.ExecContext(ctx, t.Tool, args...); err != nil { if errors.Is(err, context.Canceled) { return nil, err } logrus.Errorf("Failed to do test task on device %s, error: %s", device, err.Error()) return nil, err } return t.processResult() } // DoTestCase run the specified test case on the specified device func (t *Tester) DoTestCase(device string, testCase string, ctx context.Context) (tester.Result, error) { args := strings.Split(t.Param, " ") args = append(args, []string{testCaseFlag, testCase}...) if device != "" { args = append(args, []string{deviceFlag, device}...) } args = append(args, []string{resultPathFlag, t.ResultPath}...) args = append(args, []string{resultFileFlag, t.ResultFile}...) defaultResult := tester.Result{} if err := utils.ExecContext(ctx, t.Tool, args...); err != nil { if errors.Is(err, context.Canceled) { return defaultResult, err } logrus.Errorf("Failed to do test case %s on device %s, error: %s", testCase, device, err.Error()) return defaultResult, err } rs, err := t.processResult() if err != nil { return defaultResult, err } if len(rs) == 0 { return defaultResult, fmt.Errorf("failed to process test result: no test result found") } if rs[0].TestCaseName != testCase { return defaultResult, fmt.Errorf("failed to process test result: no matched test result found") } logrus.Infof("test case %s on device %s finished, the result is %s", testCase, device, rs[0].Status) return rs[0], nil } // DoTestCases run the specified test cases on the specified device func (t *Tester) DoTestCases(device string, testCases []string, ctx context.Context) ([]tester.Result, error) { args := strings.Split(t.Param, " ") args = append(args, testCaseFlag) args = append(args, testCases...) if device != "" { args = append(args, []string{deviceFlag, device}...) } args = append(args, []string{resultPathFlag, t.ResultPath}...) args = append(args, []string{resultFileFlag, t.ResultFile}...) if err := utils.ExecContext(ctx, t.Tool, args...); err != nil { if errors.Is(err, context.Canceled) { return nil, err } logrus.Errorf("Failed to do test cases %v on device %s, error: %s", testCases, device, err.Error()) return nil, err } return t.processResult() } // processResult parse the test result file func (t *Tester) processResult() ([]tester.Result, error) { resultFile := filepath.Join(t.ResultPath, t.ResultFile) data, err := os.ReadFile(resultFile) if err != nil { logrus.Errorf("Failed to read from result file %s, error: %s", resultFile, err.Error()) return nil, err } var result []TestResult if err := json.Unmarshal(data, &result); err != nil { logrus.Errorf("Failed to unmarshal test result %s into json array, error: %s", string(data), err.Error()) return nil, err } var ret []tester.Result for _, r := range result { if r.Result == testResultPass { ret = append(ret, tester.Result{TestCaseName: r.TestCase, Status: tester.ResultPass}) } else { ret = append(ret, tester.Result{TestCaseName: r.TestCase, Status: tester.ResultFail}) } } return ret, nil }