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