github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/core/watcher/watchertest/notify.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package watchertest
     5  
     6  import (
     7  	"time"
     8  
     9  	jc "github.com/juju/testing/checkers"
    10  	gc "gopkg.in/check.v1"
    11  	tomb "gopkg.in/tomb.v2"
    12  
    13  	"github.com/juju/juju/core/watcher"
    14  	"github.com/juju/juju/testing"
    15  )
    16  
    17  type MockNotifyWatcher struct {
    18  	tomb tomb.Tomb
    19  	ch   <-chan struct{}
    20  }
    21  
    22  func NewMockNotifyWatcher(ch <-chan struct{}) *MockNotifyWatcher {
    23  	w := &MockNotifyWatcher{ch: ch}
    24  	w.tomb.Go(func() error {
    25  		<-w.tomb.Dying()
    26  		return tomb.ErrDying
    27  	})
    28  	return w
    29  }
    30  
    31  func (w *MockNotifyWatcher) Changes() watcher.NotifyChannel {
    32  	return watcher.NotifyChannel(w.ch)
    33  }
    34  
    35  func (w *MockNotifyWatcher) Stop() error {
    36  	w.Kill()
    37  	return w.Wait()
    38  }
    39  
    40  func (w *MockNotifyWatcher) Kill() {
    41  	w.tomb.Kill(nil)
    42  }
    43  
    44  // KillErr can be used to kill the worker with
    45  // an error, to simulate a failing watcher.
    46  func (w *MockNotifyWatcher) KillErr(err error) {
    47  	w.tomb.Kill(err)
    48  }
    49  
    50  func (w *MockNotifyWatcher) Err() error {
    51  	return w.tomb.Err()
    52  }
    53  
    54  func (w *MockNotifyWatcher) Wait() error {
    55  	return w.tomb.Wait()
    56  }
    57  
    58  func NewNotifyWatcherC(c *gc.C, watcher watcher.NotifyWatcher, preAssert func()) NotifyWatcherC {
    59  	if preAssert == nil {
    60  		preAssert = func() {}
    61  	}
    62  	return NotifyWatcherC{
    63  		C:         c,
    64  		Watcher:   watcher,
    65  		PreAssert: preAssert,
    66  	}
    67  }
    68  
    69  type NotifyWatcherC struct {
    70  	*gc.C
    71  	Watcher   watcher.NotifyWatcher
    72  	PreAssert func()
    73  }
    74  
    75  // AssertOneChange fails if no change is sent before a long time has passed; or
    76  // if, subsequent to that, any further change is sent before a short time has
    77  // passed.
    78  func (c NotifyWatcherC) AssertOneChange() {
    79  	c.PreAssert()
    80  	select {
    81  	case _, ok := <-c.Watcher.Changes():
    82  		c.Assert(ok, jc.IsTrue)
    83  	case <-time.After(testing.LongWait):
    84  		c.Fatalf("watcher did not send change")
    85  	}
    86  	c.AssertNoChange()
    87  }
    88  
    89  // AssertNoChange fails if it manages to read a value from Changes before a
    90  // short time has passed.
    91  func (c NotifyWatcherC) AssertNoChange() {
    92  	c.PreAssert()
    93  	select {
    94  	case _, ok := <-c.Watcher.Changes():
    95  		c.Fatalf("watcher sent unexpected change: (_, %v)", ok)
    96  	case <-time.After(testing.ShortWait):
    97  	}
    98  }
    99  
   100  // AssertStops Kills the watcher and asserts (1) that Wait completes without
   101  // error before a long time has passed; and (2) that Changes remains open but
   102  // no values are being sent.
   103  func (c NotifyWatcherC) AssertStops() {
   104  	c.Watcher.Kill()
   105  	wait := make(chan error)
   106  	go func() {
   107  		c.PreAssert()
   108  		wait <- c.Watcher.Wait()
   109  	}()
   110  	select {
   111  	case <-time.After(testing.LongWait):
   112  		c.Fatalf("watcher never stopped")
   113  	case err := <-wait:
   114  		c.Assert(err, jc.ErrorIsNil)
   115  	}
   116  
   117  	c.PreAssert()
   118  	select {
   119  	case _, ok := <-c.Watcher.Changes():
   120  		c.Fatalf("watcher sent unexpected change: (_, %v)", ok)
   121  	default:
   122  	}
   123  }