github.com/cloud-green/juju@v0.0.0-20151002100041-a00291338d3d/api/storageprovisioner/provisioner_test.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package storageprovisioner_test
     5  
     6  import (
     7  	"errors"
     8  
     9  	"github.com/juju/names"
    10  	jc "github.com/juju/testing/checkers"
    11  	gc "gopkg.in/check.v1"
    12  
    13  	"github.com/juju/juju/api/base/testing"
    14  	"github.com/juju/juju/api/storageprovisioner"
    15  	"github.com/juju/juju/apiserver/params"
    16  	"github.com/juju/juju/storage"
    17  	coretesting "github.com/juju/juju/testing"
    18  )
    19  
    20  var _ = gc.Suite(&provisionerSuite{})
    21  
    22  type provisionerSuite struct {
    23  	coretesting.BaseSuite
    24  }
    25  
    26  func (s *provisionerSuite) TestNewState(c *gc.C) {
    27  	apiCaller := testing.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error {
    28  		return nil
    29  	})
    30  
    31  	st := storageprovisioner.NewState(apiCaller, names.NewMachineTag("123"))
    32  	c.Assert(st, gc.NotNil)
    33  	st = storageprovisioner.NewState(apiCaller, names.NewEnvironTag("87927ace-9e41-4fd5-8103-1a6fb5ff7eb4"))
    34  	c.Assert(st, gc.NotNil)
    35  	c.Assert(func() {
    36  		storageprovisioner.NewState(apiCaller, names.NewUnitTag("mysql/0"))
    37  	}, gc.PanicMatches, "expected EnvironTag or MachineTag, got names.UnitTag")
    38  }
    39  
    40  func (s *provisionerSuite) TestWatchVolumes(c *gc.C) {
    41  	var callCount int
    42  	apiCaller := testing.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error {
    43  		c.Check(objType, gc.Equals, "StorageProvisioner")
    44  		c.Check(version, gc.Equals, 0)
    45  		c.Check(id, gc.Equals, "")
    46  		c.Check(request, gc.Equals, "WatchVolumes")
    47  		c.Assert(result, gc.FitsTypeOf, &params.StringsWatchResults{})
    48  		*(result.(*params.StringsWatchResults)) = params.StringsWatchResults{
    49  			Results: []params.StringsWatchResult{{
    50  				Error: &params.Error{Message: "FAIL"},
    51  			}},
    52  		}
    53  		callCount++
    54  		return nil
    55  	})
    56  
    57  	st := storageprovisioner.NewState(apiCaller, names.NewMachineTag("123"))
    58  	_, err := st.WatchVolumes()
    59  	c.Check(err, gc.ErrorMatches, "FAIL")
    60  	c.Check(callCount, gc.Equals, 1)
    61  }
    62  
    63  func (s *provisionerSuite) TestWatchFilesystems(c *gc.C) {
    64  	var callCount int
    65  	apiCaller := testing.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error {
    66  		c.Check(objType, gc.Equals, "StorageProvisioner")
    67  		c.Check(version, gc.Equals, 0)
    68  		c.Check(id, gc.Equals, "")
    69  		c.Check(request, gc.Equals, "WatchFilesystems")
    70  		c.Assert(result, gc.FitsTypeOf, &params.StringsWatchResults{})
    71  		*(result.(*params.StringsWatchResults)) = params.StringsWatchResults{
    72  			Results: []params.StringsWatchResult{{
    73  				Error: &params.Error{Message: "FAIL"},
    74  			}},
    75  		}
    76  		callCount++
    77  		return nil
    78  	})
    79  
    80  	st := storageprovisioner.NewState(apiCaller, names.NewMachineTag("123"))
    81  	_, err := st.WatchFilesystems()
    82  	c.Check(err, gc.ErrorMatches, "FAIL")
    83  	c.Check(callCount, gc.Equals, 1)
    84  }
    85  
    86  func (s *provisionerSuite) TestWatchVolumeAttachments(c *gc.C) {
    87  	var callCount int
    88  	apiCaller := testing.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error {
    89  		c.Check(objType, gc.Equals, "StorageProvisioner")
    90  		c.Check(version, gc.Equals, 0)
    91  		c.Check(id, gc.Equals, "")
    92  		c.Check(request, gc.Equals, "WatchVolumeAttachments")
    93  		c.Assert(result, gc.FitsTypeOf, &params.MachineStorageIdsWatchResults{})
    94  		*(result.(*params.MachineStorageIdsWatchResults)) = params.MachineStorageIdsWatchResults{
    95  			Results: []params.MachineStorageIdsWatchResult{{
    96  				Error: &params.Error{Message: "FAIL"},
    97  			}},
    98  		}
    99  		callCount++
   100  		return nil
   101  	})
   102  
   103  	st := storageprovisioner.NewState(apiCaller, names.NewMachineTag("123"))
   104  	_, err := st.WatchVolumeAttachments()
   105  	c.Check(err, gc.ErrorMatches, "FAIL")
   106  	c.Check(callCount, gc.Equals, 1)
   107  }
   108  
   109  func (s *provisionerSuite) TestWatchFilesystemAttachments(c *gc.C) {
   110  	var callCount int
   111  	apiCaller := testing.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error {
   112  		c.Check(objType, gc.Equals, "StorageProvisioner")
   113  		c.Check(version, gc.Equals, 0)
   114  		c.Check(id, gc.Equals, "")
   115  		c.Check(request, gc.Equals, "WatchFilesystemAttachments")
   116  		c.Assert(result, gc.FitsTypeOf, &params.MachineStorageIdsWatchResults{})
   117  		*(result.(*params.MachineStorageIdsWatchResults)) = params.MachineStorageIdsWatchResults{
   118  			Results: []params.MachineStorageIdsWatchResult{{
   119  				Error: &params.Error{Message: "FAIL"},
   120  			}},
   121  		}
   122  		callCount++
   123  		return nil
   124  	})
   125  
   126  	st := storageprovisioner.NewState(apiCaller, names.NewMachineTag("123"))
   127  	_, err := st.WatchFilesystemAttachments()
   128  	c.Check(err, gc.ErrorMatches, "FAIL")
   129  	c.Check(callCount, gc.Equals, 1)
   130  }
   131  
   132  func (s *provisionerSuite) TestWatchBlockDevices(c *gc.C) {
   133  	apiCaller := testing.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error {
   134  		c.Check(objType, gc.Equals, "StorageProvisioner")
   135  		c.Check(version, gc.Equals, 0)
   136  		c.Check(id, gc.Equals, "")
   137  		c.Check(request, gc.Equals, "WatchBlockDevices")
   138  		c.Assert(arg, gc.DeepEquals, params.Entities{
   139  			Entities: []params.Entity{{"machine-123"}},
   140  		})
   141  		c.Assert(result, gc.FitsTypeOf, &params.NotifyWatchResults{})
   142  		*(result.(*params.NotifyWatchResults)) = params.NotifyWatchResults{
   143  			Results: []params.NotifyWatchResult{{
   144  				Error: &params.Error{Message: "FAIL"},
   145  			}},
   146  		}
   147  		return nil
   148  	})
   149  
   150  	st := storageprovisioner.NewState(apiCaller, names.NewMachineTag("123"))
   151  	_, err := st.WatchBlockDevices(names.NewMachineTag("123"))
   152  	c.Check(err, gc.ErrorMatches, "FAIL")
   153  }
   154  
   155  func (s *provisionerSuite) TestVolumes(c *gc.C) {
   156  	var callCount int
   157  	apiCaller := testing.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error {
   158  		c.Check(objType, gc.Equals, "StorageProvisioner")
   159  		c.Check(version, gc.Equals, 0)
   160  		c.Check(id, gc.Equals, "")
   161  		c.Check(request, gc.Equals, "Volumes")
   162  		c.Check(arg, gc.DeepEquals, params.Entities{Entities: []params.Entity{{"volume-100"}}})
   163  		c.Assert(result, gc.FitsTypeOf, &params.VolumeResults{})
   164  		*(result.(*params.VolumeResults)) = params.VolumeResults{
   165  			Results: []params.VolumeResult{{
   166  				Result: params.Volume{
   167  					VolumeTag: "volume-100",
   168  					Info: params.VolumeInfo{
   169  						VolumeId:   "volume-id",
   170  						HardwareId: "abc",
   171  						Size:       1024,
   172  					},
   173  				},
   174  			}},
   175  		}
   176  		callCount++
   177  		return nil
   178  	})
   179  
   180  	st := storageprovisioner.NewState(apiCaller, names.NewMachineTag("123"))
   181  	volumes, err := st.Volumes([]names.VolumeTag{names.NewVolumeTag("100")})
   182  	c.Check(err, jc.ErrorIsNil)
   183  	c.Check(callCount, gc.Equals, 1)
   184  	c.Assert(volumes, jc.DeepEquals, []params.VolumeResult{{
   185  		Result: params.Volume{
   186  			VolumeTag: "volume-100",
   187  			Info: params.VolumeInfo{
   188  				VolumeId:   "volume-id",
   189  				HardwareId: "abc",
   190  				Size:       1024,
   191  			},
   192  		},
   193  	}})
   194  }
   195  
   196  func (s *provisionerSuite) TestFilesystems(c *gc.C) {
   197  	var callCount int
   198  	apiCaller := testing.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error {
   199  		c.Check(objType, gc.Equals, "StorageProvisioner")
   200  		c.Check(version, gc.Equals, 0)
   201  		c.Check(id, gc.Equals, "")
   202  		c.Check(request, gc.Equals, "Filesystems")
   203  		c.Check(arg, gc.DeepEquals, params.Entities{Entities: []params.Entity{{"filesystem-100"}}})
   204  		c.Assert(result, gc.FitsTypeOf, &params.FilesystemResults{})
   205  		*(result.(*params.FilesystemResults)) = params.FilesystemResults{
   206  			Results: []params.FilesystemResult{{
   207  				Result: params.Filesystem{
   208  					FilesystemTag: "filesystem-100",
   209  					Info: params.FilesystemInfo{
   210  						FilesystemId: "filesystem-id",
   211  						Size:         1024,
   212  					},
   213  				},
   214  			}},
   215  		}
   216  		callCount++
   217  		return nil
   218  	})
   219  
   220  	st := storageprovisioner.NewState(apiCaller, names.NewMachineTag("123"))
   221  	filesystems, err := st.Filesystems([]names.FilesystemTag{names.NewFilesystemTag("100")})
   222  	c.Check(err, jc.ErrorIsNil)
   223  	c.Check(callCount, gc.Equals, 1)
   224  	c.Assert(filesystems, jc.DeepEquals, []params.FilesystemResult{{
   225  		Result: params.Filesystem{
   226  			FilesystemTag: "filesystem-100",
   227  			Info: params.FilesystemInfo{
   228  				FilesystemId: "filesystem-id",
   229  				Size:         1024,
   230  			},
   231  		},
   232  	}})
   233  }
   234  
   235  func (s *provisionerSuite) TestVolumeAttachments(c *gc.C) {
   236  	volumeAttachmentResults := []params.VolumeAttachmentResult{{
   237  		Result: params.VolumeAttachment{
   238  			MachineTag: "machine-100",
   239  			VolumeTag:  "volume-100",
   240  			Info: params.VolumeAttachmentInfo{
   241  				DeviceName: "xvdf1",
   242  			},
   243  		},
   244  	}}
   245  
   246  	var callCount int
   247  	apiCaller := testing.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error {
   248  		c.Check(objType, gc.Equals, "StorageProvisioner")
   249  		c.Check(version, gc.Equals, 0)
   250  		c.Check(id, gc.Equals, "")
   251  		c.Check(request, gc.Equals, "VolumeAttachments")
   252  		c.Check(arg, gc.DeepEquals, params.MachineStorageIds{
   253  			Ids: []params.MachineStorageId{{
   254  				MachineTag: "machine-100", AttachmentTag: "volume-100",
   255  			}},
   256  		})
   257  		c.Assert(result, gc.FitsTypeOf, &params.VolumeAttachmentResults{})
   258  		*(result.(*params.VolumeAttachmentResults)) = params.VolumeAttachmentResults{
   259  			Results: volumeAttachmentResults,
   260  		}
   261  		callCount++
   262  		return nil
   263  	})
   264  
   265  	st := storageprovisioner.NewState(apiCaller, names.NewMachineTag("123"))
   266  	volumes, err := st.VolumeAttachments([]params.MachineStorageId{{
   267  		MachineTag: "machine-100", AttachmentTag: "volume-100",
   268  	}})
   269  	c.Check(err, jc.ErrorIsNil)
   270  	c.Check(callCount, gc.Equals, 1)
   271  	c.Assert(volumes, jc.DeepEquals, volumeAttachmentResults)
   272  }
   273  
   274  func (s *provisionerSuite) TestVolumeBlockDevices(c *gc.C) {
   275  	blockDeviceResults := []params.BlockDeviceResult{{
   276  		Result: storage.BlockDevice{
   277  			DeviceName: "xvdf1",
   278  			HardwareId: "kjlaksjdlasjdklasd123123",
   279  			Size:       1024,
   280  		},
   281  	}}
   282  
   283  	apiCaller := testing.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error {
   284  		c.Check(objType, gc.Equals, "StorageProvisioner")
   285  		c.Check(version, gc.Equals, 0)
   286  		c.Check(id, gc.Equals, "")
   287  		c.Check(request, gc.Equals, "VolumeBlockDevices")
   288  		c.Check(arg, gc.DeepEquals, params.MachineStorageIds{
   289  			Ids: []params.MachineStorageId{{
   290  				MachineTag: "machine-100", AttachmentTag: "volume-100",
   291  			}},
   292  		})
   293  		c.Assert(result, gc.FitsTypeOf, &params.BlockDeviceResults{})
   294  		*(result.(*params.BlockDeviceResults)) = params.BlockDeviceResults{
   295  			Results: blockDeviceResults,
   296  		}
   297  		return nil
   298  	})
   299  
   300  	st := storageprovisioner.NewState(apiCaller, names.NewMachineTag("123"))
   301  	volumes, err := st.VolumeBlockDevices([]params.MachineStorageId{{
   302  		MachineTag: "machine-100", AttachmentTag: "volume-100",
   303  	}})
   304  	c.Check(err, jc.ErrorIsNil)
   305  	c.Assert(volumes, jc.DeepEquals, blockDeviceResults)
   306  }
   307  
   308  func (s *provisionerSuite) TestFilesystemAttachments(c *gc.C) {
   309  	filesystemAttachmentResults := []params.FilesystemAttachmentResult{{
   310  		Result: params.FilesystemAttachment{
   311  			MachineTag:    "machine-100",
   312  			FilesystemTag: "filesystem-100",
   313  			Info: params.FilesystemAttachmentInfo{
   314  				MountPoint: "/srv",
   315  			},
   316  		},
   317  	}}
   318  
   319  	var callCount int
   320  	apiCaller := testing.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error {
   321  		c.Check(objType, gc.Equals, "StorageProvisioner")
   322  		c.Check(version, gc.Equals, 0)
   323  		c.Check(id, gc.Equals, "")
   324  		c.Check(request, gc.Equals, "FilesystemAttachments")
   325  		c.Check(arg, gc.DeepEquals, params.MachineStorageIds{
   326  			Ids: []params.MachineStorageId{{
   327  				MachineTag: "machine-100", AttachmentTag: "filesystem-100",
   328  			}},
   329  		})
   330  		c.Assert(result, gc.FitsTypeOf, &params.FilesystemAttachmentResults{})
   331  		*(result.(*params.FilesystemAttachmentResults)) = params.FilesystemAttachmentResults{
   332  			Results: filesystemAttachmentResults,
   333  		}
   334  		callCount++
   335  		return nil
   336  	})
   337  
   338  	st := storageprovisioner.NewState(apiCaller, names.NewMachineTag("123"))
   339  	filesystems, err := st.FilesystemAttachments([]params.MachineStorageId{{
   340  		MachineTag: "machine-100", AttachmentTag: "filesystem-100",
   341  	}})
   342  	c.Check(err, jc.ErrorIsNil)
   343  	c.Check(callCount, gc.Equals, 1)
   344  	c.Assert(filesystems, jc.DeepEquals, filesystemAttachmentResults)
   345  }
   346  
   347  func (s *provisionerSuite) TestVolumeParams(c *gc.C) {
   348  	var callCount int
   349  	apiCaller := testing.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error {
   350  		c.Check(objType, gc.Equals, "StorageProvisioner")
   351  		c.Check(version, gc.Equals, 0)
   352  		c.Check(id, gc.Equals, "")
   353  		c.Check(request, gc.Equals, "VolumeParams")
   354  		c.Check(arg, gc.DeepEquals, params.Entities{Entities: []params.Entity{{"volume-100"}}})
   355  		c.Assert(result, gc.FitsTypeOf, &params.VolumeParamsResults{})
   356  		*(result.(*params.VolumeParamsResults)) = params.VolumeParamsResults{
   357  			Results: []params.VolumeParamsResult{{
   358  				Result: params.VolumeParams{
   359  					VolumeTag: "volume-100",
   360  					Size:      1024,
   361  					Provider:  "loop",
   362  				},
   363  			}},
   364  		}
   365  		callCount++
   366  		return nil
   367  	})
   368  
   369  	st := storageprovisioner.NewState(apiCaller, names.NewMachineTag("123"))
   370  	volumeParams, err := st.VolumeParams([]names.VolumeTag{names.NewVolumeTag("100")})
   371  	c.Check(err, jc.ErrorIsNil)
   372  	c.Check(callCount, gc.Equals, 1)
   373  	c.Assert(volumeParams, jc.DeepEquals, []params.VolumeParamsResult{{
   374  		Result: params.VolumeParams{
   375  			VolumeTag: "volume-100", Size: 1024, Provider: "loop",
   376  		},
   377  	}})
   378  }
   379  
   380  func (s *provisionerSuite) TestFilesystemParams(c *gc.C) {
   381  	var callCount int
   382  	apiCaller := testing.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error {
   383  		c.Check(objType, gc.Equals, "StorageProvisioner")
   384  		c.Check(version, gc.Equals, 0)
   385  		c.Check(id, gc.Equals, "")
   386  		c.Check(request, gc.Equals, "FilesystemParams")
   387  		c.Check(arg, gc.DeepEquals, params.Entities{Entities: []params.Entity{{"filesystem-100"}}})
   388  		c.Assert(result, gc.FitsTypeOf, &params.FilesystemParamsResults{})
   389  		*(result.(*params.FilesystemParamsResults)) = params.FilesystemParamsResults{
   390  			Results: []params.FilesystemParamsResult{{
   391  				Result: params.FilesystemParams{
   392  					FilesystemTag: "filesystem-100",
   393  					Size:          1024,
   394  					Provider:      "loop",
   395  				},
   396  			}},
   397  		}
   398  		callCount++
   399  		return nil
   400  	})
   401  
   402  	st := storageprovisioner.NewState(apiCaller, names.NewMachineTag("123"))
   403  	filesystemParams, err := st.FilesystemParams([]names.FilesystemTag{names.NewFilesystemTag("100")})
   404  	c.Check(err, jc.ErrorIsNil)
   405  	c.Check(callCount, gc.Equals, 1)
   406  	c.Assert(filesystemParams, jc.DeepEquals, []params.FilesystemParamsResult{{
   407  		Result: params.FilesystemParams{
   408  			FilesystemTag: "filesystem-100", Size: 1024, Provider: "loop",
   409  		},
   410  	}})
   411  }
   412  
   413  func (s *provisionerSuite) TestVolumeAttachmentParams(c *gc.C) {
   414  	paramsResults := []params.VolumeAttachmentParamsResult{{
   415  		Result: params.VolumeAttachmentParams{
   416  			MachineTag: "machine-100",
   417  			VolumeTag:  "volume-100",
   418  			InstanceId: "inst-ance",
   419  			Provider:   "loop",
   420  		},
   421  	}}
   422  
   423  	var callCount int
   424  	apiCaller := testing.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error {
   425  		c.Check(objType, gc.Equals, "StorageProvisioner")
   426  		c.Check(version, gc.Equals, 0)
   427  		c.Check(id, gc.Equals, "")
   428  		c.Check(request, gc.Equals, "VolumeAttachmentParams")
   429  		c.Check(arg, gc.DeepEquals, params.MachineStorageIds{
   430  			Ids: []params.MachineStorageId{{
   431  				MachineTag: "machine-100", AttachmentTag: "volume-100",
   432  			}},
   433  		})
   434  		c.Assert(result, gc.FitsTypeOf, &params.VolumeAttachmentParamsResults{})
   435  		*(result.(*params.VolumeAttachmentParamsResults)) = params.VolumeAttachmentParamsResults{
   436  			Results: paramsResults,
   437  		}
   438  		callCount++
   439  		return nil
   440  	})
   441  
   442  	st := storageprovisioner.NewState(apiCaller, names.NewMachineTag("123"))
   443  	volumeParams, err := st.VolumeAttachmentParams([]params.MachineStorageId{{
   444  		MachineTag: "machine-100", AttachmentTag: "volume-100",
   445  	}})
   446  	c.Check(err, jc.ErrorIsNil)
   447  	c.Check(callCount, gc.Equals, 1)
   448  	c.Assert(volumeParams, jc.DeepEquals, paramsResults)
   449  }
   450  
   451  func (s *provisionerSuite) TestFilesystemAttachmentParams(c *gc.C) {
   452  	paramsResults := []params.FilesystemAttachmentParamsResult{{
   453  		Result: params.FilesystemAttachmentParams{
   454  			MachineTag:    "machine-100",
   455  			FilesystemTag: "filesystem-100",
   456  			InstanceId:    "inst-ance",
   457  			Provider:      "loop",
   458  			MountPoint:    "/srv",
   459  		},
   460  	}}
   461  
   462  	var callCount int
   463  	apiCaller := testing.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error {
   464  		c.Check(objType, gc.Equals, "StorageProvisioner")
   465  		c.Check(version, gc.Equals, 0)
   466  		c.Check(id, gc.Equals, "")
   467  		c.Check(request, gc.Equals, "FilesystemAttachmentParams")
   468  		c.Check(arg, gc.DeepEquals, params.MachineStorageIds{
   469  			Ids: []params.MachineStorageId{{
   470  				MachineTag: "machine-100", AttachmentTag: "filesystem-100",
   471  			}},
   472  		})
   473  		c.Assert(result, gc.FitsTypeOf, &params.FilesystemAttachmentParamsResults{})
   474  		*(result.(*params.FilesystemAttachmentParamsResults)) = params.FilesystemAttachmentParamsResults{
   475  			Results: paramsResults,
   476  		}
   477  		callCount++
   478  		return nil
   479  	})
   480  
   481  	st := storageprovisioner.NewState(apiCaller, names.NewMachineTag("123"))
   482  	filesystemParams, err := st.FilesystemAttachmentParams([]params.MachineStorageId{{
   483  		MachineTag: "machine-100", AttachmentTag: "filesystem-100",
   484  	}})
   485  	c.Check(err, jc.ErrorIsNil)
   486  	c.Check(callCount, gc.Equals, 1)
   487  	c.Assert(filesystemParams, jc.DeepEquals, paramsResults)
   488  }
   489  
   490  func (s *provisionerSuite) TestSetVolumeInfo(c *gc.C) {
   491  	var callCount int
   492  	apiCaller := testing.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error {
   493  		c.Check(objType, gc.Equals, "StorageProvisioner")
   494  		c.Check(version, gc.Equals, 0)
   495  		c.Check(id, gc.Equals, "")
   496  		c.Check(request, gc.Equals, "SetVolumeInfo")
   497  		c.Check(arg, gc.DeepEquals, params.Volumes{
   498  			Volumes: []params.Volume{{
   499  				VolumeTag: "volume-100",
   500  				Info: params.VolumeInfo{
   501  					VolumeId:   "123",
   502  					HardwareId: "abc",
   503  					Size:       1024,
   504  					Persistent: true,
   505  				},
   506  			}},
   507  		})
   508  		c.Assert(result, gc.FitsTypeOf, &params.ErrorResults{})
   509  		*(result.(*params.ErrorResults)) = params.ErrorResults{
   510  			Results: []params.ErrorResult{{Error: nil}},
   511  		}
   512  		callCount++
   513  		return nil
   514  	})
   515  
   516  	st := storageprovisioner.NewState(apiCaller, names.NewMachineTag("123"))
   517  	volumes := []params.Volume{{
   518  		VolumeTag: "volume-100",
   519  		Info: params.VolumeInfo{
   520  			VolumeId: "123", HardwareId: "abc", Size: 1024, Persistent: true,
   521  		},
   522  	}}
   523  	errorResults, err := st.SetVolumeInfo(volumes)
   524  	c.Check(err, jc.ErrorIsNil)
   525  	c.Check(callCount, gc.Equals, 1)
   526  	c.Assert(errorResults, gc.HasLen, 1)
   527  	c.Assert(errorResults[0].Error, gc.IsNil)
   528  }
   529  
   530  func (s *provisionerSuite) TestSetFilesystemInfo(c *gc.C) {
   531  	var callCount int
   532  	apiCaller := testing.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error {
   533  		c.Check(objType, gc.Equals, "StorageProvisioner")
   534  		c.Check(version, gc.Equals, 0)
   535  		c.Check(id, gc.Equals, "")
   536  		c.Check(request, gc.Equals, "SetFilesystemInfo")
   537  		c.Check(arg, gc.DeepEquals, params.Filesystems{
   538  			Filesystems: []params.Filesystem{{
   539  				FilesystemTag: "filesystem-100",
   540  				Info: params.FilesystemInfo{
   541  					FilesystemId: "123",
   542  					Size:         1024,
   543  				},
   544  			}},
   545  		})
   546  		c.Assert(result, gc.FitsTypeOf, &params.ErrorResults{})
   547  		*(result.(*params.ErrorResults)) = params.ErrorResults{
   548  			Results: []params.ErrorResult{{Error: nil}},
   549  		}
   550  		callCount++
   551  		return nil
   552  	})
   553  
   554  	st := storageprovisioner.NewState(apiCaller, names.NewMachineTag("123"))
   555  	filesystems := []params.Filesystem{{
   556  		FilesystemTag: "filesystem-100",
   557  		Info: params.FilesystemInfo{
   558  			FilesystemId: "123",
   559  			Size:         1024,
   560  		},
   561  	}}
   562  	errorResults, err := st.SetFilesystemInfo(filesystems)
   563  	c.Check(err, jc.ErrorIsNil)
   564  	c.Check(callCount, gc.Equals, 1)
   565  	c.Assert(errorResults, gc.HasLen, 1)
   566  	c.Assert(errorResults[0].Error, gc.IsNil)
   567  }
   568  
   569  func (s *provisionerSuite) TestSetVolumeAttachmentInfo(c *gc.C) {
   570  	volumeAttachments := []params.VolumeAttachment{{
   571  		VolumeTag:  "volume-100",
   572  		MachineTag: "machine-200",
   573  		Info: params.VolumeAttachmentInfo{
   574  			DeviceName: "xvdf1",
   575  		},
   576  	}}
   577  
   578  	var callCount int
   579  	apiCaller := testing.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error {
   580  		c.Check(objType, gc.Equals, "StorageProvisioner")
   581  		c.Check(version, gc.Equals, 0)
   582  		c.Check(id, gc.Equals, "")
   583  		c.Check(request, gc.Equals, "SetVolumeAttachmentInfo")
   584  		c.Check(arg, jc.DeepEquals, params.VolumeAttachments{volumeAttachments})
   585  		c.Assert(result, gc.FitsTypeOf, &params.ErrorResults{})
   586  		*(result.(*params.ErrorResults)) = params.ErrorResults{
   587  			Results: []params.ErrorResult{{Error: nil}},
   588  		}
   589  		callCount++
   590  		return nil
   591  	})
   592  
   593  	st := storageprovisioner.NewState(apiCaller, names.NewMachineTag("123"))
   594  	errorResults, err := st.SetVolumeAttachmentInfo(volumeAttachments)
   595  	c.Check(err, jc.ErrorIsNil)
   596  	c.Check(callCount, gc.Equals, 1)
   597  	c.Assert(errorResults, gc.HasLen, 1)
   598  	c.Assert(errorResults[0].Error, gc.IsNil)
   599  }
   600  
   601  func (s *provisionerSuite) TestSetFilesystemAttachmentInfo(c *gc.C) {
   602  	filesystemAttachments := []params.FilesystemAttachment{{
   603  		FilesystemTag: "filesystem-100",
   604  		MachineTag:    "machine-200",
   605  		Info: params.FilesystemAttachmentInfo{
   606  			MountPoint: "/srv",
   607  		},
   608  	}}
   609  
   610  	var callCount int
   611  	apiCaller := testing.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error {
   612  		c.Check(objType, gc.Equals, "StorageProvisioner")
   613  		c.Check(version, gc.Equals, 0)
   614  		c.Check(id, gc.Equals, "")
   615  		c.Check(request, gc.Equals, "SetFilesystemAttachmentInfo")
   616  		c.Check(arg, jc.DeepEquals, params.FilesystemAttachments{filesystemAttachments})
   617  		c.Assert(result, gc.FitsTypeOf, &params.ErrorResults{})
   618  		*(result.(*params.ErrorResults)) = params.ErrorResults{
   619  			Results: []params.ErrorResult{{Error: nil}},
   620  		}
   621  		callCount++
   622  		return nil
   623  	})
   624  
   625  	st := storageprovisioner.NewState(apiCaller, names.NewMachineTag("123"))
   626  	errorResults, err := st.SetFilesystemAttachmentInfo(filesystemAttachments)
   627  	c.Check(err, jc.ErrorIsNil)
   628  	c.Check(callCount, gc.Equals, 1)
   629  	c.Assert(errorResults, gc.HasLen, 1)
   630  	c.Assert(errorResults[0].Error, gc.IsNil)
   631  }
   632  
   633  func (s *provisionerSuite) testOpWithTags(
   634  	c *gc.C, opName string, apiCall func(*storageprovisioner.State, []names.Tag) ([]params.ErrorResult, error),
   635  ) {
   636  	var callCount int
   637  	apiCaller := testing.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error {
   638  		c.Check(objType, gc.Equals, "StorageProvisioner")
   639  		c.Check(version, gc.Equals, 0)
   640  		c.Check(id, gc.Equals, "")
   641  		c.Check(request, gc.Equals, opName)
   642  		c.Check(arg, gc.DeepEquals, params.Entities{Entities: []params.Entity{{Tag: "volume-100"}}})
   643  		c.Assert(result, gc.FitsTypeOf, &params.ErrorResults{})
   644  		*(result.(*params.ErrorResults)) = params.ErrorResults{
   645  			Results: []params.ErrorResult{{Error: nil}},
   646  		}
   647  		callCount++
   648  		return nil
   649  	})
   650  
   651  	st := storageprovisioner.NewState(apiCaller, names.NewMachineTag("123"))
   652  	volumes := []names.Tag{names.NewVolumeTag("100")}
   653  	errorResults, err := apiCall(st, volumes)
   654  	c.Check(err, jc.ErrorIsNil)
   655  	c.Check(callCount, gc.Equals, 1)
   656  	c.Assert(errorResults, jc.DeepEquals, []params.ErrorResult{{}})
   657  }
   658  
   659  func (s *provisionerSuite) TestRemove(c *gc.C) {
   660  	s.testOpWithTags(c, "Remove", func(st *storageprovisioner.State, tags []names.Tag) ([]params.ErrorResult, error) {
   661  		return st.Remove(tags)
   662  	})
   663  }
   664  
   665  func (s *provisionerSuite) TestEnsureDead(c *gc.C) {
   666  	s.testOpWithTags(c, "EnsureDead", func(st *storageprovisioner.State, tags []names.Tag) ([]params.ErrorResult, error) {
   667  		return st.EnsureDead(tags)
   668  	})
   669  }
   670  
   671  func (s *provisionerSuite) TestLife(c *gc.C) {
   672  	var callCount int
   673  	apiCaller := testing.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error {
   674  		c.Check(objType, gc.Equals, "StorageProvisioner")
   675  		c.Check(version, gc.Equals, 0)
   676  		c.Check(id, gc.Equals, "")
   677  		c.Check(request, gc.Equals, "Life")
   678  		c.Check(arg, gc.DeepEquals, params.Entities{Entities: []params.Entity{{Tag: "volume-100"}}})
   679  		c.Assert(result, gc.FitsTypeOf, &params.LifeResults{})
   680  		*(result.(*params.LifeResults)) = params.LifeResults{
   681  			Results: []params.LifeResult{{Life: params.Alive}},
   682  		}
   683  		callCount++
   684  		return nil
   685  	})
   686  
   687  	st := storageprovisioner.NewState(apiCaller, names.NewMachineTag("123"))
   688  	volumes := []names.Tag{names.NewVolumeTag("100")}
   689  	lifeResults, err := st.Life(volumes)
   690  	c.Check(err, jc.ErrorIsNil)
   691  	c.Check(callCount, gc.Equals, 1)
   692  	c.Assert(lifeResults, jc.DeepEquals, []params.LifeResult{{Life: params.Alive}})
   693  }
   694  
   695  func (s *provisionerSuite) testClientError(c *gc.C, apiCall func(*storageprovisioner.State) error) {
   696  	apiCaller := testing.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error {
   697  		return errors.New("blargh")
   698  	})
   699  	st := storageprovisioner.NewState(apiCaller, names.NewMachineTag("123"))
   700  	err := apiCall(st)
   701  	c.Check(err, gc.ErrorMatches, "blargh")
   702  }
   703  
   704  func (s *provisionerSuite) TestWatchVolumesClientError(c *gc.C) {
   705  	s.testClientError(c, func(st *storageprovisioner.State) error {
   706  		_, err := st.WatchVolumes()
   707  		return err
   708  	})
   709  }
   710  
   711  func (s *provisionerSuite) TestVolumesClientError(c *gc.C) {
   712  	s.testClientError(c, func(st *storageprovisioner.State) error {
   713  		_, err := st.Volumes(nil)
   714  		return err
   715  	})
   716  }
   717  
   718  func (s *provisionerSuite) TestVolumeParamsClientError(c *gc.C) {
   719  	s.testClientError(c, func(st *storageprovisioner.State) error {
   720  		_, err := st.VolumeParams(nil)
   721  		return err
   722  	})
   723  }
   724  
   725  func (s *provisionerSuite) TestRemoveClientError(c *gc.C) {
   726  	s.testClientError(c, func(st *storageprovisioner.State) error {
   727  		_, err := st.Remove(nil)
   728  		return err
   729  	})
   730  }
   731  
   732  func (s *provisionerSuite) TestRemoveAttachmentsClientError(c *gc.C) {
   733  	s.testClientError(c, func(st *storageprovisioner.State) error {
   734  		_, err := st.RemoveAttachments(nil)
   735  		return err
   736  	})
   737  }
   738  
   739  func (s *provisionerSuite) TestSetVolumeInfoClientError(c *gc.C) {
   740  	s.testClientError(c, func(st *storageprovisioner.State) error {
   741  		_, err := st.SetVolumeInfo(nil)
   742  		return err
   743  	})
   744  }
   745  
   746  func (s *provisionerSuite) TestEnsureDeadClientError(c *gc.C) {
   747  	s.testClientError(c, func(st *storageprovisioner.State) error {
   748  		_, err := st.EnsureDead(nil)
   749  		return err
   750  	})
   751  }
   752  
   753  func (s *provisionerSuite) TestLifeClientError(c *gc.C) {
   754  	s.testClientError(c, func(st *storageprovisioner.State) error {
   755  		_, err := st.Life(nil)
   756  		return err
   757  	})
   758  }
   759  
   760  func (s *provisionerSuite) TestAttachmentLifeClientError(c *gc.C) {
   761  	s.testClientError(c, func(st *storageprovisioner.State) error {
   762  		_, err := st.AttachmentLife(nil)
   763  		return err
   764  	})
   765  }
   766  
   767  func (s *provisionerSuite) TestWatchVolumesServerError(c *gc.C) {
   768  	apiCaller := testing.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error {
   769  		*(result.(*params.StringsWatchResults)) = params.StringsWatchResults{
   770  			Results: []params.StringsWatchResult{{
   771  				Error: &params.Error{Message: "MSG", Code: "621"},
   772  			}},
   773  		}
   774  		return nil
   775  	})
   776  	st := storageprovisioner.NewState(apiCaller, names.NewMachineTag("123"))
   777  	_, err := st.WatchVolumes()
   778  	c.Check(err, gc.ErrorMatches, "MSG")
   779  }
   780  
   781  func (s *provisionerSuite) TestVolumesServerError(c *gc.C) {
   782  	apiCaller := testing.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error {
   783  		*(result.(*params.VolumeResults)) = params.VolumeResults{
   784  			Results: []params.VolumeResult{{
   785  				Error: &params.Error{Message: "MSG", Code: "621"},
   786  			}},
   787  		}
   788  		return nil
   789  	})
   790  	st := storageprovisioner.NewState(apiCaller, names.NewMachineTag("123"))
   791  	results, err := st.Volumes([]names.VolumeTag{names.NewVolumeTag("100")})
   792  	c.Assert(err, jc.ErrorIsNil)
   793  	c.Assert(results, gc.HasLen, 1)
   794  	c.Check(results[0].Error, gc.ErrorMatches, "MSG")
   795  }
   796  
   797  func (s *provisionerSuite) TestVolumeParamsServerError(c *gc.C) {
   798  	apiCaller := testing.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error {
   799  		*(result.(*params.VolumeParamsResults)) = params.VolumeParamsResults{
   800  			Results: []params.VolumeParamsResult{{
   801  				Error: &params.Error{Message: "MSG", Code: "621"},
   802  			}},
   803  		}
   804  		return nil
   805  	})
   806  	st := storageprovisioner.NewState(apiCaller, names.NewMachineTag("123"))
   807  	results, err := st.VolumeParams([]names.VolumeTag{names.NewVolumeTag("100")})
   808  	c.Assert(err, jc.ErrorIsNil)
   809  	c.Assert(results, gc.HasLen, 1)
   810  	c.Check(results[0].Error, gc.ErrorMatches, "MSG")
   811  }
   812  
   813  func (s *provisionerSuite) TestSetVolumeInfoServerError(c *gc.C) {
   814  	apiCaller := testing.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error {
   815  		*(result.(*params.ErrorResults)) = params.ErrorResults{
   816  			Results: []params.ErrorResult{{
   817  				Error: &params.Error{Message: "MSG", Code: "621"},
   818  			}},
   819  		}
   820  		return nil
   821  	})
   822  	st := storageprovisioner.NewState(apiCaller, names.NewMachineTag("123"))
   823  	results, err := st.SetVolumeInfo([]params.Volume{{
   824  		VolumeTag: names.NewVolumeTag("100").String(),
   825  	}})
   826  	c.Assert(err, jc.ErrorIsNil)
   827  	c.Assert(results, gc.HasLen, 1)
   828  	c.Check(results[0].Error, gc.ErrorMatches, "MSG")
   829  }
   830  
   831  func (s *provisionerSuite) testServerError(c *gc.C, apiCall func(*storageprovisioner.State, []names.Tag) ([]params.ErrorResult, error)) {
   832  	apiCaller := testing.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error {
   833  		*(result.(*params.ErrorResults)) = params.ErrorResults{
   834  			Results: []params.ErrorResult{{
   835  				Error: &params.Error{Message: "MSG", Code: "621"},
   836  			}},
   837  		}
   838  		return nil
   839  	})
   840  	st := storageprovisioner.NewState(apiCaller, names.NewMachineTag("123"))
   841  	tags := []names.Tag{
   842  		names.NewVolumeTag("100"),
   843  	}
   844  	results, err := apiCall(st, tags)
   845  	c.Assert(err, jc.ErrorIsNil)
   846  	c.Assert(results, gc.HasLen, 1)
   847  	c.Check(results[0].Error, gc.ErrorMatches, "MSG")
   848  }
   849  
   850  func (s *provisionerSuite) TestRemoveServerError(c *gc.C) {
   851  	s.testServerError(c, func(st *storageprovisioner.State, tags []names.Tag) ([]params.ErrorResult, error) {
   852  		return st.Remove(tags)
   853  	})
   854  }
   855  
   856  func (s *provisionerSuite) TestEnsureDeadServerError(c *gc.C) {
   857  	s.testServerError(c, func(st *storageprovisioner.State, tags []names.Tag) ([]params.ErrorResult, error) {
   858  		return st.EnsureDead(tags)
   859  	})
   860  }
   861  
   862  func (s *provisionerSuite) TestLifeServerError(c *gc.C) {
   863  	apiCaller := testing.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error {
   864  		*(result.(*params.LifeResults)) = params.LifeResults{
   865  			Results: []params.LifeResult{{
   866  				Error: &params.Error{Message: "MSG", Code: "621"},
   867  			}},
   868  		}
   869  		return nil
   870  	})
   871  	st := storageprovisioner.NewState(apiCaller, names.NewMachineTag("123"))
   872  	tags := []names.Tag{
   873  		names.NewVolumeTag("100"),
   874  	}
   875  	results, err := st.Life(tags)
   876  	c.Assert(err, jc.ErrorIsNil)
   877  	c.Assert(results, gc.HasLen, 1)
   878  	c.Check(results[0].Error, gc.ErrorMatches, "MSG")
   879  }
   880  
   881  func (s *provisionerSuite) TestWatchForEnvironConfigChanges(c *gc.C) {
   882  	apiCaller := testing.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error {
   883  		c.Check(objType, gc.Equals, "StorageProvisioner")
   884  		c.Check(version, gc.Equals, 0)
   885  		c.Check(id, gc.Equals, "")
   886  		c.Check(request, gc.Equals, "WatchForEnvironConfigChanges")
   887  		c.Assert(result, gc.FitsTypeOf, &params.NotifyWatchResult{})
   888  		*(result.(*params.NotifyWatchResult)) = params.NotifyWatchResult{
   889  			NotifyWatcherId: "abc",
   890  		}
   891  		return errors.New("FAIL")
   892  	})
   893  	st := storageprovisioner.NewState(apiCaller, names.NewMachineTag("123"))
   894  	_, err := st.WatchForEnvironConfigChanges()
   895  	c.Assert(err, gc.ErrorMatches, "FAIL")
   896  }
   897  
   898  func (s *provisionerSuite) TestEnvironConfig(c *gc.C) {
   899  	inputCfg := coretesting.EnvironConfig(c)
   900  	apiCaller := testing.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error {
   901  		c.Check(objType, gc.Equals, "StorageProvisioner")
   902  		c.Check(version, gc.Equals, 0)
   903  		c.Check(id, gc.Equals, "")
   904  		c.Check(request, gc.Equals, "EnvironConfig")
   905  		c.Assert(result, gc.FitsTypeOf, &params.EnvironConfigResult{})
   906  		*(result.(*params.EnvironConfigResult)) = params.EnvironConfigResult{
   907  			Config: inputCfg.AllAttrs(),
   908  		}
   909  		return nil
   910  	})
   911  	st := storageprovisioner.NewState(apiCaller, names.NewMachineTag("123"))
   912  	outputCfg, err := st.EnvironConfig()
   913  	c.Assert(err, jc.ErrorIsNil)
   914  	c.Assert(outputCfg.AllAttrs(), jc.DeepEquals, inputCfg.AllAttrs())
   915  }