func (transformer *Transformer) StepFor( logStreamer log_streamer.LogStreamer, action *models.Action, container garden.Container, externalIP string, ports []executor.PortMapping, logger lager.Logger, ) steps.Step { a := action.GetValue() switch actionModel := a.(type) { case *models.RunAction: return steps.NewRun( container, *actionModel, logStreamer.WithSource(actionModel.LogSource), logger, externalIP, ports, transformer.exportNetworkEnvVars, transformer.clock, ) case *models.DownloadAction: return steps.NewDownload( container, *actionModel, transformer.cachedDownloader, transformer.downloadLimiter, logStreamer.WithSource(actionModel.LogSource), logger, ) case *models.UploadAction: return steps.NewUpload( container, *actionModel, transformer.uploader, transformer.compressor, transformer.tempDir, logStreamer.WithSource(actionModel.LogSource), transformer.uploadLimiter, logger, ) case *models.EmitProgressAction: return steps.NewEmitProgress( transformer.StepFor( logStreamer, actionModel.Action, container, externalIP, ports, logger, ), actionModel.StartMessage, actionModel.SuccessMessage, actionModel.FailureMessagePrefix, logStreamer.WithSource(actionModel.LogSource), logger, ) case *models.TimeoutAction: return steps.NewTimeout( transformer.StepFor( logStreamer.WithSource(actionModel.LogSource), actionModel.Action, container, externalIP, ports, logger, ), time.Duration(actionModel.Timeout), logger, ) case *models.TryAction: return steps.NewTry( transformer.StepFor( logStreamer.WithSource(actionModel.LogSource), actionModel.Action, container, externalIP, ports, logger, ), logger, ) case *models.ParallelAction: subSteps := make([]steps.Step, len(actionModel.Actions)) for i, action := range actionModel.Actions { subSteps[i] = transformer.StepFor( logStreamer.WithSource(actionModel.LogSource), action, container, externalIP, ports, logger, ) } return steps.NewParallel(subSteps) case *models.CodependentAction: subSteps := make([]steps.Step, len(actionModel.Actions)) for i, action := range actionModel.Actions { subSteps[i] = transformer.StepFor( logStreamer.WithSource(actionModel.LogSource), action, container, externalIP, ports, logger, ) } errorOnExit := true return steps.NewCodependent(subSteps, errorOnExit) case *models.SerialAction: subSteps := make([]steps.Step, len(actionModel.Actions)) for i, action := range actionModel.Actions { subSteps[i] = transformer.StepFor( logStreamer, action, container, externalIP, ports, logger, ) } return steps.NewSerial(subSteps) } panic(fmt.Sprintf("unknown action: %T", action)) }
subStep2 = &fakes.FakeStep{ PerformStub: func() error { running.Done() running.Wait() thingHappened <- true return nil }, CancelStub: func() { cancelled <- true }, } }) JustBeforeEach(func() { step = steps.NewParallel([]steps.Step{subStep1, subStep2}) }) It("performs its substeps in parallel", func(done Done) { defer close(done) err := step.Perform() Expect(err).NotTo(HaveOccurred()) Eventually(thingHappened).Should(Receive()) Eventually(thingHappened).Should(Receive()) }, 2) Context("when one of the substeps fails", func() { disaster := errors.New("oh no!") var triggerStep2 chan struct{}