github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/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  	jc "github.com/juju/testing/checkers"
    11  	"github.com/juju/utils/set"
    12  	gc "gopkg.in/check.v1"
    13  	"gopkg.in/juju/names.v2"
    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: &params.StorageDetails{StorageTag: oneTag.String()},
    54  					},
    55  					params.StorageDetailsResult{
    56  						Result: &params.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, &params.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, &params.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, &params.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, &params.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, &params.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  }