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

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package apicaller_test
     5  
     6  import (
     7  	"github.com/juju/errors"
     8  	"github.com/juju/testing"
     9  	jc "github.com/juju/testing/checkers"
    10  	gc "gopkg.in/check.v1"
    11  	"gopkg.in/juju/names.v2"
    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/agent"
    17  	"github.com/juju/juju/api"
    18  	"github.com/juju/juju/api/base"
    19  	coretesting "github.com/juju/juju/testing"
    20  	"github.com/juju/juju/worker/apicaller"
    21  )
    22  
    23  type ManifoldSuite struct {
    24  	testing.IsolationSuite
    25  	testing.Stub
    26  
    27  	manifold       dependency.Manifold
    28  	manifoldConfig apicaller.ManifoldConfig
    29  	agent          *mockAgent
    30  	conn           *mockConn
    31  	context        dependency.Context
    32  }
    33  
    34  var _ = gc.Suite(&ManifoldSuite{})
    35  
    36  func (s *ManifoldSuite) SetUpTest(c *gc.C) {
    37  	s.IsolationSuite.SetUpTest(c)
    38  	s.Stub = testing.Stub{}
    39  	s.manifoldConfig = apicaller.ManifoldConfig{
    40  		AgentName:            "agent-name",
    41  		APIConfigWatcherName: "api-config-watcher-name",
    42  		APIOpen: func(*api.Info, api.DialOpts) (api.Connection, error) {
    43  			panic("just a fake")
    44  		},
    45  		NewConnection: func(a agent.Agent, apiOpen api.OpenFunc) (api.Connection, error) {
    46  			c.Check(apiOpen, gc.NotNil) // uncomparable
    47  			s.AddCall("NewConnection", a)
    48  			if err := s.NextErr(); err != nil {
    49  				return nil, err
    50  			}
    51  			return s.conn, nil
    52  		},
    53  		Filter: func(err error) error {
    54  			panic(err)
    55  		},
    56  	}
    57  	s.manifold = apicaller.Manifold(s.manifoldConfig)
    58  	checkFilter := func() {
    59  		s.manifold.Filter(errors.New("arrgh"))
    60  	}
    61  	c.Check(checkFilter, gc.PanicMatches, "arrgh")
    62  
    63  	s.agent = &mockAgent{
    64  		stub:   &s.Stub,
    65  		model:  coretesting.ModelTag,
    66  		entity: names.NewMachineTag("42"),
    67  	}
    68  	s.context = dt.StubContext(nil, map[string]interface{}{
    69  		"agent-name": s.agent,
    70  	})
    71  
    72  	// Watch out for this: it uses its own Stub because Close calls
    73  	// are made from the worker's loop goroutine. You should make
    74  	// sure to stop the worker before checking the mock conn's calls.
    75  	s.conn = &mockConn{
    76  		stub:   &testing.Stub{},
    77  		broken: make(chan struct{}),
    78  	}
    79  }
    80  
    81  func (s *ManifoldSuite) TestInputsOptionalConfigPropertiesUnset(c *gc.C) {
    82  	s.manifoldConfig.APIConfigWatcherName = ""
    83  	c.Check(apicaller.Manifold(s.manifoldConfig).Inputs, jc.DeepEquals, []string{
    84  		"agent-name",
    85  	})
    86  }
    87  
    88  func (s *ManifoldSuite) TestInputs(c *gc.C) {
    89  	c.Check(s.manifold.Inputs, jc.DeepEquals, []string{
    90  		"agent-name",
    91  		"api-config-watcher-name",
    92  	})
    93  }
    94  
    95  func (s *ManifoldSuite) TestStartMissingAgent(c *gc.C) {
    96  	context := dt.StubContext(nil, map[string]interface{}{
    97  		"agent-name": dependency.ErrMissing,
    98  	})
    99  
   100  	worker, err := s.manifold.Start(context)
   101  	c.Check(worker, gc.IsNil)
   102  	c.Check(err, gc.Equals, dependency.ErrMissing)
   103  	s.CheckCalls(c, nil)
   104  }
   105  
   106  func (s *ManifoldSuite) TestStartCannotOpenAPI(c *gc.C) {
   107  	s.SetErrors(errors.New("no api for you"))
   108  
   109  	worker, err := s.manifold.Start(s.context)
   110  	c.Check(worker, gc.IsNil)
   111  	c.Check(err, gc.ErrorMatches, `\[deadbe\] "machine-42" cannot open api: no api for you`)
   112  	s.CheckCalls(c, []testing.StubCall{{
   113  		FuncName: "NewConnection",
   114  		Args:     []interface{}{s.agent},
   115  	}})
   116  }
   117  
   118  func (s *ManifoldSuite) TestStartSuccess(c *gc.C) {
   119  	worker, err := s.manifold.Start(s.context)
   120  	c.Check(err, jc.ErrorIsNil)
   121  	defer assertStop(c, worker)
   122  	s.CheckCalls(c, []testing.StubCall{{
   123  		FuncName: "NewConnection",
   124  		Args:     []interface{}{s.agent},
   125  	}})
   126  }
   127  
   128  func (s *ManifoldSuite) setupWorkerTest(c *gc.C) worker.Worker {
   129  	w, err := s.manifold.Start(s.context)
   130  	c.Assert(err, jc.ErrorIsNil)
   131  	s.AddCleanup(func(c *gc.C) { w.Kill() })
   132  	return w
   133  }
   134  
   135  func (s *ManifoldSuite) TestKillWorkerClosesConnection(c *gc.C) {
   136  	worker := s.setupWorkerTest(c)
   137  	assertStop(c, worker)
   138  	s.conn.stub.CheckCalls(c, []testing.StubCall{{
   139  		FuncName: "Close",
   140  	}})
   141  }
   142  
   143  func (s *ManifoldSuite) TestKillWorkerReportsCloseErr(c *gc.C) {
   144  	s.conn.stub.SetErrors(errors.New("bad plumbing"))
   145  	worker := s.setupWorkerTest(c)
   146  
   147  	assertStopError(c, worker, "bad plumbing")
   148  	s.conn.stub.CheckCalls(c, []testing.StubCall{{
   149  		FuncName: "Close",
   150  	}})
   151  }
   152  
   153  func (s *ManifoldSuite) TestBrokenConnectionKillsWorkerWithCloseErr(c *gc.C) {
   154  	s.conn.stub.SetErrors(errors.New("bad plumbing"))
   155  	worker := s.setupWorkerTest(c)
   156  
   157  	close(s.conn.broken)
   158  	err := worker.Wait()
   159  	c.Check(err, gc.ErrorMatches, "bad plumbing")
   160  	s.conn.stub.CheckCalls(c, []testing.StubCall{{
   161  		FuncName: "Close",
   162  	}})
   163  }
   164  
   165  func (s *ManifoldSuite) TestBrokenConnectionKillsWorkerWithFallbackErr(c *gc.C) {
   166  	worker := s.setupWorkerTest(c)
   167  
   168  	close(s.conn.broken)
   169  	err := worker.Wait()
   170  	c.Check(err, gc.ErrorMatches, "api connection broken unexpectedly")
   171  	s.conn.stub.CheckCalls(c, []testing.StubCall{{
   172  		FuncName: "Close",
   173  	}})
   174  }
   175  
   176  func (s *ManifoldSuite) TestOutputSuccess(c *gc.C) {
   177  	worker := s.setupWorkerTest(c)
   178  
   179  	var apicaller base.APICaller
   180  	err := s.manifold.Output(worker, &apicaller)
   181  	c.Check(err, jc.ErrorIsNil)
   182  	c.Check(apicaller, gc.Equals, s.conn)
   183  
   184  	var conn api.Connection
   185  	err = s.manifold.Output(worker, &conn)
   186  	c.Check(err, jc.ErrorIsNil)
   187  	c.Check(conn, gc.Equals, s.conn)
   188  }
   189  
   190  func (s *ManifoldSuite) TestOutputBadWorker(c *gc.C) {
   191  	var apicaller base.APICaller
   192  	err := s.manifold.Output(dummyWorker{}, &apicaller)
   193  	c.Check(apicaller, gc.IsNil)
   194  	c.Check(err.Error(), gc.Equals, "in should be a *apicaller.apiConnWorker; got apicaller_test.dummyWorker")
   195  }
   196  
   197  func (s *ManifoldSuite) TestOutputBadTarget(c *gc.C) {
   198  	worker := s.setupWorkerTest(c)
   199  
   200  	var apicaller interface{}
   201  	err := s.manifold.Output(worker, &apicaller)
   202  	c.Check(apicaller, gc.IsNil)
   203  	c.Check(err.Error(), gc.Equals, "out should be *base.APICaller or *api.Connection; got *interface {}")
   204  }