Bench configs define command and console serial paths; scenarios can reset nodes via esptool before tests. Smoke resets all nodes then waits for ESP-NOW join. Co-authored-by: Cursor <cursoragent@cursor.com>
126 lines
3.0 KiB
Go
126 lines
3.0 KiB
Go
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
|
|
}
|