func forwardSignals(signals <-chan os.Signal, process ifrit.Process) { exit := process.Wait() for { select { case sig := <-signals: process.Signal(sig) case <-exit: return } } }
{"child1", childRunner1}, {"child2", childRunner2}, {"child3", childRunner3}, } groupRunner = grouper.NewOrdered(os.Interrupt, members) }) AfterEach(func() { childRunner1.EnsureExit() childRunner2.EnsureExit() childRunner3.EnsureExit() Eventually(started).Should(BeClosed()) groupProcess.Signal(os.Kill) Eventually(groupProcess.Wait()).Should(Receive()) }) BeforeEach(func() { started = make(chan struct{}) go func() { groupProcess = ifrit.Invoke(groupRunner) close(started) }() }) It("runs the first runner, then the second, then becomes ready", func() { Eventually(childRunner1.RunCallCount).Should(Equal(1)) Consistently(childRunner2.RunCallCount, Δ).Should(BeZero()) Consistently(started, Δ).ShouldNot(BeClosed())
}) Context("when the daemon won't start", func() { fakeDeamonRunner = func(signals <-chan os.Signal, ready chan<- struct{}) error { close(ready) select { case signal := <-signals: return errors.New(signal.String()) case <-time.After(1 * time.Second): // Daemon "crashes" after a while } return nil } It("times out", func() { err := <-lifecycle.Wait() Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("Timed out waiting for docker daemon to start")) }) Context("and the process is interrupted", func() { BeforeEach(func() { lifecycle.Signal(os.Interrupt) }) It("exists with error", func() { err := <-lifecycle.Wait() Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("fake_docker_daemon exited with error: interrupt")) Expect(err.Error()).To(ContainSubstring("builder exited with error: interrupt")) })
port := 8000 + GinkgoParallelNode() address = fmt.Sprintf("127.0.0.1:%d", port) server = http_server.New(address, handler) }) Describe("Envoke", func() { var process ifrit.Process Context("when the server starts successfully", func() { BeforeEach(func() { process = ifrit.Envoke(server) }) AfterEach(func() { process.Signal(syscall.SIGINT) Eventually(process.Wait()).Should(Receive()) }) Context("and a request is in flight", func() { type httpResponse struct { response *http.Response err error } var responses chan httpResponse BeforeEach(func() { responses = make(chan httpResponse, 1) go func() { response, err := httpGet("http://" + address) responses <- httpResponse{response, err} close(responses)
func Kill(process ifrit.Process, intervals ...interface{}) { if process != nil { process.Signal(os.Kill) Eventually(process.Wait(), intervals...).Should(Receive(), "killed ginkgomon process failed to exit in time") } }
func Interrupt(process ifrit.Process, intervals ...interface{}) { process.Signal(os.Interrupt) Eventually(process.Wait(), intervals...).Should(Receive(), "interrupted ginkgomon process failed to exit in time") }
restarter = restart.Restarter{ Runner: testRunner, Load: func(runner ifrit.Runner, err error) ifrit.Runner { return nil }, } }) JustBeforeEach(func() { process = ifrit.Background(restarter) }) AfterEach(func() { process.Signal(os.Kill) testRunner.EnsureExit() Eventually(process.Wait()).Should(Receive()) }) Describe("Process Behavior", func() { It("waits for the internal runner to be ready", func() { Consistently(process.Ready()).ShouldNot(BeClosed()) testRunner.TriggerReady() Eventually(process.Ready()).Should(BeClosed()) }) }) Describe("Load", func() { Context("when load returns a runner", func() { var loadedRunner *fake_runner.TestRunner
var _ = Describe("Process", func() { Context("when a process is envoked", func() { var pinger test_helpers.PingChan var pingProc ifrit.Process var errChan chan error BeforeEach(func() { pinger = make(test_helpers.PingChan) pingProc = ifrit.Envoke(pinger) errChan = make(chan error) }) Describe("Wait()", func() { BeforeEach(func() { go func() { errChan <- <-pingProc.Wait() }() go func() { errChan <- <-pingProc.Wait() }() }) Context("when the process exits", func() { BeforeEach(func() { go func() { <-pinger }() }) It("returns the run result upon completion", func() { err1 := <-errChan