github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/worker/resumer/resumer_test.go (about)

     1  // Copyright 2013 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package resumer_test
     5  
     6  import (
     7  	"errors"
     8  	"time"
     9  
    10  	"github.com/juju/clock/testclock"
    11  	"github.com/juju/testing"
    12  	jc "github.com/juju/testing/checkers"
    13  	gc "gopkg.in/check.v1"
    14  	"gopkg.in/juju/worker.v1/workertest"
    15  
    16  	coretesting "github.com/juju/juju/testing"
    17  	"github.com/juju/juju/worker/resumer"
    18  )
    19  
    20  type ResumerSuite struct {
    21  	testing.IsolationSuite
    22  }
    23  
    24  var _ = gc.Suite(&ResumerSuite{})
    25  
    26  func (*ResumerSuite) TestImmediateFailure(c *gc.C) {
    27  	fix := newFixture(errors.New("zap"))
    28  	stub := fix.Run(c, func(_ *testclock.Clock, worker *resumer.Resumer) {
    29  		err := workertest.CheckKilled(c, worker)
    30  		c.Check(err, gc.ErrorMatches, "cannot resume transactions: zap")
    31  	})
    32  	stub.CheckCallNames(c, "ResumeTransactions")
    33  }
    34  
    35  func (*ResumerSuite) TestWaitsToResume(c *gc.C) {
    36  	fix := newFixture(nil, errors.New("unexpected"))
    37  	stub := fix.Run(c, func(clock *testclock.Clock, worker *resumer.Resumer) {
    38  		waitAlarms(c, clock, 2)
    39  		clock.Advance(time.Hour - time.Nanosecond)
    40  		workertest.CheckAlive(c, worker)
    41  		workertest.CleanKill(c, worker)
    42  	})
    43  	stub.CheckCallNames(c, "ResumeTransactions")
    44  }
    45  
    46  func (*ResumerSuite) TestResumesAfterWait(c *gc.C) {
    47  	fix := newFixture(nil, nil, errors.New("unexpected"))
    48  	stub := fix.Run(c, func(clock *testclock.Clock, worker *resumer.Resumer) {
    49  		waitAlarms(c, clock, 2)
    50  		clock.Advance(time.Hour)
    51  		waitAlarms(c, clock, 1)
    52  		workertest.CleanKill(c, worker)
    53  	})
    54  	stub.CheckCallNames(c, "ResumeTransactions", "ResumeTransactions")
    55  }
    56  
    57  func (*ResumerSuite) TestSeveralResumes(c *gc.C) {
    58  	fix := newFixture(nil, nil, nil, errors.New("unexpected"))
    59  	stub := fix.Run(c, func(clock *testclock.Clock, worker *resumer.Resumer) {
    60  		waitAlarms(c, clock, 2)
    61  		clock.Advance(time.Hour)
    62  		waitAlarms(c, clock, 1)
    63  		clock.Advance(time.Hour)
    64  		waitAlarms(c, clock, 1)
    65  		workertest.CleanKill(c, worker)
    66  	})
    67  	stub.CheckCallNames(c, "ResumeTransactions", "ResumeTransactions", "ResumeTransactions")
    68  }
    69  
    70  func newFixture(errs ...error) *fixture {
    71  	return &fixture{errors: errs}
    72  }
    73  
    74  type fixture struct {
    75  	errors []error
    76  }
    77  
    78  type TestFunc func(*testclock.Clock, *resumer.Resumer)
    79  
    80  func (fix fixture) Run(c *gc.C, test TestFunc) *testing.Stub {
    81  
    82  	stub := &testing.Stub{}
    83  	stub.SetErrors(fix.errors...)
    84  	clock := testclock.NewClock(time.Now())
    85  	facade := newMockFacade(stub)
    86  
    87  	worker, err := resumer.NewResumer(resumer.Config{
    88  		Facade:   facade,
    89  		Interval: time.Hour,
    90  		Clock:    clock,
    91  	})
    92  	c.Assert(err, jc.ErrorIsNil)
    93  	defer workertest.DirtyKill(c, worker)
    94  
    95  	test(clock, worker)
    96  	return stub
    97  }
    98  
    99  func newMockFacade(stub *testing.Stub) *mockFacade {
   100  	return &mockFacade{stub: stub}
   101  }
   102  
   103  type mockFacade struct {
   104  	stub *testing.Stub
   105  }
   106  
   107  func (mock *mockFacade) ResumeTransactions() error {
   108  	mock.stub.AddCall("ResumeTransactions")
   109  	return mock.stub.NextErr()
   110  }
   111  
   112  func waitAlarms(c *gc.C, clock *testclock.Clock, count int) {
   113  	timeout := time.After(coretesting.LongWait)
   114  	for i := 0; i < count; i++ {
   115  		select {
   116  		case <-clock.Alarms():
   117  		case <-timeout:
   118  			c.Fatalf("timed out waiting for alarm %d", i)
   119  		}
   120  	}
   121  }