github.com/juju/juju@v0.0.0-20240327075706-a90865de2538/api/controller/remoterelations/remoterelations_test.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package remoterelations_test
     5  
     6  import (
     7  	"github.com/juju/names/v5"
     8  	jc "github.com/juju/testing/checkers"
     9  	gc "gopkg.in/check.v1"
    10  
    11  	"github.com/juju/juju/api/base/testing"
    12  	"github.com/juju/juju/api/controller/remoterelations"
    13  	apitesting "github.com/juju/juju/api/testing"
    14  	"github.com/juju/juju/core/crossmodel"
    15  	"github.com/juju/juju/core/secrets"
    16  	"github.com/juju/juju/core/status"
    17  	"github.com/juju/juju/core/watcher"
    18  	"github.com/juju/juju/rpc/params"
    19  	coretesting "github.com/juju/juju/testing"
    20  )
    21  
    22  var _ = gc.Suite(&remoteRelationsSuite{})
    23  
    24  type remoteRelationsSuite struct {
    25  	coretesting.BaseSuite
    26  }
    27  
    28  func (s *remoteRelationsSuite) TestNewClient(c *gc.C) {
    29  	apiCaller := testing.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error {
    30  		return nil
    31  	})
    32  	client := remoterelations.NewClient(apiCaller)
    33  	c.Assert(client, gc.NotNil)
    34  }
    35  
    36  func (s *remoteRelationsSuite) TestWatchRemoteApplications(c *gc.C) {
    37  	var callCount int
    38  	apiCaller := testing.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error {
    39  		c.Check(objType, gc.Equals, "RemoteRelations")
    40  		c.Check(version, gc.Equals, 0)
    41  		c.Check(id, gc.Equals, "")
    42  		c.Check(request, gc.Equals, "WatchRemoteApplications")
    43  		c.Assert(result, gc.FitsTypeOf, &params.StringsWatchResult{})
    44  		*(result.(*params.StringsWatchResult)) = params.StringsWatchResult{
    45  			Error: &params.Error{Message: "FAIL"},
    46  		}
    47  		callCount++
    48  		return nil
    49  	})
    50  	client := remoterelations.NewClient(apiCaller)
    51  	_, err := client.WatchRemoteApplications()
    52  	c.Check(err, gc.ErrorMatches, "FAIL")
    53  	c.Check(callCount, gc.Equals, 1)
    54  }
    55  
    56  func (s *remoteRelationsSuite) TestWatchRemoteApplicationRelations(c *gc.C) {
    57  	var callCount int
    58  	apiCaller := testing.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error {
    59  		c.Check(objType, gc.Equals, "RemoteRelations")
    60  		c.Check(version, gc.Equals, 0)
    61  		c.Check(id, gc.Equals, "")
    62  		c.Check(request, gc.Equals, "WatchRemoteApplicationRelations")
    63  		c.Assert(result, gc.FitsTypeOf, &params.StringsWatchResults{})
    64  		*(result.(*params.StringsWatchResults)) = params.StringsWatchResults{
    65  			Results: []params.StringsWatchResult{{
    66  				Error: &params.Error{Message: "FAIL"},
    67  			}},
    68  		}
    69  		callCount++
    70  		return nil
    71  	})
    72  	client := remoterelations.NewClient(apiCaller)
    73  	_, err := client.WatchRemoteApplicationRelations("db2")
    74  	c.Check(err, gc.ErrorMatches, "FAIL")
    75  	c.Check(callCount, gc.Equals, 1)
    76  }
    77  
    78  func (s *remoteRelationsSuite) TestWatchRemoteApplicationInvalidApplication(c *gc.C) {
    79  	apiCaller := testing.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error {
    80  		return nil
    81  	})
    82  	client := remoterelations.NewClient(apiCaller)
    83  	_, err := client.WatchRemoteApplicationRelations("!@#")
    84  	c.Assert(err, gc.ErrorMatches, `application name "!@#" not valid`)
    85  }
    86  
    87  func (s *remoteRelationsSuite) TestWatchLocalRelationChanges(c *gc.C) {
    88  	var callCount int
    89  	apiCaller := testing.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error {
    90  		c.Check(objType, gc.Equals, "RemoteRelations")
    91  		c.Check(version, gc.Equals, 0)
    92  		c.Check(id, gc.Equals, "")
    93  		c.Check(request, gc.Equals, "WatchLocalRelationChanges")
    94  		c.Assert(result, gc.FitsTypeOf, &params.RemoteRelationWatchResults{})
    95  		*(result.(*params.RemoteRelationWatchResults)) = params.RemoteRelationWatchResults{
    96  			Results: []params.RemoteRelationWatchResult{{
    97  				Error: &params.Error{Message: "FAIL"},
    98  			}},
    99  		}
   100  		callCount++
   101  		return nil
   102  	})
   103  	client := remoterelations.NewClient(apiCaller)
   104  	_, err := client.WatchLocalRelationChanges("relation-wordpress:db mysql:db")
   105  	c.Check(err, gc.ErrorMatches, "FAIL")
   106  	c.Check(callCount, gc.Equals, 1)
   107  }
   108  
   109  func (s *remoteRelationsSuite) TestExportEntities(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, "RemoteRelations")
   113  		c.Check(version, gc.Equals, 0)
   114  		c.Check(id, gc.Equals, "")
   115  		c.Check(request, gc.Equals, "ExportEntities")
   116  		c.Check(arg, gc.DeepEquals, params.Entities{Entities: []params.Entity{{Tag: "application-foo"}}})
   117  		c.Assert(result, gc.FitsTypeOf, &params.TokenResults{})
   118  		*(result.(*params.TokenResults)) = params.TokenResults{
   119  			Results: []params.TokenResult{{
   120  				Error: &params.Error{Message: "FAIL"},
   121  			}},
   122  		}
   123  		callCount++
   124  		return nil
   125  	})
   126  	client := remoterelations.NewClient(apiCaller)
   127  	result, err := client.ExportEntities([]names.Tag{names.NewApplicationTag("foo")})
   128  	c.Check(err, jc.ErrorIsNil)
   129  	c.Assert(result, gc.HasLen, 1)
   130  	c.Check(result[0].Error, gc.ErrorMatches, "FAIL")
   131  	c.Check(callCount, gc.Equals, 1)
   132  }
   133  
   134  func (s *remoteRelationsSuite) TestExportEntitiesResultCount(c *gc.C) {
   135  	apiCaller := testing.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error {
   136  		*(result.(*params.TokenResults)) = params.TokenResults{
   137  			Results: []params.TokenResult{
   138  				{Error: &params.Error{Message: "FAIL"}},
   139  				{Error: &params.Error{Message: "FAIL"}},
   140  			},
   141  		}
   142  		return nil
   143  	})
   144  	client := remoterelations.NewClient(apiCaller)
   145  	_, err := client.ExportEntities([]names.Tag{names.NewApplicationTag("foo")})
   146  	c.Check(err, gc.ErrorMatches, `expected 1 result\(s\), got 2`)
   147  }
   148  
   149  func (s *remoteRelationsSuite) TestRelations(c *gc.C) {
   150  	var callCount int
   151  	apiCaller := testing.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error {
   152  		c.Check(objType, gc.Equals, "RemoteRelations")
   153  		c.Check(version, gc.Equals, 0)
   154  		c.Check(id, gc.Equals, "")
   155  		c.Check(request, gc.Equals, "Relations")
   156  		c.Check(arg, gc.DeepEquals, params.Entities{Entities: []params.Entity{{Tag: "relation-foo.db#bar.db"}}})
   157  		c.Assert(result, gc.FitsTypeOf, &params.RemoteRelationResults{})
   158  		*(result.(*params.RemoteRelationResults)) = params.RemoteRelationResults{
   159  			Results: []params.RemoteRelationResult{{
   160  				Error: &params.Error{Message: "FAIL"},
   161  			}},
   162  		}
   163  		callCount++
   164  		return nil
   165  	})
   166  	client := remoterelations.NewClient(apiCaller)
   167  	result, err := client.Relations([]string{"foo:db bar:db"})
   168  	c.Check(err, jc.ErrorIsNil)
   169  	c.Assert(result, gc.HasLen, 1)
   170  	c.Check(result[0].Error, gc.ErrorMatches, "FAIL")
   171  	c.Check(callCount, gc.Equals, 1)
   172  }
   173  
   174  func (s *remoteRelationsSuite) TestRelationsResultsCount(c *gc.C) {
   175  	apiCaller := testing.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error {
   176  		*(result.(*params.RemoteRelationResults)) = params.RemoteRelationResults{
   177  			Results: []params.RemoteRelationResult{
   178  				{Error: &params.Error{Message: "FAIL"}},
   179  				{Error: &params.Error{Message: "FAIL"}},
   180  			},
   181  		}
   182  		return nil
   183  	})
   184  	client := remoterelations.NewClient(apiCaller)
   185  	_, err := client.Relations([]string{"foo:db bar:db"})
   186  	c.Check(err, gc.ErrorMatches, `expected 1 result\(s\), got 2`)
   187  }
   188  
   189  func (s *remoteRelationsSuite) TestRemoteApplications(c *gc.C) {
   190  	var callCount int
   191  	apiCaller := testing.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error {
   192  		c.Check(objType, gc.Equals, "RemoteRelations")
   193  		c.Check(version, gc.Equals, 0)
   194  		c.Check(id, gc.Equals, "")
   195  		c.Check(request, gc.Equals, "RemoteApplications")
   196  		c.Check(arg, gc.DeepEquals, params.Entities{Entities: []params.Entity{{Tag: "application-foo"}}})
   197  		c.Assert(result, gc.FitsTypeOf, &params.RemoteApplicationResults{})
   198  		*(result.(*params.RemoteApplicationResults)) = params.RemoteApplicationResults{
   199  			Results: []params.RemoteApplicationResult{{
   200  				Error: &params.Error{Message: "FAIL"},
   201  			}},
   202  		}
   203  		callCount++
   204  		return nil
   205  	})
   206  	client := remoterelations.NewClient(apiCaller)
   207  	result, err := client.RemoteApplications([]string{"foo"})
   208  	c.Check(err, jc.ErrorIsNil)
   209  	c.Assert(result, gc.HasLen, 1)
   210  	c.Check(result[0].Error, gc.ErrorMatches, "FAIL")
   211  	c.Check(callCount, gc.Equals, 1)
   212  }
   213  
   214  func (s *remoteRelationsSuite) TestRemoteApplicationsResultsCount(c *gc.C) {
   215  	apiCaller := testing.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error {
   216  		*(result.(*params.RemoteApplicationResults)) = params.RemoteApplicationResults{
   217  			Results: []params.RemoteApplicationResult{
   218  				{Error: &params.Error{Message: "FAIL"}},
   219  				{Error: &params.Error{Message: "FAIL"}},
   220  			},
   221  		}
   222  		return nil
   223  	})
   224  	client := remoterelations.NewClient(apiCaller)
   225  	_, err := client.RemoteApplications([]string{"foo"})
   226  	c.Check(err, gc.ErrorMatches, `expected 1 result\(s\), got 2`)
   227  }
   228  
   229  func (s *remoteRelationsSuite) TestGetToken(c *gc.C) {
   230  	var callCount int
   231  	apiCaller := testing.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error {
   232  		c.Check(objType, gc.Equals, "RemoteRelations")
   233  		c.Check(version, gc.Equals, 0)
   234  		c.Check(id, gc.Equals, "")
   235  		c.Check(request, gc.Equals, "GetTokens")
   236  		c.Check(arg, gc.DeepEquals, params.GetTokenArgs{
   237  			Args: []params.GetTokenArg{{Tag: "application-app"}}})
   238  		c.Assert(result, gc.FitsTypeOf, &params.StringResults{})
   239  		*(result.(*params.StringResults)) = params.StringResults{
   240  			Results: []params.StringResult{{
   241  				Error: &params.Error{Message: "FAIL"},
   242  			}},
   243  		}
   244  		callCount++
   245  		return nil
   246  	})
   247  	client := remoterelations.NewClient(apiCaller)
   248  	_, err := client.GetToken(names.NewApplicationTag("app"))
   249  	c.Check(err, gc.ErrorMatches, "FAIL")
   250  	c.Check(callCount, gc.Equals, 1)
   251  }
   252  
   253  func (s *remoteRelationsSuite) TestGetTokenCount(c *gc.C) {
   254  	apiCaller := testing.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error {
   255  		*(result.(*params.StringResults)) = params.StringResults{
   256  			Results: []params.StringResult{
   257  				{Error: &params.Error{Message: "FAIL"}},
   258  				{Error: &params.Error{Message: "FAIL"}},
   259  			},
   260  		}
   261  		return nil
   262  	})
   263  	client := remoterelations.NewClient(apiCaller)
   264  	_, err := client.GetToken(names.NewApplicationTag("app"))
   265  	c.Check(err, gc.ErrorMatches, `expected 1 result, got 2`)
   266  }
   267  
   268  func (s *remoteRelationsSuite) TestImportRemoteEntity(c *gc.C) {
   269  	var callCount int
   270  	apiCaller := testing.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error {
   271  		c.Check(objType, gc.Equals, "RemoteRelations")
   272  		c.Check(version, gc.Equals, 0)
   273  		c.Check(id, gc.Equals, "")
   274  		c.Check(request, gc.Equals, "ImportRemoteEntities")
   275  		c.Check(arg, gc.DeepEquals, params.RemoteEntityTokenArgs{
   276  			Args: []params.RemoteEntityTokenArg{{Tag: "application-app", Token: "token"}}})
   277  		c.Assert(result, gc.FitsTypeOf, &params.ErrorResults{})
   278  		*(result.(*params.ErrorResults)) = params.ErrorResults{
   279  			Results: []params.ErrorResult{{
   280  				Error: &params.Error{Message: "FAIL"},
   281  			}},
   282  		}
   283  		callCount++
   284  		return nil
   285  	})
   286  	client := remoterelations.NewClient(apiCaller)
   287  	err := client.ImportRemoteEntity(names.NewApplicationTag("app"), "token")
   288  	c.Check(err, gc.ErrorMatches, "FAIL")
   289  	c.Check(callCount, gc.Equals, 1)
   290  }
   291  
   292  func (s *remoteRelationsSuite) TestImportRemoteEntityCount(c *gc.C) {
   293  	apiCaller := testing.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error {
   294  		*(result.(*params.ErrorResults)) = params.ErrorResults{
   295  			Results: []params.ErrorResult{
   296  				{Error: &params.Error{Message: "FAIL"}},
   297  				{Error: &params.Error{Message: "FAIL"}},
   298  			},
   299  		}
   300  		return nil
   301  	})
   302  	client := remoterelations.NewClient(apiCaller)
   303  	err := client.ImportRemoteEntity(names.NewApplicationTag("app"), "token")
   304  	c.Check(err, gc.ErrorMatches, `expected 1 result, got 2`)
   305  }
   306  
   307  func (s *remoteRelationsSuite) TestWatchRemoteRelations(c *gc.C) {
   308  	var callCount int
   309  	apiCaller := testing.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error {
   310  		c.Check(objType, gc.Equals, "RemoteRelations")
   311  		c.Check(version, gc.Equals, 0)
   312  		c.Check(id, gc.Equals, "")
   313  		c.Check(request, gc.Equals, "WatchRemoteRelations")
   314  		c.Assert(result, gc.FitsTypeOf, &params.StringsWatchResult{})
   315  		*(result.(*params.StringsWatchResult)) = params.StringsWatchResult{
   316  			Error: &params.Error{Message: "FAIL"},
   317  		}
   318  		callCount++
   319  		return nil
   320  	})
   321  	client := remoterelations.NewClient(apiCaller)
   322  	_, err := client.WatchRemoteRelations()
   323  	c.Check(err, gc.ErrorMatches, "FAIL")
   324  	c.Check(callCount, gc.Equals, 1)
   325  }
   326  
   327  func (s *remoteRelationsSuite) TestConsumeRemoteRelationChange(c *gc.C) {
   328  	var callCount int
   329  	change := params.RemoteRelationChangeEvent{}
   330  	changes := params.RemoteRelationsChanges{
   331  		Changes: []params.RemoteRelationChangeEvent{change},
   332  	}
   333  	apiCaller := testing.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error {
   334  		c.Check(objType, gc.Equals, "RemoteRelations")
   335  		c.Check(version, gc.Equals, 0)
   336  		c.Check(id, gc.Equals, "")
   337  		c.Check(request, gc.Equals, "ConsumeRemoteRelationChanges")
   338  		c.Check(arg, jc.DeepEquals, changes)
   339  		c.Assert(result, gc.FitsTypeOf, &params.ErrorResults{})
   340  		*(result.(*params.ErrorResults)) = params.ErrorResults{
   341  			Results: []params.ErrorResult{{
   342  				Error: &params.Error{Message: "FAIL"},
   343  			}}}
   344  		callCount++
   345  		return nil
   346  	})
   347  	client := remoterelations.NewClient(apiCaller)
   348  	err := client.ConsumeRemoteRelationChange(change)
   349  	c.Check(err, gc.ErrorMatches, "FAIL")
   350  	c.Check(callCount, gc.Equals, 1)
   351  }
   352  
   353  func (s *remoteRelationsSuite) TestControllerAPIInfoForModel(c *gc.C) {
   354  	var callCount int
   355  	apiCaller := testing.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error {
   356  		c.Check(objType, gc.Equals, "RemoteRelations")
   357  		c.Check(version, gc.Equals, 0)
   358  		c.Check(id, gc.Equals, "")
   359  		c.Check(request, gc.Equals, "ControllerAPIInfoForModels")
   360  		c.Assert(arg, gc.DeepEquals, params.Entities{Entities: []params.Entity{{Tag: coretesting.ModelTag.String()}}})
   361  		c.Assert(result, gc.FitsTypeOf, &params.ControllerAPIInfoResults{})
   362  		*(result.(*params.ControllerAPIInfoResults)) = params.ControllerAPIInfoResults{
   363  			Results: []params.ControllerAPIInfoResult{{
   364  				Error: &params.Error{Message: "FAIL"},
   365  			}},
   366  		}
   367  		callCount++
   368  		return nil
   369  	})
   370  	client := remoterelations.NewClient(apiCaller)
   371  	_, err := client.ControllerAPIInfoForModel(coretesting.ModelTag.Id())
   372  	c.Check(err, gc.ErrorMatches, "FAIL")
   373  	c.Check(callCount, gc.Equals, 1)
   374  }
   375  
   376  func (s *remoteRelationsSuite) TestSaveMacaroon(c *gc.C) {
   377  	rel := names.NewRelationTag("mysql:db wordpress:db")
   378  	mac, err := apitesting.NewMacaroon("id")
   379  	c.Check(err, jc.ErrorIsNil)
   380  	var callCount int
   381  	apiCaller := testing.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error {
   382  		c.Check(objType, gc.Equals, "RemoteRelations")
   383  		c.Check(version, gc.Equals, 0)
   384  		c.Check(id, gc.Equals, "")
   385  		c.Check(request, gc.Equals, "SaveMacaroons")
   386  		c.Assert(arg, gc.DeepEquals, params.EntityMacaroonArgs{Args: []params.EntityMacaroonArg{
   387  			{Tag: rel.String(), Macaroon: mac}}})
   388  		c.Assert(result, gc.FitsTypeOf, &params.ErrorResults{})
   389  		*(result.(*params.ErrorResults)) = params.ErrorResults{
   390  			Results: []params.ErrorResult{{
   391  				Error: &params.Error{Message: "FAIL"},
   392  			}},
   393  		}
   394  		callCount++
   395  		return nil
   396  	})
   397  	client := remoterelations.NewClient(apiCaller)
   398  	err = client.SaveMacaroon(rel, mac)
   399  	c.Check(err, gc.ErrorMatches, "FAIL")
   400  	c.Check(callCount, gc.Equals, 1)
   401  }
   402  
   403  func (s *remoteRelationsSuite) TestSetRemoteApplicationStatus(c *gc.C) {
   404  	var callCount int
   405  	apiCaller := testing.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error {
   406  		c.Check(objType, gc.Equals, "RemoteRelations")
   407  		c.Check(version, gc.Equals, 0)
   408  		c.Check(id, gc.Equals, "")
   409  		c.Check(request, gc.Equals, "SetRemoteApplicationsStatus")
   410  		c.Assert(arg, gc.DeepEquals, params.SetStatus{Entities: []params.EntityStatusArgs{
   411  			{
   412  				Tag:    names.NewApplicationTag("mysql").String(),
   413  				Status: "blocked",
   414  				Info:   "a message",
   415  			}}})
   416  		c.Assert(result, gc.FitsTypeOf, &params.ErrorResults{})
   417  		*(result.(*params.ErrorResults)) = params.ErrorResults{
   418  			Results: []params.ErrorResult{{
   419  				Error: &params.Error{Message: "FAIL"},
   420  			}},
   421  		}
   422  		callCount++
   423  		return nil
   424  	})
   425  	client := remoterelations.NewClient(apiCaller)
   426  	err := client.SetRemoteApplicationStatus("mysql", status.Blocked, "a message")
   427  	c.Check(err, gc.ErrorMatches, "FAIL")
   428  	c.Check(callCount, gc.Equals, 1)
   429  }
   430  
   431  func (s *remoteRelationsSuite) TestUpdateControllerForModelResultCount(c *gc.C) {
   432  	apiCaller := testing.APICallerFunc(
   433  		func(objType string, version int, id, request string, arg, result interface{}) error {
   434  			c.Assert(request, gc.Equals, "UpdateControllersForModels")
   435  			*(result.(*params.ErrorResults)) = params.ErrorResults{
   436  				Results: []params.ErrorResult{
   437  					{Error: &params.Error{Message: "FAIL"}},
   438  					{Error: &params.Error{Message: "FAIL"}},
   439  				},
   440  			}
   441  			return nil
   442  		},
   443  	)
   444  
   445  	client := remoterelations.NewClient(apiCaller)
   446  	err := client.UpdateControllerForModel(crossmodel.ControllerInfo{}, "some-model-uuid")
   447  	c.Check(err, gc.ErrorMatches, `expected 1 result, got 2`)
   448  }
   449  
   450  func (s *remoteRelationsSuite) TestUpdateControllerForModelResultError(c *gc.C) {
   451  	apiCaller := testing.APICallerFunc(
   452  		func(objType string, version int, id, request string, arg, result interface{}) error {
   453  			c.Assert(request, gc.Equals, "UpdateControllersForModels")
   454  			*(result.(*params.ErrorResults)) = params.ErrorResults{
   455  				Results: []params.ErrorResult{{Error: &params.Error{Message: "FAIL"}}},
   456  			}
   457  			return nil
   458  		},
   459  	)
   460  
   461  	client := remoterelations.NewClient(apiCaller)
   462  	err := client.UpdateControllerForModel(crossmodel.ControllerInfo{}, "some-model-uuid")
   463  	c.Check(err, gc.ErrorMatches, `FAIL`)
   464  }
   465  
   466  func (s *remoteRelationsSuite) TestUpdateControllerForModelResultSuccess(c *gc.C) {
   467  	apiCaller := testing.APICallerFunc(
   468  		func(objType string, version int, id, request string, arg, result interface{}) error {
   469  			c.Assert(request, gc.Equals, "UpdateControllersForModels")
   470  			*(result.(*params.ErrorResults)) = params.ErrorResults{Results: []params.ErrorResult{{}}}
   471  			return nil
   472  		},
   473  	)
   474  
   475  	client := remoterelations.NewClient(apiCaller)
   476  	err := client.UpdateControllerForModel(crossmodel.ControllerInfo{}, "some-model-uuid")
   477  	c.Check(err, jc.ErrorIsNil)
   478  }
   479  
   480  func (s *remoteRelationsSuite) TestConsumeRemoteSecretChange(c *gc.C) {
   481  	var callCount int
   482  	uri := secrets.NewURI()
   483  	apiCaller := testing.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error {
   484  		c.Check(objType, gc.Equals, "RemoteRelations")
   485  		c.Check(version, gc.Equals, 0)
   486  		c.Check(id, gc.Equals, "")
   487  		c.Check(request, gc.Equals, "ConsumeRemoteSecretChanges")
   488  		c.Check(arg, jc.DeepEquals, params.LatestSecretRevisionChanges{
   489  			Changes: []params.SecretRevisionChange{{
   490  				URI:      uri.String(),
   491  				Revision: 666,
   492  			}},
   493  		})
   494  		c.Assert(result, gc.FitsTypeOf, &params.ErrorResults{})
   495  		*(result.(*params.ErrorResults)) = params.ErrorResults{
   496  			Results: []params.ErrorResult{{
   497  				Error: &params.Error{Message: "FAIL"},
   498  			}}}
   499  		callCount++
   500  		return nil
   501  	})
   502  
   503  	changes := []watcher.SecretRevisionChange{{
   504  		URI:      uri,
   505  		Revision: 666,
   506  	}}
   507  	client := remoterelations.NewClient(apiCaller)
   508  	err := client.ConsumeRemoteSecretChanges(changes)
   509  	c.Check(err, gc.ErrorMatches, "FAIL")
   510  	c.Check(callCount, gc.Equals, 1)
   511  }