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: &params.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, &params.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, &params.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  }