github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/payload/api/private/client/unitfacade_test.go (about) 1 // Copyright 2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package client_test 5 6 import ( 7 "github.com/juju/errors" 8 "github.com/juju/testing" 9 jc "github.com/juju/testing/checkers" 10 gc "gopkg.in/check.v1" 11 "gopkg.in/juju/names.v2" 12 13 "github.com/juju/juju/apiserver/common" 14 "github.com/juju/juju/apiserver/params" 15 "github.com/juju/juju/payload" 16 "github.com/juju/juju/payload/api" 17 "github.com/juju/juju/payload/api/private/client" 18 ) 19 20 type clientSuite struct { 21 testing.IsolationSuite 22 23 stub *testing.Stub 24 facade *stubFacade 25 payload params.Payload 26 } 27 28 var _ = gc.Suite(&clientSuite{}) 29 30 func (s *clientSuite) SetUpTest(c *gc.C) { 31 s.IsolationSuite.SetUpTest(c) 32 33 s.stub = &testing.Stub{} 34 s.facade = &stubFacade{stub: s.stub} 35 s.facade.methods = &unitMethods{} 36 s.payload = params.Payload{ 37 Class: "foobar", 38 Type: "type", 39 ID: "idfoo", 40 Status: payload.StateRunning, 41 } 42 43 } 44 45 func (s *clientSuite) TestTrack(c *gc.C) { 46 id := "ce5bc2a7-65d8-4800-8199-a7c3356ab309" 47 numStubCalls := 0 48 s.facade.FacadeCallFn = func(name string, args, response interface{}) error { 49 numStubCalls++ 50 c.Check(name, gc.Equals, "Track") 51 52 typedResponse, ok := response.(*params.PayloadResults) 53 c.Assert(ok, gc.Equals, true) 54 typedResponse.Results = []params.PayloadResult{{ 55 Entity: params.Entity{ 56 Tag: names.NewPayloadTag(id).String(), 57 }, 58 Payload: nil, 59 NotFound: false, 60 Error: nil, 61 }} 62 return nil 63 } 64 65 pclient := client.NewUnitFacadeClient(s.facade) 66 67 pl, err := api.API2Payload(s.payload) 68 c.Assert(err, jc.ErrorIsNil) 69 results, err := pclient.Track(pl.Payload) 70 c.Assert(err, jc.ErrorIsNil) 71 72 c.Check(numStubCalls, gc.Equals, 1) 73 c.Check(results, jc.DeepEquals, []payload.Result{{ 74 ID: id, 75 Payload: nil, 76 NotFound: false, 77 Error: nil, 78 }}) 79 } 80 81 func (s *clientSuite) TestList(c *gc.C) { 82 id := "ce5bc2a7-65d8-4800-8199-a7c3356ab309" 83 responses := []interface{}{ 84 ¶ms.PayloadResults{ 85 Results: []params.PayloadResult{{ 86 Entity: params.Entity{ 87 Tag: names.NewPayloadTag(id).String(), 88 }, 89 Payload: nil, 90 NotFound: false, 91 Error: nil, 92 }}, 93 }, 94 ¶ms.PayloadResults{ 95 Results: []params.PayloadResult{{ 96 Entity: params.Entity{ 97 Tag: names.NewPayloadTag(id).String(), 98 }, 99 Payload: &s.payload, 100 NotFound: false, 101 Error: nil, 102 }}, 103 }, 104 } 105 s.facade.responses = append(s.facade.responses, responses...) 106 107 pclient := client.NewUnitFacadeClient(s.facade) 108 109 results, err := pclient.List("idfoo/bar") 110 c.Assert(err, jc.ErrorIsNil) 111 112 expected, err := api.API2Payload(s.payload) 113 c.Assert(err, jc.ErrorIsNil) 114 c.Check(results, jc.DeepEquals, []payload.Result{{ 115 ID: id, 116 Payload: &expected, 117 NotFound: false, 118 Error: nil, 119 }}) 120 s.stub.CheckCalls(c, []testing.StubCall{{ 121 FuncName: "FacadeCall", 122 Args: []interface{}{ 123 "LookUp", 124 ¶ms.LookUpPayloadArgs{ 125 Args: []params.LookUpPayloadArg{{ 126 Name: "idfoo", 127 ID: "bar", 128 }}, 129 }, 130 responses[0], 131 }, 132 }, { 133 FuncName: "FacadeCall", 134 Args: []interface{}{ 135 "List", 136 ¶ms.Entities{ 137 Entities: []params.Entity{{ 138 Tag: names.NewPayloadTag(id).String(), 139 }}, 140 }, 141 responses[1], 142 }, 143 }}) 144 } 145 146 func (s *clientSuite) TestLookUpOkay(c *gc.C) { 147 id := "ce5bc2a7-65d8-4800-8199-a7c3356ab309" 148 response := ¶ms.PayloadResults{ 149 Results: []params.PayloadResult{{ 150 Entity: params.Entity{ 151 Tag: names.NewPayloadTag(id).String(), 152 }, 153 Payload: nil, 154 NotFound: false, 155 Error: nil, 156 }}, 157 } 158 s.facade.responses = append(s.facade.responses, response) 159 160 pclient := client.NewUnitFacadeClient(s.facade) 161 results, err := pclient.LookUp("idfoo/bar") 162 c.Assert(err, jc.ErrorIsNil) 163 164 c.Check(results, jc.DeepEquals, []payload.Result{{ 165 ID: id, 166 Payload: nil, 167 NotFound: false, 168 Error: nil, 169 }}) 170 s.stub.CheckCalls(c, []testing.StubCall{{ 171 FuncName: "FacadeCall", 172 Args: []interface{}{ 173 "LookUp", 174 ¶ms.LookUpPayloadArgs{ 175 Args: []params.LookUpPayloadArg{{ 176 Name: "idfoo", 177 ID: "bar", 178 }}, 179 }, 180 response, 181 }, 182 }}) 183 } 184 185 func (s *clientSuite) TestLookUpMulti(c *gc.C) { 186 id1 := "ce5bc2a7-65d8-4800-8199-a7c3356ab309" 187 id2 := "ce5bc2a7-65d8-4800-8199-a7c3356ab311" 188 response := ¶ms.PayloadResults{ 189 Results: []params.PayloadResult{{ 190 Entity: params.Entity{ 191 Tag: names.NewPayloadTag(id1).String(), 192 }, 193 Payload: nil, 194 NotFound: false, 195 Error: nil, 196 }, { 197 Entity: params.Entity{ 198 Tag: "", 199 }, 200 Payload: nil, 201 NotFound: true, 202 Error: common.ServerError(errors.NotFoundf("payload")), 203 }, { 204 Entity: params.Entity{ 205 Tag: names.NewPayloadTag(id2).String(), 206 }, 207 Payload: nil, 208 NotFound: false, 209 Error: nil, 210 }}, 211 } 212 s.facade.responses = append(s.facade.responses, response) 213 214 pclient := client.NewUnitFacadeClient(s.facade) 215 results, err := pclient.LookUp("idfoo/bar", "idbaz/bam", "spam/eggs") 216 c.Assert(err, jc.ErrorIsNil) 217 218 c.Assert(results, gc.HasLen, 3) 219 c.Assert(results[1].Error, gc.NotNil) 220 results[1].Error = nil 221 c.Check(results, jc.DeepEquals, []payload.Result{{ 222 ID: id1, 223 Payload: nil, 224 NotFound: false, 225 Error: nil, 226 }, { 227 ID: "", 228 Payload: nil, 229 NotFound: true, 230 Error: nil, 231 }, { 232 ID: id2, 233 Payload: nil, 234 NotFound: false, 235 Error: nil, 236 }}) 237 s.stub.CheckCalls(c, []testing.StubCall{{ 238 FuncName: "FacadeCall", 239 Args: []interface{}{ 240 "LookUp", 241 ¶ms.LookUpPayloadArgs{ 242 Args: []params.LookUpPayloadArg{{ 243 Name: "idfoo", 244 ID: "bar", 245 }, { 246 Name: "idbaz", 247 ID: "bam", 248 }, { 249 Name: "spam", 250 ID: "eggs", 251 }}, 252 }, 253 response, 254 }, 255 }}) 256 } 257 258 func (s *clientSuite) TestSetStatus(c *gc.C) { 259 id := "ce5bc2a7-65d8-4800-8199-a7c3356ab309" 260 responses := []interface{}{ 261 ¶ms.PayloadResults{ 262 Results: []params.PayloadResult{{ 263 Entity: params.Entity{ 264 Tag: names.NewPayloadTag(id).String(), 265 }, 266 Payload: nil, 267 NotFound: false, 268 Error: nil, 269 }}, 270 }, 271 ¶ms.PayloadResults{ 272 Results: []params.PayloadResult{{ 273 Entity: params.Entity{ 274 Tag: names.NewPayloadTag(id).String(), 275 }, 276 Payload: nil, 277 NotFound: false, 278 Error: nil, 279 }}, 280 }, 281 } 282 s.facade.responses = append(s.facade.responses, responses...) 283 284 pclient := client.NewUnitFacadeClient(s.facade) 285 results, err := pclient.SetStatus(payload.StateRunning, "idfoo/bar") 286 c.Assert(err, jc.ErrorIsNil) 287 288 c.Check(results, jc.DeepEquals, []payload.Result{{ 289 ID: id, 290 Payload: nil, 291 NotFound: false, 292 Error: nil, 293 }}) 294 s.stub.CheckCalls(c, []testing.StubCall{{ 295 FuncName: "FacadeCall", 296 Args: []interface{}{ 297 "LookUp", 298 ¶ms.LookUpPayloadArgs{ 299 Args: []params.LookUpPayloadArg{{ 300 Name: "idfoo", 301 ID: "bar", 302 }}, 303 }, 304 responses[0], 305 }, 306 }, { 307 FuncName: "FacadeCall", 308 Args: []interface{}{ 309 "SetStatus", 310 ¶ms.SetPayloadStatusArgs{ 311 Args: []params.SetPayloadStatusArg{{ 312 Entity: params.Entity{ 313 Tag: names.NewPayloadTag(id).String(), 314 }, 315 Status: "running", 316 }}, 317 }, 318 responses[1], 319 }, 320 }}) 321 } 322 323 func (s *clientSuite) TestUntrack(c *gc.C) { 324 id := "ce5bc2a7-65d8-4800-8199-a7c3356ab309" 325 responses := []interface{}{ 326 ¶ms.PayloadResults{ 327 Results: []params.PayloadResult{{ 328 Entity: params.Entity{ 329 Tag: names.NewPayloadTag(id).String(), 330 }, 331 Payload: nil, 332 NotFound: false, 333 Error: nil, 334 }}, 335 }, 336 ¶ms.PayloadResults{ 337 Results: []params.PayloadResult{{ 338 Entity: params.Entity{ 339 Tag: names.NewPayloadTag(id).String(), 340 }, 341 Payload: nil, 342 NotFound: false, 343 Error: nil, 344 }}, 345 }, 346 } 347 s.facade.responses = append(s.facade.responses, responses...) 348 349 pclient := client.NewUnitFacadeClient(s.facade) 350 results, err := pclient.Untrack("idfoo/bar") 351 c.Assert(err, jc.ErrorIsNil) 352 353 c.Check(results, jc.DeepEquals, []payload.Result{{ 354 ID: id, 355 Payload: nil, 356 NotFound: false, 357 Error: nil, 358 }}) 359 s.stub.CheckCalls(c, []testing.StubCall{{ 360 FuncName: "FacadeCall", 361 Args: []interface{}{ 362 "LookUp", 363 ¶ms.LookUpPayloadArgs{ 364 Args: []params.LookUpPayloadArg{{ 365 Name: "idfoo", 366 ID: "bar", 367 }}, 368 }, 369 responses[0], 370 }, 371 }, { 372 FuncName: "FacadeCall", 373 Args: []interface{}{ 374 "Untrack", 375 ¶ms.Entities{ 376 Entities: []params.Entity{{ 377 Tag: names.NewPayloadTag(id).String(), 378 }}, 379 }, 380 responses[1], 381 }, 382 }}) 383 } 384 385 type apiMethods interface { 386 Handler(name string) (func(target, response interface{}), bool) 387 } 388 389 type stubFacade struct { 390 stub *testing.Stub 391 responses []interface{} 392 methods apiMethods 393 394 // TODO(ericsnow) Eliminate this. 395 FacadeCallFn func(name string, params, response interface{}) error 396 } 397 398 func (s *stubFacade) nextResponse() interface{} { 399 if len(s.responses) == 0 { 400 return nil 401 } 402 resp := s.responses[0] 403 s.responses = s.responses[1:] 404 return resp 405 } 406 407 func (s *stubFacade) FacadeCall(request string, params, response interface{}) error { 408 s.stub.AddCall("FacadeCall", request, params, response) 409 resp := s.nextResponse() 410 if err := s.stub.NextErr(); err != nil { 411 return errors.Trace(err) 412 } 413 414 if s.FacadeCallFn != nil { 415 return s.FacadeCallFn(request, params, response) 416 } 417 418 if resp == nil { 419 // TODO(ericsnow) Fail? 420 return nil 421 } 422 handler, ok := s.methods.Handler(request) 423 if !ok { 424 return errors.Errorf("unknown request %q", request) 425 } 426 handler(response, resp) 427 return nil 428 } 429 430 func (s *stubFacade) Close() error { 431 s.stub.AddCall("Close") 432 if err := s.stub.NextErr(); err != nil { 433 return errors.Trace(err) 434 } 435 436 return nil 437 } 438 439 type unitMethods struct{} 440 441 func (m unitMethods) Handler(name string) (func(target, response interface{}), bool) { 442 switch name { 443 case "List", "LookUp", "SetStatus", "Untrack": 444 return m.generic, true 445 default: 446 return nil, false 447 } 448 } 449 450 func (unitMethods) generic(target, response interface{}) { 451 typedTarget := target.(*params.PayloadResults) 452 typedResponse := response.(*params.PayloadResults) 453 *typedTarget = *typedResponse 454 }