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 := ¶ms.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 }