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

     1  // Copyright 2018 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package modelcache_test
     5  
     6  import (
     7  	"unsafe"
     8  
     9  	"github.com/juju/errors"
    10  	"github.com/juju/loggo"
    11  	"github.com/juju/testing"
    12  	jc "github.com/juju/testing/checkers"
    13  	gc "gopkg.in/check.v1"
    14  	"gopkg.in/juju/worker.v1"
    15  	"gopkg.in/juju/worker.v1/dependency"
    16  	dt "gopkg.in/juju/worker.v1/dependency/testing"
    17  
    18  	"github.com/juju/juju/state"
    19  	"github.com/juju/juju/worker/modelcache"
    20  	workerstate "github.com/juju/juju/worker/state"
    21  )
    22  
    23  type ManifoldSuite struct {
    24  	testing.IsolationSuite
    25  	config modelcache.ManifoldConfig
    26  }
    27  
    28  var _ = gc.Suite(&ManifoldSuite{})
    29  
    30  func (s *ManifoldSuite) SetUpTest(c *gc.C) {
    31  	s.IsolationSuite.SetUpTest(c)
    32  	s.config = modelcache.ManifoldConfig{
    33  		StateName:            "state",
    34  		Logger:               loggo.GetLogger("test"),
    35  		PrometheusRegisterer: noopRegisterer{},
    36  		NewWorker: func(modelcache.Config) (worker.Worker, error) {
    37  			return nil, errors.New("boom")
    38  		},
    39  	}
    40  }
    41  
    42  func (s *ManifoldSuite) manifold() dependency.Manifold {
    43  	return modelcache.Manifold(s.config)
    44  }
    45  
    46  func (s *ManifoldSuite) TestInputs(c *gc.C) {
    47  	c.Check(s.manifold().Inputs, jc.DeepEquals, []string{"state"})
    48  }
    49  
    50  func (s *ManifoldSuite) TestConfigValidation(c *gc.C) {
    51  	err := s.config.Validate()
    52  	c.Assert(err, jc.ErrorIsNil)
    53  }
    54  
    55  func (s *ManifoldSuite) TestConfigValidationMissingStateName(c *gc.C) {
    56  	s.config.StateName = ""
    57  	err := s.config.Validate()
    58  	c.Check(err, jc.Satisfies, errors.IsNotValid)
    59  	c.Check(err, gc.ErrorMatches, "empty StateName not valid")
    60  }
    61  
    62  func (s *ManifoldSuite) TestConfigValidationMissingPrometheusRegisterer(c *gc.C) {
    63  	s.config.PrometheusRegisterer = nil
    64  	err := s.config.Validate()
    65  	c.Check(err, jc.Satisfies, errors.IsNotValid)
    66  	c.Check(err, gc.ErrorMatches, "missing PrometheusRegisterer not valid")
    67  }
    68  
    69  func (s *ManifoldSuite) TestConfigValidationMissingLogger(c *gc.C) {
    70  	s.config.Logger = nil
    71  	err := s.config.Validate()
    72  	c.Check(err, jc.Satisfies, errors.IsNotValid)
    73  	c.Check(err, gc.ErrorMatches, "missing Logger not valid")
    74  }
    75  
    76  func (s *ManifoldSuite) TestConfigValidationMissingNewWorker(c *gc.C) {
    77  	s.config.NewWorker = nil
    78  	err := s.config.Validate()
    79  	c.Check(err, jc.Satisfies, errors.IsNotValid)
    80  	c.Check(err, gc.ErrorMatches, "missing NewWorker func not valid")
    81  }
    82  
    83  func (s *ManifoldSuite) TestManifoldCallsValidate(c *gc.C) {
    84  	context := dt.StubContext(nil, map[string]interface{}{})
    85  	s.config.Logger = nil
    86  	worker, err := s.manifold().Start(context)
    87  	c.Check(worker, gc.IsNil)
    88  	c.Check(err, jc.Satisfies, errors.IsNotValid)
    89  	c.Check(err, gc.ErrorMatches, `missing Logger not valid`)
    90  }
    91  
    92  func (s *ManifoldSuite) TestAgentMissing(c *gc.C) {
    93  	context := dt.StubContext(nil, map[string]interface{}{
    94  		"state": dependency.ErrMissing,
    95  	})
    96  
    97  	worker, err := s.manifold().Start(context)
    98  	c.Check(worker, gc.IsNil)
    99  	c.Check(errors.Cause(err), gc.Equals, dependency.ErrMissing)
   100  }
   101  
   102  func (s *ManifoldSuite) TestNewWorkerArgs(c *gc.C) {
   103  	var config modelcache.Config
   104  	s.config.NewWorker = func(c modelcache.Config) (worker.Worker, error) {
   105  		config = c
   106  		return &fakeWorker{}, nil
   107  	}
   108  
   109  	tracker := &fakeStateTracker{}
   110  	context := dt.StubContext(nil, map[string]interface{}{
   111  		"state": tracker,
   112  	})
   113  
   114  	worker, err := s.manifold().Start(context)
   115  	c.Check(err, jc.ErrorIsNil)
   116  	c.Check(worker, gc.NotNil)
   117  
   118  	c.Check(config.Validate(), jc.ErrorIsNil)
   119  	c.Check(config.StatePool, gc.Equals, tracker.pool())
   120  	c.Check(config.Logger, gc.Equals, s.config.Logger)
   121  	c.Check(config.PrometheusRegisterer, gc.Equals, s.config.PrometheusRegisterer)
   122  
   123  	c.Check(tracker.released, jc.IsFalse)
   124  	config.Cleanup()
   125  	c.Check(tracker.released, jc.IsTrue)
   126  }
   127  
   128  func (s *ManifoldSuite) TestNewWorkerErrorReleasesState(c *gc.C) {
   129  	tracker := &fakeStateTracker{}
   130  	context := dt.StubContext(nil, map[string]interface{}{
   131  		"state": tracker,
   132  	})
   133  
   134  	worker, err := s.manifold().Start(context)
   135  	c.Check(err, gc.ErrorMatches, "boom")
   136  	c.Check(worker, gc.IsNil)
   137  	c.Check(tracker.released, jc.IsTrue)
   138  }
   139  
   140  type fakeWorker struct {
   141  	worker.Worker
   142  }
   143  
   144  type fakeStateTracker struct {
   145  	workerstate.StateTracker
   146  	released bool
   147  }
   148  
   149  // Return an invalid but non-zero state pool pointer.
   150  // Is only ever used for comparison.
   151  func (f *fakeStateTracker) Use() (*state.StatePool, error) {
   152  	return f.pool(), nil
   153  }
   154  
   155  func (f *fakeStateTracker) pool() *state.StatePool {
   156  	return (*state.StatePool)(unsafe.Pointer(f))
   157  }
   158  
   159  // Done tracks that the used pool is released.
   160  func (f *fakeStateTracker) Done() error {
   161  	f.released = true
   162  	return nil
   163  }