github.com/axw/juju@v0.0.0-20161005053422-4bd6544d08d4/cmd/juju/romulus/allocate/allocate_test.go (about)

     1  // Copyright 2016 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package allocate_test
     5  
     6  import (
     7  	"github.com/juju/cmd"
     8  	"github.com/juju/cmd/cmdtesting"
     9  	"github.com/juju/errors"
    10  	"github.com/juju/testing"
    11  	jc "github.com/juju/testing/checkers"
    12  	gc "gopkg.in/check.v1"
    13  
    14  	"github.com/juju/juju/cmd/juju/romulus/allocate"
    15  	"github.com/juju/juju/jujuclient"
    16  	"github.com/juju/juju/jujuclient/jujuclienttesting"
    17  	coretesting "github.com/juju/juju/testing"
    18  )
    19  
    20  var _ = gc.Suite(&allocateSuite{})
    21  
    22  type allocateSuite struct {
    23  	coretesting.FakeJujuXDGDataHomeSuite
    24  	stub    *testing.Stub
    25  	mockAPI *mockapi
    26  	store   jujuclient.ClientStore
    27  }
    28  
    29  func (s *allocateSuite) SetUpTest(c *gc.C) {
    30  	s.FakeJujuXDGDataHomeSuite.SetUpTest(c)
    31  	s.store = &jujuclienttesting.MemStore{
    32  		CurrentControllerName: "controller",
    33  		Controllers: map[string]jujuclient.ControllerDetails{
    34  			"controller": {},
    35  		},
    36  		Models: map[string]*jujuclient.ControllerModels{
    37  			"controller": {
    38  				Models: map[string]jujuclient.ModelDetails{
    39  					"admin@local/model": {"model-uuid"},
    40  				},
    41  				CurrentModel: "admin@local/model",
    42  			},
    43  		},
    44  		Accounts: map[string]jujuclient.AccountDetails{
    45  			"controller": {
    46  				User: "admin@local",
    47  			},
    48  		},
    49  	}
    50  	s.stub = &testing.Stub{}
    51  	s.mockAPI = newMockAPI(s.stub)
    52  }
    53  
    54  func (s *allocateSuite) run(c *gc.C, args ...string) (*cmd.Context, error) {
    55  	alloc := allocate.NewAllocateCommandForTest(s.mockAPI, s.store)
    56  	a := []string{"-m", "controller:model"}
    57  	a = append(a, args...)
    58  	return cmdtesting.RunCommand(c, alloc, a...)
    59  }
    60  
    61  func (s *allocateSuite) TestAllocate(c *gc.C) {
    62  	s.mockAPI.resp = "allocation updated"
    63  	ctx, err := s.run(c, "name:100", "db")
    64  	c.Assert(err, jc.ErrorIsNil)
    65  	c.Assert(cmdtesting.Stdout(ctx), jc.DeepEquals, "allocation updated\n")
    66  	s.mockAPI.CheckCall(c, 0, "CreateAllocation", "name", "100", "model-uuid", []string{"db"})
    67  }
    68  
    69  func (s *allocateSuite) TestAllocateAPIError(c *gc.C) {
    70  	s.stub.SetErrors(errors.New("something failed"))
    71  	_, err := s.run(c, "name:100", "db")
    72  	c.Assert(err, gc.ErrorMatches, "failed to create allocation: something failed")
    73  	s.mockAPI.CheckCall(c, 0, "CreateAllocation", "name", "100", "model-uuid", []string{"db"})
    74  }
    75  
    76  func (s *allocateSuite) TestAllocateZero(c *gc.C) {
    77  	s.mockAPI.resp = "allocation updated"
    78  	_, err := s.run(c, "name:0", "db")
    79  	c.Assert(err, jc.ErrorIsNil)
    80  	s.mockAPI.CheckCall(c, 0, "CreateAllocation", "name", "0", "model-uuid", []string{"db"})
    81  }
    82  
    83  func (s *allocateSuite) TestAllocateModelUUID(c *gc.C) {
    84  	s.mockAPI.resp = "allocation updated"
    85  	_, err := s.run(c, "name:0", "--model-uuid", "30f7a9f2-220d-4268-b336-35e7daacae79", "db")
    86  	c.Assert(err, jc.ErrorIsNil)
    87  	s.mockAPI.CheckCall(c, 0, "CreateAllocation", "name", "0", "30f7a9f2-220d-4268-b336-35e7daacae79", []string{"db"})
    88  }
    89  
    90  func (s *allocateSuite) TestAllocateErrors(c *gc.C) {
    91  	tests := []struct {
    92  		about         string
    93  		args          []string
    94  		expectedError string
    95  	}{{
    96  		about:         "no args",
    97  		args:          []string{},
    98  		expectedError: "budget and application name required",
    99  	}, {
   100  		about:         "budget without allocation limit",
   101  		args:          []string{"name", "db"},
   102  		expectedError: `expected args in the form "budget:limit \[application ...\]": invalid budget specification, expecting <budget>:<limit>`,
   103  	}, {
   104  		about:         "application not specified",
   105  		args:          []string{"name:100"},
   106  		expectedError: "budget and application name required",
   107  	}, {
   108  		about:         "negative allocation limit",
   109  		args:          []string{"name:-100", "db"},
   110  		expectedError: `expected args in the form "budget:limit \[application ...\]": invalid budget specification, expecting <budget>:<limit>`,
   111  	}, {
   112  		about:         "non-numeric allocation limit",
   113  		args:          []string{"name:abcd", "db"},
   114  		expectedError: `expected args in the form "budget:limit \[application ...\]": invalid budget specification, expecting <budget>:<limit>`,
   115  	}, {
   116  		about:         "empty allocation limit",
   117  		args:          []string{"name:", "db"},
   118  		expectedError: `expected args in the form "budget:limit \[application ...\]": invalid budget specification, expecting <budget>:<limit>`,
   119  	}, {
   120  		about:         "invalid model UUID",
   121  		args:          []string{"--model-uuid", "nope", "name:100", "db"},
   122  		expectedError: `model UUID "nope" not valid`,
   123  	}, {
   124  		about:         "arguments in wrong order",
   125  		args:          []string{"name:", "db:50"},
   126  		expectedError: `expected args in the form "budget:limit \[application ...\]": invalid budget specification, expecting <budget>:<limit>`,
   127  	}}
   128  	for i, test := range tests {
   129  		c.Logf("test %d: %s", i, test.about)
   130  		_, err := s.run(c, test.args...)
   131  		c.Check(err, gc.ErrorMatches, test.expectedError)
   132  		s.mockAPI.CheckNoCalls(c)
   133  	}
   134  }
   135  
   136  func newMockAPI(s *testing.Stub) *mockapi {
   137  	return &mockapi{Stub: s}
   138  }
   139  
   140  type mockapi struct {
   141  	*testing.Stub
   142  	resp string
   143  }
   144  
   145  func (api *mockapi) CreateAllocation(name, limit, modelUUID string, services []string) (string, error) {
   146  	api.MethodCall(api, "CreateAllocation", name, limit, modelUUID, services)
   147  	return api.resp, api.NextErr()
   148  }