github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/cmd/juju/common/controller_test.go (about) 1 // Copyright 2016 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package common 5 6 import ( 7 "io" 8 "time" 9 10 "github.com/juju/errors" 11 jc "github.com/juju/testing/checkers" 12 gc "gopkg.in/check.v1" 13 14 "github.com/juju/juju/apiserver/params" 15 "github.com/juju/juju/cmd/modelcmd" 16 cmdtesting "github.com/juju/juju/cmd/testing" 17 "github.com/juju/juju/jujuclient/jujuclienttesting" 18 "github.com/juju/juju/rpc" 19 "github.com/juju/juju/testing" 20 "github.com/juju/juju/version" 21 ) 22 23 var _ = gc.Suite(&controllerSuite{}) 24 25 type controllerSuite struct { 26 testing.BaseSuite 27 mockBlockClient *mockBlockClient 28 } 29 30 func (s *controllerSuite) SetUpTest(c *gc.C) { 31 s.mockBlockClient = &mockBlockClient{} 32 s.PatchValue(&blockAPI, func(*modelcmd.ModelCommandBase) (listBlocksAPI, error) { 33 err := s.mockBlockClient.loginError 34 if err != nil { 35 s.mockBlockClient.loginError = nil 36 return nil, err 37 } 38 if s.mockBlockClient.discoveringSpacesError > 0 { 39 s.mockBlockClient.discoveringSpacesError -= 1 40 return nil, errors.New("spaces are still being discovered") 41 } 42 return s.mockBlockClient, nil 43 }) 44 } 45 46 type mockBlockClient struct { 47 retryCount int 48 numRetries int 49 discoveringSpacesError int 50 loginError error 51 } 52 53 var errOther = errors.New("other error") 54 55 func (c *mockBlockClient) List() ([]params.Block, error) { 56 c.retryCount += 1 57 if c.retryCount == 5 { 58 return nil, &rpc.RequestError{Message: params.CodeUpgradeInProgress, Code: params.CodeUpgradeInProgress} 59 } 60 if c.numRetries < 0 { 61 return nil, errOther 62 } 63 if c.retryCount < c.numRetries { 64 return nil, &rpc.RequestError{Message: params.CodeUpgradeInProgress, Code: params.CodeUpgradeInProgress} 65 } 66 return []params.Block{}, nil 67 } 68 69 func (c *mockBlockClient) Close() error { 70 return nil 71 } 72 73 func (s *controllerSuite) TestWaitForAgentAPIReadyRetries(c *gc.C) { 74 s.PatchValue(&bootstrapReadyPollDelay, 1*time.Millisecond) 75 s.PatchValue(&bootstrapReadyPollCount, 5) 76 defaultSeriesVersion := version.Current 77 // Force a dev version by having a non zero build number. 78 // This is because we have not uploaded any tools and auto 79 // upload is only enabled for dev versions. 80 defaultSeriesVersion.Build = 1234 81 s.PatchValue(&version.Current, defaultSeriesVersion) 82 for _, t := range []struct { 83 numRetries int 84 err error 85 }{ 86 {0, nil}, // agent ready immediately 87 {2, nil}, // agent ready after 2 polls 88 {6, &rpc.RequestError{ 89 Message: params.CodeUpgradeInProgress, 90 Code: params.CodeUpgradeInProgress, 91 }}, // agent ready after 6 polls but that's too long 92 {-1, errOther}, // another error is returned 93 } { 94 s.mockBlockClient.numRetries = t.numRetries 95 s.mockBlockClient.retryCount = 0 96 cmd := &modelcmd.ModelCommandBase{} 97 cmd.SetClientStore(jujuclienttesting.NewMemStore()) 98 err := WaitForAgentInitialisation(cmdtesting.NullContext(c), cmd, "controller", "default") 99 c.Check(errors.Cause(err), gc.DeepEquals, t.err) 100 expectedRetries := t.numRetries 101 if t.numRetries <= 0 { 102 expectedRetries = 1 103 } 104 // Only retry maximum of bootstrapReadyPollCount times. 105 if expectedRetries > 5 { 106 expectedRetries = 5 107 } 108 c.Check(s.mockBlockClient.retryCount, gc.Equals, expectedRetries) 109 } 110 } 111 112 func (s *controllerSuite) TestWaitForAgentAPIReadyWaitsForSpaceDiscovery(c *gc.C) { 113 s.mockBlockClient.discoveringSpacesError = 2 114 cmd := &modelcmd.ModelCommandBase{} 115 cmd.SetClientStore(jujuclienttesting.NewMemStore()) 116 err := WaitForAgentInitialisation(cmdtesting.NullContext(c), cmd, "controller", "default") 117 c.Assert(err, jc.ErrorIsNil) 118 c.Assert(s.mockBlockClient.discoveringSpacesError, gc.Equals, 0) 119 } 120 121 func (s *controllerSuite) TestWaitForAgentAPIReadyRetriesWithOpenEOFErr(c *gc.C) { 122 s.mockBlockClient.numRetries = 0 123 s.mockBlockClient.retryCount = 0 124 s.mockBlockClient.loginError = io.EOF 125 cmd := &modelcmd.ModelCommandBase{} 126 cmd.SetClientStore(jujuclienttesting.NewMemStore()) 127 err := WaitForAgentInitialisation(cmdtesting.NullContext(c), cmd, "controller", "default") 128 c.Check(err, jc.ErrorIsNil) 129 130 c.Check(s.mockBlockClient.retryCount, gc.Equals, 1) 131 } 132 133 func (s *controllerSuite) TestWaitForAgentAPIReadyStopsRetriesWithOpenErr(c *gc.C) { 134 s.mockBlockClient.numRetries = 0 135 s.mockBlockClient.retryCount = 0 136 s.mockBlockClient.loginError = errors.NewUnauthorized(nil, "") 137 cmd := &modelcmd.ModelCommandBase{} 138 cmd.SetClientStore(jujuclienttesting.NewMemStore()) 139 err := WaitForAgentInitialisation(cmdtesting.NullContext(c), cmd, "controller", "default") 140 c.Check(err, jc.Satisfies, errors.IsUnauthorized) 141 142 c.Check(s.mockBlockClient.retryCount, gc.Equals, 0) 143 }