github.com/mhilton/juju-juju@v0.0.0-20150901100907-a94dd2c73455/api/storage/client_test.go (about) 1 // Copyright 2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package storage_test 5 6 import ( 7 "fmt" 8 9 "github.com/juju/errors" 10 "github.com/juju/names" 11 jc "github.com/juju/testing/checkers" 12 "github.com/juju/utils/set" 13 gc "gopkg.in/check.v1" 14 15 basetesting "github.com/juju/juju/api/base/testing" 16 "github.com/juju/juju/api/storage" 17 "github.com/juju/juju/apiserver/common" 18 "github.com/juju/juju/apiserver/params" 19 "github.com/juju/juju/testing" 20 ) 21 22 type storageMockSuite struct { 23 testing.BaseSuite 24 } 25 26 var _ = gc.Suite(&storageMockSuite{}) 27 28 func (s *storageMockSuite) TestShow(c *gc.C) { 29 one := "shared-fs/0" 30 oneTag := names.NewStorageTag(one) 31 two := "db-dir/1000" 32 twoTag := names.NewStorageTag(two) 33 expected := set.NewStrings(oneTag.String(), twoTag.String()) 34 msg := "call failure" 35 36 apiCaller := basetesting.APICallerFunc( 37 func(objType string, 38 version int, 39 id, request string, 40 a, result interface{}, 41 ) error { 42 c.Check(objType, gc.Equals, "Storage") 43 c.Check(id, gc.Equals, "") 44 c.Check(request, gc.Equals, "Show") 45 46 args, ok := a.(params.Entities) 47 c.Assert(ok, jc.IsTrue) 48 c.Assert(args.Entities, gc.HasLen, 2) 49 50 if results, k := result.(*params.StorageDetailsResults); k { 51 instances := []params.StorageDetailsResult{ 52 params.StorageDetailsResult{ 53 Result: params.StorageDetails{StorageTag: oneTag.String()}, 54 }, 55 params.StorageDetailsResult{ 56 Result: params.StorageDetails{ 57 StorageTag: twoTag.String(), 58 Status: "attached", 59 Persistent: true, 60 }, 61 }, 62 params.StorageDetailsResult{Error: common.ServerError(errors.New(msg))}, 63 } 64 results.Results = instances 65 } 66 67 return nil 68 }) 69 storageClient := storage.NewClient(apiCaller) 70 tags := []names.StorageTag{oneTag, twoTag} 71 found, err := storageClient.Show(tags) 72 c.Check(errors.Cause(err), gc.ErrorMatches, msg) 73 c.Assert(found, gc.HasLen, 2) 74 c.Assert(expected.Contains(found[0].StorageTag), jc.IsTrue) 75 c.Assert(expected.Contains(found[1].StorageTag), jc.IsTrue) 76 } 77 78 func (s *storageMockSuite) TestShowFacadeCallError(c *gc.C) { 79 one := "shared-fs/0" 80 oneTag := names.NewStorageTag(one) 81 82 msg := "facade failure" 83 apiCaller := basetesting.APICallerFunc( 84 func(objType string, 85 version int, 86 id, request string, 87 a, result interface{}, 88 ) error { 89 c.Check(objType, gc.Equals, "Storage") 90 c.Check(id, gc.Equals, "") 91 c.Check(request, gc.Equals, "Show") 92 93 return errors.New(msg) 94 }) 95 storageClient := storage.NewClient(apiCaller) 96 found, err := storageClient.Show([]names.StorageTag{oneTag}) 97 c.Assert(errors.Cause(err), gc.ErrorMatches, msg) 98 c.Assert(found, gc.HasLen, 0) 99 } 100 101 func (s *storageMockSuite) TestList(c *gc.C) { 102 one := "shared-fs/0" 103 oneTag := names.NewStorageTag(one) 104 two := "db-dir/1000" 105 twoTag := names.NewStorageTag(two) 106 msg := "call failure" 107 108 apiCaller := basetesting.APICallerFunc( 109 func(objType string, 110 version int, 111 id, request string, 112 a, result interface{}, 113 ) error { 114 c.Check(objType, gc.Equals, "Storage") 115 c.Check(id, gc.Equals, "") 116 c.Check(request, gc.Equals, "List") 117 c.Check(a, gc.IsNil) 118 119 if results, k := result.(*params.StorageInfosResult); k { 120 instances := []params.StorageInfo{ 121 params.StorageInfo{ 122 params.StorageDetails{StorageTag: oneTag.String()}, 123 common.ServerError(errors.New(msg)), 124 }, 125 params.StorageInfo{ 126 params.StorageDetails{ 127 StorageTag: twoTag.String(), 128 Status: "attached", 129 Persistent: true, 130 }, 131 nil, 132 }, 133 } 134 results.Results = instances 135 } 136 137 return nil 138 }) 139 storageClient := storage.NewClient(apiCaller) 140 found, err := storageClient.List() 141 c.Check(err, jc.ErrorIsNil) 142 c.Assert(found, gc.HasLen, 2) 143 expected := []params.StorageInfo{ 144 params.StorageInfo{ 145 StorageDetails: params.StorageDetails{ 146 StorageTag: "storage-shared-fs-0"}, 147 Error: ¶ms.Error{Message: msg}, 148 }, 149 params.StorageInfo{ 150 params.StorageDetails{ 151 StorageTag: "storage-db-dir-1000", 152 Status: "attached", 153 Persistent: true}, 154 nil}, 155 } 156 157 c.Assert(found, jc.DeepEquals, expected) 158 } 159 160 func (s *storageMockSuite) TestListFacadeCallError(c *gc.C) { 161 msg := "facade failure" 162 apiCaller := basetesting.APICallerFunc( 163 func(objType string, 164 version int, 165 id, request string, 166 a, result interface{}, 167 ) error { 168 c.Check(objType, gc.Equals, "Storage") 169 c.Check(id, gc.Equals, "") 170 c.Check(request, gc.Equals, "List") 171 172 return errors.New(msg) 173 }) 174 storageClient := storage.NewClient(apiCaller) 175 found, err := storageClient.List() 176 c.Assert(errors.Cause(err), gc.ErrorMatches, msg) 177 c.Assert(found, gc.HasLen, 0) 178 } 179 180 func (s *storageMockSuite) TestListPools(c *gc.C) { 181 expected := []params.StoragePool{ 182 params.StoragePool{Name: "name0", Provider: "type0"}, 183 params.StoragePool{Name: "name1", Provider: "type1"}, 184 params.StoragePool{Name: "name2", Provider: "type2"}, 185 } 186 want := len(expected) 187 188 apiCaller := basetesting.APICallerFunc( 189 func(objType string, 190 version int, 191 id, request string, 192 a, result interface{}, 193 ) error { 194 c.Check(objType, gc.Equals, "Storage") 195 c.Check(id, gc.Equals, "") 196 c.Check(request, gc.Equals, "ListPools") 197 198 args, ok := a.(params.StoragePoolFilter) 199 c.Assert(ok, jc.IsTrue) 200 c.Assert(args.Names, gc.HasLen, 2) 201 c.Assert(args.Providers, gc.HasLen, 1) 202 203 if results, k := result.(*params.StoragePoolsResult); k { 204 instances := make([]params.StoragePool, want) 205 for i := 0; i < want; i++ { 206 instances[i] = params.StoragePool{ 207 Name: fmt.Sprintf("name%v", i), 208 Provider: fmt.Sprintf("type%v", i), 209 } 210 } 211 results.Results = instances 212 } 213 214 return nil 215 }) 216 storageClient := storage.NewClient(apiCaller) 217 names := []string{"a", "b"} 218 types := []string{"1"} 219 found, err := storageClient.ListPools(types, names) 220 c.Assert(err, jc.ErrorIsNil) 221 c.Assert(found, gc.HasLen, want) 222 c.Assert(found, gc.DeepEquals, expected) 223 } 224 225 func (s *storageMockSuite) TestListPoolsFacadeCallError(c *gc.C) { 226 msg := "facade failure" 227 apiCaller := basetesting.APICallerFunc( 228 func(objType string, 229 version int, 230 id, request string, 231 a, result interface{}, 232 ) error { 233 c.Check(objType, gc.Equals, "Storage") 234 c.Check(id, gc.Equals, "") 235 c.Check(request, gc.Equals, "ListPools") 236 237 return errors.New(msg) 238 }) 239 storageClient := storage.NewClient(apiCaller) 240 found, err := storageClient.ListPools(nil, nil) 241 c.Assert(errors.Cause(err), gc.ErrorMatches, msg) 242 c.Assert(found, gc.HasLen, 0) 243 } 244 245 func (s *storageMockSuite) TestCreatePool(c *gc.C) { 246 var called bool 247 poolName := "poolName" 248 poolType := "poolType" 249 poolConfig := map[string]interface{}{ 250 "test": "one", 251 "pass": true, 252 } 253 254 apiCaller := basetesting.APICallerFunc( 255 func(objType string, 256 version int, 257 id, request string, 258 a, result interface{}, 259 ) error { 260 called = true 261 c.Check(objType, gc.Equals, "Storage") 262 c.Check(id, gc.Equals, "") 263 c.Check(request, gc.Equals, "CreatePool") 264 265 args, ok := a.(params.StoragePool) 266 c.Assert(ok, jc.IsTrue) 267 c.Assert(args.Name, gc.Equals, poolName) 268 c.Assert(args.Provider, gc.Equals, poolType) 269 c.Assert(args.Attrs, gc.DeepEquals, poolConfig) 270 271 return nil 272 }) 273 storageClient := storage.NewClient(apiCaller) 274 err := storageClient.CreatePool(poolName, poolType, poolConfig) 275 c.Assert(err, jc.ErrorIsNil) 276 c.Assert(called, jc.IsTrue) 277 } 278 279 func (s *storageMockSuite) TestCreatePoolFacadeCallError(c *gc.C) { 280 msg := "facade failure" 281 apiCaller := basetesting.APICallerFunc( 282 func(objType string, 283 version int, 284 id, request string, 285 a, result interface{}, 286 ) error { 287 c.Check(objType, gc.Equals, "Storage") 288 c.Check(id, gc.Equals, "") 289 c.Check(request, gc.Equals, "CreatePool") 290 291 return errors.New(msg) 292 }) 293 storageClient := storage.NewClient(apiCaller) 294 err := storageClient.CreatePool("", "", nil) 295 c.Assert(errors.Cause(err), gc.ErrorMatches, msg) 296 } 297 298 func (s *storageMockSuite) TestListVolumes(c *gc.C) { 299 var called bool 300 machines := []string{"one", "two"} 301 machineTags := set.NewStrings( 302 names.NewMachineTag(machines[0]).String(), 303 names.NewMachineTag(machines[1]).String(), 304 ) 305 apiCaller := basetesting.APICallerFunc( 306 func(objType string, 307 version int, 308 id, request string, 309 a, result interface{}, 310 ) error { 311 called = true 312 c.Check(objType, gc.Equals, "Storage") 313 c.Check(id, gc.Equals, "") 314 c.Check(request, gc.Equals, "ListVolumes") 315 316 c.Assert(a, gc.FitsTypeOf, params.VolumeFilter{}) 317 args := a.(params.VolumeFilter) 318 c.Assert(args.Machines, gc.HasLen, 2) 319 320 c.Assert(result, gc.FitsTypeOf, ¶ms.VolumeItemsResult{}) 321 results := result.(*params.VolumeItemsResult) 322 attachments := make([]params.VolumeAttachment, len(args.Machines)) 323 for i, m := range args.Machines { 324 attachments[i] = params.VolumeAttachment{ 325 MachineTag: m} 326 } 327 results.Results = []params.VolumeItem{ 328 params.VolumeItem{Attachments: attachments}, 329 } 330 return nil 331 }) 332 storageClient := storage.NewClient(apiCaller) 333 found, err := storageClient.ListVolumes(machines) 334 c.Assert(called, jc.IsTrue) 335 c.Assert(err, jc.ErrorIsNil) 336 c.Assert(found, gc.HasLen, 1) 337 c.Assert(found[0].Attachments, gc.HasLen, len(machines)) 338 c.Assert(machineTags.Contains(found[0].Attachments[0].MachineTag), jc.IsTrue) 339 c.Assert(machineTags.Contains(found[0].Attachments[1].MachineTag), jc.IsTrue) 340 } 341 342 func (s *storageMockSuite) TestListVolumesEmptyFilter(c *gc.C) { 343 var called bool 344 tag := "ok" 345 apiCaller := basetesting.APICallerFunc( 346 func(objType string, 347 version int, 348 id, request string, 349 a, result interface{}, 350 ) error { 351 called = true 352 c.Check(objType, gc.Equals, "Storage") 353 c.Check(id, gc.Equals, "") 354 c.Check(request, gc.Equals, "ListVolumes") 355 356 c.Assert(a, gc.FitsTypeOf, params.VolumeFilter{}) 357 args := a.(params.VolumeFilter) 358 c.Assert(args.IsEmpty(), jc.IsTrue) 359 360 c.Assert(result, gc.FitsTypeOf, ¶ms.VolumeItemsResult{}) 361 results := result.(*params.VolumeItemsResult) 362 results.Results = []params.VolumeItem{ 363 {Volume: params.VolumeInstance{VolumeTag: tag}}, 364 } 365 return nil 366 }) 367 storageClient := storage.NewClient(apiCaller) 368 found, err := storageClient.ListVolumes(nil) 369 c.Assert(called, jc.IsTrue) 370 c.Assert(err, jc.ErrorIsNil) 371 c.Assert(found, gc.HasLen, 1) 372 c.Assert(found[0].Volume.VolumeTag, gc.Equals, tag) 373 } 374 375 func (s *storageMockSuite) TestListVolumesFacadeCallError(c *gc.C) { 376 msg := "facade failure" 377 apiCaller := basetesting.APICallerFunc( 378 func(objType string, 379 version int, 380 id, request string, 381 a, result interface{}, 382 ) error { 383 c.Check(objType, gc.Equals, "Storage") 384 c.Check(id, gc.Equals, "") 385 c.Check(request, gc.Equals, "ListVolumes") 386 387 return errors.New(msg) 388 }) 389 storageClient := storage.NewClient(apiCaller) 390 _, err := storageClient.ListVolumes(nil) 391 c.Assert(errors.Cause(err), gc.ErrorMatches, msg) 392 } 393 394 func (s *storageMockSuite) TestAddToUnit(c *gc.C) { 395 size := uint64(42) 396 cons := params.StorageConstraints{ 397 Pool: "value", 398 Size: &size, 399 } 400 401 errOut := "error" 402 unitStorages := []params.StorageAddParams{ 403 params.StorageAddParams{UnitTag: "u-a", StorageName: "one", Constraints: cons}, 404 params.StorageAddParams{UnitTag: "u-b", StorageName: errOut, Constraints: cons}, 405 params.StorageAddParams{UnitTag: "u-b", StorageName: "nil-constraints"}, 406 } 407 408 storageN := 3 409 expectedError := common.ServerError(errors.NotValidf("storage directive")) 410 one := func(u, s string, attrs params.StorageConstraints) params.ErrorResult { 411 result := params.ErrorResult{} 412 if s == errOut { 413 result.Error = expectedError 414 } 415 return result 416 } 417 418 apiCaller := basetesting.APICallerFunc( 419 func(objType string, 420 version int, 421 id, request string, 422 a, result interface{}, 423 ) error { 424 c.Check(objType, gc.Equals, "Storage") 425 c.Check(id, gc.Equals, "") 426 c.Check(request, gc.Equals, "AddToUnit") 427 428 args, ok := a.(params.StoragesAddParams) 429 c.Assert(ok, jc.IsTrue) 430 c.Assert(args.Storages, gc.HasLen, storageN) 431 c.Assert(args.Storages, gc.DeepEquals, unitStorages) 432 433 if results, k := result.(*params.ErrorResults); k { 434 out := []params.ErrorResult{} 435 for _, s := range args.Storages { 436 out = append(out, one(s.UnitTag, s.StorageName, s.Constraints)) 437 } 438 results.Results = out 439 } 440 441 return nil 442 }) 443 storageClient := storage.NewClient(apiCaller) 444 r, err := storageClient.AddToUnit(unitStorages) 445 c.Assert(err, jc.ErrorIsNil) 446 c.Assert(r, gc.HasLen, storageN) 447 expected := []params.ErrorResult{ 448 {nil}, 449 {expectedError}, 450 {nil}, 451 } 452 c.Assert(r, jc.SameContents, expected) 453 } 454 455 func (s *storageMockSuite) TestAddToUnitFacadeCallError(c *gc.C) { 456 unitStorages := []params.StorageAddParams{ 457 params.StorageAddParams{UnitTag: "u-a", StorageName: "one"}, 458 } 459 460 msg := "facade failure" 461 apiCaller := basetesting.APICallerFunc( 462 func(objType string, 463 version int, 464 id, request string, 465 a, result interface{}, 466 ) error { 467 c.Check(objType, gc.Equals, "Storage") 468 c.Check(id, gc.Equals, "") 469 c.Check(request, gc.Equals, "AddToUnit") 470 return errors.New(msg) 471 }) 472 storageClient := storage.NewClient(apiCaller) 473 found, err := storageClient.AddToUnit(unitStorages) 474 c.Assert(errors.Cause(err), gc.ErrorMatches, msg) 475 c.Assert(found, gc.HasLen, 0) 476 }