package main import ( "flag" "fmt" "io" "log" "powerpod/gotool/autotest" ) func runTest(portOverride string, baudOverride int, args []string) error { fs := flag.NewFlagSet("test", flag.ExitOnError) configName := fs.String("config", "", "bench config id or path (testdata/configs/)") scenarioName := fs.String("scenario", "", "scenario id or path (testdata/scenarios/)") listConfigs := fs.Bool("list-configs", false, "list available bench configs") listScenarios := fs.Bool("list-scenarios", false, "list available scenarios") verbose := fs.Bool("v", false, "verbose (log UART traffic)") if err := fs.Parse(args); err != nil { return err } if *listConfigs { return printList("configs", autotest.ConfigDir) } if *listScenarios { return printList("scenarios", autotest.ScenarioDir) } if *configName == "" || *scenarioName == "" { return fmt.Errorf("need -config and -scenario (or -list-configs / -list-scenarios)") } configPath, err := autotest.ResolveConfigPath(*configName) if err != nil { return err } scenarioPath, err := autotest.ResolveScenarioPath(*scenarioName) if err != nil { return err } bench, err := autotest.LoadConfig(configPath) if err != nil { return fmt.Errorf("load config: %w", err) } sc, err := autotest.LoadScenario(scenarioPath) if err != nil { return fmt.Errorf("load scenario: %w", err) } port := portOverride if port == "" { port = bench.UART.Master } baud := baudOverride if baud <= 0 { baud = int(bench.UART.Baud) } sp, err := openSerial(port, baud) if err != nil { return fmt.Errorf("open %s: %w", port, err) } defer sp.Close() if !*verbose { log.SetOutput(io.Discard) } fmt.Printf("bench config %q (network %d, master %s)\n", bench.ID, bench.Network, bench.MasterMAC) fmt.Printf(" uart.master %s (baud %d)\n", bench.UART.Master, bench.UART.Baud) if bench.UART.MasterConsole != "" { fmt.Printf(" uart.master_console %s\n", bench.UART.MasterConsole) } for _, s := range bench.Slaves { line := fmt.Sprintf(" slave %q mac=%s client_id=%d", s.ID, s.MAC, *s.ClientID) if s.Console != "" { line += fmt.Sprintf(" console=%s", s.Console) } fmt.Println(line) } fmt.Printf("scenario %q (%d steps)\n\n", sc.ID, len(sc.Steps)) result, err := autotest.Run(bench, sc, sp) if err != nil { return err } failed := false for _, sr := range result.Steps { mark := "PASS" if !sr.Pass { mark = "FAIL" failed = true } cmd := sr.Command if cmd == "" { cmd = "delay" } fmt.Printf("[%s] %s (%s) — %s\n", mark, sr.Name, cmd, sr.Detail) } fmt.Printf("\n%d passed, %d failed\n", result.Passed, result.Failed) if failed { return fmt.Errorf("scenario %q failed", sc.ID) } return nil } func printList(kind, dir string) error { names, err := autotest.ListJSONFiles(dir) if err != nil { return err } if len(names) == 0 { fmt.Printf("no %s found under %s\n", kind, dir) return nil } fmt.Printf("%s:\n", kind) for _, n := range names { fmt.Printf(" %s\n", n) } return nil }