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: &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.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: &params.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: &params.Error{Message: msg},
   144  	}, {
   145  		Result: &params.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, &params.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, &params.VolumeDetailsResults{})
   358  			results := result.(*params.VolumeDetailsResults)
   359  			results.Results = []params.VolumeDetailsResult{
   360  				{LegacyVolume: &params.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, &params.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  }