github.com/Pankov404/juju@v0.0.0-20150703034450-be266991dceb/apiserver/common/getstatus_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 "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 statusGetterSuite struct{} 21 22 var _ = gc.Suite(&statusGetterSuite{}) 23 24 var _ state.StatusGetter = new(fakeStatus) 25 26 func fakeServiceFromUnitTag(st state.EntityFinder, unitTag string) (common.StatusService, error) { 27 tag, err := names.ParseUnitTag(unitTag) 28 if err != nil { 29 return nil, err 30 } 31 entity, err := st.FindEntity(tag) 32 service, ok := entity.(*fakeService) 33 if !ok { 34 return nil, err 35 } 36 return service, nil 37 } 38 39 func fakeIsLeaderCheck(_ state.EntityFinder, _ string) (bool, error) { 40 return true, nil 41 } 42 43 type fakeService struct { 44 tag names.Tag 45 status state.StatusInfo 46 statusError error 47 48 unitsStatus map[string]state.StatusInfo 49 unitsStatusError error 50 serviceStatus state.StatusInfo 51 err error 52 fetchError 53 } 54 55 func (s *fakeService) Status() (state.StatusInfo, error) { 56 return s.status, s.statusError 57 } 58 59 func (s *fakeService) ServiceAndUnitsStatus() (state.StatusInfo, map[string]state.StatusInfo, error) { 60 return s.status, s.unitsStatus, s.unitsStatusError 61 } 62 63 func (s *fakeService) Tag() names.Tag { 64 return s.tag 65 } 66 67 func (s *fakeService) SetStatus(status state.Status, info string, data map[string]interface{}) error { 68 s.serviceStatus.Status = status 69 s.serviceStatus.Message = info 70 s.serviceStatus.Data = data 71 updated := time.Now() 72 s.serviceStatus.Since = &updated 73 return s.err 74 } 75 76 func (*statusGetterSuite) TestServiceStatus(c *gc.C) { 77 now := time.Now() 78 st := &fakeState{ 79 entities: map[names.Tag]entityWithError{ 80 u("x/1"): &fakeService{ 81 tag: serviceTag("wordpress-1"), 82 status: state.StatusInfo{ 83 Status: state.StatusActive, 84 Message: "foo service", 85 Since: &now, 86 }, 87 statusError: nil, 88 unitsStatus: map[string]state.StatusInfo{ 89 "unit-x-1": state.StatusInfo{ 90 Status: state.StatusActive, 91 Message: "foo", 92 Since: &now, 93 }, 94 "unit-x-2": state.StatusInfo{ 95 Status: state.StatusActive, 96 Message: "foo 2", 97 Since: &now, 98 }, 99 }, 100 unitsStatusError: nil, 101 }, 102 }, 103 } 104 105 expected := params.ServiceStatusResults{ 106 Results: []params.ServiceStatusResult{ 107 params.ServiceStatusResult{ 108 Service: params.StatusResult{ 109 Error: nil, 110 Id: "", 111 Life: "", 112 Status: "active", 113 Info: "foo service", 114 Data: nil, 115 Since: &now, 116 }, 117 Units: map[string]params.StatusResult{ 118 "unit-x-1": params.StatusResult{ 119 Error: nil, 120 Id: "", 121 Life: "", 122 Status: "active", 123 Info: "foo", 124 Data: nil, 125 Since: &now, 126 }, 127 "unit-x-2": params.StatusResult{ 128 Error: nil, 129 Id: "", 130 Life: "", 131 Status: "active", 132 Info: "foo 2", 133 Data: nil, 134 Since: &now, 135 }, 136 }, 137 Error: nil}, 138 }, 139 } 140 getCanAccess := func() (common.AuthFunc, error) { 141 return func(tag names.Tag) bool { return true }, nil 142 } 143 144 args := params.Entities{ 145 Entities: []params.Entity{ 146 params.Entity{ 147 Tag: "unit-x-1", 148 }, 149 }, 150 } 151 152 sg := common.NewServiceStatusGetter(st, getCanAccess) 153 result, err := common.ServiceStatus(sg, args, fakeServiceFromUnitTag, fakeIsLeaderCheck) 154 c.Assert(err, jc.ErrorIsNil) 155 c.Assert(result, gc.DeepEquals, expected) 156 } 157 158 func (*statusGetterSuite) TestServiceStatusNotLeader(c *gc.C) { 159 now := time.Now() 160 leaderCheck := func(_ state.EntityFinder, tag string) (bool, error) { 161 return false, nil 162 } 163 164 getCanAccess := func() (common.AuthFunc, error) { 165 return func(tag names.Tag) bool { return true }, nil 166 } 167 168 st := &fakeState{ 169 entities: map[names.Tag]entityWithError{ 170 u("x/1"): &fakeService{ 171 tag: serviceTag("wordpress-1"), 172 status: state.StatusInfo{ 173 Status: state.StatusActive, 174 Message: "foo service", 175 Since: &now, 176 }, 177 statusError: nil, 178 unitsStatus: map[string]state.StatusInfo{ 179 "unit-x-1": state.StatusInfo{ 180 Status: state.StatusActive, 181 Message: "foo", 182 Since: &now, 183 }, 184 "unit-x-2": state.StatusInfo{ 185 Status: state.StatusActive, 186 Message: "foo 2", 187 Since: &now, 188 }, 189 }, 190 unitsStatusError: nil, 191 }, 192 }, 193 } 194 195 expected := params.ServiceStatusResults{ 196 Results: []params.ServiceStatusResult{ 197 { 198 Service: params.StatusResult{ 199 Error: nil, 200 Id: "", 201 Life: "", 202 Status: "", 203 Info: "", 204 Data: nil, 205 Since: nil}, 206 Units: map[string]params.StatusResult(nil), 207 Error: ¶ms.Error{"this unit is not the leader", ""}, 208 }, 209 }, 210 } 211 args := params.Entities{ 212 Entities: []params.Entity{ 213 params.Entity{ 214 Tag: "unit-x-1", 215 }, 216 }, 217 } 218 219 sg := common.NewServiceStatusGetter(st, getCanAccess) 220 result, err := common.ServiceStatus(sg, args, fakeServiceFromUnitTag, leaderCheck) 221 c.Assert(err, jc.ErrorIsNil) 222 c.Assert(result, gc.DeepEquals, expected) 223 224 } 225 226 func (*statusGetterSuite) TestStatus(c *gc.C) { 227 st := &fakeState{ 228 entities: map[names.Tag]entityWithError{ 229 u("x/0"): &fakeStatus{status: state.StatusAllocating, info: "blah", err: fmt.Errorf("x0 fails")}, 230 u("x/1"): &fakeStatus{status: state.StatusInstalling, info: "blah"}, 231 u("x/2"): &fakeStatus{status: state.StatusActive, info: "foo"}, 232 u("x/3"): &fakeStatus{status: state.StatusError, info: "some info", data: map[string]interface{}{"foo": "bar"}}, 233 u("x/4"): &fakeStatus{fetchError: "x3 error"}, 234 u("x/5"): &fakeStatus{status: state.StatusStopping, info: "blah"}, 235 }, 236 } 237 getCanAccess := func() (common.AuthFunc, error) { 238 x0 := u("x/0") 239 x1 := u("x/1") 240 x2 := u("x/2") 241 x3 := u("x/3") 242 x4 := u("x/4") 243 x5 := u("x/5") 244 return func(tag names.Tag) bool { 245 return tag == x0 || tag == x1 || tag == x2 || tag == x3 || tag == x4 || tag == x5 246 }, nil 247 } 248 s := common.NewStatusGetter(st, getCanAccess) 249 args := params.Entities{ 250 Entities: []params.Entity{ 251 {"unit-x-0"}, 252 {"unit-x-1"}, 253 {"unit-x-2"}, 254 {"unit-x-3"}, 255 {"unit-x-4"}, 256 {"unit-x-5"}, 257 {"unit-x-6"}, 258 {"unit-x-7"}, 259 {"machine-1"}, 260 {"invalid"}, 261 }, 262 } 263 result, err := s.Status(args) 264 c.Assert(err, jc.ErrorIsNil) 265 // Zero out the updated timestamps so we can easily check the results. 266 for i, statusResult := range result.Results { 267 r := statusResult 268 if r.Status != "" { 269 c.Assert(r.Since, gc.NotNil) 270 } 271 r.Since = nil 272 result.Results[i] = r 273 } 274 c.Assert(result, gc.DeepEquals, params.StatusResults{ 275 Results: []params.StatusResult{ 276 {Status: "allocating", Info: "blah", Error: ¶ms.Error{Message: "x0 fails"}}, 277 {Status: "installing", Info: "blah"}, 278 {Status: "active", Info: "foo"}, 279 {Status: "error", Info: "some info", Data: map[string]interface{}{"foo": "bar"}}, 280 {Error: ¶ms.Error{Message: "x3 error"}}, 281 {Status: "stopping", Info: "blah"}, 282 {Error: apiservertesting.ErrUnauthorized}, 283 {Error: apiservertesting.ErrUnauthorized}, 284 {Error: apiservertesting.ErrUnauthorized}, 285 {Error: apiservertesting.ServerError(`"invalid" is not a valid tag`)}, 286 }, 287 }) 288 } 289 290 func (*statusGetterSuite) TestStatusError(c *gc.C) { 291 getCanAccess := func() (common.AuthFunc, error) { 292 return nil, fmt.Errorf("pow") 293 } 294 s := common.NewStatusGetter(&fakeState{}, getCanAccess) 295 args := params.Entities{ 296 Entities: []params.Entity{{"x0"}}, 297 } 298 _, err := s.Status(args) 299 c.Assert(err, gc.ErrorMatches, "pow") 300 }