github.com/juju/juju@v0.0.0-20240327075706-a90865de2538/worker/modelworkermanager/manifold_test.go (about)

     1  // Copyright 2017 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package modelworkermanager_test
     5  
     6  import (
     7  	"github.com/juju/errors"
     8  	"github.com/juju/loggo"
     9  	"github.com/juju/names/v5"
    10  	"github.com/juju/testing"
    11  	jc "github.com/juju/testing/checkers"
    12  	"github.com/juju/worker/v3"
    13  	"github.com/juju/worker/v3/dependency"
    14  	dt "github.com/juju/worker/v3/dependency/testing"
    15  	"github.com/juju/worker/v3/workertest"
    16  	gc "gopkg.in/check.v1"
    17  
    18  	"github.com/juju/juju/agent"
    19  	"github.com/juju/juju/apiserver/apiserverhttp"
    20  	corelogger "github.com/juju/juju/core/logger"
    21  	"github.com/juju/juju/pki"
    22  	pkitest "github.com/juju/juju/pki/test"
    23  	"github.com/juju/juju/state"
    24  	statetesting "github.com/juju/juju/state/testing"
    25  	jworker "github.com/juju/juju/worker"
    26  	"github.com/juju/juju/worker/modelworkermanager"
    27  )
    28  
    29  type ManifoldSuite struct {
    30  	statetesting.StateSuite
    31  
    32  	authority    pki.Authority
    33  	manifold     dependency.Manifold
    34  	context      dependency.Context
    35  	stateTracker stubStateTracker
    36  	sysLogger    stubLogger
    37  
    38  	stub testing.Stub
    39  }
    40  
    41  var _ = gc.Suite(&ManifoldSuite{})
    42  
    43  func (s *ManifoldSuite) SetUpTest(c *gc.C) {
    44  	var err error
    45  	s.authority, err = pkitest.NewTestAuthority()
    46  	c.Assert(err, jc.ErrorIsNil)
    47  
    48  	s.StateSuite.SetUpTest(c)
    49  
    50  	s.stateTracker = stubStateTracker{pool: s.StatePool}
    51  	s.stub.ResetCalls()
    52  
    53  	s.sysLogger = stubLogger{}
    54  
    55  	s.context = s.newContext(nil)
    56  	s.manifold = modelworkermanager.Manifold(modelworkermanager.ManifoldConfig{
    57  		AgentName:      "agent",
    58  		AuthorityName:  "authority",
    59  		StateName:      "state",
    60  		MuxName:        "mux",
    61  		SyslogName:     "syslog",
    62  		NewWorker:      s.newWorker,
    63  		NewModelWorker: s.newModelWorker,
    64  		ModelMetrics:   dummyModelMetrics{},
    65  		Logger:         loggo.GetLogger("test"),
    66  	})
    67  }
    68  
    69  var mux = apiserverhttp.NewMux()
    70  
    71  func (s *ManifoldSuite) newContext(overlay map[string]interface{}) dependency.Context {
    72  	resources := map[string]interface{}{
    73  		"agent":     &fakeAgent{},
    74  		"authority": s.authority,
    75  		"mux":       mux,
    76  		"state":     &s.stateTracker,
    77  		"syslog":    s.sysLogger,
    78  	}
    79  	for k, v := range overlay {
    80  		resources[k] = v
    81  	}
    82  	return dt.StubContext(nil, resources)
    83  }
    84  
    85  func (s *ManifoldSuite) newWorker(config modelworkermanager.Config) (worker.Worker, error) {
    86  	s.stub.MethodCall(s, "NewWorker", config)
    87  	if err := s.stub.NextErr(); err != nil {
    88  		return nil, err
    89  	}
    90  	return worker.NewRunner(worker.RunnerParams{}), nil
    91  }
    92  
    93  func (s *ManifoldSuite) newModelWorker(config modelworkermanager.NewModelConfig) (worker.Worker, error) {
    94  	s.stub.MethodCall(s, "NewModelWorker", config)
    95  	if err := s.stub.NextErr(); err != nil {
    96  		return nil, err
    97  	}
    98  	return worker.NewRunner(worker.RunnerParams{}), nil
    99  }
   100  
   101  var expectedInputs = []string{"agent", "authority", "mux", "state", "syslog"}
   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) TestStart(c *gc.C) {
   118  	w := s.startWorkerClean(c)
   119  	workertest.CleanKill(c, w)
   120  
   121  	s.stub.CheckCallNames(c, "NewWorker")
   122  	args := s.stub.Calls()[0].Args
   123  	c.Assert(args, gc.HasLen, 1)
   124  	c.Assert(args[0], gc.FitsTypeOf, modelworkermanager.Config{})
   125  	config := args[0].(modelworkermanager.Config)
   126  	config.Authority = s.authority
   127  
   128  	c.Assert(config.NewModelWorker, gc.NotNil)
   129  	modelConfig := modelworkermanager.NewModelConfig{
   130  		Authority:    s.authority,
   131  		ModelUUID:    "foo",
   132  		ModelType:    state.ModelTypeIAAS,
   133  		ModelMetrics: dummyMetricSink{},
   134  	}
   135  	mw, err := config.NewModelWorker(modelConfig)
   136  	c.Assert(err, jc.ErrorIsNil)
   137  	workertest.CleanKill(c, mw)
   138  	s.stub.CheckCallNames(c, "NewWorker", "NewModelWorker")
   139  	s.stub.CheckCall(c, 1, "NewModelWorker", modelConfig)
   140  	config.NewModelWorker = nil
   141  
   142  	c.Assert(config, jc.DeepEquals, modelworkermanager.Config{
   143  		Authority:    s.authority,
   144  		ModelWatcher: s.State,
   145  		ModelMetrics: dummyModelMetrics{},
   146  		Mux:          mux,
   147  		Controller: modelworkermanager.StatePoolController{
   148  			StatePool: s.StatePool,
   149  			SysLogger: s.sysLogger,
   150  		},
   151  		ErrorDelay: jworker.RestartDelay,
   152  		Logger:     loggo.GetLogger("test"),
   153  		MachineID:  "1",
   154  	})
   155  }
   156  
   157  func (s *ManifoldSuite) TestStopWorkerClosesState(c *gc.C) {
   158  	w := s.startWorkerClean(c)
   159  	defer workertest.CleanKill(c, w)
   160  
   161  	s.stateTracker.CheckCallNames(c, "Use")
   162  
   163  	workertest.CleanKill(c, w)
   164  	s.stateTracker.CheckCallNames(c, "Use", "Done")
   165  }
   166  
   167  func (s *ManifoldSuite) startWorkerClean(c *gc.C) worker.Worker {
   168  	w, err := s.manifold.Start(s.context)
   169  	c.Assert(err, jc.ErrorIsNil)
   170  	workertest.CheckAlive(c, w)
   171  	return w
   172  }
   173  
   174  type stubStateTracker struct {
   175  	testing.Stub
   176  	pool *state.StatePool
   177  }
   178  
   179  func (s *stubStateTracker) Use() (*state.StatePool, error) {
   180  	s.MethodCall(s, "Use")
   181  	return s.pool, s.NextErr()
   182  }
   183  
   184  func (s *stubStateTracker) Done() error {
   185  	s.MethodCall(s, "Done")
   186  	return s.NextErr()
   187  }
   188  
   189  func (s *stubStateTracker) Report() map[string]interface{} {
   190  	s.MethodCall(s, "Report")
   191  	return nil
   192  }
   193  
   194  type fakeAgent struct {
   195  	agent.Agent
   196  	agent.Config
   197  }
   198  
   199  func (f *fakeAgent) CurrentConfig() agent.Config {
   200  	return f
   201  }
   202  
   203  func (f *fakeAgent) Tag() names.Tag {
   204  	return names.NewMachineTag("1")
   205  }
   206  
   207  type stubLogger struct {
   208  	corelogger.LoggerCloser
   209  }