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