209 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
		
		
			
		
	
	
			209 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 * Copyright (c) 2022 Huawei Device Co., Ltd.
							 | 
						||
| 
								 | 
							
								 * Licensed under the Apache License, Version 2.0 (the "License");
							 | 
						||
| 
								 | 
							
								 * you may not use this file except in compliance with the License.
							 | 
						||
| 
								 | 
							
								 * You may obtain a copy of the License at
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 *     http://www.apache.org/licenses/LICENSE-2.0
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * Unless required by applicable law or agreed to in writing, software
							 | 
						||
| 
								 | 
							
								 * distributed under the License is distributed on an "AS IS" BASIS,
							 | 
						||
| 
								 | 
							
								 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
							 | 
						||
| 
								 | 
							
								 * See the License for the specific language governing permissions and
							 | 
						||
| 
								 | 
							
								 * limitations under the License.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								package main
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								import (
							 | 
						||
| 
								 | 
							
									"context"
							 | 
						||
| 
								 | 
							
									"fotff/pkg"
							 | 
						||
| 
								 | 
							
									"fotff/pkg/dayu200"
							 | 
						||
| 
								 | 
							
									"fotff/pkg/gitee_build"
							 | 
						||
| 
								 | 
							
									"fotff/pkg/mock"
							 | 
						||
| 
								 | 
							
									"fotff/rec"
							 | 
						||
| 
								 | 
							
									"fotff/res"
							 | 
						||
| 
								 | 
							
									"fotff/tester"
							 | 
						||
| 
								 | 
							
									"fotff/tester/common"
							 | 
						||
| 
								 | 
							
									"fotff/tester/manual"
							 | 
						||
| 
								 | 
							
									testermock "fotff/tester/mock"
							 | 
						||
| 
								 | 
							
									"fotff/tester/pkg_available"
							 | 
						||
| 
								 | 
							
									"fotff/tester/smoke"
							 | 
						||
| 
								 | 
							
									"fotff/tester/xdevice"
							 | 
						||
| 
								 | 
							
									"fotff/utils"
							 | 
						||
| 
								 | 
							
									"os"
							 | 
						||
| 
								 | 
							
									"path/filepath"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									"github.com/sirupsen/logrus"
							 | 
						||
| 
								 | 
							
									"github.com/spf13/cobra"
							 | 
						||
| 
								 | 
							
								)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								var newPkgMgrFuncs = map[string]pkg.NewFunc{
							 | 
						||
| 
								 | 
							
									"mock":        mock.NewManager,
							 | 
						||
| 
								 | 
							
									"dayu200":     dayu200.NewManager,
							 | 
						||
| 
								 | 
							
									"gitee_build": gitee_build.NewManager,
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								var newTesterFuncs = map[string]tester.NewFunc{
							 | 
						||
| 
								 | 
							
									"mock":          testermock.NewTester,
							 | 
						||
| 
								 | 
							
									"manual":        manual.NewTester,
							 | 
						||
| 
								 | 
							
									"common":        common.NewTester,
							 | 
						||
| 
								 | 
							
									"xdevice":       xdevice.NewTester,
							 | 
						||
| 
								 | 
							
									"smoke":         smoke.NewTester,
							 | 
						||
| 
								 | 
							
									"pkg_available": pkg_available.NewTester,
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								var rootCmd *cobra.Command
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func init() {
							 | 
						||
| 
								 | 
							
									m, t := initExecutor()
							 | 
						||
| 
								 | 
							
									rootCmd = &cobra.Command{
							 | 
						||
| 
								 | 
							
										Run: func(cmd *cobra.Command, args []string) {
							 | 
						||
| 
								 | 
							
											loop(m, t)
							 | 
						||
| 
								 | 
							
										},
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									runCmd := initRunCmd(m, t)
							 | 
						||
| 
								 | 
							
									flashCmd := initFlashCmd(m)
							 | 
						||
| 
								 | 
							
									testCmd := initTestCmd(m, t)
							 | 
						||
| 
								 | 
							
									rootCmd.AddCommand(runCmd, flashCmd, testCmd)
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func initRunCmd(m pkg.Manager, t tester.Tester) *cobra.Command {
							 | 
						||
| 
								 | 
							
									var success, fail, testcase string
							 | 
						||
| 
								 | 
							
									runCmd := &cobra.Command{
							 | 
						||
| 
								 | 
							
										Use:   "run",
							 | 
						||
| 
								 | 
							
										Short: "bin-search in (success, fail] by do given testcase to find out the fist fail, and print the corresponding issue",
							 | 
						||
| 
								 | 
							
										RunE: func(cmd *cobra.Command, args []string) error {
							 | 
						||
| 
								 | 
							
											return fotff(m, t, success, fail, testcase)
							 | 
						||
| 
								 | 
							
										},
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									runCmd.PersistentFlags().StringVarP(&success, "success", "s", "", "success package directory")
							 | 
						||
| 
								 | 
							
									runCmd.PersistentFlags().StringVarP(&fail, "fail", "f", "", "fail package directory")
							 | 
						||
| 
								 | 
							
									runCmd.PersistentFlags().StringVarP(&testcase, "testcase", "t", "", "testcase name")
							 | 
						||
| 
								 | 
							
									runCmd.MarkPersistentFlagRequired("success")
							 | 
						||
| 
								 | 
							
									runCmd.MarkPersistentFlagRequired("fail")
							 | 
						||
| 
								 | 
							
									runCmd.MarkPersistentFlagRequired("testcase")
							 | 
						||
| 
								 | 
							
									return runCmd
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func initFlashCmd(m pkg.Manager) *cobra.Command {
							 | 
						||
| 
								 | 
							
									var flashPkg, device string
							 | 
						||
| 
								 | 
							
									flashCmd := &cobra.Command{
							 | 
						||
| 
								 | 
							
										Use:   "flash",
							 | 
						||
| 
								 | 
							
										Short: "flash the given package",
							 | 
						||
| 
								 | 
							
										RunE: func(cmd *cobra.Command, args []string) error {
							 | 
						||
| 
								 | 
							
											return m.Flash(device, flashPkg, context.TODO())
							 | 
						||
| 
								 | 
							
										},
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									flashCmd.PersistentFlags().StringVarP(&flashPkg, "package", "p", "", "package directory")
							 | 
						||
| 
								 | 
							
									flashCmd.PersistentFlags().StringVarP(&device, "device", "d", "", "device sn")
							 | 
						||
| 
								 | 
							
									flashCmd.MarkPersistentFlagRequired("package")
							 | 
						||
| 
								 | 
							
									return flashCmd
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func initTestCmd(m pkg.Manager, t tester.Tester) *cobra.Command {
							 | 
						||
| 
								 | 
							
									var targetPkg, device, testCase string
							 | 
						||
| 
								 | 
							
									testCmd := &cobra.Command{
							 | 
						||
| 
								 | 
							
										Use:   "test",
							 | 
						||
| 
								 | 
							
										Short: "build and flash and test the given package on the specified device",
							 | 
						||
| 
								 | 
							
										RunE: func(cmd *cobra.Command, args []string) error {
							 | 
						||
| 
								 | 
							
											opt := &rec.FlashAndTestOptions{
							 | 
						||
| 
								 | 
							
												M:        m,
							 | 
						||
| 
								 | 
							
												T:        t,
							 | 
						||
| 
								 | 
							
												Version:  targetPkg,
							 | 
						||
| 
								 | 
							
												Device:   device,
							 | 
						||
| 
								 | 
							
												TestCase: testCase,
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											return rec.FlashAndTest(context.TODO(), opt)
							 | 
						||
| 
								 | 
							
										},
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									testCmd.PersistentFlags().StringVarP(&targetPkg, "package", "p", "", "package directory")
							 | 
						||
| 
								 | 
							
									testCmd.PersistentFlags().StringVarP(&device, "device", "d", "", "target device sn")
							 | 
						||
| 
								 | 
							
									testCmd.PersistentFlags().StringVarP(&testCase, "testcase", "t", "", "test case to run")
							 | 
						||
| 
								 | 
							
									testCmd.MarkPersistentFlagRequired("package")
							 | 
						||
| 
								 | 
							
									testCmd.MarkPersistentFlagRequired("device")
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									return testCmd
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func main() {
							 | 
						||
| 
								 | 
							
									utils.EnablePprof()
							 | 
						||
| 
								 | 
							
									if err := rootCmd.Execute(); err != nil {
							 | 
						||
| 
								 | 
							
										logrus.Errorf("failed to execute: %v", err)
							 | 
						||
| 
								 | 
							
										os.Exit(1)
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func loop(m pkg.Manager, t tester.Tester) {
							 | 
						||
| 
								 | 
							
									data, _ := utils.ReadRuntimeData("last_handled.rec")
							 | 
						||
| 
								 | 
							
									var curPkg = string(data)
							 | 
						||
| 
								 | 
							
									for {
							 | 
						||
| 
								 | 
							
										utils.ResetLogOutput()
							 | 
						||
| 
								 | 
							
										if err := utils.WriteRuntimeData("last_handled.rec", []byte(curPkg)); err != nil {
							 | 
						||
| 
								 | 
							
											logrus.Errorf("failed to write last_handled.rec: %v", err)
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										logrus.Info("waiting for a newer package...")
							 | 
						||
| 
								 | 
							
										var err error
							 | 
						||
| 
								 | 
							
										curPkg, err = m.GetNewer(curPkg)
							 | 
						||
| 
								 | 
							
										if err != nil {
							 | 
						||
| 
								 | 
							
											logrus.Infof("get newer package err: %v", err)
							 | 
						||
| 
								 | 
							
											continue
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										utils.SetLogOutput(filepath.Base(curPkg))
							 | 
						||
| 
								 | 
							
										logrus.Infof("now flash %s...", curPkg)
							 | 
						||
| 
								 | 
							
										device := res.GetDevice()
							 | 
						||
| 
								 | 
							
										if err := m.Flash(device, curPkg, context.TODO()); err != nil {
							 | 
						||
| 
								 | 
							
											logrus.Errorf("flash package dir %s err: %v", curPkg, err)
							 | 
						||
| 
								 | 
							
											res.ReleaseDevice(device)
							 | 
						||
| 
								 | 
							
											continue
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										if err := t.Prepare(m.PkgDir(curPkg), device, context.TODO()); err != nil {
							 | 
						||
| 
								 | 
							
											logrus.Errorf("do test preperation for package %s err: %v", curPkg, err)
							 | 
						||
| 
								 | 
							
											continue
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										logrus.Info("now do test suite...")
							 | 
						||
| 
								 | 
							
										results, err := t.DoTestTask(device, context.TODO())
							 | 
						||
| 
								 | 
							
										if err != nil {
							 | 
						||
| 
								 | 
							
											logrus.Errorf("do test suite for package %s err: %v", curPkg, err)
							 | 
						||
| 
								 | 
							
											continue
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										for _, r := range results {
							 | 
						||
| 
								 | 
							
											logrus.Infof("do test case %s at %s done, result is %v", r.TestCaseName, device, r.Status)
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										logrus.Infof("now analysis test results...")
							 | 
						||
| 
								 | 
							
										toFotff := rec.HandleResults(t, device, curPkg, results)
							 | 
						||
| 
								 | 
							
										res.ReleaseDevice(device)
							 | 
						||
| 
								 | 
							
										rec.Analysis(m, t, curPkg, toFotff)
							 | 
						||
| 
								 | 
							
										rec.Save()
							 | 
						||
| 
								 | 
							
										rec.Report(curPkg, t.TaskName())
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func fotff(m pkg.Manager, t tester.Tester, success, fail, testcase string) error {
							 | 
						||
| 
								 | 
							
									issueURL, err := rec.FindOutTheFirstFail(m, t, testcase, success, fail)
							 | 
						||
| 
								 | 
							
									if err != nil {
							 | 
						||
| 
								 | 
							
										logrus.Errorf("failed to find out the first fail: %v", err)
							 | 
						||
| 
								 | 
							
										return err
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									logrus.Infof("the first fail found: %v", issueURL)
							 | 
						||
| 
								 | 
							
									return nil
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func initExecutor() (pkg.Manager, tester.Tester) {
							 | 
						||
| 
								 | 
							
									//TODO load from config file
							 | 
						||
| 
								 | 
							
									var conf = struct {
							 | 
						||
| 
								 | 
							
										PkgManager string `key:"pkg_manager" default:"mock"`
							 | 
						||
| 
								 | 
							
										Tester     string `key:"tester" default:"mock"`
							 | 
						||
| 
								 | 
							
									}{}
							 | 
						||
| 
								 | 
							
									utils.ParseFromConfigFile("", &conf)
							 | 
						||
| 
								 | 
							
									newPkgMgrFunc, ok := newPkgMgrFuncs[conf.PkgManager]
							 | 
						||
| 
								 | 
							
									if !ok {
							 | 
						||
| 
								 | 
							
										logrus.Panicf("no package manager found for %s", conf.PkgManager)
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									newTesterFunc, ok := newTesterFuncs[conf.Tester]
							 | 
						||
| 
								 | 
							
									if !ok {
							 | 
						||
| 
								 | 
							
										logrus.Panicf("no tester found for %s", conf.Tester)
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									return newPkgMgrFunc(), newTesterFunc()
							 | 
						||
| 
								 | 
							
								}
							 |