github.com/mhilton/juju-juju@v0.0.0-20150901100907-a94dd2c73455/worker/uniter/operation/metrics_test.go (about)

     1  // Copyright 2012-2014 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package operation_test
     5  
     6  import (
     7  	"errors"
     8  	"time"
     9  
    10  	jc "github.com/juju/testing/checkers"
    11  	gc "gopkg.in/check.v1"
    12  	corecharm "gopkg.in/juju/charm.v5"
    13  
    14  	"github.com/juju/juju/apiserver/params"
    15  	"github.com/juju/juju/worker/uniter/metrics"
    16  	"github.com/juju/juju/worker/uniter/operation"
    17  )
    18  
    19  var _ = gc.Suite(&MetricsOperationSuite{})
    20  
    21  type MetricsOperationSuite struct {
    22  	spoolDir string
    23  }
    24  
    25  func (s *MetricsOperationSuite) SetUpTest(c *gc.C) {
    26  	s.spoolDir = c.MkDir()
    27  
    28  	declaredMetrics := map[string]corecharm.Metric{
    29  		"pings": corecharm.Metric{Description: "test pings", Type: corecharm.MetricTypeAbsolute},
    30  	}
    31  	recorder, err := metrics.NewJSONMetricRecorder(s.spoolDir, declaredMetrics, "local:trusty/testcharm")
    32  	c.Assert(err, jc.ErrorIsNil)
    33  
    34  	err = recorder.AddMetric("pings", "50", time.Now())
    35  	c.Assert(err, jc.ErrorIsNil)
    36  
    37  	err = recorder.Close()
    38  	c.Assert(err, jc.ErrorIsNil)
    39  }
    40  
    41  func (s *MetricsOperationSuite) TestMetricSendingSuccess(c *gc.C) {
    42  	apiSender := newTestAPIMetricSender()
    43  
    44  	factory := operation.NewFactory(operation.FactoryParams{
    45  		MetricSender:   apiSender,
    46  		MetricSpoolDir: s.spoolDir,
    47  	})
    48  
    49  	sendOperation, err := factory.NewSendMetrics()
    50  	c.Assert(err, gc.IsNil)
    51  
    52  	_, err = sendOperation.Prepare(operation.State{})
    53  	c.Assert(err, jc.ErrorIsNil)
    54  
    55  	_, err = sendOperation.Execute(operation.State{})
    56  	c.Assert(err, jc.ErrorIsNil)
    57  
    58  	c.Assert(apiSender.batches, gc.HasLen, 1)
    59  
    60  	reader, err := metrics.NewJSONMetricReader(s.spoolDir)
    61  	c.Assert(err, gc.IsNil)
    62  	batches, err := reader.Read()
    63  	c.Assert(err, gc.IsNil)
    64  	c.Assert(batches, gc.HasLen, 0)
    65  }
    66  
    67  func (s *MetricsOperationSuite) TestSendingGetDuplicate(c *gc.C) {
    68  	apiSender := newTestAPIMetricSender()
    69  
    70  	factory := operation.NewFactory(operation.FactoryParams{
    71  		MetricSender:   apiSender,
    72  		MetricSpoolDir: s.spoolDir,
    73  	})
    74  
    75  	sendOperation, err := factory.NewSendMetrics()
    76  	c.Assert(err, gc.IsNil)
    77  
    78  	_, err = sendOperation.Prepare(operation.State{})
    79  	c.Assert(err, jc.ErrorIsNil)
    80  
    81  	apiErr := &params.Error{Message: "already exists", Code: params.CodeAlreadyExists}
    82  	select {
    83  	case apiSender.errors <- apiErr:
    84  	default:
    85  		c.Fatalf("blocked error channel")
    86  	}
    87  
    88  	_, err = sendOperation.Execute(operation.State{})
    89  	c.Assert(err, jc.ErrorIsNil)
    90  
    91  	c.Assert(apiSender.batches, gc.HasLen, 1)
    92  
    93  	reader, err := metrics.NewJSONMetricReader(s.spoolDir)
    94  	c.Assert(err, gc.IsNil)
    95  	batches, err := reader.Read()
    96  	c.Assert(err, gc.IsNil)
    97  	c.Assert(batches, gc.HasLen, 0)
    98  }
    99  
   100  func (s *MetricsOperationSuite) TestSendingFails(c *gc.C) {
   101  	apiSender := newTestAPIMetricSender()
   102  
   103  	factory := operation.NewFactory(operation.FactoryParams{
   104  		MetricSender:   apiSender,
   105  		MetricSpoolDir: s.spoolDir,
   106  	})
   107  
   108  	sendOperation, err := factory.NewSendMetrics()
   109  	c.Assert(err, gc.IsNil)
   110  
   111  	_, err = sendOperation.Prepare(operation.State{})
   112  	c.Assert(err, jc.ErrorIsNil)
   113  
   114  	select {
   115  	case apiSender.sendError <- errors.New("something went wrong"):
   116  	default:
   117  		c.Fatalf("blocked error channel")
   118  	}
   119  
   120  	_, err = sendOperation.Execute(operation.State{})
   121  	c.Assert(err, jc.ErrorIsNil)
   122  
   123  	c.Assert(apiSender.batches, gc.HasLen, 1)
   124  
   125  	reader, err := metrics.NewJSONMetricReader(s.spoolDir)
   126  	c.Assert(err, gc.IsNil)
   127  	batches, err := reader.Read()
   128  	c.Assert(err, gc.IsNil)
   129  	c.Assert(batches, gc.HasLen, 1)
   130  }
   131  
   132  func (s *MetricsOperationSuite) TestNoSpoolDirectory(c *gc.C) {
   133  	apiSender := newTestAPIMetricSender()
   134  
   135  	factory := operation.NewFactory(operation.FactoryParams{
   136  		MetricSender:   apiSender,
   137  		MetricSpoolDir: "/some/random/spool/dir",
   138  	})
   139  
   140  	sendOperation, err := factory.NewSendMetrics()
   141  	c.Assert(err, gc.IsNil)
   142  
   143  	_, err = sendOperation.Prepare(operation.State{})
   144  	c.Assert(err, jc.ErrorIsNil)
   145  
   146  	_, err = sendOperation.Execute(operation.State{})
   147  	c.Assert(err, jc.ErrorIsNil)
   148  
   149  	c.Assert(apiSender.batches, gc.HasLen, 0)
   150  }
   151  
   152  func (s *MetricsOperationSuite) TestNoMetricsToSend(c *gc.C) {
   153  	apiSender := newTestAPIMetricSender()
   154  
   155  	newTmpSpoolDir := c.MkDir()
   156  
   157  	factory := operation.NewFactory(operation.FactoryParams{
   158  		MetricSender:   apiSender,
   159  		MetricSpoolDir: newTmpSpoolDir,
   160  	})
   161  
   162  	sendOperation, err := factory.NewSendMetrics()
   163  	c.Assert(err, gc.IsNil)
   164  
   165  	_, err = sendOperation.Prepare(operation.State{})
   166  	c.Assert(err, jc.ErrorIsNil)
   167  
   168  	_, err = sendOperation.Execute(operation.State{})
   169  	c.Assert(err, jc.ErrorIsNil)
   170  
   171  	c.Assert(apiSender.batches, gc.HasLen, 0)
   172  }
   173  
   174  func newTestAPIMetricSender() *testAPIMetricSender {
   175  	return &testAPIMetricSender{errors: make(chan error, 1), sendError: make(chan error, 1)}
   176  }
   177  
   178  type testAPIMetricSender struct {
   179  	batches   []params.MetricBatch
   180  	errors    chan error
   181  	sendError chan error
   182  }
   183  
   184  // AddMetricsBatches implements the operation.apiMetricsSender interface.
   185  func (t *testAPIMetricSender) AddMetricBatches(batches []params.MetricBatch) (map[string]error, error) {
   186  	t.batches = batches
   187  
   188  	var err error
   189  	select {
   190  	case e := <-t.errors:
   191  		err = e
   192  	default:
   193  		err = (*params.Error)(nil)
   194  	}
   195  
   196  	var sendErr error
   197  	select {
   198  	case e := <-t.sendError:
   199  		sendErr = e
   200  	default:
   201  		sendErr = nil
   202  	}
   203  
   204  	errors := make(map[string]error)
   205  	for _, b := range batches {
   206  		errors[b.UUID] = err
   207  	}
   208  	return errors, sendErr
   209  }