github.com/mhilton/juju-juju@v0.0.0-20150901100907-a94dd2c73455/apiserver/common/setstatus_test.go (about) 1 // Copyright 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package common_test 5 6 import ( 7 "time" 8 9 "github.com/juju/names" 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/apiserver/params" 15 "github.com/juju/juju/state" 16 "github.com/juju/juju/testing/factory" 17 ) 18 19 type statusSetterSuite struct { 20 statusBaseSuite 21 setter *common.StatusSetter 22 } 23 24 var _ = gc.Suite(&statusSetterSuite{}) 25 26 func (s *statusSetterSuite) SetUpTest(c *gc.C) { 27 s.statusBaseSuite.SetUpTest(c) 28 29 s.setter = common.NewStatusSetter(s.State, func() (common.AuthFunc, error) { 30 return s.authFunc, nil 31 }) 32 } 33 34 func (s *statusSetterSuite) TestUnauthorized(c *gc.C) { 35 tag := names.NewMachineTag("42") 36 s.badTag = tag 37 result, err := s.setter.SetStatus(params.SetStatus{[]params.EntityStatusArgs{{ 38 Tag: tag.String(), 39 Status: params.StatusExecuting, 40 }}}) 41 c.Assert(err, jc.ErrorIsNil) 42 c.Assert(result.Results, gc.HasLen, 1) 43 c.Assert(result.Results[0].Error, jc.Satisfies, params.IsCodeUnauthorized) 44 } 45 46 func (s *statusSetterSuite) TestNotATag(c *gc.C) { 47 result, err := s.setter.SetStatus(params.SetStatus{[]params.EntityStatusArgs{{ 48 Tag: "not a tag", 49 Status: params.StatusExecuting, 50 }}}) 51 c.Assert(err, jc.ErrorIsNil) 52 c.Assert(result.Results, gc.HasLen, 1) 53 c.Assert(result.Results[0].Error, gc.ErrorMatches, `"not a tag" is not a valid tag`) 54 } 55 56 func (s *statusSetterSuite) TestNotFound(c *gc.C) { 57 result, err := s.setter.SetStatus(params.SetStatus{[]params.EntityStatusArgs{{ 58 Tag: names.NewMachineTag("42").String(), 59 Status: params.StatusDown, 60 }}}) 61 c.Assert(err, jc.ErrorIsNil) 62 c.Assert(result.Results, gc.HasLen, 1) 63 c.Assert(result.Results[0].Error, jc.Satisfies, params.IsCodeNotFound) 64 } 65 66 func (s *statusSetterSuite) TestSetMachineStatus(c *gc.C) { 67 machine := s.Factory.MakeMachine(c, nil) 68 result, err := s.setter.SetStatus(params.SetStatus{[]params.EntityStatusArgs{{ 69 Tag: machine.Tag().String(), 70 Status: params.StatusStarted, 71 }}}) 72 c.Assert(err, jc.ErrorIsNil) 73 c.Assert(result.Results, gc.HasLen, 1) 74 c.Assert(result.Results[0].Error, gc.IsNil) 75 76 err = machine.Refresh() 77 c.Assert(err, jc.ErrorIsNil) 78 status, err := machine.Status() 79 c.Assert(err, jc.ErrorIsNil) 80 c.Assert(status.Status, gc.Equals, state.StatusStarted) 81 } 82 83 func (s *statusSetterSuite) TestSetUnitStatus(c *gc.C) { 84 // The status has to be a valid workload status, because get status 85 // on the unit returns the workload status not the agent status as it 86 // does on a machine. 87 unit := s.Factory.MakeUnit(c, &factory.UnitParams{Status: &state.StatusInfo{ 88 Status: state.StatusMaintenance, 89 }}) 90 result, err := s.setter.SetStatus(params.SetStatus{[]params.EntityStatusArgs{{ 91 Tag: unit.Tag().String(), 92 Status: params.StatusActive, 93 }}}) 94 c.Assert(err, jc.ErrorIsNil) 95 c.Assert(result.Results, gc.HasLen, 1) 96 c.Assert(result.Results[0].Error, gc.IsNil) 97 98 err = unit.Refresh() 99 c.Assert(err, jc.ErrorIsNil) 100 status, err := unit.Status() 101 c.Assert(err, jc.ErrorIsNil) 102 c.Assert(status.Status, gc.Equals, state.StatusActive) 103 } 104 105 func (s *statusSetterSuite) TestSetServiceStatus(c *gc.C) { 106 // Calls to set the status of a service should be going through the 107 // ServiceStatusSetter that checks for leadership, so permission denied 108 // here. 109 service := s.Factory.MakeService(c, &factory.ServiceParams{Status: &state.StatusInfo{ 110 Status: state.StatusMaintenance, 111 }}) 112 result, err := s.setter.SetStatus(params.SetStatus{[]params.EntityStatusArgs{{ 113 Tag: service.Tag().String(), 114 Status: params.StatusActive, 115 }}}) 116 c.Assert(err, jc.ErrorIsNil) 117 c.Assert(result.Results, gc.HasLen, 1) 118 c.Assert(result.Results[0].Error, jc.Satisfies, params.IsCodeUnauthorized) 119 120 err = service.Refresh() 121 c.Assert(err, jc.ErrorIsNil) 122 status, err := service.Status() 123 c.Assert(err, jc.ErrorIsNil) 124 c.Assert(status.Status, gc.Equals, state.StatusMaintenance) 125 } 126 127 func (s *statusSetterSuite) TestBulk(c *gc.C) { 128 s.badTag = names.NewMachineTag("42") 129 result, err := s.setter.SetStatus(params.SetStatus{[]params.EntityStatusArgs{{ 130 Tag: s.badTag.String(), 131 Status: params.StatusActive, 132 }, { 133 Tag: "bad-tag", 134 Status: params.StatusActive, 135 }}}) 136 c.Assert(err, jc.ErrorIsNil) 137 c.Assert(result.Results, gc.HasLen, 2) 138 c.Assert(result.Results[0].Error, jc.Satisfies, params.IsCodeUnauthorized) 139 c.Assert(result.Results[1].Error, gc.ErrorMatches, `"bad-tag" is not a valid tag`) 140 } 141 142 type serviceStatusSetterSuite struct { 143 statusBaseSuite 144 setter *common.ServiceStatusSetter 145 } 146 147 var _ = gc.Suite(&serviceStatusSetterSuite{}) 148 149 func (s *serviceStatusSetterSuite) SetUpTest(c *gc.C) { 150 s.statusBaseSuite.SetUpTest(c) 151 152 s.setter = common.NewServiceStatusSetter(s.State, func() (common.AuthFunc, error) { 153 return s.authFunc, nil 154 }) 155 } 156 157 func (s *serviceStatusSetterSuite) TestUnauthorized(c *gc.C) { 158 // Machines are unauthorized since they are not units 159 tag := names.NewUnitTag("foo/0") 160 s.badTag = tag 161 result, err := s.setter.SetStatus(params.SetStatus{[]params.EntityStatusArgs{{ 162 Tag: tag.String(), 163 Status: params.StatusActive, 164 }}}) 165 c.Assert(err, jc.ErrorIsNil) 166 c.Assert(result.Results, gc.HasLen, 1) 167 c.Assert(result.Results[0].Error, jc.Satisfies, params.IsCodeUnauthorized) 168 } 169 170 func (s *serviceStatusSetterSuite) TestNotATag(c *gc.C) { 171 result, err := s.setter.SetStatus(params.SetStatus{[]params.EntityStatusArgs{{ 172 Tag: "not a tag", 173 Status: params.StatusActive, 174 }}}) 175 c.Assert(err, jc.ErrorIsNil) 176 c.Assert(result.Results, gc.HasLen, 1) 177 c.Assert(result.Results[0].Error, gc.ErrorMatches, `"not a tag" is not a valid tag`) 178 } 179 180 func (s *serviceStatusSetterSuite) TestNotFound(c *gc.C) { 181 result, err := s.setter.SetStatus(params.SetStatus{[]params.EntityStatusArgs{{ 182 Tag: names.NewUnitTag("foo/0").String(), 183 Status: params.StatusActive, 184 }}}) 185 c.Assert(err, jc.ErrorIsNil) 186 c.Assert(result.Results, gc.HasLen, 1) 187 c.Assert(result.Results[0].Error, jc.Satisfies, params.IsCodeNotFound) 188 } 189 190 func (s *serviceStatusSetterSuite) TestSetMachineStatus(c *gc.C) { 191 machine := s.Factory.MakeMachine(c, nil) 192 result, err := s.setter.SetStatus(params.SetStatus{[]params.EntityStatusArgs{{ 193 Tag: machine.Tag().String(), 194 Status: params.StatusActive, 195 }}}) 196 c.Assert(err, jc.ErrorIsNil) 197 c.Assert(result.Results, gc.HasLen, 1) 198 // Can't call set service status on a machine. 199 c.Assert(result.Results[0].Error, jc.Satisfies, params.IsCodeUnauthorized) 200 } 201 202 func (s *serviceStatusSetterSuite) TestSetServiceStatus(c *gc.C) { 203 // TODO: the correct way to fix this is to have the authorizer on the 204 // simple status setter to check to see if the unit (authTag) is a leader 205 // and able to set the service status. However, that is for another day. 206 service := s.Factory.MakeService(c, &factory.ServiceParams{Status: &state.StatusInfo{ 207 Status: state.StatusMaintenance, 208 }}) 209 result, err := s.setter.SetStatus(params.SetStatus{[]params.EntityStatusArgs{{ 210 Tag: service.Tag().String(), 211 Status: params.StatusActive, 212 }}}) 213 c.Assert(err, jc.ErrorIsNil) 214 c.Assert(result.Results, gc.HasLen, 1) 215 // Can't call set service status on a service. Weird I know, but the only 216 // way is to go through the unit leader. 217 c.Assert(result.Results[0].Error, jc.Satisfies, params.IsCodeUnauthorized) 218 } 219 220 func (s *serviceStatusSetterSuite) TestSetUnitStatusNotLeader(c *gc.C) { 221 // If the unit isn't the leader, it can't set it. 222 unit := s.Factory.MakeUnit(c, &factory.UnitParams{Status: &state.StatusInfo{ 223 Status: state.StatusMaintenance, 224 }}) 225 result, err := s.setter.SetStatus(params.SetStatus{[]params.EntityStatusArgs{{ 226 Tag: unit.Tag().String(), 227 Status: params.StatusActive, 228 }}}) 229 c.Assert(err, jc.ErrorIsNil) 230 c.Assert(result.Results, gc.HasLen, 1) 231 status := result.Results[0] 232 c.Assert(status.Error, gc.ErrorMatches, ".* is not leader of .*") 233 } 234 235 func (s *serviceStatusSetterSuite) TestSetUnitStatusIsLeader(c *gc.C) { 236 service := s.Factory.MakeService(c, &factory.ServiceParams{Status: &state.StatusInfo{ 237 Status: state.StatusMaintenance, 238 }}) 239 unit := s.Factory.MakeUnit(c, &factory.UnitParams{ 240 Service: service, 241 Status: &state.StatusInfo{ 242 Status: state.StatusMaintenance, 243 }}) 244 s.State.LeadershipClaimer().ClaimLeadership( 245 service.Name(), 246 unit.Name(), 247 time.Minute) 248 result, err := s.setter.SetStatus(params.SetStatus{[]params.EntityStatusArgs{{ 249 Tag: unit.Tag().String(), 250 Status: params.StatusActive, 251 }}}) 252 253 c.Assert(err, jc.ErrorIsNil) 254 c.Assert(result.Results, gc.HasLen, 1) 255 c.Assert(result.Results[0].Error, gc.IsNil) 256 257 err = service.Refresh() 258 c.Assert(err, jc.ErrorIsNil) 259 status, err := service.Status() 260 c.Assert(err, jc.ErrorIsNil) 261 c.Assert(status.Status, gc.Equals, state.StatusActive) 262 } 263 264 func (s *serviceStatusSetterSuite) TestBulk(c *gc.C) { 265 s.badTag = names.NewMachineTag("42") 266 machine := s.Factory.MakeMachine(c, nil) 267 result, err := s.setter.SetStatus(params.SetStatus{[]params.EntityStatusArgs{{ 268 Tag: s.badTag.String(), 269 Status: params.StatusActive, 270 }, { 271 Tag: machine.Tag().String(), 272 Status: params.StatusActive, 273 }, { 274 Tag: "bad-tag", 275 Status: params.StatusActive, 276 }}}) 277 c.Assert(err, jc.ErrorIsNil) 278 c.Assert(result.Results, gc.HasLen, 3) 279 c.Assert(result.Results[0].Error, jc.Satisfies, params.IsCodeUnauthorized) 280 c.Assert(result.Results[1].Error, jc.Satisfies, params.IsCodeUnauthorized) 281 c.Assert(result.Results[2].Error, gc.ErrorMatches, `"bad-tag" is not a valid tag`) 282 }