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

     1  // Copyright 2017 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package firewaller_test
     5  
     6  import (
     7  	"sync"
     8  
     9  	"github.com/juju/collections/set"
    10  	"github.com/juju/errors"
    11  	"github.com/juju/testing"
    12  	"gopkg.in/juju/names.v2"
    13  	"gopkg.in/macaroon.v2-unstable"
    14  	"gopkg.in/tomb.v2"
    15  
    16  	"github.com/juju/juju/apiserver/common/cloudspec"
    17  	"github.com/juju/juju/apiserver/common/firewall"
    18  	"github.com/juju/juju/apiserver/params"
    19  	"github.com/juju/juju/controller"
    20  	"github.com/juju/juju/core/crossmodel"
    21  	"github.com/juju/juju/core/status"
    22  	"github.com/juju/juju/environs/config"
    23  	"github.com/juju/juju/network"
    24  	"github.com/juju/juju/state"
    25  	coretesting "github.com/juju/juju/testing"
    26  )
    27  
    28  type mockCloudSpecAPI struct {
    29  	// TODO - implement when remaining firewaller tests become unit tests
    30  	cloudspec.CloudSpecAPI
    31  }
    32  
    33  type mockState struct {
    34  	firewall.State
    35  
    36  	testing.Stub
    37  	modelUUID      string
    38  	remoteEntities map[names.Tag]string
    39  	macaroons      map[names.Tag]*macaroon.Macaroon
    40  	relations      map[string]*mockRelation
    41  	controllerInfo map[string]*mockControllerInfo
    42  	firewallRules  map[state.WellKnownServiceType]*state.FirewallRule
    43  	subnetsWatcher *mockStringsWatcher
    44  	modelWatcher   *mockNotifyWatcher
    45  	configAttrs    map[string]interface{}
    46  }
    47  
    48  func newMockState(modelUUID string) *mockState {
    49  	return &mockState{
    50  		modelUUID:      modelUUID,
    51  		relations:      make(map[string]*mockRelation),
    52  		remoteEntities: make(map[names.Tag]string),
    53  		macaroons:      make(map[names.Tag]*macaroon.Macaroon),
    54  		controllerInfo: make(map[string]*mockControllerInfo),
    55  		firewallRules:  make(map[state.WellKnownServiceType]*state.FirewallRule),
    56  		subnetsWatcher: newMockStringsWatcher(),
    57  		modelWatcher:   newMockNotifyWatcher(),
    58  		configAttrs:    coretesting.FakeConfig(),
    59  	}
    60  }
    61  
    62  func (st *mockState) WatchForModelConfigChanges() state.NotifyWatcher {
    63  	return st.modelWatcher
    64  }
    65  
    66  func (st *mockState) ModelConfig() (*config.Config, error) {
    67  	return config.New(config.UseDefaults, st.configAttrs)
    68  }
    69  
    70  func (st *mockState) ControllerConfig() (controller.Config, error) {
    71  	return nil, errors.NotImplementedf("ControllerConfig")
    72  }
    73  
    74  func (st *mockState) ControllerInfo(modelUUID string) ([]string, string, error) {
    75  	if info, ok := st.controllerInfo[modelUUID]; !ok {
    76  		return nil, "", errors.NotFoundf("controller info for %v", modelUUID)
    77  	} else {
    78  		return info.ControllerInfo().Addrs, info.ControllerInfo().CACert, nil
    79  	}
    80  }
    81  
    82  func (st *mockState) GetMacaroon(entity names.Tag) (*macaroon.Macaroon, error) {
    83  	st.MethodCall(st, "GetMacaroon", entity)
    84  	if err := st.NextErr(); err != nil {
    85  		return nil, err
    86  	}
    87  	mac, ok := st.macaroons[entity]
    88  	if !ok {
    89  		return nil, errors.NotFoundf("macaroon for %v", entity)
    90  	}
    91  	return mac, nil
    92  }
    93  
    94  func (st *mockState) ModelUUID() string {
    95  	return st.modelUUID
    96  }
    97  
    98  func (st *mockState) WatchSubnets(func(id interface{}) bool) state.StringsWatcher {
    99  	st.MethodCall(st, "WatchSubnets")
   100  	return st.subnetsWatcher
   101  }
   102  
   103  func (st *mockState) WatchOpenedPorts() state.StringsWatcher {
   104  	st.MethodCall(st, "WatchOpenedPorts")
   105  	// TODO - implement when remaining firewaller tests become unit tests
   106  	return nil
   107  }
   108  
   109  func (st *mockState) FindEntity(tag names.Tag) (state.Entity, error) {
   110  	st.MethodCall(st, "FindEntity")
   111  	// TODO - implement when remaining firewaller tests become unit tests
   112  	return nil, errors.NotImplementedf("FindEntity")
   113  }
   114  
   115  func (st *mockState) FirewallRule(service state.WellKnownServiceType) (*state.FirewallRule, error) {
   116  	r, ok := st.firewallRules[service]
   117  	if !ok {
   118  		return nil, errors.NotFoundf("firewall rule for %q", service)
   119  	}
   120  	return r, nil
   121  }
   122  
   123  type mockWatcher struct {
   124  	testing.Stub
   125  	tomb.Tomb
   126  }
   127  
   128  func (w *mockWatcher) Kill() {
   129  	w.MethodCall(w, "Kill")
   130  	w.Tomb.Kill(nil)
   131  }
   132  
   133  func (w *mockWatcher) Stop() error {
   134  	w.MethodCall(w, "Stop")
   135  	if err := w.NextErr(); err != nil {
   136  		return err
   137  	}
   138  	w.Tomb.Kill(nil)
   139  	return w.Tomb.Wait()
   140  }
   141  
   142  func (w *mockWatcher) Err() error {
   143  	w.MethodCall(w, "Err")
   144  	return w.Tomb.Err()
   145  }
   146  
   147  type mockStringsWatcher struct {
   148  	mockWatcher
   149  	changes chan []string
   150  }
   151  
   152  func newMockStringsWatcher() *mockStringsWatcher {
   153  	w := &mockStringsWatcher{changes: make(chan []string, 1)}
   154  	w.Tomb.Go(func() error {
   155  		<-w.Tomb.Dying()
   156  		return nil
   157  	})
   158  	return w
   159  }
   160  
   161  func (w *mockStringsWatcher) Changes() <-chan []string {
   162  	w.MethodCall(w, "Changes")
   163  	return w.changes
   164  }
   165  
   166  func newMockNotifyWatcher() *mockNotifyWatcher {
   167  	w := &mockNotifyWatcher{changes: make(chan struct{}, 1)}
   168  	// Initial event
   169  	w.changes <- struct{}{}
   170  	w.Tomb.Go(func() error {
   171  		<-w.Tomb.Dying()
   172  		return nil
   173  	})
   174  	return w
   175  }
   176  
   177  type mockNotifyWatcher struct {
   178  	mockWatcher
   179  	changes chan struct{}
   180  }
   181  
   182  func (w *mockNotifyWatcher) Changes() <-chan struct{} {
   183  	w.MethodCall(w, "Changes")
   184  	return w.changes
   185  }
   186  
   187  type mockApplication struct {
   188  	testing.Stub
   189  	name  string
   190  	units []*mockUnit
   191  }
   192  
   193  func newMockApplication(name string) *mockApplication {
   194  	return &mockApplication{
   195  		name: name,
   196  	}
   197  }
   198  
   199  type mockControllerInfo struct {
   200  	uuid string
   201  	info crossmodel.ControllerInfo
   202  }
   203  
   204  func (c *mockControllerInfo) Id() string {
   205  	return c.uuid
   206  }
   207  
   208  func (c *mockControllerInfo) ControllerInfo() crossmodel.ControllerInfo {
   209  	return c.info
   210  }
   211  
   212  type mockRelation struct {
   213  	testing.Stub
   214  	firewall.Relation
   215  	id        int
   216  	key       string
   217  	endpoints []state.Endpoint
   218  	ruw       *mockRelationUnitsWatcher
   219  	ruwApp    string
   220  	inScope   set.Strings
   221  	status    status.StatusInfo
   222  }
   223  
   224  func newMockRelation(id int) *mockRelation {
   225  	return &mockRelation{
   226  		id:      id,
   227  		ruw:     newMockRelationUnitsWatcher(),
   228  		inScope: make(set.Strings),
   229  	}
   230  }
   231  
   232  func (r *mockRelation) Id() int {
   233  	r.MethodCall(r, "Id")
   234  	return r.id
   235  }
   236  
   237  func (r *mockRelation) WatchRelationIngressNetworks() state.StringsWatcher {
   238  	w := newMockStringsWatcher()
   239  	w.changes <- []string{"1.2.3.4/32"}
   240  	return w
   241  }
   242  
   243  func (r *mockRelation) SetStatus(info status.StatusInfo) error {
   244  	r.status = info
   245  	return nil
   246  }
   247  
   248  func newMockRelationUnitsWatcher() *mockRelationUnitsWatcher {
   249  	w := &mockRelationUnitsWatcher{changes: make(chan params.RelationUnitsChange, 1)}
   250  	w.Tomb.Go(func() error {
   251  		<-w.Tomb.Dying()
   252  		return nil
   253  	})
   254  	return w
   255  }
   256  
   257  type mockRelationUnitsWatcher struct {
   258  	mockWatcher
   259  	changes chan params.RelationUnitsChange
   260  }
   261  
   262  func (w *mockRelationUnitsWatcher) Changes() <-chan params.RelationUnitsChange {
   263  	return w.changes
   264  }
   265  
   266  func (st *mockState) GetRemoteEntity(sourceModel names.ModelTag, token string) (names.Tag, error) {
   267  	st.MethodCall(st, "GetRemoteEntity", sourceModel, token)
   268  	if err := st.NextErr(); err != nil {
   269  		return nil, err
   270  	}
   271  	for e, t := range st.remoteEntities {
   272  		if t == token {
   273  			return e, nil
   274  		}
   275  	}
   276  	return nil, errors.NotFoundf("token %v", token)
   277  }
   278  
   279  func (st *mockState) KeyRelation(key string) (firewall.Relation, error) {
   280  	st.MethodCall(st, "KeyRelation", key)
   281  	if err := st.NextErr(); err != nil {
   282  		return nil, err
   283  	}
   284  	r, ok := st.relations[key]
   285  	if !ok {
   286  		return nil, errors.NotFoundf("relation %q", key)
   287  	}
   288  	return r, nil
   289  }
   290  
   291  type mockUnit struct {
   292  	testing.Stub
   293  	mu            sync.Mutex
   294  	name          string
   295  	assigned      bool
   296  	publicAddress network.Address
   297  	machineId     string
   298  }
   299  
   300  func newMockUnit(name string) *mockUnit {
   301  	return &mockUnit{
   302  		name:     name,
   303  		assigned: true,
   304  	}
   305  }
   306  
   307  func (u *mockUnit) Name() string {
   308  	u.MethodCall(u, "Name")
   309  	return u.name
   310  }
   311  
   312  func (u *mockUnit) PublicAddress() (network.Address, error) {
   313  	u.MethodCall(u, "PublicAddress")
   314  	u.mu.Lock()
   315  	defer u.mu.Unlock()
   316  
   317  	if err := u.NextErr(); err != nil {
   318  		return network.Address{}, err
   319  	}
   320  	if !u.assigned {
   321  		return network.Address{}, errors.NotAssignedf(u.name)
   322  	}
   323  	if u.publicAddress.Value == "" {
   324  		return network.Address{}, network.NoAddressError("public")
   325  	}
   326  	return u.publicAddress, nil
   327  }
   328  
   329  func (u *mockUnit) AssignedMachineId() (string, error) {
   330  	u.MethodCall(u, "AssignedMachineId")
   331  	if err := u.NextErr(); err != nil {
   332  		return "", err
   333  	}
   334  	if !u.assigned {
   335  		return "", errors.NotAssignedf(u.name)
   336  	}
   337  	return u.machineId, nil
   338  }
   339  
   340  func (u *mockUnit) updateAddress(value string) {
   341  	u.mu.Lock()
   342  	defer u.mu.Unlock()
   343  
   344  	u.publicAddress = network.Address{Value: value}
   345  }