github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/apiserver/facades/client/applicationoffers/mock_test.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package applicationoffers_test
     5  
     6  import (
     7  	"fmt"
     8  	"time"
     9  
    10  	"github.com/juju/errors"
    11  	jtesting "github.com/juju/testing"
    12  	"gopkg.in/juju/charm.v6"
    13  	"gopkg.in/juju/names.v2"
    14  	"gopkg.in/macaroon-bakery.v2-unstable/bakery/checkers"
    15  	"gopkg.in/macaroon.v2-unstable"
    16  
    17  	"github.com/juju/juju/apiserver/authentication"
    18  	"github.com/juju/juju/apiserver/common"
    19  	"github.com/juju/juju/apiserver/common/crossmodel"
    20  	"github.com/juju/juju/apiserver/facades/client/applicationoffers"
    21  	jujucrossmodel "github.com/juju/juju/core/crossmodel"
    22  	"github.com/juju/juju/core/status"
    23  	"github.com/juju/juju/environs"
    24  	"github.com/juju/juju/environs/context"
    25  	"github.com/juju/juju/network"
    26  	"github.com/juju/juju/permission"
    27  	"github.com/juju/juju/state"
    28  	"github.com/juju/juju/testing"
    29  )
    30  
    31  const (
    32  	offerCall       = "offerCall"
    33  	offerCallUUID   = "offerCallUUID"
    34  	addOfferCall    = "addOffersCall"
    35  	listOffersCall  = "listOffersCall"
    36  	updateOfferCall = "updateOfferCall"
    37  	removeOfferCall = "removeOfferCall"
    38  )
    39  
    40  type stubApplicationOffers struct {
    41  	jtesting.Stub
    42  	jujucrossmodel.ApplicationOffers
    43  
    44  	addOffer   func(offer jujucrossmodel.AddApplicationOfferArgs) (*jujucrossmodel.ApplicationOffer, error)
    45  	listOffers func(filters ...jujucrossmodel.ApplicationOfferFilter) ([]jujucrossmodel.ApplicationOffer, error)
    46  }
    47  
    48  func (m *stubApplicationOffers) AddOffer(offer jujucrossmodel.AddApplicationOfferArgs) (*jujucrossmodel.ApplicationOffer, error) {
    49  	m.AddCall(addOfferCall)
    50  	return m.addOffer(offer)
    51  }
    52  
    53  func (m *stubApplicationOffers) ListOffers(filters ...jujucrossmodel.ApplicationOfferFilter) ([]jujucrossmodel.ApplicationOffer, error) {
    54  	m.AddCall(listOffersCall)
    55  	return m.listOffers(filters...)
    56  }
    57  
    58  func (m *stubApplicationOffers) UpdateOffer(offer jujucrossmodel.AddApplicationOfferArgs) (*jujucrossmodel.ApplicationOffer, error) {
    59  	m.AddCall(updateOfferCall)
    60  	panic("not implemented")
    61  }
    62  
    63  func (m *stubApplicationOffers) Remove(url string, force bool) error {
    64  	m.AddCall(removeOfferCall)
    65  	panic("not implemented")
    66  }
    67  
    68  func (m *stubApplicationOffers) ApplicationOffer(name string) (*jujucrossmodel.ApplicationOffer, error) {
    69  	m.AddCall(offerCall)
    70  	panic("not implemented")
    71  }
    72  
    73  func (m *stubApplicationOffers) ApplicationOfferForUUID(uuid string) (*jujucrossmodel.ApplicationOffer, error) {
    74  	m.AddCall(offerCallUUID)
    75  	panic("not implemented")
    76  }
    77  
    78  type mockEnviron struct {
    79  	environs.NetworkingEnviron
    80  
    81  	stub      jtesting.Stub
    82  	spaceInfo *environs.ProviderSpaceInfo
    83  }
    84  
    85  func (e *mockEnviron) ProviderSpaceInfo(ctx context.ProviderCallContext, space *network.SpaceInfo) (*environs.ProviderSpaceInfo, error) {
    86  	e.stub.MethodCall(e, "ProviderSpaceInfo", space)
    87  	spaceName := environs.DefaultSpaceName
    88  	if space != nil {
    89  		spaceName = space.Name
    90  	}
    91  	if e.spaceInfo == nil || spaceName != e.spaceInfo.Name {
    92  		return nil, errors.NotFoundf("space %q", spaceName)
    93  	}
    94  	return e.spaceInfo, e.stub.NextErr()
    95  }
    96  
    97  type mockModel struct {
    98  	uuid      string
    99  	name      string
   100  	owner     string
   101  	modelType state.ModelType
   102  }
   103  
   104  func (m *mockModel) UUID() string {
   105  	return m.uuid
   106  }
   107  
   108  func (m *mockModel) ModelTag() names.ModelTag {
   109  	return names.NewModelTag(m.uuid)
   110  }
   111  
   112  func (m *mockModel) Type() state.ModelType {
   113  	return m.modelType
   114  }
   115  
   116  func (m *mockModel) Name() string {
   117  	return m.name
   118  }
   119  
   120  func (m *mockModel) Owner() names.UserTag {
   121  	return names.NewUserTag(m.owner)
   122  }
   123  
   124  type mockCharm struct {
   125  	meta *charm.Meta
   126  }
   127  
   128  func (m *mockCharm) Meta() *charm.Meta {
   129  	return m.meta
   130  }
   131  
   132  func (m *mockCharm) StoragePath() string {
   133  	return "storage-path"
   134  }
   135  
   136  type mockApplication struct {
   137  	crossmodel.Application
   138  	name      string
   139  	charm     *mockCharm
   140  	curl      *charm.URL
   141  	endpoints []state.Endpoint
   142  	bindings  map[string]string
   143  }
   144  
   145  func (m *mockApplication) Name() string {
   146  	return m.name
   147  }
   148  
   149  func (m *mockApplication) Charm() (crossmodel.Charm, bool, error) {
   150  	return m.charm, true, nil
   151  }
   152  
   153  func (m *mockApplication) CharmURL() (curl *charm.URL, force bool) {
   154  	return m.curl, true
   155  }
   156  
   157  func (m *mockApplication) Endpoints() ([]state.Endpoint, error) {
   158  	return m.endpoints, nil
   159  }
   160  
   161  func (m *mockApplication) EndpointBindings() (map[string]string, error) {
   162  	return m.bindings, nil
   163  }
   164  
   165  type mockSpace struct {
   166  	name       string
   167  	providerId network.Id
   168  	subnets    []applicationoffers.Subnet
   169  }
   170  
   171  func (m *mockSpace) Name() string {
   172  	return m.name
   173  }
   174  
   175  func (m *mockSpace) Subnets() ([]applicationoffers.Subnet, error) {
   176  	return m.subnets, nil
   177  }
   178  
   179  func (m *mockSpace) ProviderId() network.Id {
   180  	return m.providerId
   181  }
   182  
   183  type mockSubnet struct {
   184  	cidr              string
   185  	vlantag           int
   186  	providerId        network.Id
   187  	providerNetworkId network.Id
   188  	zones             []string
   189  }
   190  
   191  func (m *mockSubnet) CIDR() string {
   192  	return m.cidr
   193  }
   194  
   195  func (m *mockSubnet) VLANTag() int {
   196  	return m.vlantag
   197  }
   198  
   199  func (m *mockSubnet) ProviderId() network.Id {
   200  	return m.providerId
   201  }
   202  
   203  func (m *mockSubnet) ProviderNetworkId() network.Id {
   204  	return m.providerNetworkId
   205  }
   206  
   207  func (m *mockSubnet) AvailabilityZones() []string {
   208  	return m.zones
   209  }
   210  
   211  type mockRelation struct {
   212  	crossmodel.Relation
   213  	id       int
   214  	endpoint state.Endpoint
   215  }
   216  
   217  func (m *mockRelation) Status() (status.StatusInfo, error) {
   218  	return status.StatusInfo{Status: status.Joined}, nil
   219  }
   220  
   221  func (m *mockRelation) Endpoint(appName string) (state.Endpoint, error) {
   222  	if m.endpoint.ApplicationName != appName {
   223  		return state.Endpoint{}, errors.NotFoundf("endpoint for %q", appName)
   224  	}
   225  	return m.endpoint, nil
   226  }
   227  
   228  type mockOfferConnection struct {
   229  	modelUUID   string
   230  	username    string
   231  	relationKey string
   232  	relationId  int
   233  }
   234  
   235  func (m *mockOfferConnection) SourceModelUUID() string {
   236  	return m.modelUUID
   237  }
   238  
   239  func (m *mockOfferConnection) UserName() string {
   240  	return m.username
   241  }
   242  
   243  func (m *mockOfferConnection) RelationKey() string {
   244  	return m.relationKey
   245  }
   246  
   247  func (m *mockOfferConnection) RelationId() int {
   248  	return m.relationId
   249  }
   250  
   251  type mockApplicationOffers struct {
   252  	jujucrossmodel.ApplicationOffers
   253  	st *mockState
   254  }
   255  
   256  func (m *mockApplicationOffers) ListOffers(filters ...jujucrossmodel.ApplicationOfferFilter) ([]jujucrossmodel.ApplicationOffer, error) {
   257  	var result []jujucrossmodel.ApplicationOffer
   258  	for _, f := range filters {
   259  		if offer, ok := m.st.applicationOffers[f.OfferName]; ok {
   260  			result = append(result, offer)
   261  		}
   262  	}
   263  	return result, nil
   264  }
   265  
   266  func (m *mockApplicationOffers) Remove(name string, force bool) error {
   267  	if len(m.st.connections) > 0 && !force {
   268  		return errors.Errorf("offer has %d relations", len(m.st.connections))
   269  	}
   270  	_, ok := m.st.applicationOffers[name]
   271  	if !ok {
   272  		return errors.NotFoundf("application offer %q", name)
   273  	}
   274  	delete(m.st.applicationOffers, name)
   275  	return nil
   276  }
   277  
   278  type offerAccess struct {
   279  	user      names.UserTag
   280  	offerUUID string
   281  }
   282  
   283  type mockState struct {
   284  	crossmodel.Backend
   285  	common.AddressAndCertGetter
   286  	modelUUID         string
   287  	model             *mockModel
   288  	allmodels         []applicationoffers.Model
   289  	users             map[string]applicationoffers.User
   290  	applications      map[string]crossmodel.Application
   291  	applicationOffers map[string]jujucrossmodel.ApplicationOffer
   292  	spaces            map[string]applicationoffers.Space
   293  	relations         map[string]crossmodel.Relation
   294  	connections       []applicationoffers.OfferConnection
   295  	accessPerms       map[offerAccess]permission.Access
   296  	relationNetworks  state.RelationNetworks
   297  }
   298  
   299  func (m *mockState) GetAddressAndCertGetter() common.AddressAndCertGetter {
   300  	return m
   301  }
   302  
   303  func (m *mockState) ControllerTag() names.ControllerTag {
   304  	return testing.ControllerTag
   305  }
   306  
   307  func (m *mockState) Charm(*charm.URL) (crossmodel.Charm, error) {
   308  	return &mockCharm{}, nil
   309  }
   310  
   311  func (m *mockState) Application(name string) (crossmodel.Application, error) {
   312  	app, ok := m.applications[name]
   313  	if !ok {
   314  		return nil, errors.NotFoundf("application %q", name)
   315  	}
   316  	return app, nil
   317  }
   318  
   319  func (m *mockState) ApplicationOffer(name string) (*jujucrossmodel.ApplicationOffer, error) {
   320  	offer, ok := m.applicationOffers[name]
   321  	if !ok {
   322  		return nil, errors.NotFoundf("application offer %q", name)
   323  	}
   324  	return &offer, nil
   325  }
   326  
   327  func (m *mockState) Space(name string) (applicationoffers.Space, error) {
   328  	space, ok := m.spaces[name]
   329  	if !ok {
   330  		return nil, errors.NotFoundf("space %q", name)
   331  	}
   332  	return space, nil
   333  }
   334  
   335  func (m *mockState) Model() (applicationoffers.Model, error) {
   336  	return m.model, nil
   337  }
   338  
   339  func (m *mockState) ModelUUID() string {
   340  	return m.modelUUID
   341  }
   342  
   343  func (m *mockState) ModelTag() names.ModelTag {
   344  	return names.NewModelTag(m.modelUUID)
   345  }
   346  
   347  func (m *mockState) AllModelUUIDs() ([]string, error) {
   348  	if len(m.allmodels) == 0 {
   349  		return []string{m.model.UUID()}, nil
   350  	}
   351  
   352  	var out []string
   353  	for _, model := range m.allmodels {
   354  		out = append(out, model.UUID())
   355  	}
   356  	return out, nil
   357  }
   358  
   359  func (m *mockState) KeyRelation(key string) (crossmodel.Relation, error) {
   360  	rel, ok := m.relations[key]
   361  	if !ok {
   362  		return nil, errors.NotFoundf("relation key %v", key)
   363  	}
   364  	return rel, nil
   365  }
   366  
   367  func (m *mockState) OfferConnections(offerUUID string) ([]applicationoffers.OfferConnection, error) {
   368  	return m.connections, nil
   369  }
   370  
   371  func (m *mockState) User(tag names.UserTag) (applicationoffers.User, error) {
   372  	user, ok := m.users[tag.Id()]
   373  	if !ok {
   374  		return nil, errors.NotFoundf("user %v", tag.Id())
   375  	}
   376  	return user, nil
   377  }
   378  
   379  type mockUser struct {
   380  	name string
   381  }
   382  
   383  func (m *mockUser) DisplayName() string {
   384  	return m.name
   385  }
   386  
   387  type mockRelationNetworks struct {
   388  	state.RelationNetworks
   389  }
   390  
   391  func (m *mockRelationNetworks) CIDRS() []string {
   392  	return []string{"192.168.1.0/32", "10.0.0.0/8"}
   393  }
   394  
   395  func (m *mockState) IngressNetworks(relationKey string) (state.RelationNetworks, error) {
   396  	if m.relationNetworks == nil {
   397  		return nil, errors.NotFoundf("ingress networks")
   398  	}
   399  	return m.relationNetworks, nil
   400  }
   401  
   402  func (m *mockState) GetOfferAccess(offerUUID string, user names.UserTag) (permission.Access, error) {
   403  	access, ok := m.accessPerms[offerAccess{user: user, offerUUID: offerUUID}]
   404  	if !ok {
   405  		return "", errors.NotFoundf("offer access for %v", user)
   406  	}
   407  	return access, nil
   408  }
   409  
   410  func (m *mockState) CreateOfferAccess(offer names.ApplicationOfferTag, user names.UserTag, access permission.Access) error {
   411  	if _, ok := m.users[user.Name()]; !ok {
   412  		return errors.NotFoundf("user %q", user.Name())
   413  	}
   414  	if _, ok := m.accessPerms[offerAccess{user: user, offerUUID: offer.Id() + "-uuid"}]; ok {
   415  		return errors.NewAlreadyExists(nil, fmt.Sprintf("offer user %s", user.Name()))
   416  	}
   417  	m.accessPerms[offerAccess{user: user, offerUUID: offer.Id() + "-uuid"}] = access
   418  	return nil
   419  }
   420  
   421  func (m *mockState) UpdateOfferAccess(offer names.ApplicationOfferTag, user names.UserTag, access permission.Access) error {
   422  	if _, ok := m.users[user.Name()]; !ok {
   423  		return errors.NotFoundf("user %q", user.Name())
   424  	}
   425  	if _, ok := m.accessPerms[offerAccess{user: user, offerUUID: offer.Id() + "-uuid"}]; !ok {
   426  		return errors.NewNotFound(nil, fmt.Sprintf("offer user %s", user.Name()))
   427  	}
   428  	m.accessPerms[offerAccess{user: user, offerUUID: offer.Id() + "-uuid"}] = access
   429  	return nil
   430  }
   431  
   432  func (m *mockState) RemoveOfferAccess(offer names.ApplicationOfferTag, user names.UserTag) error {
   433  	if _, ok := m.users[user.Name()]; !ok {
   434  		return errors.NewNotFound(nil, fmt.Sprintf("offer user %q does not exist", user.Name()))
   435  	}
   436  	delete(m.accessPerms, offerAccess{user: user, offerUUID: offer.Id() + "-uuid"})
   437  	return nil
   438  }
   439  
   440  func (m *mockState) GetOfferUsers(offerUUID string) (map[string]permission.Access, error) {
   441  	result := make(map[string]permission.Access)
   442  	for offerAccess, access := range m.accessPerms {
   443  		if offerAccess.offerUUID != offerUUID {
   444  			continue
   445  		}
   446  		result[offerAccess.user.Id()] = access
   447  	}
   448  	return result, nil
   449  }
   450  
   451  type mockStatePool struct {
   452  	st map[string]applicationoffers.Backend
   453  }
   454  
   455  func (st *mockStatePool) Get(modelUUID string) (applicationoffers.Backend, func(), error) {
   456  	backend, ok := st.st[modelUUID]
   457  	if !ok {
   458  		return nil, nil, errors.NotFoundf("model for uuid %s", modelUUID)
   459  	}
   460  	return backend, func() {}, nil
   461  }
   462  
   463  func (st *mockStatePool) GetModel(modelUUID string) (applicationoffers.Model, func(), error) {
   464  	backend, ok := st.st[modelUUID]
   465  	if !ok {
   466  		return nil, nil, errors.NotFoundf("model for uuid %s", modelUUID)
   467  	}
   468  	model, err := backend.Model()
   469  	if err != nil {
   470  		return nil, nil, err
   471  	}
   472  	return model, func() {}, nil
   473  }
   474  
   475  type mockCommonStatePool struct {
   476  	*mockStatePool
   477  }
   478  
   479  func (st *mockCommonStatePool) Get(modelUUID string) (crossmodel.Backend, func(), error) {
   480  	return st.mockStatePool.Get(modelUUID)
   481  }
   482  
   483  type mockBakeryService struct {
   484  	authentication.ExpirableStorageBakeryService
   485  	jtesting.Stub
   486  	caveats map[string][]checkers.Caveat
   487  }
   488  
   489  func (s *mockBakeryService) NewMacaroon(caveats []checkers.Caveat) (*macaroon.Macaroon, error) {
   490  	s.MethodCall(s, "NewMacaroon", caveats)
   491  	s.caveats["id"] = caveats
   492  	return macaroon.New(nil, []byte("id"), "")
   493  }
   494  
   495  func (s *mockBakeryService) ExpireStorageAfter(when time.Duration) (authentication.ExpirableStorageBakeryService, error) {
   496  	s.MethodCall(s, "ExpireStorageAfter", when)
   497  	return s, nil
   498  }
   499  
   500  func getFakeControllerInfo() ([]string, string, error) {
   501  	return []string{"192.168.1.1:17070"}, testing.CACert, nil
   502  }