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