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 }