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

     1  // Copyright 2016 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package undertaker_test
     5  
     6  import (
     7  	"context"
     8  
     9  	"github.com/juju/errors"
    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  	gc "gopkg.in/check.v1"
    16  
    17  	"github.com/juju/juju/api/base"
    18  	"github.com/juju/juju/caas"
    19  	"github.com/juju/juju/environs"
    20  	"github.com/juju/juju/worker/common"
    21  	"github.com/juju/juju/worker/undertaker"
    22  )
    23  
    24  type manifoldSuite struct {
    25  	testing.IsolationSuite
    26  	modelType string
    27  	logger    fakeLogger
    28  }
    29  
    30  type CAASManifoldSuite struct {
    31  	manifoldSuite
    32  }
    33  
    34  type IAASManifoldSuite struct {
    35  	manifoldSuite
    36  }
    37  
    38  var (
    39  	_ = gc.Suite(&IAASManifoldSuite{})
    40  	_ = gc.Suite(&CAASManifoldSuite{})
    41  )
    42  
    43  func (s *CAASManifoldSuite) SetUpTest(c *gc.C) {
    44  	s.modelType = "caas"
    45  }
    46  
    47  func (s *IAASManifoldSuite) SetUpTest(c *gc.C) {
    48  	s.modelType = "iaas"
    49  }
    50  
    51  func (s *manifoldSuite) namesConfig() undertaker.ManifoldConfig {
    52  	return undertaker.ManifoldConfig{
    53  		APICallerName: "api-caller",
    54  		Logger:        &s.logger,
    55  		NewCredentialValidatorFacade: func(base.APICaller) (common.CredentialAPI, error) {
    56  			return &fakeCredentialAPI{}, nil
    57  		},
    58  		NewCloudDestroyerFunc: func(ctx context.Context, params environs.OpenParams) (environs.CloudDestroyer, error) {
    59  			return &fakeEnviron{}, nil
    60  		},
    61  	}
    62  }
    63  
    64  func (s *manifoldSuite) TestInputs(c *gc.C) {
    65  	manifold := undertaker.Manifold(s.namesConfig())
    66  	c.Check(manifold.Inputs, jc.DeepEquals, []string{
    67  		"api-caller",
    68  	})
    69  }
    70  
    71  func (s *manifoldSuite) TestOutput(c *gc.C) {
    72  	manifold := undertaker.Manifold(s.namesConfig())
    73  	c.Check(manifold.Output, gc.IsNil)
    74  }
    75  
    76  func (s *manifoldSuite) TestAPICallerMissing(c *gc.C) {
    77  	resources := resourcesMissing("api-caller")
    78  	manifold := undertaker.Manifold(s.namesConfig())
    79  
    80  	worker, err := manifold.Start(resources.Context())
    81  	c.Check(errors.Cause(err), gc.Equals, dependency.ErrMissing)
    82  	c.Check(worker, gc.IsNil)
    83  }
    84  
    85  func (s *manifoldSuite) TestNewFacadeError(c *gc.C) {
    86  	resources := resourcesMissing()
    87  	config := s.namesConfig()
    88  	config.NewFacade = func(apiCaller base.APICaller) (undertaker.Facade, error) {
    89  		checkResource(c, apiCaller, resources, "api-caller")
    90  		return nil, errors.New("blort")
    91  	}
    92  	manifold := undertaker.Manifold(config)
    93  
    94  	worker, err := manifold.Start(resources.Context())
    95  	c.Check(err, gc.ErrorMatches, "blort")
    96  	c.Check(worker, gc.IsNil)
    97  }
    98  
    99  func (s *manifoldSuite) TestNewCredentialAPIError(c *gc.C) {
   100  	config := s.namesConfig()
   101  	config.NewFacade = func(_ base.APICaller) (undertaker.Facade, error) {
   102  		return &fakeFacade{}, nil
   103  	}
   104  	config.NewCredentialValidatorFacade = func(apiCaller base.APICaller) (common.CredentialAPI, error) {
   105  		return nil, errors.New("blort")
   106  	}
   107  	manifold := undertaker.Manifold(config)
   108  
   109  	resources := resourcesMissing()
   110  	worker, err := manifold.Start(resources.Context())
   111  	c.Check(err, gc.ErrorMatches, "blort")
   112  	c.Check(worker, gc.IsNil)
   113  }
   114  
   115  func (s *manifoldSuite) TestNewWorkerError(c *gc.C) {
   116  	resources := resourcesMissing()
   117  	expectFacade := &fakeFacade{}
   118  	config := s.namesConfig()
   119  	config.NewFacade = func(_ base.APICaller) (undertaker.Facade, error) {
   120  		return expectFacade, nil
   121  	}
   122  	config.NewWorker = func(cfg undertaker.Config) (worker.Worker, error) {
   123  		c.Check(cfg.Facade, gc.Equals, expectFacade)
   124  		return nil, errors.New("lhiis")
   125  	}
   126  	manifold := undertaker.Manifold(config)
   127  
   128  	worker, err := manifold.Start(resources.Context())
   129  	c.Check(err, gc.ErrorMatches, "lhiis")
   130  	c.Check(worker, gc.IsNil)
   131  }
   132  
   133  func (s *manifoldSuite) TestNewWorkerSuccess(c *gc.C) {
   134  	expectWorker := &fakeWorker{}
   135  	config := s.namesConfig()
   136  	var gotConfig undertaker.Config
   137  	config.NewFacade = func(_ base.APICaller) (undertaker.Facade, error) {
   138  		return &fakeFacade{}, nil
   139  	}
   140  	config.NewWorker = func(workerConfig undertaker.Config) (worker.Worker, error) {
   141  		gotConfig = workerConfig
   142  		return expectWorker, nil
   143  	}
   144  	manifold := undertaker.Manifold(config)
   145  	resources := resourcesMissing()
   146  
   147  	worker, err := manifold.Start(resources.Context())
   148  	c.Check(err, jc.ErrorIsNil)
   149  	c.Check(worker, gc.Equals, expectWorker)
   150  	c.Assert(gotConfig.Logger, gc.Equals, &s.logger)
   151  }
   152  
   153  func resourcesMissing(missing ...string) dt.StubResources {
   154  	resources := dt.StubResources{
   155  		"api-caller": dt.NewStubResource(&fakeAPICaller{}),
   156  		"environ":    dt.NewStubResource(&fakeEnviron{}),
   157  		"broker":     dt.NewStubResource(&fakeBroker{}),
   158  	}
   159  	for _, name := range missing {
   160  		resources[name] = dt.StubResource{Error: dependency.ErrMissing}
   161  	}
   162  	return resources
   163  }
   164  
   165  func checkResource(c *gc.C, actual interface{}, resources dt.StubResources, name string) {
   166  	c.Check(actual, gc.Equals, resources[name].Outputs[0])
   167  }
   168  
   169  type fakeAPICaller struct {
   170  	base.APICaller
   171  }
   172  
   173  type fakeEnviron struct {
   174  	environs.Environ
   175  }
   176  
   177  type fakeBroker struct {
   178  	caas.Broker
   179  }
   180  
   181  type fakeFacade struct {
   182  	undertaker.Facade
   183  }
   184  
   185  type fakeWorker struct {
   186  	worker.Worker
   187  }
   188  
   189  type fakeCredentialAPI struct{}
   190  
   191  func (*fakeCredentialAPI) InvalidateModelCredential(reason string) error {
   192  	return nil
   193  }
   194  
   195  type fakeLogger struct {
   196  	stub testing.Stub
   197  }
   198  
   199  func (l *fakeLogger) Errorf(format string, args ...interface{}) {
   200  	l.stub.AddCall("Errorf", format, args)
   201  }
   202  
   203  func (l *fakeLogger) Debugf(format string, args ...interface{}) {
   204  }
   205  
   206  func (l *fakeLogger) Tracef(format string, args ...interface{}) {
   207  }
   208  
   209  func (l *fakeLogger) Infof(format string, args ...interface{}) {
   210  }
   211  
   212  func (l *fakeLogger) Warningf(format string, args ...interface{}) {
   213  	l.stub.AddCall("Warningf", format, args)
   214  }