github.com/mwhudson/juju@v0.0.0-20160512215208-90ff01f3497f/cmd/juju/service/addunit_test.go (about)

     1  // Copyright 2012-2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package service_test
     5  
     6  import (
     7  	"strings"
     8  
     9  	"github.com/juju/errors"
    10  	jc "github.com/juju/testing/checkers"
    11  	gc "gopkg.in/check.v1"
    12  
    13  	"github.com/juju/juju/apiserver/common"
    14  	"github.com/juju/juju/cmd/juju/service"
    15  	"github.com/juju/juju/environs/config"
    16  	"github.com/juju/juju/instance"
    17  	"github.com/juju/juju/testing"
    18  )
    19  
    20  type AddUnitSuite struct {
    21  	testing.FakeJujuXDGDataHomeSuite
    22  	fake *fakeServiceAddUnitAPI
    23  }
    24  
    25  type fakeServiceAddUnitAPI struct {
    26  	envType   string
    27  	service   string
    28  	numUnits  int
    29  	placement []*instance.Placement
    30  	err       error
    31  }
    32  
    33  func (f *fakeServiceAddUnitAPI) Close() error {
    34  	return nil
    35  }
    36  
    37  func (f *fakeServiceAddUnitAPI) ModelUUID() string {
    38  	return "fake-uuid"
    39  }
    40  
    41  func (f *fakeServiceAddUnitAPI) AddUnits(service string, numUnits int, placement []*instance.Placement) ([]string, error) {
    42  	if f.err != nil {
    43  		return nil, f.err
    44  	}
    45  	if service != f.service {
    46  		return nil, errors.NotFoundf("service %q", service)
    47  	}
    48  
    49  	f.numUnits += numUnits
    50  	f.placement = placement
    51  	return nil, nil
    52  }
    53  
    54  func (f *fakeServiceAddUnitAPI) ModelGet() (map[string]interface{}, error) {
    55  	cfg, err := config.New(config.UseDefaults, map[string]interface{}{
    56  		"type": f.envType,
    57  		"name": "dummy",
    58  	})
    59  	if err != nil {
    60  		return nil, err
    61  	}
    62  
    63  	return cfg.AllAttrs(), nil
    64  }
    65  
    66  func (s *AddUnitSuite) SetUpTest(c *gc.C) {
    67  	s.FakeJujuXDGDataHomeSuite.SetUpTest(c)
    68  	s.fake = &fakeServiceAddUnitAPI{service: "some-service-name", numUnits: 1, envType: "dummy"}
    69  }
    70  
    71  var _ = gc.Suite(&AddUnitSuite{})
    72  
    73  var initAddUnitErrorTests = []struct {
    74  	args []string
    75  	err  string
    76  }{
    77  	{
    78  		args: []string{"some-service-name", "-n", "0"},
    79  		err:  `--num-units must be a positive integer`,
    80  	}, {
    81  		args: []string{},
    82  		err:  `no service specified`,
    83  	}, {
    84  		args: []string{"some-service-name", "--to", "1,#:foo"},
    85  		err:  `invalid --to parameter "#:foo"`,
    86  	},
    87  }
    88  
    89  func (s *AddUnitSuite) TestInitErrors(c *gc.C) {
    90  	for i, t := range initAddUnitErrorTests {
    91  		c.Logf("test %d", i)
    92  		err := testing.InitCommand(service.NewAddUnitCommandForTest(s.fake), t.args)
    93  		c.Check(err, gc.ErrorMatches, t.err)
    94  	}
    95  }
    96  
    97  func (s *AddUnitSuite) runAddUnit(c *gc.C, args ...string) error {
    98  	_, err := testing.RunCommand(c, service.NewAddUnitCommandForTest(s.fake), args...)
    99  	return err
   100  }
   101  
   102  func (s *AddUnitSuite) TestAddUnit(c *gc.C) {
   103  	err := s.runAddUnit(c, "some-service-name")
   104  	c.Assert(err, jc.ErrorIsNil)
   105  	c.Assert(s.fake.numUnits, gc.Equals, 2)
   106  
   107  	err = s.runAddUnit(c, "--num-units", "2", "some-service-name")
   108  	c.Assert(err, jc.ErrorIsNil)
   109  	c.Assert(s.fake.numUnits, gc.Equals, 4)
   110  }
   111  
   112  func (s *AddUnitSuite) TestAddUnitWithPlacement(c *gc.C) {
   113  	err := s.runAddUnit(c, "some-service-name")
   114  	c.Assert(err, jc.ErrorIsNil)
   115  	c.Assert(s.fake.numUnits, gc.Equals, 2)
   116  
   117  	err = s.runAddUnit(c, "--num-units", "2", "--to", "123,lxc:1,1/lxc/2,foo", "some-service-name")
   118  	c.Assert(err, jc.ErrorIsNil)
   119  	c.Assert(s.fake.numUnits, gc.Equals, 4)
   120  	c.Assert(s.fake.placement, jc.DeepEquals, []*instance.Placement{
   121  		{"#", "123"},
   122  		{"lxc", "1"},
   123  		{"#", "1/lxc/2"},
   124  		{"fake-uuid", "foo"},
   125  	})
   126  }
   127  
   128  func (s *AddUnitSuite) TestBlockAddUnit(c *gc.C) {
   129  	// Block operation
   130  	s.fake.err = common.OperationBlockedError("TestBlockAddUnit")
   131  	s.runAddUnit(c, "some-service-name")
   132  
   133  	// msg is logged
   134  	stripped := strings.Replace(c.GetTestLog(), "\n", "", -1)
   135  	c.Check(stripped, gc.Matches, ".*TestBlockAddUnit.*")
   136  }
   137  
   138  func (s *AddUnitSuite) TestForceMachine(c *gc.C) {
   139  	err := s.runAddUnit(c, "some-service-name", "--to", "3")
   140  	c.Assert(err, jc.ErrorIsNil)
   141  	c.Assert(s.fake.numUnits, gc.Equals, 2)
   142  	c.Assert(s.fake.placement[0].Directive, gc.Equals, "3")
   143  
   144  	err = s.runAddUnit(c, "some-service-name", "--to", "23")
   145  	c.Assert(err, jc.ErrorIsNil)
   146  	c.Assert(s.fake.numUnits, gc.Equals, 3)
   147  	c.Assert(s.fake.placement[0].Directive, gc.Equals, "23")
   148  }
   149  
   150  func (s *AddUnitSuite) TestForceMachineNewContainer(c *gc.C) {
   151  	err := s.runAddUnit(c, "some-service-name", "--to", "lxc:1")
   152  	c.Assert(err, jc.ErrorIsNil)
   153  	c.Assert(s.fake.numUnits, gc.Equals, 2)
   154  	c.Assert(s.fake.placement[0].Directive, gc.Equals, "1")
   155  	c.Assert(s.fake.placement[0].Scope, gc.Equals, "lxc")
   156  }
   157  
   158  func (s *AddUnitSuite) TestNameChecks(c *gc.C) {
   159  	assertMachineOrNewContainer := func(s string, expect bool) {
   160  		c.Logf("%s -> %v", s, expect)
   161  		c.Assert(service.IsMachineOrNewContainer(s), gc.Equals, expect)
   162  	}
   163  	assertMachineOrNewContainer("0", true)
   164  	assertMachineOrNewContainer("00", false)
   165  	assertMachineOrNewContainer("1", true)
   166  	assertMachineOrNewContainer("0/lxc/0", true)
   167  	assertMachineOrNewContainer("lxc:0", true)
   168  	assertMachineOrNewContainer("lxc:lxc:0", false)
   169  	assertMachineOrNewContainer("kvm:0/lxc/1", true)
   170  	assertMachineOrNewContainer("lxc:", false)
   171  	assertMachineOrNewContainer(":lxc", false)
   172  	assertMachineOrNewContainer("0/lxc/", false)
   173  	assertMachineOrNewContainer("0/lxc", false)
   174  	assertMachineOrNewContainer("kvm:0/lxc", false)
   175  	assertMachineOrNewContainer("0/lxc/01", false)
   176  	assertMachineOrNewContainer("0/lxc/10", true)
   177  	assertMachineOrNewContainer("0/kvm/4", true)
   178  }