github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/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) TestStorageDetails(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, "StorageDetails") 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: ¶ms.StorageDetails{StorageTag: oneTag.String()}, 54 }, 55 params.StorageDetailsResult{ 56 Result: ¶ms.StorageDetails{ 57 StorageTag: twoTag.String(), 58 Status: params.EntityStatus{ 59 Status: "attached", 60 }, 61 Persistent: true, 62 }, 63 }, 64 params.StorageDetailsResult{ 65 Error: common.ServerError(errors.New(msg)), 66 }, 67 } 68 results.Results = instances 69 } 70 71 return nil 72 }) 73 storageClient := storage.NewClient(apiCaller) 74 tags := []names.StorageTag{oneTag, twoTag} 75 found, err := storageClient.StorageDetails(tags) 76 c.Assert(err, jc.ErrorIsNil) 77 c.Assert(found, gc.HasLen, 3) 78 c.Assert(expected.Contains(found[0].Result.StorageTag), jc.IsTrue) 79 c.Assert(expected.Contains(found[1].Result.StorageTag), jc.IsTrue) 80 c.Assert(found[2].Error, gc.ErrorMatches, msg) 81 } 82 83 func (s *storageMockSuite) TestStorageDetailsFacadeCallError(c *gc.C) { 84 one := "shared-fs/0" 85 oneTag := names.NewStorageTag(one) 86 87 msg := "facade failure" 88 apiCaller := basetesting.APICallerFunc( 89 func(objType string, 90 version int, 91 id, request string, 92 a, result interface{}, 93 ) error { 94 c.Check(objType, gc.Equals, "Storage") 95 c.Check(id, gc.Equals, "") 96 c.Check(request, gc.Equals, "StorageDetails") 97 98 return errors.New(msg) 99 }) 100 storageClient := storage.NewClient(apiCaller) 101 found, err := storageClient.StorageDetails([]names.StorageTag{oneTag}) 102 c.Assert(errors.Cause(err), gc.ErrorMatches, msg) 103 c.Assert(found, gc.HasLen, 0) 104 } 105 106 func (s *storageMockSuite) TestListStorageDetails(c *gc.C) { 107 storageTag := names.NewStorageTag("db-dir/1000") 108 109 apiCaller := basetesting.APICallerFunc( 110 func(objType string, 111 version int, 112 id, request string, 113 a, result interface{}, 114 ) error { 115 c.Check(objType, gc.Equals, "Storage") 116 c.Check(id, gc.Equals, "") 117 c.Check(request, gc.Equals, "ListStorageDetails") 118 c.Check(a, jc.DeepEquals, params.StorageFilters{ 119 []params.StorageFilter{{}}, 120 }) 121 122 c.Assert(result, gc.FitsTypeOf, ¶ms.StorageDetailsListResults{}) 123 results := result.(*params.StorageDetailsListResults) 124 results.Results = []params.StorageDetailsListResult{{ 125 Result: []params.StorageDetails{{ 126 StorageTag: storageTag.String(), 127 Status: params.EntityStatus{ 128 Status: "attached", 129 }, 130 Persistent: true, 131 }}, 132 }} 133 134 return nil 135 }, 136 ) 137 storageClient := storage.NewClient(apiCaller) 138 found, err := storageClient.ListStorageDetails() 139 c.Check(err, jc.ErrorIsNil) 140 c.Assert(found, gc.HasLen, 1) 141 expected := []params.StorageDetails{{ 142 StorageTag: "storage-db-dir-1000", 143 Status: params.EntityStatus{ 144 Status: "attached", 145 }, 146 Persistent: true, 147 }} 148 149 c.Assert(found, jc.DeepEquals, expected) 150 } 151 152 func (s *storageMockSuite) TestListStorageDetailsFacadeCallError(c *gc.C) { 153 msg := "facade failure" 154 apiCaller := basetesting.APICallerFunc( 155 func(objType string, 156 version int, 157 id, request string, 158 a, result interface{}, 159 ) error { 160 c.Check(objType, gc.Equals, "Storage") 161 c.Check(id, gc.Equals, "") 162 c.Check(request, gc.Equals, "ListStorageDetails") 163 164 return errors.New(msg) 165 }) 166 storageClient := storage.NewClient(apiCaller) 167 found, err := storageClient.ListStorageDetails() 168 c.Assert(errors.Cause(err), gc.ErrorMatches, msg) 169 c.Assert(found, gc.HasLen, 0) 170 } 171 172 func (s *storageMockSuite) TestListPools(c *gc.C) { 173 expected := []params.StoragePool{ 174 params.StoragePool{Name: "name0", Provider: "type0"}, 175 params.StoragePool{Name: "name1", Provider: "type1"}, 176 params.StoragePool{Name: "name2", Provider: "type2"}, 177 } 178 want := len(expected) 179 180 apiCaller := basetesting.APICallerFunc( 181 func(objType string, 182 version int, 183 id, request string, 184 a, result interface{}, 185 ) error { 186 c.Check(objType, gc.Equals, "Storage") 187 c.Check(id, gc.Equals, "") 188 c.Check(request, gc.Equals, "ListPools") 189 190 args := a.(params.StoragePoolFilters) 191 c.Assert(args.Filters, gc.HasLen, 1) 192 c.Assert(args.Filters[0].Names, gc.HasLen, 2) 193 c.Assert(args.Filters[0].Providers, gc.HasLen, 1) 194 195 results := result.(*params.StoragePoolsResults) 196 pools := make([]params.StoragePool, want) 197 for i := 0; i < want; i++ { 198 pools[i] = params.StoragePool{ 199 Name: fmt.Sprintf("name%v", i), 200 Provider: fmt.Sprintf("type%v", i), 201 } 202 } 203 results.Results = []params.StoragePoolsResult{{ 204 Result: pools, 205 }} 206 207 return nil 208 }) 209 storageClient := storage.NewClient(apiCaller) 210 names := []string{"a", "b"} 211 types := []string{"1"} 212 found, err := storageClient.ListPools(types, names) 213 c.Assert(err, jc.ErrorIsNil) 214 c.Assert(found, gc.HasLen, want) 215 c.Assert(found, gc.DeepEquals, expected) 216 } 217 218 func (s *storageMockSuite) TestListPoolsFacadeCallError(c *gc.C) { 219 msg := "facade failure" 220 apiCaller := basetesting.APICallerFunc( 221 func(objType string, 222 version int, 223 id, request string, 224 a, result interface{}, 225 ) error { 226 c.Check(objType, gc.Equals, "Storage") 227 c.Check(id, gc.Equals, "") 228 c.Check(request, gc.Equals, "ListPools") 229 230 return errors.New(msg) 231 }) 232 storageClient := storage.NewClient(apiCaller) 233 found, err := storageClient.ListPools(nil, nil) 234 c.Assert(errors.Cause(err), gc.ErrorMatches, msg) 235 c.Assert(found, gc.HasLen, 0) 236 } 237 238 func (s *storageMockSuite) TestCreatePool(c *gc.C) { 239 var called bool 240 poolName := "poolName" 241 poolType := "poolType" 242 poolConfig := map[string]interface{}{ 243 "test": "one", 244 "pass": true, 245 } 246 247 apiCaller := basetesting.APICallerFunc( 248 func(objType string, 249 version int, 250 id, request string, 251 a, result interface{}, 252 ) error { 253 called = true 254 c.Check(objType, gc.Equals, "Storage") 255 c.Check(id, gc.Equals, "") 256 c.Check(request, gc.Equals, "CreatePool") 257 258 args, ok := a.(params.StoragePool) 259 c.Assert(ok, jc.IsTrue) 260 c.Assert(args.Name, gc.Equals, poolName) 261 c.Assert(args.Provider, gc.Equals, poolType) 262 c.Assert(args.Attrs, gc.DeepEquals, poolConfig) 263 264 return nil 265 }) 266 storageClient := storage.NewClient(apiCaller) 267 err := storageClient.CreatePool(poolName, poolType, poolConfig) 268 c.Assert(err, jc.ErrorIsNil) 269 c.Assert(called, jc.IsTrue) 270 } 271 272 func (s *storageMockSuite) TestCreatePoolFacadeCallError(c *gc.C) { 273 msg := "facade failure" 274 apiCaller := basetesting.APICallerFunc( 275 func(objType string, 276 version int, 277 id, request string, 278 a, result interface{}, 279 ) error { 280 c.Check(objType, gc.Equals, "Storage") 281 c.Check(id, gc.Equals, "") 282 c.Check(request, gc.Equals, "CreatePool") 283 284 return errors.New(msg) 285 }) 286 storageClient := storage.NewClient(apiCaller) 287 err := storageClient.CreatePool("", "", nil) 288 c.Assert(errors.Cause(err), gc.ErrorMatches, msg) 289 } 290 291 func (s *storageMockSuite) TestListVolumes(c *gc.C) { 292 var called bool 293 machines := []string{"0", "1"} 294 apiCaller := basetesting.APICallerFunc( 295 func(objType string, 296 version int, 297 id, request string, 298 a, result interface{}, 299 ) error { 300 called = true 301 c.Check(objType, gc.Equals, "Storage") 302 c.Check(id, gc.Equals, "") 303 c.Check(request, gc.Equals, "ListVolumes") 304 305 c.Assert(a, gc.FitsTypeOf, params.VolumeFilters{}) 306 args := a.(params.VolumeFilters) 307 c.Assert(args.Filters, gc.HasLen, 2) 308 c.Assert(args.Filters[0].Machines, jc.DeepEquals, []string{"machine-0"}) 309 c.Assert(args.Filters[1].Machines, jc.DeepEquals, []string{"machine-1"}) 310 311 c.Assert(result, gc.FitsTypeOf, ¶ms.VolumeDetailsListResults{}) 312 results := result.(*params.VolumeDetailsListResults) 313 314 details := params.VolumeDetails{ 315 VolumeTag: "volume-0", 316 MachineAttachments: map[string]params.VolumeAttachmentInfo{ 317 "machine-0": params.VolumeAttachmentInfo{}, 318 "machine-1": params.VolumeAttachmentInfo{}, 319 }, 320 } 321 results.Results = []params.VolumeDetailsListResult{{ 322 Result: []params.VolumeDetails{details}, 323 }, { 324 Result: []params.VolumeDetails{details}, 325 }} 326 return nil 327 }) 328 storageClient := storage.NewClient(apiCaller) 329 found, err := storageClient.ListVolumes(machines) 330 c.Assert(called, jc.IsTrue) 331 c.Assert(err, jc.ErrorIsNil) 332 c.Assert(found, gc.HasLen, 2) 333 for i := 0; i < 2; i++ { 334 c.Assert(found[i].Result, jc.DeepEquals, []params.VolumeDetails{{ 335 VolumeTag: "volume-0", 336 MachineAttachments: map[string]params.VolumeAttachmentInfo{ 337 "machine-0": params.VolumeAttachmentInfo{}, 338 "machine-1": params.VolumeAttachmentInfo{}, 339 }, 340 }}) 341 } 342 } 343 344 func (s *storageMockSuite) TestListVolumesEmptyFilter(c *gc.C) { 345 var called bool 346 tag := "ok" 347 apiCaller := basetesting.APICallerFunc( 348 func(objType string, 349 version int, 350 id, request string, 351 a, result interface{}, 352 ) error { 353 called = true 354 c.Check(objType, gc.Equals, "Storage") 355 c.Check(id, gc.Equals, "") 356 c.Check(request, gc.Equals, "ListVolumes") 357 358 c.Assert(a, gc.FitsTypeOf, params.VolumeFilters{}) 359 args := a.(params.VolumeFilters) 360 c.Assert(args.Filters, gc.HasLen, 1) 361 c.Assert(args.Filters[0].IsEmpty(), jc.IsTrue) 362 363 c.Assert(result, gc.FitsTypeOf, ¶ms.VolumeDetailsListResults{}) 364 results := result.(*params.VolumeDetailsListResults) 365 results.Results = []params.VolumeDetailsListResult{ 366 {Result: []params.VolumeDetails{{VolumeTag: tag}}}, 367 } 368 return nil 369 }, 370 ) 371 storageClient := storage.NewClient(apiCaller) 372 found, err := storageClient.ListVolumes(nil) 373 c.Assert(called, jc.IsTrue) 374 c.Assert(err, jc.ErrorIsNil) 375 c.Assert(found, gc.HasLen, 1) 376 c.Assert(found[0].Result, gc.HasLen, 1) 377 c.Assert(found[0].Result[0].VolumeTag, gc.Equals, tag) 378 } 379 380 func (s *storageMockSuite) TestListVolumesFacadeCallError(c *gc.C) { 381 msg := "facade failure" 382 apiCaller := basetesting.APICallerFunc( 383 func(objType string, 384 version int, 385 id, request string, 386 a, result interface{}, 387 ) error { 388 c.Check(objType, gc.Equals, "Storage") 389 c.Check(id, gc.Equals, "") 390 c.Check(request, gc.Equals, "ListVolumes") 391 392 return errors.New(msg) 393 }) 394 storageClient := storage.NewClient(apiCaller) 395 _, err := storageClient.ListVolumes(nil) 396 c.Assert(errors.Cause(err), gc.ErrorMatches, msg) 397 } 398 399 func (s *storageMockSuite) TestListFilesystems(c *gc.C) { 400 expected := params.FilesystemDetails{ 401 FilesystemTag: "filesystem-1", 402 Info: params.FilesystemInfo{ 403 FilesystemId: "fs-id", 404 Size: 4096, 405 }, 406 Status: params.EntityStatus{ 407 Status: "attached", 408 }, 409 MachineAttachments: map[string]params.FilesystemAttachmentInfo{ 410 "0": params.FilesystemAttachmentInfo{ 411 MountPoint: "/mnt/kinabalu", 412 ReadOnly: false, 413 }, 414 }, 415 } 416 417 apiCaller := basetesting.APICallerFunc( 418 func(objType string, 419 version int, 420 id, request string, 421 a, result interface{}, 422 ) error { 423 c.Check(objType, gc.Equals, "Storage") 424 c.Check(id, gc.Equals, "") 425 c.Check(request, gc.Equals, "ListFilesystems") 426 427 c.Assert(a, gc.FitsTypeOf, params.FilesystemFilters{}) 428 args := a.(params.FilesystemFilters) 429 c.Assert(args.Filters, jc.DeepEquals, []params.FilesystemFilter{{ 430 Machines: []string{"machine-1"}, 431 }, { 432 Machines: []string{"machine-2"}, 433 }}) 434 435 c.Assert(result, gc.FitsTypeOf, ¶ms.FilesystemDetailsListResults{}) 436 results := result.(*params.FilesystemDetailsListResults) 437 results.Results = []params.FilesystemDetailsListResult{{ 438 Result: []params.FilesystemDetails{expected}, 439 }, {}} 440 return nil 441 }, 442 ) 443 storageClient := storage.NewClient(apiCaller) 444 found, err := storageClient.ListFilesystems([]string{"1", "2"}) 445 c.Assert(err, jc.ErrorIsNil) 446 c.Assert(found, gc.HasLen, 2) 447 c.Assert(found[0].Result, jc.DeepEquals, []params.FilesystemDetails{expected}) 448 c.Assert(found[1].Result, jc.DeepEquals, []params.FilesystemDetails{}) 449 } 450 451 func (s *storageMockSuite) TestListFilesystemsEmptyFilter(c *gc.C) { 452 var called bool 453 apiCaller := basetesting.APICallerFunc( 454 func(objType string, 455 version int, 456 id, request string, 457 a, result interface{}, 458 ) error { 459 called = true 460 c.Check(objType, gc.Equals, "Storage") 461 c.Check(id, gc.Equals, "") 462 c.Check(request, gc.Equals, "ListFilesystems") 463 464 c.Assert(a, gc.FitsTypeOf, params.FilesystemFilters{}) 465 args := a.(params.FilesystemFilters) 466 c.Assert(args.Filters, gc.HasLen, 1) 467 c.Assert(args.Filters[0].IsEmpty(), jc.IsTrue) 468 469 c.Assert(result, gc.FitsTypeOf, ¶ms.FilesystemDetailsListResults{}) 470 results := result.(*params.FilesystemDetailsListResults) 471 results.Results = []params.FilesystemDetailsListResult{{}} 472 473 return nil 474 }, 475 ) 476 storageClient := storage.NewClient(apiCaller) 477 _, err := storageClient.ListFilesystems(nil) 478 c.Assert(called, jc.IsTrue) 479 c.Assert(err, jc.ErrorIsNil) 480 } 481 482 func (s *storageMockSuite) TestListFilesystemsFacadeCallError(c *gc.C) { 483 msg := "facade failure" 484 apiCaller := basetesting.APICallerFunc( 485 func(objType string, 486 version int, 487 id, request string, 488 a, result interface{}, 489 ) error { 490 c.Check(objType, gc.Equals, "Storage") 491 c.Check(id, gc.Equals, "") 492 c.Check(request, gc.Equals, "ListFilesystems") 493 494 return errors.New(msg) 495 }) 496 storageClient := storage.NewClient(apiCaller) 497 _, err := storageClient.ListFilesystems(nil) 498 c.Assert(errors.Cause(err), gc.ErrorMatches, msg) 499 } 500 501 func (s *storageMockSuite) TestAddToUnit(c *gc.C) { 502 size := uint64(42) 503 cons := params.StorageConstraints{ 504 Pool: "value", 505 Size: &size, 506 } 507 508 errOut := "error" 509 unitStorages := []params.StorageAddParams{ 510 params.StorageAddParams{UnitTag: "u-a", StorageName: "one", Constraints: cons}, 511 params.StorageAddParams{UnitTag: "u-b", StorageName: errOut, Constraints: cons}, 512 params.StorageAddParams{UnitTag: "u-b", StorageName: "nil-constraints"}, 513 } 514 515 storageN := 3 516 expectedError := common.ServerError(errors.NotValidf("storage directive")) 517 one := func(u, s string, attrs params.StorageConstraints) params.ErrorResult { 518 result := params.ErrorResult{} 519 if s == errOut { 520 result.Error = expectedError 521 } 522 return result 523 } 524 525 apiCaller := basetesting.APICallerFunc( 526 func(objType string, 527 version int, 528 id, request string, 529 a, result interface{}, 530 ) error { 531 c.Check(objType, gc.Equals, "Storage") 532 c.Check(id, gc.Equals, "") 533 c.Check(request, gc.Equals, "AddToUnit") 534 535 args, ok := a.(params.StoragesAddParams) 536 c.Assert(ok, jc.IsTrue) 537 c.Assert(args.Storages, gc.HasLen, storageN) 538 c.Assert(args.Storages, gc.DeepEquals, unitStorages) 539 540 if results, k := result.(*params.ErrorResults); k { 541 out := []params.ErrorResult{} 542 for _, s := range args.Storages { 543 out = append(out, one(s.UnitTag, s.StorageName, s.Constraints)) 544 } 545 results.Results = out 546 } 547 548 return nil 549 }) 550 storageClient := storage.NewClient(apiCaller) 551 r, err := storageClient.AddToUnit(unitStorages) 552 c.Assert(err, jc.ErrorIsNil) 553 c.Assert(r, gc.HasLen, storageN) 554 expected := []params.ErrorResult{ 555 {nil}, 556 {expectedError}, 557 {nil}, 558 } 559 c.Assert(r, jc.SameContents, expected) 560 } 561 562 func (s *storageMockSuite) TestAddToUnitFacadeCallError(c *gc.C) { 563 unitStorages := []params.StorageAddParams{ 564 params.StorageAddParams{UnitTag: "u-a", StorageName: "one"}, 565 } 566 567 msg := "facade failure" 568 apiCaller := basetesting.APICallerFunc( 569 func(objType string, 570 version int, 571 id, request string, 572 a, result interface{}, 573 ) error { 574 c.Check(objType, gc.Equals, "Storage") 575 c.Check(id, gc.Equals, "") 576 c.Check(request, gc.Equals, "AddToUnit") 577 return errors.New(msg) 578 }) 579 storageClient := storage.NewClient(apiCaller) 580 found, err := storageClient.AddToUnit(unitStorages) 581 c.Assert(errors.Cause(err), gc.ErrorMatches, msg) 582 c.Assert(found, gc.HasLen, 0) 583 }