github.com/cloud-green/juju@v0.0.0-20151002100041-a00291338d3d/worker/metrics/sender/sender_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  	"errors"
     8  	"time"
     9  
    10  	"github.com/juju/testing"
    11  	jc "github.com/juju/testing/checkers"
    12  	gc "gopkg.in/check.v1"
    13  	corecharm "gopkg.in/juju/charm.v6-unstable"
    14  
    15  	"github.com/juju/juju/apiserver/params"
    16  	"github.com/juju/juju/worker/metrics/sender"
    17  	"github.com/juju/juju/worker/metrics/spool"
    18  )
    19  
    20  var _ = gc.Suite(&senderSuite{})
    21  
    22  type senderSuite struct {
    23  	spoolDir      string
    24  	metricfactory spool.MetricFactory
    25  }
    26  
    27  func (s *senderSuite) SetUpTest(c *gc.C) {
    28  	s.spoolDir = c.MkDir()
    29  
    30  	s.metricfactory = &stubMetricFactory{
    31  		&testing.Stub{},
    32  		s.spoolDir,
    33  	}
    34  
    35  	declaredMetrics := map[string]corecharm.Metric{
    36  		"pings": corecharm.Metric{Description: "test pings", Type: corecharm.MetricTypeAbsolute},
    37  	}
    38  	recorder, err := s.metricfactory.Recorder(declaredMetrics, "local:trusty/testcharm", "testcharm/0")
    39  	c.Assert(err, jc.ErrorIsNil)
    40  
    41  	err = recorder.AddMetric("pings", "50", time.Now())
    42  	c.Assert(err, jc.ErrorIsNil)
    43  
    44  	err = recorder.Close()
    45  	c.Assert(err, jc.ErrorIsNil)
    46  
    47  	reader, err := s.metricfactory.Reader()
    48  	c.Assert(err, jc.ErrorIsNil)
    49  	batches, err := reader.Read()
    50  	c.Assert(err, jc.ErrorIsNil)
    51  	c.Assert(batches, gc.HasLen, 1)
    52  
    53  }
    54  
    55  func (s *senderSuite) TestMetricSendingSuccess(c *gc.C) {
    56  	apiSender := newTestAPIMetricSender()
    57  
    58  	metricSender := sender.NewSender(apiSender, s.metricfactory)
    59  	stopCh := make(chan struct{})
    60  	err := metricSender.Do(stopCh)
    61  	c.Assert(err, jc.ErrorIsNil)
    62  
    63  	c.Assert(apiSender.batches, gc.HasLen, 1)
    64  
    65  	reader, err := spool.NewJSONMetricReader(s.spoolDir)
    66  	c.Assert(err, jc.ErrorIsNil)
    67  	batches, err := reader.Read()
    68  	c.Assert(err, jc.ErrorIsNil)
    69  	c.Assert(batches, gc.HasLen, 0)
    70  }
    71  
    72  func (s *senderSuite) TestSendingGetDuplicate(c *gc.C) {
    73  	apiSender := newTestAPIMetricSender()
    74  
    75  	apiErr := &params.Error{Message: "already exists", Code: params.CodeAlreadyExists}
    76  	select {
    77  	case apiSender.errors <- apiErr:
    78  	default:
    79  		c.Fatalf("blocked error channel")
    80  	}
    81  
    82  	metricSender := sender.NewSender(apiSender, s.metricfactory)
    83  	stopCh := make(chan struct{})
    84  	err := metricSender.Do(stopCh)
    85  	c.Assert(err, jc.ErrorIsNil)
    86  
    87  	c.Assert(apiSender.batches, gc.HasLen, 1)
    88  
    89  	reader, err := spool.NewJSONMetricReader(s.spoolDir)
    90  	c.Assert(err, jc.ErrorIsNil)
    91  	batches, err := reader.Read()
    92  	c.Assert(err, jc.ErrorIsNil)
    93  	c.Assert(batches, gc.HasLen, 0)
    94  }
    95  
    96  func (s *senderSuite) TestSendingFails(c *gc.C) {
    97  	apiSender := newTestAPIMetricSender()
    98  
    99  	select {
   100  	case apiSender.sendError <- errors.New("something went wrong"):
   101  	default:
   102  		c.Fatalf("blocked error channel")
   103  	}
   104  
   105  	metricSender := sender.NewSender(apiSender, s.metricfactory)
   106  	stopCh := make(chan struct{})
   107  	err := metricSender.Do(stopCh)
   108  	c.Assert(err, gc.ErrorMatches, "something went wrong")
   109  
   110  	c.Assert(apiSender.batches, gc.HasLen, 1)
   111  
   112  	reader, err := spool.NewJSONMetricReader(s.spoolDir)
   113  	c.Assert(err, jc.ErrorIsNil)
   114  	batches, err := reader.Read()
   115  	c.Assert(err, jc.ErrorIsNil)
   116  	c.Assert(batches, gc.HasLen, 1)
   117  }
   118  
   119  func (s *senderSuite) TestNoSpoolDirectory(c *gc.C) {
   120  	apiSender := newTestAPIMetricSender()
   121  
   122  	metricfactory := &stubMetricFactory{
   123  		&testing.Stub{},
   124  		"/some/random/spool/dir",
   125  	}
   126  
   127  	metricSender := sender.NewSender(apiSender, metricfactory)
   128  	stopCh := make(chan struct{})
   129  	err := metricSender.Do(stopCh)
   130  	c.Assert(err, gc.ErrorMatches, `failed to open spool directory "/some/random/spool/dir": .*`)
   131  
   132  	c.Assert(apiSender.batches, gc.HasLen, 0)
   133  }
   134  
   135  func (s *senderSuite) TestNoMetricsToSend(c *gc.C) {
   136  	apiSender := newTestAPIMetricSender()
   137  
   138  	newTmpSpoolDir := c.MkDir()
   139  	metricfactory := &stubMetricFactory{
   140  		&testing.Stub{},
   141  		newTmpSpoolDir,
   142  	}
   143  
   144  	metricSender := sender.NewSender(apiSender, metricfactory)
   145  	stopCh := make(chan struct{})
   146  	err := metricSender.Do(stopCh)
   147  	c.Assert(err, jc.ErrorIsNil)
   148  
   149  	c.Assert(apiSender.batches, gc.HasLen, 0)
   150  }
   151  
   152  func newTestAPIMetricSender() *testAPIMetricSender {
   153  	return &testAPIMetricSender{errors: make(chan error, 1), sendError: make(chan error, 1)}
   154  }
   155  
   156  type testAPIMetricSender struct {
   157  	batches   []params.MetricBatchParam
   158  	errors    chan error
   159  	sendError chan error
   160  }
   161  
   162  func (t *testAPIMetricSender) AddMetricBatches(batches []params.MetricBatchParam) (map[string]error, error) {
   163  	t.batches = batches
   164  
   165  	var err error
   166  	select {
   167  	case e := <-t.errors:
   168  		err = e
   169  	default:
   170  		err = (*params.Error)(nil)
   171  	}
   172  
   173  	var sendErr error
   174  	select {
   175  	case e := <-t.sendError:
   176  		sendErr = e
   177  	default:
   178  		sendErr = nil
   179  	}
   180  
   181  	errors := make(map[string]error)
   182  	for _, b := range batches {
   183  		errors[b.Batch.UUID] = err
   184  	}
   185  	return errors, sendErr
   186  }
   187  
   188  type stubMetricFactory struct {
   189  	*testing.Stub
   190  	spoolDir string
   191  }
   192  
   193  func (s *stubMetricFactory) Recorder(declaredMetrics map[string]corecharm.Metric, charmURL, unitTag string) (spool.MetricRecorder, error) {
   194  	s.MethodCall(s, "Recorder", declaredMetrics, charmURL, unitTag)
   195  	config := spool.MetricRecorderConfig{
   196  		SpoolDir: s.spoolDir,
   197  		Metrics:  declaredMetrics,
   198  		CharmURL: charmURL,
   199  		UnitTag:  unitTag,
   200  	}
   201  
   202  	return spool.NewJSONMetricRecorder(config)
   203  }
   204  
   205  func (s *stubMetricFactory) Reader() (spool.MetricReader, error) {
   206  	s.MethodCall(s, "Reader")
   207  	return spool.NewJSONMetricReader(s.spoolDir)
   208  
   209  }