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

     1  // Copyright 2018 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package controllerport_test
     5  
     6  import (
     7  	"github.com/juju/errors"
     8  	"github.com/juju/loggo"
     9  	"github.com/juju/pubsub"
    10  	"github.com/juju/testing"
    11  	jc "github.com/juju/testing/checkers"
    12  	gc "gopkg.in/check.v1"
    13  	"gopkg.in/juju/worker.v1"
    14  	"gopkg.in/juju/worker.v1/dependency"
    15  	dt "gopkg.in/juju/worker.v1/dependency/testing"
    16  	"gopkg.in/juju/worker.v1/workertest"
    17  
    18  	"github.com/juju/juju/agent"
    19  	"github.com/juju/juju/apiserver/params"
    20  	"github.com/juju/juju/controller"
    21  	"github.com/juju/juju/state"
    22  	"github.com/juju/juju/worker/controllerport"
    23  )
    24  
    25  type ManifoldSuite struct {
    26  	testing.IsolationSuite
    27  
    28  	config           controllerport.ManifoldConfig
    29  	manifold         dependency.Manifold
    30  	context          dependency.Context
    31  	agent            *mockAgent
    32  	hub              *pubsub.StructuredHub
    33  	state            stubStateTracker
    34  	logger           loggo.Logger
    35  	controllerConfig controller.Config
    36  	worker           worker.Worker
    37  
    38  	stub testing.Stub
    39  }
    40  
    41  var _ = gc.Suite(&ManifoldSuite{})
    42  
    43  func (s *ManifoldSuite) SetUpTest(c *gc.C) {
    44  	s.IsolationSuite.SetUpTest(c)
    45  
    46  	s.agent = &mockAgent{}
    47  	s.hub = pubsub.NewStructuredHub(nil)
    48  	s.state = stubStateTracker{}
    49  	s.logger = loggo.GetLogger("controllerport_manifold")
    50  	s.controllerConfig = controller.Config(map[string]interface{}{
    51  		"controller-api-port": 2048,
    52  	})
    53  	s.worker = &struct{ worker.Worker }{}
    54  	s.stub.ResetCalls()
    55  
    56  	s.context = s.newContext(nil)
    57  	s.config = controllerport.ManifoldConfig{
    58  		AgentName:               "agent",
    59  		HubName:                 "hub",
    60  		StateName:               "state",
    61  		Logger:                  s.logger,
    62  		UpdateControllerAPIPort: s.updatePort,
    63  		GetControllerConfig:     s.getControllerConfig,
    64  		NewWorker:               s.newWorker,
    65  	}
    66  	s.manifold = controllerport.Manifold(s.config)
    67  }
    68  
    69  func (s *ManifoldSuite) newContext(overlay map[string]interface{}) dependency.Context {
    70  	resources := map[string]interface{}{
    71  		"agent": s.agent,
    72  		"hub":   s.hub,
    73  		"state": &s.state,
    74  	}
    75  	for k, v := range overlay {
    76  		resources[k] = v
    77  	}
    78  	return dt.StubContext(nil, resources)
    79  }
    80  
    81  func (s *ManifoldSuite) getControllerConfig(st *state.State) (controller.Config, error) {
    82  	s.stub.MethodCall(s, "GetControllerConfig", st)
    83  	if err := s.stub.NextErr(); err != nil {
    84  		return nil, err
    85  	}
    86  	return s.controllerConfig, nil
    87  }
    88  
    89  func (s *ManifoldSuite) updatePort(port int) error {
    90  	return errors.Errorf("braincake")
    91  }
    92  
    93  func (s *ManifoldSuite) newWorker(config controllerport.Config) (worker.Worker, error) {
    94  	s.stub.MethodCall(s, "NewWorker", config)
    95  	if err := s.stub.NextErr(); err != nil {
    96  		return nil, err
    97  	}
    98  	return s.worker, nil
    99  }
   100  
   101  var expectedInputs = []string{"state", "agent", "hub"}
   102  
   103  func (s *ManifoldSuite) TestInputs(c *gc.C) {
   104  	c.Assert(s.manifold.Inputs, jc.SameContents, expectedInputs)
   105  }
   106  
   107  func (s *ManifoldSuite) TestMissingInputs(c *gc.C) {
   108  	for _, input := range expectedInputs {
   109  		context := s.newContext(map[string]interface{}{
   110  			input: dependency.ErrMissing,
   111  		})
   112  		_, err := s.manifold.Start(context)
   113  		c.Assert(errors.Cause(err), gc.Equals, dependency.ErrMissing)
   114  	}
   115  }
   116  
   117  func (s *ManifoldSuite) TestValidate(c *gc.C) {
   118  	type test struct {
   119  		f      func(*controllerport.ManifoldConfig)
   120  		expect string
   121  	}
   122  	tests := []test{{
   123  		func(cfg *controllerport.ManifoldConfig) { cfg.StateName = "" },
   124  		"empty StateName not valid",
   125  	}, {
   126  		func(cfg *controllerport.ManifoldConfig) { cfg.HubName = "" },
   127  		"empty HubName not valid",
   128  	}, {
   129  		func(cfg *controllerport.ManifoldConfig) { cfg.AgentName = "" },
   130  		"empty AgentName not valid",
   131  	}, {
   132  		func(cfg *controllerport.ManifoldConfig) { cfg.Logger = nil },
   133  		"nil Logger not valid",
   134  	}, {
   135  		func(cfg *controllerport.ManifoldConfig) { cfg.UpdateControllerAPIPort = nil },
   136  		"nil UpdateControllerAPIPort not valid",
   137  	}, {
   138  		func(cfg *controllerport.ManifoldConfig) { cfg.GetControllerConfig = nil },
   139  		"nil GetControllerConfig not valid",
   140  	}, {
   141  		func(cfg *controllerport.ManifoldConfig) { cfg.NewWorker = nil },
   142  		"nil NewWorker not valid",
   143  	}}
   144  	for i, test := range tests {
   145  		c.Logf("test #%d (%s)", i, test.expect)
   146  		config := s.config
   147  		test.f(&config)
   148  		manifold := controllerport.Manifold(config)
   149  		w, err := manifold.Start(s.context)
   150  		workertest.CheckNilOrKill(c, w)
   151  		c.Check(err, gc.ErrorMatches, test.expect)
   152  	}
   153  }
   154  
   155  func (s *ManifoldSuite) TestStart(c *gc.C) {
   156  	s.startWorkerClean(c)
   157  
   158  	s.stub.CheckCallNames(c, "GetControllerConfig", "NewWorker")
   159  	args := s.stub.Calls()[1].Args
   160  	c.Assert(args, gc.HasLen, 1)
   161  	c.Assert(args[0], gc.FitsTypeOf, controllerport.Config{})
   162  	config := args[0].(controllerport.Config)
   163  
   164  	// Can't directly compare functions, so blank it out.
   165  	c.Assert(config.UpdateControllerAPIPort(3), gc.ErrorMatches, "braincake")
   166  	config.UpdateControllerAPIPort = nil
   167  
   168  	c.Assert(config, jc.DeepEquals, controllerport.Config{
   169  		AgentConfig:       &s.agent.conf,
   170  		Hub:               s.hub,
   171  		Logger:            s.logger,
   172  		ControllerAPIPort: 2048,
   173  	})
   174  }
   175  
   176  func (s *ManifoldSuite) startWorkerClean(c *gc.C) worker.Worker {
   177  	w, err := s.manifold.Start(s.context)
   178  	c.Assert(err, jc.ErrorIsNil)
   179  	c.Assert(w, gc.Equals, s.worker)
   180  	return w
   181  }
   182  
   183  type stubStateTracker struct {
   184  	testing.Stub
   185  	pool state.StatePool
   186  }
   187  
   188  func (s *stubStateTracker) Use() (*state.StatePool, error) {
   189  	s.MethodCall(s, "Use")
   190  	return &s.pool, s.NextErr()
   191  }
   192  
   193  func (s *stubStateTracker) Done() error {
   194  	s.MethodCall(s, "Done")
   195  	return s.NextErr()
   196  }
   197  
   198  func (s *stubStateTracker) Report() map[string]interface{} {
   199  	s.MethodCall(s, "Report")
   200  	return nil
   201  }
   202  
   203  type mockAgent struct {
   204  	agent.Agent
   205  	conf mockAgentConfig
   206  }
   207  
   208  func (ma *mockAgent) CurrentConfig() agent.Config {
   209  	return &ma.conf
   210  }
   211  
   212  type mockAgentConfig struct {
   213  	agent.Config
   214  	port int
   215  }
   216  
   217  func (c *mockAgentConfig) StateServingInfo() (params.StateServingInfo, bool) {
   218  	return params.StateServingInfo{ControllerAPIPort: c.port}, true
   219  }