github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/apiserver/common/firewall/mock_test.go (about)

     1  // Copyright 2017 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package firewall_test
     5  
     6  import (
     7  	"sync"
     8  
     9  	"github.com/juju/errors"
    10  	"github.com/juju/testing"
    11  	"gopkg.in/juju/names.v2"
    12  	"gopkg.in/macaroon.v2-unstable"
    13  	"gopkg.in/tomb.v2"
    14  
    15  	"github.com/juju/juju/apiserver/common/cloudspec"
    16  	"github.com/juju/juju/apiserver/common/firewall"
    17  	"github.com/juju/juju/apiserver/params"
    18  	"github.com/juju/juju/controller"
    19  	"github.com/juju/juju/core/crossmodel"
    20  	"github.com/juju/juju/environs/config"
    21  	"github.com/juju/juju/network"
    22  	"github.com/juju/juju/state"
    23  	coretesting "github.com/juju/juju/testing"
    24  )
    25  
    26  type mockCloudSpecAPI struct {
    27  	// TODO - implement when remaining firewaller tests become unit tests
    28  	cloudspec.CloudSpecAPI
    29  }
    30  
    31  type mockState struct {
    32  	// TODO - implement when remaining firewaller tests become unit tests
    33  	state.ModelMachinesWatcher
    34  
    35  	testing.Stub
    36  	modelUUID      string
    37  	remoteEntities map[names.Tag]string
    38  	macaroons      map[names.Tag]*macaroon.Macaroon
    39  	applications   map[string]*mockApplication
    40  	units          map[string]*mockUnit
    41  	machines       map[string]*mockMachine
    42  	relations      map[string]*mockRelation
    43  	controllerInfo map[string]*mockControllerInfo
    44  	subnetsWatcher *mockStringsWatcher
    45  	modelWatcher   *mockNotifyWatcher
    46  	configAttrs    map[string]interface{}
    47  }
    48  
    49  func newMockState(modelUUID string) *mockState {
    50  	return &mockState{
    51  		modelUUID:      modelUUID,
    52  		relations:      make(map[string]*mockRelation),
    53  		applications:   make(map[string]*mockApplication),
    54  		units:          make(map[string]*mockUnit),
    55  		machines:       make(map[string]*mockMachine),
    56  		remoteEntities: make(map[names.Tag]string),
    57  		macaroons:      make(map[names.Tag]*macaroon.Macaroon),
    58  		controllerInfo: make(map[string]*mockControllerInfo),
    59  		subnetsWatcher: newMockStringsWatcher(),
    60  		modelWatcher:   newMockNotifyWatcher(),
    61  		configAttrs:    coretesting.FakeConfig(),
    62  	}
    63  }
    64  
    65  func (st *mockState) WatchForModelConfigChanges() state.NotifyWatcher {
    66  	return st.modelWatcher
    67  }
    68  
    69  func (st *mockState) ModelConfig() (*config.Config, error) {
    70  	return config.New(config.UseDefaults, st.configAttrs)
    71  }
    72  
    73  func (st *mockState) ControllerConfig() (controller.Config, error) {
    74  	return nil, errors.NotImplementedf("ControllerConfig")
    75  }
    76  
    77  func (st *mockState) ControllerInfo(modelUUID string) ([]string, string, error) {
    78  	if info, ok := st.controllerInfo[modelUUID]; !ok {
    79  		return nil, "", errors.NotFoundf("controller info for %v", modelUUID)
    80  	} else {
    81  		return info.ControllerInfo().Addrs, info.ControllerInfo().CACert, nil
    82  	}
    83  }
    84  
    85  func (st *mockState) GetMacaroon(model names.ModelTag, entity names.Tag) (*macaroon.Macaroon, error) {
    86  	st.MethodCall(st, "GetMacaroon", model, entity)
    87  	if err := st.NextErr(); err != nil {
    88  		return nil, err
    89  	}
    90  	mac, ok := st.macaroons[entity]
    91  	if !ok {
    92  		return nil, errors.NotFoundf("macaroon for %v", entity)
    93  	}
    94  	return mac, nil
    95  }
    96  
    97  func (st *mockState) ModelUUID() string {
    98  	return st.modelUUID
    99  }
   100  
   101  func (st *mockState) Application(id string) (firewall.Application, error) {
   102  	st.MethodCall(st, "Application", id)
   103  	if err := st.NextErr(); err != nil {
   104  		return nil, err
   105  	}
   106  	a, ok := st.applications[id]
   107  	if !ok {
   108  		return nil, errors.NotFoundf("application %q", id)
   109  	}
   110  	return a, nil
   111  }
   112  
   113  func (st *mockState) Unit(name string) (firewall.Unit, error) {
   114  	st.MethodCall(st, "Unit", name)
   115  	if err := st.NextErr(); err != nil {
   116  		return nil, err
   117  	}
   118  	u, ok := st.units[name]
   119  	if !ok {
   120  		return nil, errors.NotFoundf("unit %q", name)
   121  	}
   122  	return u, nil
   123  }
   124  
   125  func (st *mockState) Machine(id string) (firewall.Machine, error) {
   126  	st.MethodCall(st, "Machine", id)
   127  	if err := st.NextErr(); err != nil {
   128  		return nil, err
   129  	}
   130  	m, ok := st.machines[id]
   131  	if !ok {
   132  		return nil, errors.NotFoundf("machine %q", id)
   133  	}
   134  	return m, nil
   135  }
   136  
   137  func (st *mockState) WatchSubnets(func(id interface{}) bool) state.StringsWatcher {
   138  	st.MethodCall(st, "WatchSubnets")
   139  	return st.subnetsWatcher
   140  }
   141  
   142  func (st *mockState) WatchOpenedPorts() state.StringsWatcher {
   143  	st.MethodCall(st, "WatchOpenedPorts")
   144  	// TODO - implement when remaining firewaller tests become unit tests
   145  	return nil
   146  }
   147  
   148  func (st *mockState) FindEntity(tag names.Tag) (state.Entity, error) {
   149  	st.MethodCall(st, "FindEntity")
   150  	// TODO - implement when remaining firewaller tests become unit tests
   151  	return nil, errors.NotImplementedf("FindEntity")
   152  }
   153  
   154  func (st *mockState) GetModel(tag names.ModelTag) (*state.Model, error) {
   155  	st.MethodCall(st, "GetModel", tag)
   156  	// TODO - implement when remaining firewaller tests become unit tests
   157  	return nil, errors.NotImplementedf("GetModel")
   158  }
   159  
   160  type mockWatcher struct {
   161  	testing.Stub
   162  	tomb.Tomb
   163  }
   164  
   165  func (w *mockWatcher) Kill() {
   166  	w.MethodCall(w, "Kill")
   167  	w.Tomb.Kill(nil)
   168  }
   169  
   170  func (w *mockWatcher) Stop() error {
   171  	w.MethodCall(w, "Stop")
   172  	if err := w.NextErr(); err != nil {
   173  		return err
   174  	}
   175  	w.Tomb.Kill(nil)
   176  	return w.Tomb.Wait()
   177  }
   178  
   179  func (w *mockWatcher) Err() error {
   180  	w.MethodCall(w, "Err")
   181  	return w.Tomb.Err()
   182  }
   183  
   184  type mockStringsWatcher struct {
   185  	mockWatcher
   186  	changes chan []string
   187  }
   188  
   189  func newMockStringsWatcher() *mockStringsWatcher {
   190  	w := &mockStringsWatcher{changes: make(chan []string, 1)}
   191  	w.Tomb.Go(func() error {
   192  		<-w.Tomb.Dying()
   193  		return nil
   194  	})
   195  	return w
   196  }
   197  
   198  func (w *mockStringsWatcher) Changes() <-chan []string {
   199  	w.MethodCall(w, "Changes")
   200  	return w.changes
   201  }
   202  
   203  func newMockNotifyWatcher() *mockNotifyWatcher {
   204  	w := &mockNotifyWatcher{changes: make(chan struct{}, 1)}
   205  	// Initial event
   206  	w.changes <- struct{}{}
   207  	w.Tomb.Go(func() error {
   208  		<-w.Tomb.Dying()
   209  		return nil
   210  	})
   211  	return w
   212  }
   213  
   214  type mockNotifyWatcher struct {
   215  	mockWatcher
   216  	changes chan struct{}
   217  }
   218  
   219  func (w *mockNotifyWatcher) Changes() <-chan struct{} {
   220  	w.MethodCall(w, "Changes")
   221  	return w.changes
   222  }
   223  
   224  type mockApplication struct {
   225  	testing.Stub
   226  	name  string
   227  	units []*mockUnit
   228  }
   229  
   230  func newMockApplication(name string) *mockApplication {
   231  	return &mockApplication{
   232  		name: name,
   233  	}
   234  }
   235  
   236  func (a *mockApplication) Name() string {
   237  	a.MethodCall(a, "Name")
   238  	return a.name
   239  }
   240  
   241  func (a *mockApplication) AllUnits() (results []firewall.Unit, err error) {
   242  	a.MethodCall(a, "AllUnits")
   243  	for _, unit := range a.units {
   244  		results = append(results, unit)
   245  	}
   246  	return results, a.NextErr()
   247  }
   248  
   249  type mockControllerInfo struct {
   250  	uuid string
   251  	info crossmodel.ControllerInfo
   252  }
   253  
   254  func (c *mockControllerInfo) Id() string {
   255  	return c.uuid
   256  }
   257  
   258  func (c *mockControllerInfo) ControllerInfo() crossmodel.ControllerInfo {
   259  	return c.info
   260  }
   261  
   262  type mockRelation struct {
   263  	testing.Stub
   264  	firewall.Relation
   265  	id        int
   266  	key       string
   267  	endpoints []state.Endpoint
   268  	ruw       *mockRelationUnitsWatcher
   269  	ew        *mockStringsWatcher
   270  	ruwApp    string
   271  }
   272  
   273  func newMockRelation(id int) *mockRelation {
   274  	return &mockRelation{
   275  		id:  id,
   276  		ruw: newMockRelationUnitsWatcher(),
   277  		ew:  newMockStringsWatcher(),
   278  	}
   279  }
   280  
   281  func (r *mockRelation) Id() int {
   282  	r.MethodCall(r, "Id")
   283  	return r.id
   284  }
   285  
   286  func (r *mockRelation) Endpoints() []state.Endpoint {
   287  	r.MethodCall(r, "Endpoints")
   288  	return r.endpoints
   289  }
   290  
   291  func (r *mockRelation) WatchUnits(applicationName string) (state.RelationUnitsWatcher, error) {
   292  	if r.ruwApp != applicationName {
   293  		return nil, errors.Errorf("unexpected app %v", applicationName)
   294  	}
   295  	return r.ruw, nil
   296  }
   297  
   298  func (r *mockRelation) WatchRelationEgressNetworks() state.StringsWatcher {
   299  	return r.ew
   300  }
   301  
   302  func newMockRelationUnitsWatcher() *mockRelationUnitsWatcher {
   303  	w := &mockRelationUnitsWatcher{changes: make(chan params.RelationUnitsChange, 1)}
   304  	w.Tomb.Go(func() error {
   305  		<-w.Tomb.Dying()
   306  		return nil
   307  	})
   308  	return w
   309  }
   310  
   311  type mockRelationUnitsWatcher struct {
   312  	mockWatcher
   313  	changes chan params.RelationUnitsChange
   314  }
   315  
   316  func (w *mockRelationUnitsWatcher) Changes() <-chan params.RelationUnitsChange {
   317  	return w.changes
   318  }
   319  
   320  func (st *mockState) GetRemoteEntity(sourceModel names.ModelTag, token string) (names.Tag, error) {
   321  	st.MethodCall(st, "GetRemoteEntity", sourceModel, token)
   322  	if err := st.NextErr(); err != nil {
   323  		return nil, err
   324  	}
   325  	for e, t := range st.remoteEntities {
   326  		if t == token {
   327  			return e, nil
   328  		}
   329  	}
   330  	return nil, errors.NotFoundf("token %v", token)
   331  }
   332  
   333  func (st *mockState) KeyRelation(key string) (firewall.Relation, error) {
   334  	st.MethodCall(st, "KeyRelation", key)
   335  	if err := st.NextErr(); err != nil {
   336  		return nil, err
   337  	}
   338  	r, ok := st.relations[key]
   339  	if !ok {
   340  		return nil, errors.NotFoundf("relation %q", key)
   341  	}
   342  	return r, nil
   343  }
   344  
   345  type mockUnit struct {
   346  	testing.Stub
   347  	mu            sync.Mutex
   348  	name          string
   349  	assigned      bool
   350  	publicAddress network.Address
   351  	machineId     string
   352  }
   353  
   354  func newMockUnit(name string) *mockUnit {
   355  	return &mockUnit{
   356  		name:     name,
   357  		assigned: true,
   358  	}
   359  }
   360  
   361  func (u *mockUnit) Name() string {
   362  	u.MethodCall(u, "Name")
   363  	return u.name
   364  }
   365  
   366  func (u *mockUnit) PublicAddress() (network.Address, error) {
   367  	u.MethodCall(u, "PublicAddress")
   368  	u.mu.Lock()
   369  	defer u.mu.Unlock()
   370  
   371  	if err := u.NextErr(); err != nil {
   372  		return network.Address{}, err
   373  	}
   374  	if !u.assigned {
   375  		return network.Address{}, errors.NotAssignedf(u.name)
   376  	}
   377  	if u.publicAddress.Value == "" {
   378  		return network.Address{}, network.NoAddressError("public")
   379  	}
   380  	return u.publicAddress, nil
   381  }
   382  
   383  func (u *mockUnit) AssignedMachineId() (string, error) {
   384  	u.MethodCall(u, "AssignedMachineId")
   385  	if err := u.NextErr(); err != nil {
   386  		return "", err
   387  	}
   388  	if !u.assigned {
   389  		return "", errors.NotAssignedf(u.name)
   390  	}
   391  	return u.machineId, nil
   392  }
   393  
   394  func (u *mockUnit) updateAddress(value string) {
   395  	u.mu.Lock()
   396  	defer u.mu.Unlock()
   397  
   398  	u.publicAddress = network.Address{Value: value}
   399  }
   400  
   401  type mockMachine struct {
   402  	testing.Stub
   403  	id      string
   404  	watcher *mockAddressWatcher
   405  }
   406  
   407  func newMockMachine(id string) *mockMachine {
   408  	return &mockMachine{
   409  		id:      id,
   410  		watcher: newMockAddressWatcher(),
   411  	}
   412  }
   413  
   414  func (m *mockMachine) Id() string {
   415  	m.MethodCall(m, "Id")
   416  	return m.id
   417  }
   418  
   419  func (m *mockMachine) WatchAddresses() state.NotifyWatcher {
   420  	m.MethodCall(m, "WatchAddresses")
   421  	return m.watcher
   422  }
   423  
   424  type mockAddressWatcher struct {
   425  	mockWatcher
   426  	changes chan struct{}
   427  }
   428  
   429  func newMockAddressWatcher() *mockAddressWatcher {
   430  	w := &mockAddressWatcher{changes: make(chan struct{}, 1)}
   431  	w.Tomb.Go(func() error {
   432  		<-w.Tomb.Dying()
   433  		return nil
   434  	})
   435  	return w
   436  }
   437  
   438  func (w *mockAddressWatcher) Changes() <-chan struct{} {
   439  	w.MethodCall(w, "Changes")
   440  	return w.changes
   441  }