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 main 17 18import ( 19 "context" 20 "fotff/pkg" 21 "fotff/pkg/dayu200" 22 "fotff/pkg/gitee_build" 23 "fotff/pkg/mock" 24 "fotff/rec" 25 "fotff/res" 26 "fotff/tester" 27 "fotff/tester/common" 28 "fotff/tester/manual" 29 testermock "fotff/tester/mock" 30 "fotff/tester/pkg_available" 31 "fotff/tester/smoke" 32 "fotff/tester/xdevice" 33 "fotff/utils" 34 "os" 35 "path/filepath" 36 37 "github.com/sirupsen/logrus" 38 "github.com/spf13/cobra" 39) 40 41var newPkgMgrFuncs = map[string]pkg.NewFunc{ 42 "mock": mock.NewManager, 43 "dayu200": dayu200.NewManager, 44 "gitee_build": gitee_build.NewManager, 45} 46 47var newTesterFuncs = map[string]tester.NewFunc{ 48 "mock": testermock.NewTester, 49 "manual": manual.NewTester, 50 "common": common.NewTester, 51 "xdevice": xdevice.NewTester, 52 "smoke": smoke.NewTester, 53 "pkg_available": pkg_available.NewTester, 54} 55 56var rootCmd *cobra.Command 57 58func init() { 59 m, t := initExecutor() 60 rootCmd = &cobra.Command{ 61 Run: func(cmd *cobra.Command, args []string) { 62 loop(m, t) 63 }, 64 } 65 runCmd := initRunCmd(m, t) 66 flashCmd := initFlashCmd(m) 67 testCmd := initTestCmd(m, t) 68 rootCmd.AddCommand(runCmd, flashCmd, testCmd) 69} 70 71func initRunCmd(m pkg.Manager, t tester.Tester) *cobra.Command { 72 var success, fail, testcase string 73 runCmd := &cobra.Command{ 74 Use: "run", 75 Short: "bin-search in (success, fail] by do given testcase to find out the fist fail, and print the corresponding issue", 76 RunE: func(cmd *cobra.Command, args []string) error { 77 return fotff(m, t, success, fail, testcase) 78 }, 79 } 80 runCmd.PersistentFlags().StringVarP(&success, "success", "s", "", "success package directory") 81 runCmd.PersistentFlags().StringVarP(&fail, "fail", "f", "", "fail package directory") 82 runCmd.PersistentFlags().StringVarP(&testcase, "testcase", "t", "", "testcase name") 83 runCmd.MarkPersistentFlagRequired("success") 84 runCmd.MarkPersistentFlagRequired("fail") 85 runCmd.MarkPersistentFlagRequired("testcase") 86 return runCmd 87} 88 89func initFlashCmd(m pkg.Manager) *cobra.Command { 90 var flashPkg, device string 91 flashCmd := &cobra.Command{ 92 Use: "flash", 93 Short: "flash the given package", 94 RunE: func(cmd *cobra.Command, args []string) error { 95 return m.Flash(device, flashPkg, context.TODO()) 96 }, 97 } 98 flashCmd.PersistentFlags().StringVarP(&flashPkg, "package", "p", "", "package directory") 99 flashCmd.PersistentFlags().StringVarP(&device, "device", "d", "", "device sn") 100 flashCmd.MarkPersistentFlagRequired("package") 101 return flashCmd 102} 103 104func initTestCmd(m pkg.Manager, t tester.Tester) *cobra.Command { 105 var targetPkg, device, testCase string 106 testCmd := &cobra.Command{ 107 Use: "test", 108 Short: "build and flash and test the given package on the specified device", 109 RunE: func(cmd *cobra.Command, args []string) error { 110 opt := &rec.FlashAndTestOptions{ 111 M: m, 112 T: t, 113 Version: targetPkg, 114 Device: device, 115 TestCase: testCase, 116 } 117 return rec.FlashAndTest(context.TODO(), opt) 118 }, 119 } 120 testCmd.PersistentFlags().StringVarP(&targetPkg, "package", "p", "", "package directory") 121 testCmd.PersistentFlags().StringVarP(&device, "device", "d", "", "target device sn") 122 testCmd.PersistentFlags().StringVarP(&testCase, "testcase", "t", "", "test case to run") 123 testCmd.MarkPersistentFlagRequired("package") 124 testCmd.MarkPersistentFlagRequired("device") 125 126 return testCmd 127} 128 129func main() { 130 utils.EnablePprof() 131 if err := rootCmd.Execute(); err != nil { 132 logrus.Errorf("failed to execute: %v", err) 133 os.Exit(1) 134 } 135} 136 137func loop(m pkg.Manager, t tester.Tester) { 138 data, _ := utils.ReadRuntimeData("last_handled.rec") 139 var curPkg = string(data) 140 for { 141 utils.ResetLogOutput() 142 if err := utils.WriteRuntimeData("last_handled.rec", []byte(curPkg)); err != nil { 143 logrus.Errorf("failed to write last_handled.rec: %v", err) 144 } 145 logrus.Info("waiting for a newer package...") 146 var err error 147 curPkg, err = m.GetNewer(curPkg) 148 if err != nil { 149 logrus.Infof("get newer package err: %v", err) 150 continue 151 } 152 utils.SetLogOutput(filepath.Base(curPkg)) 153 logrus.Infof("now flash %s...", curPkg) 154 device := res.GetDevice() 155 if err := m.Flash(device, curPkg, context.TODO()); err != nil { 156 logrus.Errorf("flash package dir %s err: %v", curPkg, err) 157 res.ReleaseDevice(device) 158 continue 159 } 160 if err := t.Prepare(m.PkgDir(curPkg), device, context.TODO()); err != nil { 161 logrus.Errorf("do test preperation for package %s err: %v", curPkg, err) 162 continue 163 } 164 logrus.Info("now do test suite...") 165 results, err := t.DoTestTask(device, context.TODO()) 166 if err != nil { 167 logrus.Errorf("do test suite for package %s err: %v", curPkg, err) 168 continue 169 } 170 for _, r := range results { 171 logrus.Infof("do test case %s at %s done, result is %v", r.TestCaseName, device, r.Status) 172 } 173 logrus.Infof("now analysis test results...") 174 toFotff := rec.HandleResults(t, device, curPkg, results) 175 res.ReleaseDevice(device) 176 rec.Analysis(m, t, curPkg, toFotff) 177 rec.Save() 178 rec.Report(curPkg, t.TaskName()) 179 } 180} 181 182func fotff(m pkg.Manager, t tester.Tester, success, fail, testcase string) error { 183 issueURL, err := rec.FindOutTheFirstFail(m, t, testcase, success, fail) 184 if err != nil { 185 logrus.Errorf("failed to find out the first fail: %v", err) 186 return err 187 } 188 logrus.Infof("the first fail found: %v", issueURL) 189 return nil 190} 191 192func initExecutor() (pkg.Manager, tester.Tester) { 193 //TODO load from config file 194 var conf = struct { 195 PkgManager string `key:"pkg_manager" default:"mock"` 196 Tester string `key:"tester" default:"mock"` 197 }{} 198 utils.ParseFromConfigFile("", &conf) 199 newPkgMgrFunc, ok := newPkgMgrFuncs[conf.PkgManager] 200 if !ok { 201 logrus.Panicf("no package manager found for %s", conf.PkgManager) 202 } 203 newTesterFunc, ok := newTesterFuncs[conf.Tester] 204 if !ok { 205 logrus.Panicf("no tester found for %s", conf.Tester) 206 } 207 return newPkgMgrFunc(), newTesterFunc() 208} 209