github.com/Pankov404/juju@v0.0.0-20150703034450-be266991dceb/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 "fmt" 8 "time" 9 10 "github.com/juju/names" 11 jc "github.com/juju/testing/checkers" 12 gc "gopkg.in/check.v1" 13 14 "github.com/juju/juju/apiserver/common" 15 "github.com/juju/juju/apiserver/params" 16 apiservertesting "github.com/juju/juju/apiserver/testing" 17 "github.com/juju/juju/state" 18 ) 19 20 type statusSetterSuite struct{} 21 22 var _ = gc.Suite(&statusSetterSuite{}) 23 24 var _ state.StatusSetter = new(fakeStatus) 25 26 type fakeStatus struct { 27 state.Entity 28 status state.Status 29 info string 30 data map[string]interface{} 31 updated time.Time 32 err error 33 fetchError 34 } 35 36 func (s *fakeStatus) SetStatus(status state.Status, info string, data map[string]interface{}) error { 37 s.status = status 38 s.info = info 39 s.data = data 40 s.updated = time.Now() 41 return s.err 42 } 43 44 func (s *fakeStatus) Status() (state.StatusInfo, error) { 45 return state.StatusInfo{ 46 s.status, s.info, s.data, &s.updated, 47 }, s.err 48 } 49 50 func (s *fakeStatus) UpdateStatus(data map[string]interface{}) error { 51 for k, v := range data { 52 s.data[k] = v 53 } 54 return s.err 55 } 56 57 func (*statusSetterSuite) TestSetServiceStatus(c *gc.C) { 58 st := &fakeState{ 59 entities: map[names.Tag]entityWithError{ 60 u("x/0"): &fakeService{ 61 tag: serviceTag("x/0"), 62 serviceStatus: state.StatusInfo{ 63 Status: state.StatusAllocating, 64 Message: "blah", 65 }, 66 err: fmt.Errorf("x0 fails"), 67 }, 68 u("x/1"): &fakeService{ 69 tag: serviceTag("x/1"), 70 serviceStatus: state.StatusInfo{ 71 Status: state.StatusInstalling, 72 Message: "blah", 73 }, 74 }, 75 u("x/2"): &fakeService{ 76 tag: serviceTag("x/2"), 77 serviceStatus: state.StatusInfo{ 78 Status: state.StatusActive, 79 Message: "foo", 80 }, 81 }, 82 u("x/3"): &fakeService{ 83 tag: serviceTag("x/3"), 84 serviceStatus: state.StatusInfo{ 85 Status: state.StatusError, 86 Message: "some info", 87 }, 88 }, 89 u("x/4"): &fakeService{ 90 tag: serviceTag("x/4"), 91 serviceStatus: state.StatusInfo{}, 92 fetchError: "x3 error", 93 }, 94 u("x/5"): &fakeService{ 95 tag: serviceTag("x/5"), 96 serviceStatus: state.StatusInfo{ 97 Status: state.StatusStopping, 98 Message: "blah", 99 }, 100 }, 101 }, 102 } 103 getCanModify := func() (common.AuthFunc, error) { 104 x0 := serviceTag("x/0") 105 x1 := serviceTag("x/1") 106 x2 := serviceTag("x/2") 107 x3 := serviceTag("x/3") 108 x4 := serviceTag("x/4") 109 x5 := serviceTag("x/5") 110 return func(tag names.Tag) bool { 111 return tag == x0 || tag == x1 || tag == x2 || tag == x3 || tag == x4 || tag == x5 112 }, nil 113 } 114 s := common.NewServiceStatusSetter(st, getCanModify) 115 args := params.SetStatus{ 116 Entities: []params.EntityStatus{ 117 {"unit-x-0", params.StatusInstalling, "bar", nil}, 118 {"unit-x-1", params.StatusActive, "bar", nil}, 119 {"unit-x-2", params.StatusStopping, "", nil}, 120 {"unit-x-3", params.StatusAllocating, "not really", nil}, 121 {"unit-x-4", params.StatusStopping, "", nil}, 122 {"unit-x-5", params.StatusStopping, "blah", nil}, 123 }, 124 } 125 leaderCheck := func(_ state.EntityFinder, tag string) (bool, error) { 126 if tag == "unit-x-5" { 127 return false, nil 128 } 129 return true, nil 130 } 131 result, err := common.ServiceSetStatus(s, args, fakeServiceFromUnitTag, leaderCheck) 132 c.Assert(err, jc.ErrorIsNil) 133 c.Assert(result, gc.DeepEquals, params.ErrorResults{ 134 Results: []params.ErrorResult{ 135 {¶ms.Error{Message: "x0 fails"}}, 136 {nil}, 137 {nil}, 138 {nil}, 139 {¶ms.Error{Message: "x3 error"}}, 140 {¶ms.Error{"this unit is not the leader", ""}}, 141 }, 142 }) 143 get := func(tag names.Tag) *fakeService { 144 return st.entities[tag].(*fakeService) 145 } 146 c.Assert(get(u("x/1")).serviceStatus.Status, gc.Equals, state.StatusActive) 147 c.Assert(get(u("x/1")).serviceStatus.Message, gc.Equals, "bar") 148 c.Assert(get(u("x/2")).serviceStatus.Status, gc.Equals, state.StatusStopping) 149 c.Assert(get(u("x/2")).serviceStatus.Message, gc.Equals, "") 150 c.Assert(get(u("x/3")).serviceStatus.Status, gc.Equals, state.StatusAllocating) 151 c.Assert(get(u("x/3")).serviceStatus.Message, gc.Equals, "not really") 152 c.Assert(get(u("x/5")).serviceStatus.Status, gc.Equals, state.StatusStopping) 153 c.Assert(get(u("x/5")).serviceStatus.Message, gc.Equals, "blah") 154 155 } 156 157 func (*statusSetterSuite) TestSetServiceStatusNotLeader(c *gc.C) { 158 st := &fakeState{ 159 entities: map[names.Tag]entityWithError{ 160 u("x/0"): &fakeService{ 161 tag: serviceTag("x/0"), 162 serviceStatus: state.StatusInfo{ 163 Status: state.StatusAllocating, 164 Message: "blah", 165 }, 166 err: fmt.Errorf("x0 fails"), 167 }, 168 }, 169 } 170 171 getCanModify := func() (common.AuthFunc, error) { 172 return func(_ names.Tag) bool { return true }, nil 173 } 174 s := common.NewServiceStatusSetter(st, getCanModify) 175 args := params.SetStatus{ 176 Entities: []params.EntityStatus{ 177 {"unit-x-0", params.StatusInstalling, "bar", nil}, 178 }, 179 } 180 leaderCheck := func(_ state.EntityFinder, tag string) (bool, error) { 181 return false, nil 182 } 183 result, err := common.ServiceSetStatus(s, args, fakeServiceFromUnitTag, leaderCheck) 184 c.Assert(err, jc.ErrorIsNil) 185 c.Assert(result, gc.DeepEquals, params.ErrorResults{ 186 Results: []params.ErrorResult{ 187 {¶ms.Error{"this unit is not the leader", ""}}, 188 }, 189 }) 190 191 } 192 193 func (*statusSetterSuite) TestSetStatus(c *gc.C) { 194 st := &fakeState{ 195 entities: map[names.Tag]entityWithError{ 196 u("x/0"): &fakeStatus{status: state.StatusAllocating, info: "blah", err: fmt.Errorf("x0 fails")}, 197 u("x/1"): &fakeStatus{status: state.StatusInstalling, info: "blah"}, 198 u("x/2"): &fakeStatus{status: state.StatusActive, info: "foo"}, 199 u("x/3"): &fakeStatus{status: state.StatusError, info: "some info"}, 200 u("x/4"): &fakeStatus{fetchError: "x3 error"}, 201 u("x/5"): &fakeStatus{status: state.StatusStopping, info: "blah"}, 202 }, 203 } 204 getCanModify := func() (common.AuthFunc, error) { 205 x0 := u("x/0") 206 x1 := u("x/1") 207 x2 := u("x/2") 208 x3 := u("x/3") 209 x4 := u("x/4") 210 x5 := u("x/5") 211 return func(tag names.Tag) bool { 212 return tag == x0 || tag == x1 || tag == x2 || tag == x3 || tag == x4 || tag == x5 213 }, nil 214 } 215 s := common.NewStatusSetter(st, getCanModify) 216 args := params.SetStatus{ 217 Entities: []params.EntityStatus{ 218 {"unit-x-0", params.StatusInstalling, "bar", nil}, 219 {"unit-x-1", params.StatusActive, "bar", nil}, 220 {"unit-x-2", params.StatusStopping, "", nil}, 221 {"unit-x-3", params.StatusAllocating, "not really", nil}, 222 {"unit-x-4", params.StatusStopping, "", nil}, 223 {"unit-x-5", params.StatusError, "blarg", nil}, 224 {"unit-x-6", params.StatusActive, "42", nil}, 225 {"unit-x-7", params.StatusActive, "bar", nil}, 226 }, 227 } 228 result, err := s.SetStatus(args) 229 c.Assert(err, jc.ErrorIsNil) 230 c.Assert(result, gc.DeepEquals, params.ErrorResults{ 231 Results: []params.ErrorResult{ 232 {¶ms.Error{Message: "x0 fails"}}, 233 {nil}, 234 {nil}, 235 {nil}, 236 {¶ms.Error{Message: "x3 error"}}, 237 {nil}, 238 {apiservertesting.ErrUnauthorized}, 239 {apiservertesting.ErrUnauthorized}, 240 }, 241 }) 242 get := func(tag names.Tag) *fakeStatus { 243 return st.entities[tag].(*fakeStatus) 244 } 245 c.Assert(get(u("x/1")).status, gc.Equals, state.StatusActive) 246 c.Assert(get(u("x/1")).info, gc.Equals, "bar") 247 c.Assert(get(u("x/2")).status, gc.Equals, state.StatusStopping) 248 c.Assert(get(u("x/2")).info, gc.Equals, "") 249 c.Assert(get(u("x/3")).status, gc.Equals, state.StatusAllocating) 250 c.Assert(get(u("x/3")).info, gc.Equals, "not really") 251 c.Assert(get(u("x/5")).status, gc.Equals, state.StatusError) 252 c.Assert(get(u("x/5")).info, gc.Equals, "blarg") 253 } 254 255 func (*statusSetterSuite) TestSetStatusError(c *gc.C) { 256 getCanModify := func() (common.AuthFunc, error) { 257 return nil, fmt.Errorf("pow") 258 } 259 s := common.NewStatusSetter(&fakeState{}, getCanModify) 260 args := params.SetStatus{ 261 Entities: []params.EntityStatus{{"x0", "", "", nil}}, 262 } 263 _, err := s.SetStatus(args) 264 c.Assert(err, gc.ErrorMatches, "pow") 265 } 266 267 func (*statusSetterSuite) TestSetStatusNoArgsNoError(c *gc.C) { 268 getCanModify := func() (common.AuthFunc, error) { 269 return nil, fmt.Errorf("pow") 270 } 271 s := common.NewStatusSetter(&fakeState{}, getCanModify) 272 result, err := s.SetStatus(params.SetStatus{}) 273 c.Assert(err, jc.ErrorIsNil) 274 c.Assert(result.Results, gc.HasLen, 0) 275 } 276 277 func (*statusSetterSuite) TestUpdateStatus(c *gc.C) { 278 st := &fakeState{ 279 entities: map[names.Tag]entityWithError{ 280 m("0"): &fakeStatus{status: state.StatusAllocating, info: "blah", err: fmt.Errorf("x0 fails")}, 281 m("1"): &fakeStatus{status: state.StatusError, info: "foo", data: map[string]interface{}{"foo": "blah"}}, 282 m("2"): &fakeStatus{status: state.StatusError, info: "some info"}, 283 m("3"): &fakeStatus{fetchError: "x3 error"}, 284 m("4"): &fakeStatus{status: state.StatusActive}, 285 m("5"): &fakeStatus{status: state.StatusStopping, info: ""}, 286 }, 287 } 288 getCanModify := func() (common.AuthFunc, error) { 289 x0 := m("0") 290 x1 := m("1") 291 x2 := m("2") 292 x3 := m("3") 293 x4 := m("4") 294 return func(tag names.Tag) bool { 295 return tag == x0 || tag == x1 || tag == x2 || tag == x3 || tag == x4 296 }, nil 297 } 298 s := common.NewStatusSetter(st, getCanModify) 299 args := params.SetStatus{ 300 Entities: []params.EntityStatus{ 301 {Tag: "machine-0", Data: nil}, 302 {Tag: "machine-1", Data: nil}, 303 {Tag: "machine-2", Data: map[string]interface{}{"foo": "bar"}}, 304 {Tag: "machine-3", Data: map[string]interface{}{"foo": "bar"}}, 305 {Tag: "machine-4", Data: map[string]interface{}{"foo": "bar"}}, 306 {Tag: "machine-5", Data: map[string]interface{}{"foo": "bar"}}, 307 {Tag: "machine-6", Data: nil}, 308 }, 309 } 310 result, err := s.UpdateStatus(args) 311 c.Assert(err, jc.ErrorIsNil) 312 c.Assert(result, gc.DeepEquals, params.ErrorResults{ 313 Results: []params.ErrorResult{ 314 {¶ms.Error{Message: "x0 fails"}}, 315 {nil}, 316 {nil}, 317 {¶ms.Error{Message: "x3 error"}}, 318 {¶ms.Error{Message: "machine 4 is not in an error state"}}, 319 {apiservertesting.ErrUnauthorized}, 320 {apiservertesting.ErrUnauthorized}, 321 }, 322 }) 323 get := func(tag names.Tag) *fakeStatus { 324 return st.entities[tag].(*fakeStatus) 325 } 326 c.Assert(get(m("1")).status, gc.Equals, state.StatusError) 327 c.Assert(get(m("1")).info, gc.Equals, "foo") 328 c.Assert(get(m("1")).data, gc.DeepEquals, map[string]interface{}{"foo": "blah"}) 329 c.Assert(get(m("2")).status, gc.Equals, state.StatusError) 330 c.Assert(get(m("2")).info, gc.Equals, "some info") 331 c.Assert(get(m("2")).data, gc.DeepEquals, map[string]interface{}{"foo": "bar"}) 332 }