// xts-run is an alternative xts-run for use with the // X Test Suite – http://cgit.freedesktop.org/xorg/test/xts // // Differences from the upstream xts-run: // // - Only long options are supported // // - Creates config file in results directory (instead of $TMPDIR) // // - Adds ability to run a single (or multiple) sub-test(s) (similar to run_assert) // // - Avoids shelling out to xts-config (and therefore xset/xdpyinfo) (faster remote startup) // // - Allows the user to configure the stripped font path for remote servers package main import ( "flag" "fmt" "os" "os/exec" "path/filepath" "syscall" "time" ) var config = flag.String("config", "", "Location of xts configuration file") var output = flag.String("output", "xts-results", "Output directory to use") var version = flag.Bool("version", false, "Display version number and exit") var extconfig = flag.Bool("extconfig", false, "Use external xts-config") func env(evar string, def string) string { rv := os.Getenv(evar) if rv == "" { rv = def } return rv } func createConfigExt(outdir string) error { perl := env("PERL", "perl") tetRoot := env("TET_ROOT", "/usr/local/share") config_in := filepath.Join(tetRoot, "xts5", "tetexec.cfg.in") xtsConfig := os.Getenv("XTS_CONFIG") if xtsConfig == "" { var err error xtsConfig, err = exec.LookPath("xts-config") if err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) } } in, err := os.Open(config_in) if err != nil { return err } defer in.Close() out, err := os.Create(*config) if err != nil { return err } defer out.Close() cmd := exec.Command(perl, xtsConfig) cmd.Stdin = in cmd.Stdout = out cmd.Stderr = os.Stderr return cmd.Run() } func tcc(args []string) (int, error) { tcc := env("TCC", "tcc") cmd := exec.Command(tcc, args...) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr err := cmd.Run() ret := 0 if err != nil { if ee, ok := err.(*exec.ExitError); ok { if state, ok := ee.ProcessState.Sys().(syscall.WaitStatus); ok { ret = state.ExitStatus() err = nil } } } return ret, err } func main() { flag.Usage = func() { fmt.Fprintf(os.Stderr, "Usage: %s [OPTION]... [SCENARIO]\n", os.Args[0]) flag.PrintDefaults() } flag.Parse() if *version { fmt.Println("xts-run alternative version 0.0.3") return } // Create the output directory outdir := filepath.Join(*output, time.Now().Format("2006-01-02-15:04:05")) err := os.MkdirAll(outdir, 0777) if err != nil { fmt.Println(err) os.Exit(1) } // Create the config file if necessary if *config == "" { *config = filepath.Join(outdir, "tetexec.cfg") var err error if *extconfig { err = createConfigExt(outdir) } else { err = createConfig(outdir) } if err != nil { fmt.Fprintln(os.Stdout, err) os.Exit(1) } } else { if fi, err := os.Stat(*config); err != nil || fi.IsDir() { fmt.Fprintln(os.Stderr, "error: cannot read config file "+*config) if err != nil { fmt.Fprintln(os.Stderr, err) } os.Exit(1) } } // run the tests ret := 0 if flag.NArg() > 1 { ret, err = runAssert(outdir) } else { args := []string{"-e", "-i", outdir, "-x", *config, "xts5"} if flag.NArg() >= 1 { // Scenario args = append(args, flag.Arg(0)) } ret, err = tcc(args) } if err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) } // generate a short report xtsReport := env("XTS_REPORT", "xts-report") out, err := os.Create(filepath.Join(outdir, "summary")) if err != nil { fmt.Fprintln(os.Stdout, err) os.Exit(1) } defer out.Close() cmd := exec.Command(xtsReport, "-d2", "-f", filepath.Join(outdir, "journal")) cmd.Stderr = os.Stderr cmd.Stdout = out err = cmd.Run() if err != nil { fmt.Fprintln(os.Stdout, err) os.Exit(1) } // return the tcc exit code os.Exit(ret) }