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

     1  // Copyright 2016 Canonical Ltd.
     2  // Copyright 2016 Cloudbase Solutions
     3  // Licensed under the AGPLv3, see LICENCE file for details.
     4  
     5  package retrystrategy_test
     6  
     7  import (
     8  	"time"
     9  
    10  	"github.com/juju/errors"
    11  	"github.com/juju/testing"
    12  	jc "github.com/juju/testing/checkers"
    13  	gc "gopkg.in/check.v1"
    14  	"gopkg.in/juju/names.v2"
    15  	"gopkg.in/juju/worker.v1"
    16  	"gopkg.in/juju/worker.v1/dependency"
    17  	dt "gopkg.in/juju/worker.v1/dependency/testing"
    18  
    19  	"github.com/juju/juju/agent"
    20  	"github.com/juju/juju/api/base"
    21  	"github.com/juju/juju/apiserver/params"
    22  	"github.com/juju/juju/core/watcher"
    23  	"github.com/juju/juju/worker/retrystrategy"
    24  )
    25  
    26  type ManifoldSuite struct {
    27  	testing.IsolationSuite
    28  	context    dependency.Context
    29  	fakeAgent  agent.Agent
    30  	fakeCaller base.APICaller
    31  	fakeFacade retrystrategy.Facade
    32  	fakeWorker worker.Worker
    33  	newFacade  func(retrystrategy.Facade) func(base.APICaller) retrystrategy.Facade
    34  	newWorker  func(worker.Worker, error) func(retrystrategy.WorkerConfig) (worker.Worker, error)
    35  }
    36  
    37  var _ = gc.Suite(&ManifoldSuite{})
    38  
    39  func (s *ManifoldSuite) SetUpSuite(c *gc.C) {
    40  	s.IsolationSuite.SetUpSuite(c)
    41  	s.fakeAgent = &fakeAgent{}
    42  	s.fakeCaller = &fakeCaller{}
    43  	s.context = dt.StubContext(nil, map[string]interface{}{
    44  		"agent":      s.fakeAgent,
    45  		"api-caller": s.fakeCaller,
    46  	})
    47  	s.newFacade = func(facade retrystrategy.Facade) func(base.APICaller) retrystrategy.Facade {
    48  		s.fakeFacade = facade
    49  		return func(apiCaller base.APICaller) retrystrategy.Facade {
    50  			c.Assert(apiCaller, gc.Equals, s.fakeCaller)
    51  			return facade
    52  		}
    53  	}
    54  	s.newWorker = func(w worker.Worker, err error) func(retrystrategy.WorkerConfig) (worker.Worker, error) {
    55  		s.fakeWorker = w
    56  		return func(wc retrystrategy.WorkerConfig) (worker.Worker, error) {
    57  			c.Assert(wc.Facade, gc.Equals, s.fakeFacade)
    58  			c.Assert(wc.AgentTag, gc.Equals, fakeTag)
    59  			c.Assert(wc.RetryStrategy, gc.Equals, fakeStrategy)
    60  			return w, err
    61  		}
    62  	}
    63  }
    64  
    65  func (s *ManifoldSuite) TestInputs(c *gc.C) {
    66  	manifold := retrystrategy.Manifold(retrystrategy.ManifoldConfig{
    67  		AgentName:     "wut",
    68  		APICallerName: "exactly",
    69  	})
    70  	c.Check(manifold.Inputs, jc.DeepEquals, []string{"wut", "exactly"})
    71  }
    72  
    73  func (s *ManifoldSuite) TestStartMissingAgent(c *gc.C) {
    74  	manifold := retrystrategy.Manifold(retrystrategy.ManifoldConfig{
    75  		AgentName:     "agent",
    76  		APICallerName: "api-caller",
    77  	})
    78  	context := dt.StubContext(nil, map[string]interface{}{
    79  		"agent":      dependency.ErrMissing,
    80  		"api-caller": s.fakeCaller,
    81  	})
    82  
    83  	w, err := manifold.Start(context)
    84  	c.Assert(errors.Cause(err), gc.Equals, dependency.ErrMissing)
    85  	c.Assert(w, gc.IsNil)
    86  }
    87  
    88  func (s *ManifoldSuite) TestStartMissingAPI(c *gc.C) {
    89  	manifold := retrystrategy.Manifold(retrystrategy.ManifoldConfig{
    90  		AgentName:     "agent",
    91  		APICallerName: "api-caller",
    92  	})
    93  	context := dt.StubContext(nil, map[string]interface{}{
    94  		"agent":      s.fakeAgent,
    95  		"api-caller": dependency.ErrMissing,
    96  	})
    97  
    98  	w, err := manifold.Start(context)
    99  	c.Assert(errors.Cause(err), gc.Equals, dependency.ErrMissing)
   100  	c.Assert(w, gc.IsNil)
   101  }
   102  
   103  func (s *ManifoldSuite) TestStartFacadeValueError(c *gc.C) {
   104  	manifold := retrystrategy.Manifold(retrystrategy.ManifoldConfig{
   105  		AgentName:     "agent",
   106  		APICallerName: "api-caller",
   107  		NewFacade:     s.newFacade(&fakeFacadeErr{err: errors.New("blop")}),
   108  	})
   109  
   110  	w, err := manifold.Start(s.context)
   111  	c.Assert(errors.Cause(err), gc.ErrorMatches, "blop")
   112  	c.Assert(w, gc.IsNil)
   113  }
   114  
   115  func (s *ManifoldSuite) TestStartWorkerError(c *gc.C) {
   116  	manifold := retrystrategy.Manifold(retrystrategy.ManifoldConfig{
   117  		AgentName:     "agent",
   118  		APICallerName: "api-caller",
   119  		NewFacade:     s.newFacade(&fakeFacade{}),
   120  		NewWorker:     s.newWorker(nil, errors.New("blam")),
   121  	})
   122  
   123  	w, err := manifold.Start(s.context)
   124  	c.Assert(err, gc.ErrorMatches, "blam")
   125  	c.Assert(w, gc.IsNil)
   126  }
   127  
   128  func (s *ManifoldSuite) TestStartSuccess(c *gc.C) {
   129  	fakeWorker := &fakeWorker{}
   130  	manifold := retrystrategy.Manifold(retrystrategy.ManifoldConfig{
   131  		AgentName:     "agent",
   132  		APICallerName: "api-caller",
   133  		NewFacade:     s.newFacade(&fakeFacade{}),
   134  		NewWorker:     s.newWorker(fakeWorker, nil),
   135  	})
   136  
   137  	w, err := manifold.Start(s.context)
   138  	c.Assert(err, jc.ErrorIsNil)
   139  	c.Assert(w, gc.Equals, fakeWorker)
   140  }
   141  
   142  func (s *ManifoldSuite) TestOutputSuccess(c *gc.C) {
   143  	manifold := retrystrategy.Manifold(retrystrategy.ManifoldConfig{
   144  		AgentName:     "agent",
   145  		APICallerName: "api-caller",
   146  		NewFacade:     s.newFacade(&fakeFacade{}),
   147  		NewWorker:     retrystrategy.NewRetryStrategyWorker,
   148  	})
   149  
   150  	w, err := manifold.Start(s.context)
   151  	s.AddCleanup(func(c *gc.C) { w.Kill() })
   152  	c.Assert(err, jc.ErrorIsNil)
   153  
   154  	var out params.RetryStrategy
   155  	err = manifold.Output(w, &out)
   156  	c.Assert(err, jc.ErrorIsNil)
   157  	c.Assert(out, gc.Equals, fakeStrategy)
   158  }
   159  
   160  func (s *ManifoldSuite) TestOutputBadInput(c *gc.C) {
   161  	manifold := retrystrategy.Manifold(retrystrategy.ManifoldConfig{
   162  		AgentName:     "agent",
   163  		APICallerName: "api-caller",
   164  		NewFacade:     s.newFacade(&fakeFacade{}),
   165  		NewWorker:     s.newWorker(&fakeWorker{}, nil),
   166  	})
   167  
   168  	w, err := manifold.Start(s.context)
   169  	c.Assert(err, jc.ErrorIsNil)
   170  
   171  	var out params.RetryStrategy
   172  	err = manifold.Output(w, &out)
   173  	c.Assert(out, gc.Equals, params.RetryStrategy{})
   174  	c.Assert(err.Error(), gc.Equals, "in should be a *retryStrategyWorker; is *retrystrategy_test.fakeWorker")
   175  }
   176  
   177  func (s *ManifoldSuite) TestOutputBadTarget(c *gc.C) {
   178  	manifold := retrystrategy.Manifold(retrystrategy.ManifoldConfig{
   179  		AgentName:     "agent",
   180  		APICallerName: "api-caller",
   181  		NewFacade:     s.newFacade(&fakeFacade{}),
   182  		NewWorker:     retrystrategy.NewRetryStrategyWorker,
   183  	})
   184  
   185  	w, err := manifold.Start(s.context)
   186  	s.AddCleanup(func(c *gc.C) { w.Kill() })
   187  	c.Assert(err, jc.ErrorIsNil)
   188  
   189  	var out interface{}
   190  	err = manifold.Output(w, &out)
   191  	c.Assert(err.Error(), gc.Equals, "out should be a *params.RetryStrategy; is *interface {}")
   192  }
   193  
   194  var fakeTag = names.NewUnitTag("whatatag/0")
   195  
   196  var fakeStrategy = params.RetryStrategy{
   197  	ShouldRetry:  false,
   198  	MinRetryTime: 2 * time.Second,
   199  }
   200  
   201  type fakeAgent struct {
   202  	agent.Agent
   203  }
   204  
   205  func (mock *fakeAgent) CurrentConfig() agent.Config {
   206  	return &fakeConfig{}
   207  }
   208  
   209  type fakeConfig struct {
   210  	agent.Config
   211  }
   212  
   213  func (mock *fakeConfig) Tag() names.Tag {
   214  	return fakeTag
   215  }
   216  
   217  type fakeCaller struct {
   218  	base.APICaller
   219  }
   220  
   221  type fakeFacade struct {
   222  	retrystrategy.Facade
   223  }
   224  
   225  func (mock *fakeFacade) RetryStrategy(agentTag names.Tag) (params.RetryStrategy, error) {
   226  	return fakeStrategy, nil
   227  }
   228  
   229  func (mock *fakeFacade) WatchRetryStrategy(agentTag names.Tag) (watcher.NotifyWatcher, error) {
   230  	return newStubWatcher(), nil
   231  }
   232  
   233  type fakeFacadeErr struct {
   234  	retrystrategy.Facade
   235  	err error
   236  }
   237  
   238  func (mock *fakeFacadeErr) RetryStrategy(agentTag names.Tag) (params.RetryStrategy, error) {
   239  	return params.RetryStrategy{}, mock.err
   240  }
   241  
   242  type fakeWorker struct {
   243  	worker.Worker
   244  }