github.com/cozy/cozy-stack@v0.0.0-20240603063001-31110fa4cae1/tests/system/parallel-runner.go (about) 1 package main 2 3 import ( 4 "flag" 5 "fmt" 6 "math/rand" 7 "os" 8 "os/exec" 9 "path/filepath" 10 "time" 11 ) 12 13 var shuffle bool 14 var failFast bool 15 var nb int 16 17 func main() { 18 flag.BoolVar(&shuffle, "shuffle", false, "Randomize the order of the tests") 19 flag.BoolVar(&failFast, "fail-fast", false, "Stop on the first test that fails") 20 flag.IntVar(&nb, "n", 4, "Number of tests to run in parallel") 21 flag.Parse() 22 23 tests, err := listTests() 24 if err != nil { 25 fmt.Fprintf(os.Stderr, "Error: %s\n", err) 26 os.Exit(1) 27 } 28 if err := runTests(tests); err != nil { 29 fmt.Fprintf(os.Stderr, "Error: %s\n", err) 30 os.Exit(1) 31 } 32 } 33 34 func listTests() ([]string, error) { 35 tests, err := filepath.Glob("tests/*.rb") 36 if err != nil { 37 return nil, err 38 } 39 if shuffle { 40 rand.Shuffle(len(tests), func(i, j int) { 41 tests[i], tests[j] = tests[j], tests[i] 42 }) 43 } 44 return tests, nil 45 } 46 47 type result struct { 48 Test string 49 Err error 50 Out []byte 51 } 52 53 func runTests(tests []string) error { 54 results := make(chan result, len(tests)) 55 tokens := make(chan struct{}, nb) 56 for i := 0; i < nb; i++ { 57 tokens <- struct{}{} 58 } 59 60 for i, test := range tests { 61 go func(i int, test string) { 62 k := <-tokens 63 cmd := exec.Command("bundle", "exec", "ruby", test) 64 cmd.Env = append(os.Environ(), 65 fmt.Sprintf("COZY_BASE_PORT=%d", 8091+10*i), 66 "COZY_SKIP_LOADING_TRIGGERS=true", 67 "CI=true") 68 out, err := cmd.CombinedOutput() 69 results <- result{test, err, out} 70 tokens <- k 71 }(i, test) 72 73 // Starting all the tests at the same time is not a good idea, the 74 // stack can create conflicts on the global databases. 75 time.Sleep(3 * time.Second) 76 } 77 78 var err error 79 for range tests { 80 res := <-results 81 fmt.Fprintf(os.Stderr, "\n==== Run %s ====\n%s\n", res.Test, res.Out) 82 if res.Err != nil { 83 err = res.Err 84 if failFast { 85 return err 86 } 87 } 88 } 89 90 return err 91 }