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

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package sender_test
     5  
     6  import (
     7  	"net/http"
     8  	"net/url"
     9  	"os"
    10  	"path/filepath"
    11  
    12  	"github.com/juju/errors"
    13  	"github.com/juju/httprequest"
    14  	"github.com/juju/testing"
    15  	jc "github.com/juju/testing/checkers"
    16  	gc "gopkg.in/check.v1"
    17  	"gopkg.in/juju/names.v2"
    18  	"gopkg.in/juju/worker.v1"
    19  	"gopkg.in/juju/worker.v1/dependency"
    20  	dt "gopkg.in/juju/worker.v1/dependency/testing"
    21  	"gopkg.in/macaroon-bakery.v2-unstable/httpbakery"
    22  
    23  	"github.com/juju/juju/agent"
    24  	"github.com/juju/juju/api/base"
    25  	"github.com/juju/juju/api/metricsadder"
    26  	"github.com/juju/juju/worker/metrics/sender"
    27  	"github.com/juju/juju/worker/metrics/spool"
    28  )
    29  
    30  type ManifoldSuite struct {
    31  	testing.IsolationSuite
    32  	factory   spool.MetricFactory
    33  	client    metricsadder.MetricsAdderClient
    34  	apiCaller *stubAPICaller
    35  	manifold  dependency.Manifold
    36  	resources dt.StubResources
    37  }
    38  
    39  var _ = gc.Suite(&ManifoldSuite{})
    40  
    41  func (s *ManifoldSuite) SetUpTest(c *gc.C) {
    42  	spoolDir := c.MkDir()
    43  	s.IsolationSuite.SetUpTest(c)
    44  	s.factory = &stubMetricFactory{
    45  		&testing.Stub{},
    46  		spoolDir,
    47  	}
    48  
    49  	testAPIClient := func(apiCaller base.APICaller) metricsadder.MetricsAdderClient {
    50  		return newTestAPIMetricSender()
    51  	}
    52  	s.PatchValue(&sender.NewMetricAdderClient, testAPIClient)
    53  
    54  	s.manifold = sender.Manifold(sender.ManifoldConfig{
    55  		AgentName:       "agent",
    56  		APICallerName:   "api-caller",
    57  		MetricSpoolName: "metric-spool",
    58  	})
    59  
    60  	dataDir := c.MkDir()
    61  	// create unit agent base dir so that hooks can run.
    62  	err := os.MkdirAll(filepath.Join(dataDir, "agents", "unit-u-0"), 0777)
    63  	c.Assert(err, jc.ErrorIsNil)
    64  
    65  	s.apiCaller = &stubAPICaller{&testing.Stub{}}
    66  	s.resources = dt.StubResources{
    67  		"agent":        dt.NewStubResource(&dummyAgent{dataDir: dataDir}),
    68  		"api-caller":   dt.NewStubResource(s.apiCaller),
    69  		"metric-spool": dt.NewStubResource(s.factory),
    70  	}
    71  }
    72  
    73  func (s *ManifoldSuite) TestInputs(c *gc.C) {
    74  	c.Check(s.manifold.Inputs, jc.DeepEquals, []string{"agent", "api-caller", "metric-spool"})
    75  }
    76  
    77  func (s *ManifoldSuite) TestStartMissingAPICaller(c *gc.C) {
    78  	context := dt.StubContext(nil, map[string]interface{}{
    79  		"api-caller":   dependency.ErrMissing,
    80  		"metric-spool": s.factory,
    81  	})
    82  	worker, err := s.manifold.Start(context)
    83  	c.Check(worker, gc.IsNil)
    84  	c.Check(err, gc.ErrorMatches, dependency.ErrMissing.Error())
    85  }
    86  
    87  func (s *ManifoldSuite) TestStartMissingAgent(c *gc.C) {
    88  	context := dt.StubContext(nil, map[string]interface{}{
    89  		"agent":        dependency.ErrMissing,
    90  		"api-caller":   &stubAPICaller{&testing.Stub{}},
    91  		"metric-spool": s.factory,
    92  	})
    93  	worker, err := s.manifold.Start(context)
    94  	c.Check(worker, gc.IsNil)
    95  	c.Check(err, gc.ErrorMatches, dependency.ErrMissing.Error())
    96  }
    97  
    98  func (s *ManifoldSuite) TestStartSuccess(c *gc.C) {
    99  	s.setupWorkerTest(c)
   100  }
   101  
   102  func (s *ManifoldSuite) setupWorkerTest(c *gc.C) worker.Worker {
   103  	worker, err := s.manifold.Start(s.resources.Context())
   104  	c.Check(err, jc.ErrorIsNil)
   105  	s.AddCleanup(func(c *gc.C) {
   106  		worker.Kill()
   107  		err := worker.Wait()
   108  		c.Check(err, jc.ErrorIsNil)
   109  	})
   110  	return worker
   111  }
   112  
   113  type mockListener struct {
   114  	testing.Stub
   115  	spool.ConnectionHandler
   116  }
   117  
   118  // Stop implements the stopper interface.
   119  func (l *mockListener) Stop() error {
   120  	l.AddCall("Stop")
   121  	return nil
   122  }
   123  
   124  func (s *ManifoldSuite) TestWorkerErrorStopsSender(c *gc.C) {
   125  	listener := &mockListener{}
   126  	s.PatchValue(sender.NewListener, sender.NewListenerFunc(listener))
   127  
   128  	s.apiCaller.SetErrors(errors.New("blah"))
   129  
   130  	worker, err := s.manifold.Start(s.resources.Context())
   131  	c.Assert(err, jc.ErrorIsNil)
   132  	c.Assert(worker, gc.NotNil)
   133  	err = worker.Wait()
   134  	c.Assert(err, gc.ErrorMatches, ".*blah")
   135  	listener.CheckCallNames(c, "Stop")
   136  }
   137  
   138  var _ base.APICaller = (*stubAPICaller)(nil)
   139  
   140  type stubAPICaller struct {
   141  	*testing.Stub
   142  }
   143  
   144  func (s *stubAPICaller) APICall(objType string, version int, id, request string, params, response interface{}) error {
   145  	s.MethodCall(s, "APICall", objType, version, id, request, params, response)
   146  	return s.NextErr()
   147  }
   148  
   149  func (s *stubAPICaller) BestFacadeVersion(facade string) int {
   150  	s.MethodCall(s, "BestFacadeVersion", facade)
   151  	return 42
   152  }
   153  
   154  func (s *stubAPICaller) ModelTag() (names.ModelTag, bool) {
   155  	s.MethodCall(s, "ModelTag")
   156  	return names.NewModelTag("foobar"), true
   157  }
   158  
   159  func (s *stubAPICaller) ConnectStream(string, url.Values) (base.Stream, error) {
   160  	panic("should not be called")
   161  }
   162  
   163  func (s *stubAPICaller) ConnectControllerStream(string, url.Values, http.Header) (base.Stream, error) {
   164  	panic("should not be called")
   165  }
   166  
   167  func (s *stubAPICaller) HTTPClient() (*httprequest.Client, error) {
   168  	panic("should not be called")
   169  }
   170  
   171  func (s *stubAPICaller) BakeryClient() *httpbakery.Client {
   172  	panic("should not be called")
   173  }
   174  
   175  type dummyAgent struct {
   176  	agent.Agent
   177  	dataDir string
   178  }
   179  
   180  func (a dummyAgent) CurrentConfig() agent.Config {
   181  	return &dummyAgentConfig{dataDir: a.dataDir}
   182  }
   183  
   184  type dummyAgentConfig struct {
   185  	agent.Config
   186  	dataDir string
   187  }
   188  
   189  // Tag implements agent.AgentConfig.
   190  func (ac dummyAgentConfig) Tag() names.Tag {
   191  	return names.NewUnitTag("u/0")
   192  }
   193  
   194  // DataDir implements agent.AgentConfig.
   195  func (ac dummyAgentConfig) DataDir() string {
   196  	return ac.dataDir
   197  }