1
// Copyright 2015 Canonical Ltd.
2
// Licensed under the AGPLv3, see LICENCE file for details.
4
package statushistorypruner_test
9
"github.com/juju/errors"
10
jc "github.com/juju/testing/checkers"
11
gc "gopkg.in/check.v1"
13
coretesting "github.com/juju/juju/testing"
14
"github.com/juju/juju/worker"
15
"github.com/juju/juju/worker/statushistorypruner"
18
type statusHistoryPrunerSuite struct {
22
var _ = gc.Suite(&statusHistoryPrunerSuite{})
24
func (s *statusHistoryPrunerSuite) TestWorkerCallsPrune(c *gc.C) {
25
fakeTimer := newMockTimer(coretesting.LongWait)
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)
33
facade := newFakeFacade()
34
conf := statushistorypruner.Config{
36
MaxHistoryTime: 1 * time.Second,
38
PruneInterval: coretesting.ShortWait,
39
NewTimer: fakeTimerFunc,
42
pruner, err := statushistorypruner.New(conf)
43
c.Check(err, jc.ErrorIsNil)
44
s.AddCleanup(func(*gc.C) {
45
c.Assert(worker.Stop(pruner), jc.ErrorIsNil)
48
err = fakeTimer.fire()
49
c.Check(err, jc.ErrorIsNil)
53
case passedMB = <-facade.passedMaxHistoryMB:
54
case <-time.After(coretesting.LongWait):
55
c.Fatal("timed out waiting for passed logs to pruner")
57
c.Assert(passedMB, gc.Equals, 3)
59
// Reset will have been called with the actual PruneInterval
60
var period time.Duration
62
case period = <-fakeTimer.period:
63
case <-time.After(coretesting.LongWait):
64
c.Fatal("timed out waiting for period reset by pruner")
66
c.Assert(period, gc.Equals, coretesting.ShortWait)
69
func (s *statusHistoryPrunerSuite) TestWorkerWontCallPruneBeforeFiringTimer(c *gc.C) {
70
fakeTimer := newMockTimer(coretesting.LongWait)
72
fakeTimerFunc := func(d time.Duration) worker.PeriodicTimer {
73
// construction of timer should be with 0 because we intend it to
74
// run once before waiting.
75
c.Assert(d, gc.Equals, 0*time.Nanosecond)
78
facade := newFakeFacade()
79
conf := statushistorypruner.Config{
81
MaxHistoryTime: 1 * time.Second,
83
PruneInterval: coretesting.ShortWait,
84
NewTimer: fakeTimerFunc,
87
pruner, err := statushistorypruner.New(conf)
88
c.Check(err, jc.ErrorIsNil)
89
s.AddCleanup(func(*gc.C) {
90
c.Assert(worker.Stop(pruner), jc.ErrorIsNil)
94
case <-facade.passedMaxHistoryMB:
95
c.Fatal("called before firing timer.")
96
case <-time.After(coretesting.LongWait):
100
type mockTimer struct {
101
period chan time.Duration
105
func (t *mockTimer) Reset(d time.Duration) bool {
108
case <-time.After(coretesting.LongWait):
109
panic("timed out waiting for timer to reset")
114
func (t *mockTimer) CountDown() <-chan time.Time {
118
func (t *mockTimer) fire() error {
120
case t.c <- time.Time{}:
121
case <-time.After(coretesting.LongWait):
122
return errors.New("timed out waiting for pruner to run")
127
func newMockTimer(d time.Duration) *mockTimer {
128
return &mockTimer{period: make(chan time.Duration, 1),
129
c: make(chan time.Time),
133
type fakeFacade struct {
134
passedMaxHistoryMB chan int
137
func newFakeFacade() *fakeFacade {
139
passedMaxHistoryMB: make(chan int, 1),
143
// Prune implements Facade
144
func (f *fakeFacade) Prune(_ time.Duration, maxHistoryMB int) error {
145
// TODO(perrito666) either make this send its actual args, or just use
146
// a stub and drop the unnecessary channel malarkey entirely
148
case f.passedMaxHistoryMB <- maxHistoryMB:
149
case <-time.After(coretesting.LongWait):
150
return errors.New("timed out waiting for facade call Prune to run")