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 loadedRunners chan *fake_runner.TestRunner

			BeforeEach(func() {
				loadedRunners = make(chan *fake_runner.TestRunner, 1)
				restarter.Load = func(runner ifrit.Runner, err error) ifrit.Runner {
					select {
					case runner := <-loadedRunners:
			Eventually(insert).Should(BeSent(member3))
		})

		AfterEach(func() {
			poolProcess.Signal(os.Kill)
			Eventually(poolProcess.Wait()).Should(Receive())
		})

		It("announces the events as processes move through their lifecycle", func() {
			entrance1, entrance2, entrance3 := grouper.EntranceEvent{}, grouper.EntranceEvent{}, grouper.EntranceEvent{}
			exit1, exit2, exit3 := grouper.ExitEvent{}, grouper.ExitEvent{}, grouper.ExitEvent{}

			entrances := client.EntranceListener()
			exits := client.ExitListener()

			childRunner2.TriggerReady()
			Eventually(entrances).Should(Receive(&entrance2))
			Ω(entrance2.Member).Should(Equal(member2))

			childRunner1.TriggerReady()
			Eventually(entrances).Should(Receive(&entrance1))
			Ω(entrance1.Member).Should(Equal(member1))

			childRunner3.TriggerReady()
			Eventually(entrances).Should(Receive(&entrance3))
			Ω(entrance3.Member).Should(Equal(member3))

			childRunner2.TriggerExit(nil)
			Eventually(exits).Should(Receive(&exit2))
			Ω(exit2.Member).Should(Equal(member2))