github.com/Pankov404/juju@v0.0.0-20150703034450-be266991dceb/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/envcmd"
    15  	"github.com/juju/juju/cmd/juju/service"
    16  	"github.com/juju/juju/environs/config"
    17  	"github.com/juju/juju/testing"
    18  )
    19  
    20  type AddUnitSuite struct {
    21  	testing.FakeJujuHomeSuite
    22  	fake *fakeServiceAddUnitAPI
    23  }
    24  
    25  type fakeServiceAddUnitAPI struct {
    26  	envType     string
    27  	service     string
    28  	numUnits    int
    29  	machineSpec string
    30  	err         error
    31  }
    32  
    33  func (f *fakeServiceAddUnitAPI) Close() error {
    34  	return nil
    35  }
    36  
    37  func (f *fakeServiceAddUnitAPI) AddServiceUnits(service string, numUnits int, machineSpec string) ([]string, error) {
    38  	if f.err != nil {
    39  		return nil, f.err
    40  	}
    41  
    42  	if service != f.service {
    43  		return nil, errors.NotFoundf("service %q", service)
    44  	}
    45  
    46  	f.numUnits += numUnits
    47  	f.machineSpec = machineSpec
    48  
    49  	// The add-unit subcommand doesn't check the results, so we can just return nil
    50  	return nil, nil
    51  }
    52  
    53  func (f *fakeServiceAddUnitAPI) EnvironmentGet() (map[string]interface{}, error) {
    54  	cfg, err := config.New(config.UseDefaults, map[string]interface{}{
    55  		"type": f.envType,
    56  		"name": "dummy",
    57  	})
    58  	if err != nil {
    59  		return nil, err
    60  	}
    61  
    62  	return cfg.AllAttrs(), nil
    63  }
    64  
    65  func (s *AddUnitSuite) SetUpTest(c *gc.C) {
    66  	s.FakeJujuHomeSuite.SetUpTest(c)
    67  	s.fake = &fakeServiceAddUnitAPI{service: "some-service-name", numUnits: 1, envType: "dummy"}
    68  }
    69  
    70  var _ = gc.Suite(&AddUnitSuite{})
    71  
    72  var initAddUnitErrorTests = []struct {
    73  	args []string
    74  	err  string
    75  }{
    76  	{
    77  		args: []string{"some-service-name", "-n", "0"},
    78  		err:  `--num-units must be a positive integer`,
    79  	}, {
    80  		args: []string{},
    81  		err:  `no service specified`,
    82  	}, {
    83  		args: []string{"some-service-name", "--to", "bigglesplop"},
    84  		err:  `invalid --to parameter "bigglesplop"`,
    85  	}, {
    86  		args: []string{"some-service-name", "-n", "2", "--to", "123"},
    87  		err:  `cannot use --num-units > 1 with --to`,
    88  	},
    89  }
    90  
    91  func (s *AddUnitSuite) TestInitErrors(c *gc.C) {
    92  	for i, t := range initAddUnitErrorTests {
    93  		c.Logf("test %d", i)
    94  		err := testing.InitCommand(envcmd.Wrap(service.NewAddUnitCommand(s.fake)), t.args)
    95  		c.Check(err, gc.ErrorMatches, t.err)
    96  	}
    97  }
    98  
    99  func (s *AddUnitSuite) runAddUnit(c *gc.C, args ...string) error {
   100  	_, err := testing.RunCommand(c, envcmd.Wrap(service.NewAddUnitCommand(s.fake)), args...)
   101  	return err
   102  }
   103  
   104  func (s *AddUnitSuite) TestAddUnit(c *gc.C) {
   105  	err := s.runAddUnit(c, "some-service-name")
   106  	c.Assert(err, jc.ErrorIsNil)
   107  	c.Assert(s.fake.numUnits, gc.Equals, 2)
   108  
   109  	err = s.runAddUnit(c, "--num-units", "2", "some-service-name")
   110  	c.Assert(err, jc.ErrorIsNil)
   111  	c.Assert(s.fake.numUnits, gc.Equals, 4)
   112  }
   113  
   114  func (s *AddUnitSuite) TestBlockAddUnit(c *gc.C) {
   115  	// Block operation
   116  	s.fake.err = common.ErrOperationBlocked("TestBlockAddUnit")
   117  	s.runAddUnit(c, "some-service-name")
   118  
   119  	// msg is logged
   120  	stripped := strings.Replace(c.GetTestLog(), "\n", "", -1)
   121  	c.Check(stripped, gc.Matches, ".*TestBlockAddUnit.*")
   122  }
   123  
   124  func (s *AddUnitSuite) TestNonLocalCanHostUnits(c *gc.C) {
   125  	err := s.runAddUnit(c, "some-service-name", "--to", "0")
   126  	c.Assert(err, jc.ErrorIsNil)
   127  }
   128  
   129  func (s *AddUnitSuite) TestLocalCannotHostUnits(c *gc.C) {
   130  	s.fake.envType = "local"
   131  	err := s.runAddUnit(c, "some-service-name", "--to", "0")
   132  	c.Assert(err, gc.ErrorMatches, "machine 0 is the state server for a local environment and cannot host units")
   133  }
   134  
   135  func (s *AddUnitSuite) TestForceMachine(c *gc.C) {
   136  	err := s.runAddUnit(c, "some-service-name", "--to", "3")
   137  	c.Assert(err, jc.ErrorIsNil)
   138  	c.Assert(s.fake.numUnits, gc.Equals, 2)
   139  	c.Assert(s.fake.machineSpec, gc.Equals, "3")
   140  
   141  	err = s.runAddUnit(c, "some-service-name", "--to", "23")
   142  	c.Assert(err, jc.ErrorIsNil)
   143  	c.Assert(s.fake.numUnits, gc.Equals, 3)
   144  	c.Assert(s.fake.machineSpec, gc.Equals, "23")
   145  }
   146  
   147  func (s *AddUnitSuite) TestForceMachineNewContainer(c *gc.C) {
   148  	err := s.runAddUnit(c, "some-service-name", "--to", "lxc:1")
   149  	c.Assert(err, jc.ErrorIsNil)
   150  	c.Assert(s.fake.numUnits, gc.Equals, 2)
   151  	c.Assert(s.fake.machineSpec, gc.Equals, "lxc:1")
   152  }
   153  
   154  func (s *AddUnitSuite) TestNameChecks(c *gc.C) {
   155  	assertMachineOrNewContainer := func(s string, expect bool) {
   156  		c.Logf("%s -> %v", s, expect)
   157  		c.Assert(service.IsMachineOrNewContainer(s), gc.Equals, expect)
   158  	}
   159  	assertMachineOrNewContainer("0", true)
   160  	assertMachineOrNewContainer("00", false)
   161  	assertMachineOrNewContainer("1", true)
   162  	assertMachineOrNewContainer("0/lxc/0", true)
   163  	assertMachineOrNewContainer("lxc:0", true)
   164  	assertMachineOrNewContainer("lxc:lxc:0", false)
   165  	assertMachineOrNewContainer("kvm:0/lxc/1", true)
   166  	assertMachineOrNewContainer("lxc:", false)
   167  	assertMachineOrNewContainer(":lxc", false)
   168  	assertMachineOrNewContainer("0/lxc/", false)
   169  	assertMachineOrNewContainer("0/lxc", false)
   170  	assertMachineOrNewContainer("kvm:0/lxc", false)
   171  	assertMachineOrNewContainer("0/lxc/01", false)
   172  	assertMachineOrNewContainer("0/lxc/10", true)
   173  	assertMachineOrNewContainer("0/kvm/4", true)
   174  }