github.com/axw/juju@v0.0.0-20161005053422-4bd6544d08d4/apiserver/common/machine_test.go (about) 1 // Copyright 2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package common_test 5 6 import ( 7 "github.com/juju/errors" 8 jc "github.com/juju/testing/checkers" 9 "github.com/juju/utils" 10 gc "gopkg.in/check.v1" 11 12 "github.com/juju/juju/apiserver/common" 13 "github.com/juju/juju/apiserver/params" 14 "github.com/juju/juju/instance" 15 "github.com/juju/juju/state" 16 "github.com/juju/juju/state/multiwatcher" 17 "github.com/juju/juju/status" 18 ) 19 20 type machineSuite struct{} 21 22 var _ = gc.Suite(&machineSuite{}) 23 24 func (s *machineSuite) TestMachineJobFromParams(c *gc.C) { 25 var tests = []struct { 26 name multiwatcher.MachineJob 27 want state.MachineJob 28 err string 29 }{{ 30 name: multiwatcher.JobHostUnits, 31 want: state.JobHostUnits, 32 }, { 33 name: multiwatcher.JobManageModel, 34 want: state.JobManageModel, 35 }, { 36 name: "invalid", 37 want: -1, 38 err: `invalid machine job "invalid"`, 39 }} 40 for _, test := range tests { 41 got, err := common.MachineJobFromParams(test.name) 42 if err != nil { 43 c.Check(err, gc.ErrorMatches, test.err) 44 } 45 c.Check(got, gc.Equals, test.want) 46 } 47 } 48 49 func (s *machineSuite) TestDestroyMachines(c *gc.C) { 50 st := mockState{ 51 machines: map[string]*mockMachine{ 52 "1": {}, 53 "2": {destroyErr: errors.New("unit exists error")}, 54 "3": {life: state.Dying}, 55 }, 56 } 57 err := common.MockableDestroyMachines(&st, false, "1", "2", "3", "4") 58 59 c.Assert(st.machines["1"].Life(), gc.Equals, state.Dying) 60 c.Assert(st.machines["1"].forceDestroyCalled, jc.IsFalse) 61 62 c.Assert(st.machines["2"].Life(), gc.Equals, state.Alive) 63 c.Assert(st.machines["2"].forceDestroyCalled, jc.IsFalse) 64 65 c.Assert(st.machines["3"].forceDestroyCalled, jc.IsFalse) 66 c.Assert(st.machines["3"].destroyCalled, jc.IsFalse) 67 68 c.Assert(err, gc.ErrorMatches, "some machines were not destroyed: unit exists error; machine 4 does not exist") 69 } 70 71 func (s *machineSuite) TestForceDestroyMachines(c *gc.C) { 72 st := mockState{ 73 machines: map[string]*mockMachine{ 74 "1": {}, 75 "2": {life: state.Dying}, 76 }, 77 } 78 err := common.MockableDestroyMachines(&st, true, "1", "2") 79 80 c.Assert(st.machines["1"].Life(), gc.Equals, state.Dying) 81 c.Assert(st.machines["1"].forceDestroyCalled, jc.IsTrue) 82 c.Assert(st.machines["2"].forceDestroyCalled, jc.IsTrue) 83 84 c.Assert(err, jc.ErrorIsNil) 85 } 86 87 func (s *machineSuite) TestMachineHardwareInfo(c *gc.C) { 88 one := uint64(1) 89 amd64 := "amd64" 90 gig := uint64(1024) 91 st := mockState{ 92 machines: map[string]*mockMachine{ 93 "1": {id: "1", life: state.Alive, containerType: instance.NONE, 94 hw: &instance.HardwareCharacteristics{ 95 Arch: &amd64, 96 Mem: &gig, 97 CpuCores: &one, 98 CpuPower: &one, 99 }}, 100 "2": {id: "2", life: state.Alive, containerType: instance.LXD}, 101 "3": {life: state.Dying}, 102 }, 103 } 104 info, err := common.ModelMachineInfo(&st) 105 c.Assert(err, jc.ErrorIsNil) 106 c.Assert(info, jc.DeepEquals, []params.ModelMachineInfo{ 107 { 108 Id: "1", 109 Hardware: ¶ms.MachineHardware{ 110 Arch: &amd64, 111 Mem: &gig, 112 Cores: &one, 113 CpuPower: &one, 114 }, 115 }, { 116 Id: "2", 117 }, 118 }) 119 } 120 121 func (s *machineSuite) TestMachineInstanceInfo(c *gc.C) { 122 st := mockState{ 123 machines: map[string]*mockMachine{ 124 "1": {id: "1", instId: instance.Id("123"), status: status.Down, hasVote: true, wantsVote: true}, 125 }, 126 } 127 info, err := common.ModelMachineInfo(&st) 128 c.Assert(err, jc.ErrorIsNil) 129 c.Assert(info, jc.DeepEquals, []params.ModelMachineInfo{ 130 { 131 Id: "1", 132 InstanceId: "123", 133 Status: "down", 134 HasVote: true, 135 WantsVote: true, 136 }, 137 }) 138 } 139 140 type mockState struct { 141 common.ModelManagerBackend 142 machines map[string]*mockMachine 143 } 144 145 func (st *mockState) Machine(id string) (common.Machine, error) { 146 if m, ok := st.machines[id]; ok { 147 return m, nil 148 } 149 return nil, errors.Errorf("machine %s does not exist", id) 150 } 151 152 func (st *mockState) AllMachines() (machines []common.Machine, _ error) { 153 // Ensure we get machines in id order. 154 var ids []string 155 for id := range st.machines { 156 ids = append(ids, id) 157 } 158 utils.SortStringsNaturally(ids) 159 for _, id := range ids { 160 machines = append(machines, st.machines[id]) 161 } 162 return machines, nil 163 } 164 165 type mockMachine struct { 166 state.Machine 167 id string 168 life state.Life 169 containerType instance.ContainerType 170 hw *instance.HardwareCharacteristics 171 instId instance.Id 172 hasVote, wantsVote bool 173 status status.Status 174 statusErr error 175 destroyErr error 176 forceDestroyErr error 177 forceDestroyCalled bool 178 destroyCalled bool 179 agentDead bool 180 presenceErr error 181 } 182 183 func (m *mockMachine) Id() string { 184 return m.id 185 } 186 187 func (m *mockMachine) Life() state.Life { 188 return m.life 189 } 190 191 func (m *mockMachine) InstanceId() (instance.Id, error) { 192 return m.instId, nil 193 } 194 195 func (m *mockMachine) WantsVote() bool { 196 return m.wantsVote 197 } 198 199 func (m *mockMachine) HasVote() bool { 200 return m.hasVote 201 } 202 203 func (m *mockMachine) Status() (status.StatusInfo, error) { 204 return status.StatusInfo{ 205 Status: m.status, 206 }, m.statusErr 207 } 208 209 func (m *mockMachine) HardwareCharacteristics() (*instance.HardwareCharacteristics, error) { 210 return m.hw, nil 211 } 212 213 func (m *mockMachine) AgentPresence() (bool, error) { 214 return !m.agentDead, m.presenceErr 215 } 216 217 func (m *mockMachine) ForceDestroy() error { 218 m.forceDestroyCalled = true 219 if m.forceDestroyErr != nil { 220 return m.forceDestroyErr 221 } 222 m.life = state.Dying 223 return nil 224 } 225 226 func (m *mockMachine) Destroy() error { 227 m.destroyCalled = true 228 if m.destroyErr != nil { 229 return m.destroyErr 230 } 231 m.life = state.Dying 232 return nil 233 }