func (t *TestRunner) runAndStreamParallelGinkgoSuite() RunResult { completions := make(chan RunResult) writers := make([]*logWriter, t.numCPU) server, err := remote.NewServer(t.numCPU) if err != nil { panic("Failed to start parallel spec server") } server.Start() defer server.Close() for cpu := 0; cpu < t.numCPU; cpu++ { config.GinkgoConfig.ParallelNode = cpu + 1 config.GinkgoConfig.ParallelTotal = t.numCPU config.GinkgoConfig.SyncHost = server.Address() ginkgoArgs := config.BuildFlagArgs("ginkgo", config.GinkgoConfig, config.DefaultReporterConfig) writers[cpu] = newLogWriter(os.Stdout, cpu+1) cmd := t.cmd(ginkgoArgs, writers[cpu], cpu+1) server.RegisterAlive(cpu+1, func() bool { if cmd.ProcessState == nil { return true } return !cmd.ProcessState.Exited() }) go t.run(cmd, completions) } res := PassingRunResult() for cpu := 0; cpu < t.numCPU; cpu++ { res = res.Merge(<-completions) } for _, writer := range writers { writer.Close() } os.Stdout.Sync() if t.cover { t.combineCoverprofiles() } return res }
func (t *TestRunner) runParallelGinkgoSuite() RunResult { result := make(chan bool) completions := make(chan RunResult) writers := make([]*logWriter, t.numCPU) reports := make([]*bytes.Buffer, t.numCPU) stenographer := stenographer.New(!config.DefaultReporterConfig.NoColor) aggregator := remote.NewAggregator(t.numCPU, result, config.DefaultReporterConfig, stenographer) server, err := remote.NewServer(t.numCPU) if err != nil { panic("Failed to start parallel spec server") } server.RegisterReporters(aggregator) server.Start() defer server.Close() for cpu := 0; cpu < t.numCPU; cpu++ { config.GinkgoConfig.ParallelNode = cpu + 1 config.GinkgoConfig.ParallelTotal = t.numCPU config.GinkgoConfig.SyncHost = server.Address() config.GinkgoConfig.StreamHost = server.Address() ginkgoArgs := config.BuildFlagArgs("ginkgo", config.GinkgoConfig, config.DefaultReporterConfig) reports[cpu] = &bytes.Buffer{} writers[cpu] = newLogWriter(reports[cpu], cpu+1) cmd := t.cmd(ginkgoArgs, writers[cpu], cpu+1) server.RegisterAlive(cpu+1, func() bool { if cmd.ProcessState == nil { return true } return !cmd.ProcessState.Exited() }) go t.run(cmd, completions) } res := PassingRunResult() for cpu := 0; cpu < t.numCPU; cpu++ { res = res.Merge(<-completions) } //all test processes are done, at this point //we should be able to wait for the aggregator to tell us that it's done select { case <-result: fmt.Println("") case <-time.After(time.Second): //the aggregator never got back to us! something must have gone wrong fmt.Println("") fmt.Println("") fmt.Println(" ----------------------------------------------------------- ") fmt.Println(" | |") fmt.Println(" | Ginkgo timed out waiting for all parallel nodes to end! |") fmt.Println(" | Here is some salvaged output: |") fmt.Println(" | |") fmt.Println(" ----------------------------------------------------------- ") fmt.Println("") fmt.Println("") os.Stdout.Sync() time.Sleep(time.Second) for _, writer := range writers { writer.Close() } for _, report := range reports { fmt.Print(report.String()) } os.Stdout.Sync() } if t.cover { t.combineCoverprofiles() } return res }