github.com/mhilton/juju-juju@v0.0.0-20150901100907-a94dd2c73455/worker/cleaner/cleaner_test.go (about)

     1  // Copyright 2013 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package cleaner_test
     5  
     6  import (
     7  	"errors"
     8  	stdtesting "testing"
     9  	"time"
    10  
    11  	jc "github.com/juju/testing/checkers"
    12  	gc "gopkg.in/check.v1"
    13  
    14  	"github.com/juju/juju/api/watcher"
    15  	coretesting "github.com/juju/juju/testing"
    16  	"github.com/juju/juju/worker"
    17  	"github.com/juju/juju/worker/cleaner"
    18  )
    19  
    20  func TestPackage(t *stdtesting.T) {
    21  	gc.TestingT(t)
    22  }
    23  
    24  type CleanerSuite struct {
    25  	coretesting.BaseSuite
    26  	mockState *cleanerMock
    27  }
    28  
    29  var _ = gc.Suite(&CleanerSuite{})
    30  
    31  var _ worker.NotifyWatchHandler = (*cleaner.Cleaner)(nil)
    32  
    33  func (s *CleanerSuite) SetUpTest(c *gc.C) {
    34  	s.BaseSuite.SetUpTest(c)
    35  	s.mockState = &cleanerMock{
    36  		calls: make(chan string),
    37  	}
    38  	s.mockState.watcher = newMockNotifyWatcher(nil)
    39  }
    40  
    41  func (s *CleanerSuite) AssertReceived(c *gc.C, expect string) {
    42  	select {
    43  	case call := <-s.mockState.calls:
    44  		c.Assert(call, gc.Matches, expect)
    45  	case <-time.After(coretesting.LongWait):
    46  		c.Fatalf("Timed out waiting for %s", expect)
    47  	}
    48  }
    49  
    50  func (s *CleanerSuite) AssertEmpty(c *gc.C) {
    51  	select {
    52  	case call, ok := <-s.mockState.calls:
    53  		c.Fatalf("Unexpected %s (ok: %v)", call, ok)
    54  	case <-time.After(coretesting.ShortWait):
    55  	}
    56  }
    57  
    58  func (s *CleanerSuite) TestCleaner(c *gc.C) {
    59  	cln := cleaner.NewCleaner(s.mockState)
    60  	defer func() { c.Assert(worker.Stop(cln), jc.ErrorIsNil) }()
    61  
    62  	s.AssertReceived(c, "WatchCleanups")
    63  	s.AssertReceived(c, "Cleanup")
    64  
    65  	s.mockState.watcher.Change()
    66  	s.AssertReceived(c, "Cleanup")
    67  }
    68  
    69  func (s *CleanerSuite) TestWatchCleanupsError(c *gc.C) {
    70  	s.mockState.err = []error{errors.New("hello")}
    71  	cln := cleaner.NewCleaner(s.mockState)
    72  
    73  	s.AssertReceived(c, "WatchCleanups")
    74  	s.AssertEmpty(c)
    75  	err := worker.Stop(cln)
    76  	c.Assert(err, gc.ErrorMatches, "hello")
    77  }
    78  
    79  func (s *CleanerSuite) TestCleanupError(c *gc.C) {
    80  	s.mockState.err = []error{nil, errors.New("hello")}
    81  	cln := cleaner.NewCleaner(s.mockState)
    82  
    83  	s.AssertReceived(c, "WatchCleanups")
    84  	s.AssertReceived(c, "Cleanup")
    85  	err := worker.Stop(cln)
    86  	c.Assert(err, jc.ErrorIsNil)
    87  	log := c.GetTestLog()
    88  	c.Assert(log, jc.Contains, "ERROR juju.worker.cleaner cannot cleanup state: hello")
    89  }
    90  
    91  // cleanerMock is used to check the
    92  // calls of Cleanup() and WatchCleanups()
    93  type cleanerMock struct {
    94  	watcher *mockNotifyWatcher
    95  	calls   chan string
    96  	err     []error
    97  }
    98  
    99  func (m *cleanerMock) getError() (e error) {
   100  	if len(m.err) > 0 {
   101  		e = m.err[0]
   102  		m.err = m.err[1:]
   103  	}
   104  	return
   105  }
   106  
   107  func (m *cleanerMock) Cleanup() error {
   108  	m.calls <- "Cleanup"
   109  	return m.getError()
   110  }
   111  
   112  func (m *cleanerMock) WatchCleanups() (watcher.NotifyWatcher, error) {
   113  	m.calls <- "WatchCleanups"
   114  	return m.watcher, m.getError()
   115  }
   116  
   117  var _ cleaner.StateCleaner = (*cleanerMock)(nil)
   118  
   119  type mockNotifyWatcher struct {
   120  	watcher.NotifyWatcher
   121  
   122  	err     error
   123  	changes chan struct{}
   124  }
   125  
   126  func newMockNotifyWatcher(err error) *mockNotifyWatcher {
   127  	m := &mockNotifyWatcher{
   128  		changes: make(chan struct{}, 1),
   129  		err:     err,
   130  	}
   131  	m.Change()
   132  	return m
   133  }
   134  
   135  func (m *mockNotifyWatcher) Err() error {
   136  	return m.err
   137  }
   138  
   139  func (m *mockNotifyWatcher) Changes() <-chan struct{} {
   140  	if m.err != nil {
   141  		close(m.changes)
   142  	}
   143  	return m.changes
   144  }
   145  
   146  func (m *mockNotifyWatcher) Stop() error {
   147  	return m.err
   148  }
   149  
   150  func (m *mockNotifyWatcher) Change() {
   151  	m.changes <- struct{}{}
   152  }