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  }