github.com/nimakaviani/cli@v6.37.1-0.20180619223813-e734901a73fa+incompatible/actor/pushaction/actualize_test.go (about)

     1  package pushaction_test
     2  
     3  import (
     4  	"errors"
     5  	"time"
     6  
     7  	. "code.cloudfoundry.org/cli/actor/pushaction"
     8  	"code.cloudfoundry.org/cli/actor/pushaction/pushactionfakes"
     9  	"code.cloudfoundry.org/cli/actor/v3action"
    10  
    11  	. "github.com/onsi/ginkgo"
    12  	. "github.com/onsi/gomega"
    13  	. "github.com/onsi/gomega/gstruct"
    14  )
    15  
    16  func actualizedStreamsDrainedAndClosed(
    17  	configStream <-chan PushState,
    18  	eventStream <-chan Event,
    19  	warningsStream <-chan Warnings,
    20  	errorStream <-chan error,
    21  ) bool {
    22  	var configStreamClosed, eventStreamClosed, warningsStreamClosed, errorStreamClosed bool
    23  	for {
    24  		select {
    25  		case _, ok := <-configStream:
    26  			if !ok {
    27  				configStreamClosed = true
    28  			}
    29  		case _, ok := <-eventStream:
    30  			if !ok {
    31  				eventStreamClosed = true
    32  			}
    33  		case _, ok := <-warningsStream:
    34  			if !ok {
    35  				warningsStreamClosed = true
    36  			}
    37  		case _, ok := <-errorStream:
    38  			if !ok {
    39  				errorStreamClosed = true
    40  			}
    41  		}
    42  		if configStreamClosed && eventStreamClosed && warningsStreamClosed && errorStreamClosed {
    43  			break
    44  		}
    45  	}
    46  	return true
    47  }
    48  
    49  // TODO: for refactor: We can use the following style of code to validate that
    50  // each event is received in a specific order
    51  
    52  // Expect(nextEvent()).Should(Equal(SettingUpApplication))
    53  // Expect(nextEvent()).Should(Equal(CreatingApplication))
    54  // Expect(nextEvent()).Should(Equal(...))
    55  // Expect(nextEvent()).Should(Equal(...))
    56  // Expect(nextEvent()).Should(Equal(...))
    57  func getNextEvent(c <-chan PushState, e <-chan Event, w <-chan Warnings) func() Event {
    58  	timeOut := time.Tick(500 * time.Millisecond)
    59  
    60  	return func() Event {
    61  		for {
    62  			select {
    63  			case <-c:
    64  			case event, ok := <-e:
    65  				if ok {
    66  					return event
    67  				}
    68  				return ""
    69  			case <-w:
    70  			case <-timeOut:
    71  				return ""
    72  			}
    73  		}
    74  	}
    75  }
    76  
    77  var _ = Describe("Actualize", func() {
    78  	var (
    79  		actor           *Actor
    80  		fakeV2Actor     *pushactionfakes.FakeV2Actor
    81  		fakeV3Actor     *pushactionfakes.FakeV3Actor
    82  		fakeSharedActor *pushactionfakes.FakeSharedActor
    83  
    84  		state           PushState
    85  		fakeProgressBar *pushactionfakes.FakeProgressBar
    86  
    87  		stateStream    <-chan PushState
    88  		eventStream    <-chan Event
    89  		warningsStream <-chan Warnings
    90  		errorStream    <-chan error
    91  	)
    92  
    93  	BeforeEach(func() {
    94  		fakeV2Actor = new(pushactionfakes.FakeV2Actor)
    95  		fakeV3Actor = new(pushactionfakes.FakeV3Actor)
    96  		fakeSharedActor = new(pushactionfakes.FakeSharedActor)
    97  		actor = NewActor(fakeV2Actor, fakeV3Actor, fakeSharedActor)
    98  
    99  		fakeProgressBar = new(pushactionfakes.FakeProgressBar)
   100  		state = PushState{
   101  			Application: v3action.Application{
   102  				Name: "some-app",
   103  			},
   104  			SpaceGUID: "some-space-guid",
   105  		}
   106  	})
   107  
   108  	AfterEach(func() {
   109  		Eventually(actualizedStreamsDrainedAndClosed(stateStream, eventStream, warningsStream, errorStream)).Should(BeTrue())
   110  	})
   111  
   112  	JustBeforeEach(func() {
   113  		stateStream, eventStream, warningsStream, errorStream = actor.Actualize(state, fakeProgressBar)
   114  	})
   115  
   116  	Describe("application creation", func() {
   117  		Context("when the application exists", func() {
   118  			BeforeEach(func() {
   119  				state.Application.GUID = "some-app-guid"
   120  			})
   121  
   122  			It("returns a skipped app creation event", func() {
   123  				Eventually(getNextEvent(stateStream, eventStream, warningsStream)).Should(Equal(SkipingApplicationCreation))
   124  
   125  				Eventually(stateStream).Should(Receive(MatchFields(IgnoreExtras,
   126  					Fields{
   127  						"Application": Equal(v3action.Application{
   128  							Name: "some-app",
   129  							GUID: "some-app-guid",
   130  						}),
   131  					})))
   132  
   133  				Consistently(fakeV3Actor.CreateApplicationInSpaceCallCount).Should(Equal(0))
   134  			})
   135  		})
   136  
   137  		Context("when the application does not exist", func() {
   138  			Context("when the creation is successful", func() {
   139  				var expectedApp v3action.Application
   140  
   141  				BeforeEach(func() {
   142  					expectedApp = v3action.Application{
   143  						GUID: "some-app-guid",
   144  						Name: "some-app",
   145  					}
   146  
   147  					fakeV3Actor.CreateApplicationInSpaceReturns(expectedApp, v3action.Warnings{"some-app-warnings"}, nil)
   148  				})
   149  
   150  				It("returns an app created event, warnings, and updated state", func() {
   151  					Eventually(warningsStream).Should(Receive(ConsistOf("some-app-warnings")))
   152  					Eventually(getNextEvent(stateStream, eventStream, warningsStream)).Should(Equal(CreatedApplication))
   153  					Eventually(stateStream).Should(Receive(MatchFields(IgnoreExtras,
   154  						Fields{
   155  							"Application": Equal(expectedApp),
   156  						})))
   157  				})
   158  
   159  				It("creates the application", func() {
   160  					Eventually(fakeV3Actor.CreateApplicationInSpaceCallCount).Should(Equal(1))
   161  					passedApp, passedSpaceGUID := fakeV3Actor.CreateApplicationInSpaceArgsForCall(0)
   162  					Expect(passedApp).To(Equal(state.Application))
   163  					Expect(passedSpaceGUID).To(Equal(state.SpaceGUID))
   164  				})
   165  			})
   166  
   167  			Context("when the creation errors", func() {
   168  				var expectedErr error
   169  
   170  				BeforeEach(func() {
   171  					expectedErr = errors.New("SPICY!!")
   172  
   173  					fakeV3Actor.CreateApplicationInSpaceReturns(v3action.Application{}, v3action.Warnings{"some-app-warnings"}, expectedErr)
   174  				})
   175  
   176  				It("returns warnings and error", func() {
   177  					Eventually(warningsStream).Should(Receive(ConsistOf("some-app-warnings")))
   178  					Eventually(errorStream).Should(Receive(MatchError(expectedErr)))
   179  				})
   180  			})
   181  		})
   182  	})
   183  
   184  	Context("when all operations are finished", func() {
   185  		It("returns a complete event", func() {
   186  			Eventually(getNextEvent(stateStream, eventStream, warningsStream)).Should(Equal(Complete))
   187  		})
   188  	})
   189  })