1package common 2 3import ( 4 "context" 5 "encoding/json" 6 "errors" 7 "fmt" 8 "fotff/tester" 9 "fotff/utils" 10 "os" 11 "path/filepath" 12 "strings" 13 14 "github.com/sirupsen/logrus" 15) 16 17const ( 18 testResultPass = "pass" 19 testCaseFlag = "--test-case" 20 deviceFlag = "--device" 21 resultPathFlag = "--result-path" 22 resultFileFlag = "--result-file" 23) 24 25// Tester is the common tester for most kinds of tests 26type Tester struct { 27 Tool string `key:"tool"` 28 Param string `key:"param"` 29 ResultPath string `key:"result_path"` 30 ResultFile string `key:"result_file"` 31} 32 33// TestResult is the structure of the test result json file 34type TestResult struct { 35 TestCase string `json:"test_case"` 36 Result string `json:"result"` 37} 38 39func NewTester() tester.Tester { 40 t := &Tester{} 41 utils.ParseFromConfigFile("common", t) 42 return t 43} 44 45func (t *Tester) TaskName() string { 46 return "common_tester" 47} 48 49func (t *Tester) Prepare(version string, device string, ctx context.Context) error { 50 return nil 51} 52 53// DoTestTask run all test cases on the specified device 54func (t *Tester) DoTestTask(device string, ctx context.Context) ([]tester.Result, error) { 55 args := strings.Split(t.Param, " ") 56 if device != "" { 57 args = append(args, []string{deviceFlag, device}...) 58 } 59 args = append(args, []string{resultPathFlag, t.ResultPath}...) 60 args = append(args, []string{resultFileFlag, t.ResultFile}...) 61 if err := utils.ExecContext(ctx, t.Tool, args...); err != nil { 62 if errors.Is(err, context.Canceled) { 63 return nil, err 64 } 65 logrus.Errorf("Failed to do test task on device %s, error: %s", device, err.Error()) 66 return nil, err 67 } 68 69 return t.processResult() 70} 71 72// DoTestCase run the specified test case on the specified device 73func (t *Tester) DoTestCase(device string, testCase string, ctx context.Context) (tester.Result, error) { 74 args := strings.Split(t.Param, " ") 75 args = append(args, []string{testCaseFlag, testCase}...) 76 if device != "" { 77 args = append(args, []string{deviceFlag, device}...) 78 } 79 args = append(args, []string{resultPathFlag, t.ResultPath}...) 80 args = append(args, []string{resultFileFlag, t.ResultFile}...) 81 defaultResult := tester.Result{} 82 if err := utils.ExecContext(ctx, t.Tool, args...); err != nil { 83 if errors.Is(err, context.Canceled) { 84 return defaultResult, err 85 } 86 logrus.Errorf("Failed to do test case %s on device %s, error: %s", testCase, device, err.Error()) 87 return defaultResult, err 88 } 89 90 rs, err := t.processResult() 91 if err != nil { 92 return defaultResult, err 93 } 94 if len(rs) == 0 { 95 return defaultResult, fmt.Errorf("failed to process test result: no test result found") 96 } 97 if rs[0].TestCaseName != testCase { 98 return defaultResult, fmt.Errorf("failed to process test result: no matched test result found") 99 } 100 101 logrus.Infof("test case %s on device %s finished, the result is %s", testCase, device, rs[0].Status) 102 return rs[0], nil 103} 104 105// DoTestCases run the specified test cases on the specified device 106func (t *Tester) DoTestCases(device string, testCases []string, ctx context.Context) ([]tester.Result, error) { 107 args := strings.Split(t.Param, " ") 108 args = append(args, testCaseFlag) 109 args = append(args, testCases...) 110 if device != "" { 111 args = append(args, []string{deviceFlag, device}...) 112 } 113 args = append(args, []string{resultPathFlag, t.ResultPath}...) 114 args = append(args, []string{resultFileFlag, t.ResultFile}...) 115 if err := utils.ExecContext(ctx, t.Tool, args...); err != nil { 116 if errors.Is(err, context.Canceled) { 117 return nil, err 118 } 119 logrus.Errorf("Failed to do test cases %v on device %s, error: %s", testCases, device, err.Error()) 120 return nil, err 121 } 122 123 return t.processResult() 124} 125 126// processResult parse the test result file 127func (t *Tester) processResult() ([]tester.Result, error) { 128 resultFile := filepath.Join(t.ResultPath, t.ResultFile) 129 data, err := os.ReadFile(resultFile) 130 if err != nil { 131 logrus.Errorf("Failed to read from result file %s, error: %s", resultFile, err.Error()) 132 return nil, err 133 } 134 135 var result []TestResult 136 if err := json.Unmarshal(data, &result); err != nil { 137 logrus.Errorf("Failed to unmarshal test result %s into json array, error: %s", string(data), err.Error()) 138 return nil, err 139 } 140 141 var ret []tester.Result 142 for _, r := range result { 143 if r.Result == testResultPass { 144 ret = append(ret, tester.Result{TestCaseName: r.TestCase, Status: tester.ResultPass}) 145 } else { 146 ret = append(ret, tester.Result{TestCaseName: r.TestCase, Status: tester.ResultFail}) 147 } 148 } 149 return ret, nil 150} 151