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

     1  // Copyright 2016 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package singular_test
     5  
     6  import (
     7  	"sync"
     8  	"time"
     9  
    10  	"github.com/juju/clock"
    11  	"github.com/juju/clock/testclock"
    12  	"github.com/juju/errors"
    13  	"github.com/juju/testing"
    14  	jc "github.com/juju/testing/checkers"
    15  	gc "gopkg.in/check.v1"
    16  	"gopkg.in/juju/worker.v1"
    17  
    18  	"github.com/juju/juju/api/base"
    19  	"github.com/juju/juju/core/lease"
    20  	coretesting "github.com/juju/juju/testing"
    21  	"github.com/juju/juju/worker/singular"
    22  )
    23  
    24  type fixture struct {
    25  	testing.Stub
    26  }
    27  
    28  func newFixture(c *gc.C, errs ...error) *fixture {
    29  	fix := &fixture{}
    30  	fix.Stub.SetErrors(errs...)
    31  	return fix
    32  }
    33  
    34  type testFunc func(*singular.FlagWorker, *testclock.Clock, func())
    35  
    36  func (fix *fixture) Run(c *gc.C, test testFunc) {
    37  	facade := newStubFacade(&fix.Stub)
    38  	clock := testclock.NewClock(time.Now())
    39  	flagWorker, err := singular.NewFlagWorker(singular.FlagConfig{
    40  		Facade:   facade,
    41  		Clock:    clock,
    42  		Duration: time.Minute,
    43  	})
    44  	c.Assert(err, jc.ErrorIsNil)
    45  
    46  	done := make(chan struct{})
    47  	go func() {
    48  		defer close(done)
    49  		defer worker.Stop(flagWorker)
    50  		defer facade.unblock()
    51  		test(flagWorker, clock, facade.unblock)
    52  	}()
    53  	select {
    54  	case <-done:
    55  	case <-time.After(coretesting.LongWait):
    56  		c.Fatalf("test timed out")
    57  	}
    58  }
    59  
    60  func (fix *fixture) CheckClaimWait(c *gc.C) {
    61  	fix.CheckCalls(c, []testing.StubCall{{
    62  		FuncName: "Claim",
    63  		Args:     []interface{}{time.Minute},
    64  	}, {
    65  		FuncName: "Wait",
    66  	}})
    67  }
    68  
    69  func (fix *fixture) CheckClaims(c *gc.C, count int) {
    70  	expect := make([]testing.StubCall, count)
    71  	for i := 0; i < count; i++ {
    72  		expect[i] = testing.StubCall{
    73  			FuncName: "Claim",
    74  			Args:     []interface{}{time.Minute},
    75  		}
    76  	}
    77  	fix.CheckCalls(c, expect)
    78  }
    79  
    80  type stubFacade struct {
    81  	stub  *testing.Stub
    82  	mu    sync.Mutex
    83  	block chan struct{}
    84  }
    85  
    86  func newStubFacade(stub *testing.Stub) *stubFacade {
    87  	return &stubFacade{
    88  		stub:  stub,
    89  		block: make(chan struct{}),
    90  	}
    91  }
    92  
    93  func (facade *stubFacade) unblock() {
    94  	facade.mu.Lock()
    95  	defer facade.mu.Unlock()
    96  	select {
    97  	case <-facade.block:
    98  	default:
    99  		close(facade.block)
   100  	}
   101  }
   102  
   103  func (facade *stubFacade) Claim(duration time.Duration) error {
   104  	facade.stub.AddCall("Claim", duration)
   105  	return facade.stub.NextErr()
   106  }
   107  
   108  func (facade *stubFacade) Wait() error {
   109  	facade.stub.AddCall("Wait")
   110  	<-facade.block
   111  	return facade.stub.NextErr()
   112  }
   113  
   114  type stubWorker struct {
   115  	stub *testing.Stub
   116  }
   117  
   118  func newStubWorker(stub *testing.Stub) *stubWorker {
   119  	return &stubWorker{
   120  		stub: stub,
   121  	}
   122  }
   123  
   124  func (w *stubWorker) Check() bool {
   125  	w.stub.MethodCall(w, "Check")
   126  	return true
   127  }
   128  
   129  func (w *stubWorker) Kill() {
   130  	w.stub.MethodCall(w, "Kill")
   131  }
   132  
   133  func (w *stubWorker) Wait() error {
   134  	w.stub.MethodCall(w, "Wait")
   135  	return w.stub.NextErr()
   136  }
   137  
   138  var errClaimDenied = errors.Trace(lease.ErrClaimDenied)
   139  
   140  type fakeClock struct {
   141  	clock.Clock
   142  }
   143  
   144  type fakeFacade struct {
   145  	singular.Facade
   146  }
   147  
   148  type fakeWorker struct {
   149  	worker.Worker
   150  }
   151  
   152  type fakeAPICaller struct {
   153  	base.APICaller
   154  }