github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/worker/statushistorypruner/worker_test.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package statushistorypruner_test
     5  
     6  import (
     7  	"time"
     8  
     9  	"github.com/juju/errors"
    10  	jc "github.com/juju/testing/checkers"
    11  	gc "gopkg.in/check.v1"
    12  
    13  	coretesting "github.com/juju/juju/testing"
    14  	"github.com/juju/juju/worker"
    15  	"github.com/juju/juju/worker/statushistorypruner"
    16  )
    17  
    18  type statusHistoryPrunerSuite struct {
    19  	coretesting.BaseSuite
    20  }
    21  
    22  var _ = gc.Suite(&statusHistoryPrunerSuite{})
    23  
    24  func (s *statusHistoryPrunerSuite) TestWorkerCallsPrune(c *gc.C) {
    25  	fakeTimer := newMockTimer(coretesting.LongWait)
    26  
    27  	fakeTimerFunc := func(d time.Duration) worker.PeriodicTimer {
    28  		// construction of timer should be with 0 because we intend it to
    29  		// run once before waiting.
    30  		c.Assert(d, gc.Equals, 0*time.Nanosecond)
    31  		return fakeTimer
    32  	}
    33  	facade := newFakeFacade()
    34  	conf := statushistorypruner.Config{
    35  		Facade:           facade,
    36  		MaxLogsPerEntity: 3,
    37  		PruneInterval:    coretesting.ShortWait,
    38  		NewTimer:         fakeTimerFunc,
    39  	}
    40  
    41  	pruner, err := statushistorypruner.New(conf)
    42  	c.Check(err, jc.ErrorIsNil)
    43  	s.AddCleanup(func(*gc.C) {
    44  		c.Assert(worker.Stop(pruner), jc.ErrorIsNil)
    45  	})
    46  
    47  	err = fakeTimer.fire()
    48  	c.Check(err, jc.ErrorIsNil)
    49  
    50  	var passedLogs int
    51  	select {
    52  	case passedLogs = <-facade.passedMaxLogs:
    53  	case <-time.After(coretesting.LongWait):
    54  		c.Fatal("timed out waiting for passed logs to pruner")
    55  	}
    56  	c.Assert(passedLogs, gc.Equals, 3)
    57  
    58  	// Reset will have been called with the actual PruneInterval
    59  	var period time.Duration
    60  	select {
    61  	case period = <-fakeTimer.period:
    62  	case <-time.After(coretesting.LongWait):
    63  		c.Fatal("timed out waiting for period reset by pruner")
    64  	}
    65  	c.Assert(period, gc.Equals, coretesting.ShortWait)
    66  }
    67  
    68  func (s *statusHistoryPrunerSuite) TestWorkerWontCallPruneBeforeFiringTimer(c *gc.C) {
    69  	fakeTimer := newMockTimer(coretesting.LongWait)
    70  
    71  	fakeTimerFunc := func(d time.Duration) worker.PeriodicTimer {
    72  		// construction of timer should be with 0 because we intend it to
    73  		// run once before waiting.
    74  		c.Assert(d, gc.Equals, 0*time.Nanosecond)
    75  		return fakeTimer
    76  	}
    77  	facade := newFakeFacade()
    78  	conf := statushistorypruner.Config{
    79  		Facade:           facade,
    80  		MaxLogsPerEntity: 3,
    81  		PruneInterval:    coretesting.ShortWait,
    82  		NewTimer:         fakeTimerFunc,
    83  	}
    84  
    85  	pruner, err := statushistorypruner.New(conf)
    86  	c.Check(err, jc.ErrorIsNil)
    87  	s.AddCleanup(func(*gc.C) {
    88  		c.Assert(worker.Stop(pruner), jc.ErrorIsNil)
    89  	})
    90  
    91  	select {
    92  	case <-facade.passedMaxLogs:
    93  		c.Fatal("called before firing timer.")
    94  	case <-time.After(coretesting.LongWait):
    95  	}
    96  }
    97  
    98  type mockTimer struct {
    99  	period chan time.Duration
   100  	c      chan time.Time
   101  }
   102  
   103  func (t *mockTimer) Reset(d time.Duration) bool {
   104  	select {
   105  	case t.period <- d:
   106  	case <-time.After(coretesting.LongWait):
   107  		panic("timed out waiting for timer to reset")
   108  	}
   109  	return true
   110  }
   111  
   112  func (t *mockTimer) CountDown() <-chan time.Time {
   113  	return t.c
   114  }
   115  
   116  func (t *mockTimer) fire() error {
   117  	select {
   118  	case t.c <- time.Time{}:
   119  	case <-time.After(coretesting.LongWait):
   120  		return errors.New("timed out waiting for pruner to run")
   121  	}
   122  	return nil
   123  }
   124  
   125  func newMockTimer(d time.Duration) *mockTimer {
   126  	return &mockTimer{period: make(chan time.Duration, 1),
   127  		c: make(chan time.Time),
   128  	}
   129  }
   130  
   131  type fakeFacade struct {
   132  	passedMaxLogs chan int
   133  }
   134  
   135  func newFakeFacade() *fakeFacade {
   136  	return &fakeFacade{
   137  		passedMaxLogs: make(chan int, 1),
   138  	}
   139  }
   140  
   141  // Prune implements Facade
   142  func (f *fakeFacade) Prune(maxLogs int) error {
   143  	select {
   144  	case f.passedMaxLogs <- maxLogs:
   145  	case <-time.After(coretesting.LongWait):
   146  		return errors.New("timed out waiting for facade call Prune to run")
   147  	}
   148  	return nil
   149  }