1/* 2 * Copyright (c) 2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16package smoke 17 18import ( 19 "context" 20 "crypto/md5" 21 "encoding/json" 22 "errors" 23 "fmt" 24 "fotff/tester" 25 "fotff/utils" 26 "github.com/sirupsen/logrus" 27 "math/rand" 28 "os" 29 "path/filepath" 30 "strconv" 31 "strings" 32 "time" 33) 34 35type Tester struct { 36 Py string `key:"py"` 37 Config string `key:"config"` 38 AnswerPath string `key:"answer_path"` 39 SavePath string `key:"save_path"` 40 ToolsPath string `key:"tools_path"` 41} 42 43func init() { 44 rand.Seed(time.Now().UnixNano()) 45} 46 47func NewTester() tester.Tester { 48 ret := &Tester{} 49 utils.ParseFromConfigFile("smoke", ret) 50 return ret 51} 52 53func (t *Tester) TaskName() string { 54 return "smoke_test" 55} 56 57func (t *Tester) Prepare(pkgDir string, device string, ctx context.Context) error { 58 return nil 59} 60 61func (t *Tester) DoTestTask(deviceSN string, ctx context.Context) (ret []tester.Result, err error) { 62 reportDir := fmt.Sprintf("%X", md5.Sum([]byte(fmt.Sprintf("%d", rand.Int())))) 63 if err := os.MkdirAll(filepath.Join(t.SavePath, reportDir), 0755); err != nil { 64 return nil, err 65 } 66 args := []string{t.Py, "--config", t.Config, "--answer_path", t.AnswerPath, "--save_path", filepath.Join(t.SavePath, reportDir), "--tools_path", t.ToolsPath} 67 if deviceSN != "" { 68 args = append(args, "--device_num", deviceSN) 69 } 70 if err := utils.ExecContext(ctx, "python", args...); err != nil { 71 if errors.Is(err, context.Canceled) { 72 return nil, err 73 } 74 logrus.Errorf("do test suite fail: %v", err) 75 return nil, err 76 } 77 return t.readReport(reportDir) 78} 79 80func (t *Tester) DoTestCase(deviceSN, testCase string, ctx context.Context) (ret tester.Result, err error) { 81 reportDir := fmt.Sprintf("%X", md5.Sum([]byte(fmt.Sprintf("%d", rand.Int())))) 82 if err := os.MkdirAll(filepath.Join(t.SavePath, reportDir), 0755); err != nil { 83 return ret, err 84 } 85 args := []string{t.Py, "--config", t.Config, "--answer_path", t.AnswerPath, "--save_path", filepath.Join(t.SavePath, reportDir), "--tools_path", t.ToolsPath, "--test_num", testCase} 86 if deviceSN != "" { 87 args = append(args, "--device_num", deviceSN) 88 } 89 if err := utils.ExecContext(ctx, "python", args...); err != nil { 90 if errors.Is(err, context.Canceled) { 91 return ret, err 92 } 93 logrus.Errorf("do test case %s fail: %v", testCase, err) 94 return ret, err 95 } 96 r, err := t.readReport(reportDir) 97 if len(r) == 0 { 98 return ret, fmt.Errorf("read latest report err, no result found") 99 } 100 if r[0].TestCaseName != testCase { 101 return ret, fmt.Errorf("read latest report err, no matched result found") 102 } 103 logrus.Infof("do testcase %s at %s done, result is %s", r[0].TestCaseName, deviceSN, r[0].Status) 104 return r[0], nil 105} 106 107func (t *Tester) DoTestCases(deviceSN string, testcases []string, ctx context.Context) (ret []tester.Result, err error) { 108 reportDir := fmt.Sprintf("%X", md5.Sum([]byte(fmt.Sprintf("%d", rand.Int())))) 109 if err := os.MkdirAll(filepath.Join(t.SavePath, reportDir), 0755); err != nil { 110 return nil, err 111 } 112 args := []string{t.Py, "--config", t.Config, "--answer_path", t.AnswerPath, "--save_path", filepath.Join(t.SavePath, reportDir), "--tools_path", t.ToolsPath, "--test_num", strings.Join(testcases, " ")} 113 if deviceSN != "" { 114 args = append(args, "--device_num", deviceSN) 115 } 116 if err := utils.ExecContext(ctx, "python", args...); err != nil { 117 if errors.Is(err, context.Canceled) { 118 return ret, err 119 } 120 logrus.Errorf("do test cases %v fail: %v", testcases, err) 121 return ret, err 122 } 123 return t.readReport(reportDir) 124} 125 126func (t *Tester) readReport(reportDir string) (ret []tester.Result, err error) { 127 data, err := os.ReadFile(filepath.Join(t.SavePath, reportDir, "result.json")) 128 if err != nil { 129 logrus.Errorf("read report json fail: %v", err) 130 return nil, err 131 } 132 var result []struct { 133 TestCaseName int `json:"test_case_name"` 134 Status string `json:"status"` 135 } 136 err = json.Unmarshal(data, &result) 137 if err != nil { 138 logrus.Errorf("unmarshal report xml fail: %v", err) 139 return nil, err 140 } 141 for _, r := range result { 142 if r.Status == "pass" { 143 ret = append(ret, tester.Result{TestCaseName: strconv.Itoa(r.TestCaseName), Status: tester.ResultPass}) 144 } else { 145 ret = append(ret, tester.Result{TestCaseName: strconv.Itoa(r.TestCaseName), Status: tester.ResultFail}) 146 } 147 } 148 return ret, err 149} 150