github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/worker/uniter/remotestate/mock_test.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package remotestate_test
     5  
     6  import (
     7  	"sync"
     8  
     9  	"gopkg.in/juju/charm.v6-unstable"
    10  	"gopkg.in/juju/names.v2"
    11  
    12  	"github.com/juju/juju/apiserver/params"
    13  	"github.com/juju/juju/core/leadership"
    14  	"github.com/juju/juju/watcher"
    15  	"github.com/juju/juju/worker/uniter/remotestate"
    16  )
    17  
    18  func newMockWatcher() *mockWatcher {
    19  	return &mockWatcher{
    20  		stopped: make(chan struct{}),
    21  	}
    22  }
    23  
    24  type mockWatcher struct {
    25  	mu      sync.Mutex
    26  	stopped chan struct{}
    27  }
    28  
    29  func (w *mockWatcher) Kill() {
    30  	w.mu.Lock()
    31  	defer w.mu.Unlock()
    32  	if !w.Stopped() {
    33  		close(w.stopped)
    34  	}
    35  }
    36  
    37  func (w *mockWatcher) Wait() error {
    38  	<-w.stopped
    39  	return nil
    40  }
    41  
    42  func (w *mockWatcher) Stopped() bool {
    43  	select {
    44  	case <-w.stopped:
    45  		return true
    46  	default:
    47  		return false
    48  	}
    49  }
    50  
    51  func newMockNotifyWatcher() *mockNotifyWatcher {
    52  	return &mockNotifyWatcher{
    53  		mockWatcher: newMockWatcher(),
    54  		changes:     make(chan struct{}, 1),
    55  	}
    56  }
    57  
    58  type mockNotifyWatcher struct {
    59  	*mockWatcher
    60  	changes chan struct{}
    61  }
    62  
    63  func (w *mockNotifyWatcher) Changes() watcher.NotifyChannel {
    64  	return w.changes
    65  }
    66  
    67  func newMockStringsWatcher() *mockStringsWatcher {
    68  	return &mockStringsWatcher{
    69  		mockWatcher: newMockWatcher(),
    70  		changes:     make(chan []string, 1),
    71  	}
    72  }
    73  
    74  type mockStringsWatcher struct {
    75  	*mockWatcher
    76  	changes chan []string
    77  }
    78  
    79  func (w *mockStringsWatcher) Changes() watcher.StringsChannel {
    80  	return w.changes
    81  }
    82  
    83  func newMockRelationUnitsWatcher() *mockRelationUnitsWatcher {
    84  	return &mockRelationUnitsWatcher{
    85  		mockWatcher: newMockWatcher(),
    86  		changes:     make(chan watcher.RelationUnitsChange, 1),
    87  	}
    88  }
    89  
    90  type mockRelationUnitsWatcher struct {
    91  	*mockWatcher
    92  	changes chan watcher.RelationUnitsChange
    93  }
    94  
    95  func (w *mockRelationUnitsWatcher) Changes() watcher.RelationUnitsChannel {
    96  	return w.changes
    97  }
    98  
    99  type mockState struct {
   100  	unit                      mockUnit
   101  	relations                 map[names.RelationTag]*mockRelation
   102  	storageAttachment         map[params.StorageAttachmentId]params.StorageAttachment
   103  	relationUnitsWatchers     map[names.RelationTag]*mockRelationUnitsWatcher
   104  	storageAttachmentWatchers map[names.StorageTag]*mockNotifyWatcher
   105  }
   106  
   107  func (st *mockState) Relation(tag names.RelationTag) (remotestate.Relation, error) {
   108  	r, ok := st.relations[tag]
   109  	if !ok {
   110  		return nil, &params.Error{Code: params.CodeNotFound}
   111  	}
   112  	return r, nil
   113  }
   114  
   115  func (st *mockState) StorageAttachment(
   116  	storageTag names.StorageTag, unitTag names.UnitTag,
   117  ) (params.StorageAttachment, error) {
   118  	if unitTag != st.unit.tag {
   119  		return params.StorageAttachment{}, &params.Error{Code: params.CodeNotFound}
   120  	}
   121  	attachment, ok := st.storageAttachment[params.StorageAttachmentId{
   122  		UnitTag:    unitTag.String(),
   123  		StorageTag: storageTag.String(),
   124  	}]
   125  	if !ok {
   126  		return params.StorageAttachment{}, &params.Error{Code: params.CodeNotFound}
   127  	}
   128  	if attachment.Kind == params.StorageKindUnknown {
   129  		return params.StorageAttachment{}, &params.Error{Code: params.CodeNotProvisioned}
   130  	}
   131  	return attachment, nil
   132  }
   133  
   134  func (st *mockState) StorageAttachmentLife(
   135  	ids []params.StorageAttachmentId,
   136  ) ([]params.LifeResult, error) {
   137  	results := make([]params.LifeResult, len(ids))
   138  	for i, id := range ids {
   139  		attachment, ok := st.storageAttachment[id]
   140  		if !ok {
   141  			results[i] = params.LifeResult{
   142  				Error: &params.Error{Code: params.CodeNotFound},
   143  			}
   144  			continue
   145  		}
   146  		results[i] = params.LifeResult{Life: attachment.Life}
   147  	}
   148  	return results, nil
   149  }
   150  
   151  func (st *mockState) Unit(tag names.UnitTag) (remotestate.Unit, error) {
   152  	if tag != st.unit.tag {
   153  		return nil, &params.Error{Code: params.CodeNotFound}
   154  	}
   155  	return &st.unit, nil
   156  }
   157  
   158  func (st *mockState) WatchRelationUnits(
   159  	relationTag names.RelationTag, unitTag names.UnitTag,
   160  ) (watcher.RelationUnitsWatcher, error) {
   161  	if unitTag != st.unit.tag {
   162  		return nil, &params.Error{Code: params.CodeNotFound}
   163  	}
   164  	watcher, ok := st.relationUnitsWatchers[relationTag]
   165  	if !ok {
   166  		return nil, &params.Error{Code: params.CodeNotFound}
   167  	}
   168  	return watcher, nil
   169  }
   170  
   171  func (st *mockState) WatchStorageAttachment(
   172  	storageTag names.StorageTag, unitTag names.UnitTag,
   173  ) (watcher.NotifyWatcher, error) {
   174  	if unitTag != st.unit.tag {
   175  		return nil, &params.Error{Code: params.CodeNotFound}
   176  	}
   177  	watcher, ok := st.storageAttachmentWatchers[storageTag]
   178  	if !ok {
   179  		return nil, &params.Error{Code: params.CodeNotFound}
   180  	}
   181  	return watcher, nil
   182  }
   183  
   184  type mockUnit struct {
   185  	tag                   names.UnitTag
   186  	life                  params.Life
   187  	resolved              params.ResolvedMode
   188  	service               mockService
   189  	unitWatcher           *mockNotifyWatcher
   190  	addressesWatcher      *mockNotifyWatcher
   191  	configSettingsWatcher *mockNotifyWatcher
   192  	storageWatcher        *mockStringsWatcher
   193  	actionWatcher         *mockStringsWatcher
   194  }
   195  
   196  func (u *mockUnit) Life() params.Life {
   197  	return u.life
   198  }
   199  
   200  func (u *mockUnit) Refresh() error {
   201  	return nil
   202  }
   203  
   204  func (u *mockUnit) Resolved() (params.ResolvedMode, error) {
   205  	return u.resolved, nil
   206  }
   207  
   208  func (u *mockUnit) Application() (remotestate.Application, error) {
   209  	return &u.service, nil
   210  }
   211  
   212  func (u *mockUnit) Tag() names.UnitTag {
   213  	return u.tag
   214  }
   215  
   216  func (u *mockUnit) Watch() (watcher.NotifyWatcher, error) {
   217  	return u.unitWatcher, nil
   218  }
   219  
   220  func (u *mockUnit) WatchAddresses() (watcher.NotifyWatcher, error) {
   221  	return u.addressesWatcher, nil
   222  }
   223  
   224  func (u *mockUnit) WatchConfigSettings() (watcher.NotifyWatcher, error) {
   225  	return u.configSettingsWatcher, nil
   226  }
   227  
   228  func (u *mockUnit) WatchStorage() (watcher.StringsWatcher, error) {
   229  	return u.storageWatcher, nil
   230  }
   231  
   232  func (u *mockUnit) WatchActionNotifications() (watcher.StringsWatcher, error) {
   233  	return u.actionWatcher, nil
   234  }
   235  
   236  type mockService struct {
   237  	tag                   names.ApplicationTag
   238  	life                  params.Life
   239  	curl                  *charm.URL
   240  	charmModifiedVersion  int
   241  	forceUpgrade          bool
   242  	serviceWatcher        *mockNotifyWatcher
   243  	leaderSettingsWatcher *mockNotifyWatcher
   244  	relationsWatcher      *mockStringsWatcher
   245  }
   246  
   247  func (s *mockService) CharmModifiedVersion() (int, error) {
   248  	return s.charmModifiedVersion, nil
   249  }
   250  
   251  func (s *mockService) CharmURL() (*charm.URL, bool, error) {
   252  	return s.curl, s.forceUpgrade, nil
   253  }
   254  
   255  func (s *mockService) Life() params.Life {
   256  	return s.life
   257  }
   258  
   259  func (s *mockService) Refresh() error {
   260  	return nil
   261  }
   262  
   263  func (s *mockService) Tag() names.ApplicationTag {
   264  	return s.tag
   265  }
   266  
   267  func (s *mockService) Watch() (watcher.NotifyWatcher, error) {
   268  	return s.serviceWatcher, nil
   269  }
   270  
   271  func (s *mockService) WatchLeadershipSettings() (watcher.NotifyWatcher, error) {
   272  	return s.leaderSettingsWatcher, nil
   273  }
   274  
   275  func (s *mockService) WatchRelations() (watcher.StringsWatcher, error) {
   276  	return s.relationsWatcher, nil
   277  }
   278  
   279  type mockRelation struct {
   280  	id   int
   281  	life params.Life
   282  }
   283  
   284  func (r *mockRelation) Id() int {
   285  	return r.id
   286  }
   287  
   288  func (r *mockRelation) Life() params.Life {
   289  	return r.life
   290  }
   291  
   292  type mockLeadershipTracker struct {
   293  	leadership.Tracker
   294  	claimTicket  mockTicket
   295  	leaderTicket mockTicket
   296  	minionTicket mockTicket
   297  }
   298  
   299  func (mock *mockLeadershipTracker) ClaimLeader() leadership.Ticket {
   300  	return &mock.claimTicket
   301  }
   302  
   303  func (mock *mockLeadershipTracker) WaitLeader() leadership.Ticket {
   304  	return &mock.leaderTicket
   305  }
   306  
   307  func (mock *mockLeadershipTracker) WaitMinion() leadership.Ticket {
   308  	return &mock.minionTicket
   309  }
   310  
   311  type mockTicket struct {
   312  	ch     chan struct{}
   313  	result bool
   314  }
   315  
   316  func (t *mockTicket) Ready() <-chan struct{} {
   317  	return t.ch
   318  }
   319  
   320  func (t *mockTicket) Wait() bool {
   321  	return t.result
   322  }