github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/worker/metrics/spool/metrics_test.go (about) 1 // Copyright 2012-2014 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package spool_test 5 6 import ( 7 "path/filepath" 8 "runtime" 9 "time" 10 11 "github.com/juju/testing" 12 jc "github.com/juju/testing/checkers" 13 gc "gopkg.in/check.v1" 14 corecharm "gopkg.in/juju/charm.v6" 15 "gopkg.in/juju/names.v2" 16 17 "github.com/juju/juju/worker/metrics/spool" 18 "github.com/juju/juju/worker/uniter/runner/jujuc" 19 ) 20 21 type metricsBatchSuite struct { 22 } 23 24 var _ = gc.Suite(&metricsBatchSuite{}) 25 26 func (s *metricsBatchSuite) TestAPIMetricBatch(c *gc.C) { 27 batches := []spool.MetricBatch{{ 28 CharmURL: "local:trusty/test-charm", 29 UUID: "test-uuid", 30 Created: time.Now(), 31 Metrics: []jujuc.Metric{ 32 { 33 Key: "test-key-1", 34 Value: "test-value-1", 35 Time: time.Now(), 36 }, { 37 Key: "test-key-2", 38 Value: "test-value-2", 39 Time: time.Now(), 40 }, 41 }, 42 }, { 43 CharmURL: "local:trusty/test-charm", 44 UUID: "test-uuid", 45 Created: time.Now(), 46 Metrics: []jujuc.Metric{}, 47 }, 48 } 49 for _, batch := range batches { 50 apiBatch := spool.APIMetricBatch(batch) 51 c.Assert(apiBatch.Batch.UUID, gc.DeepEquals, batch.UUID) 52 c.Assert(apiBatch.Batch.CharmURL, gc.DeepEquals, batch.CharmURL) 53 c.Assert(apiBatch.Batch.Created, gc.DeepEquals, batch.Created) 54 c.Assert(len(apiBatch.Batch.Metrics), gc.Equals, len(batch.Metrics)) 55 for i, metric := range batch.Metrics { 56 c.Assert(metric.Key, gc.DeepEquals, apiBatch.Batch.Metrics[i].Key) 57 c.Assert(metric.Value, gc.DeepEquals, apiBatch.Batch.Metrics[i].Value) 58 c.Assert(metric.Time, gc.DeepEquals, apiBatch.Batch.Metrics[i].Time) 59 } 60 } 61 } 62 63 func osDependentSockPath(c *gc.C) string { 64 sockPath := filepath.Join(c.MkDir(), "test.sock") 65 if runtime.GOOS == "windows" { 66 return `\\.\pipe` + sockPath[2:] 67 } 68 return sockPath 69 } 70 71 // testPaths implements Paths for tests that do touch the filesystem. 72 type testPaths struct { 73 tools string 74 charm string 75 socket string 76 metricsspool string 77 } 78 79 func newTestPaths(c *gc.C) testPaths { 80 return testPaths{ 81 tools: c.MkDir(), 82 charm: c.MkDir(), 83 socket: osDependentSockPath(c), 84 metricsspool: c.MkDir(), 85 } 86 } 87 88 func (p testPaths) GetMetricsSpoolDir() string { 89 return p.metricsspool 90 } 91 92 func (p testPaths) GetToolsDir() string { 93 return p.tools 94 } 95 96 func (p testPaths) GetCharmDir() string { 97 return p.charm 98 } 99 100 func (p testPaths) GetJujucSocket() string { 101 return p.socket 102 } 103 104 type metricsRecorderSuite struct { 105 testing.IsolationSuite 106 107 paths testPaths 108 unitTag string 109 } 110 111 var _ = gc.Suite(&metricsRecorderSuite{}) 112 113 func (s *metricsRecorderSuite) SetUpTest(c *gc.C) { 114 s.IsolationSuite.SetUpTest(c) 115 s.paths = newTestPaths(c) 116 s.unitTag = names.NewUnitTag("test-unit/0").String() 117 } 118 119 func (s *metricsRecorderSuite) TestInit(c *gc.C) { 120 w, err := spool.NewJSONMetricRecorder( 121 spool.MetricRecorderConfig{ 122 SpoolDir: s.paths.GetMetricsSpoolDir(), 123 Metrics: map[string]corecharm.Metric{ 124 "pings": {}, 125 "pongs": {}, 126 }, 127 CharmURL: "local:precise/wordpress", 128 UnitTag: s.unitTag, 129 }) 130 c.Assert(err, jc.ErrorIsNil) 131 c.Assert(w, gc.NotNil) 132 err = w.AddMetric("pings", "5", time.Now(), nil) 133 c.Assert(err, jc.ErrorIsNil) 134 err = w.AddMetric("pongs", "10", time.Now(), map[string]string{"foo": "bar"}) 135 c.Assert(err, jc.ErrorIsNil) 136 err = w.Close() 137 c.Assert(err, jc.ErrorIsNil) 138 139 r, err := spool.NewJSONMetricReader(s.paths.GetMetricsSpoolDir()) 140 c.Assert(err, jc.ErrorIsNil) 141 batches, err := r.Read() 142 c.Assert(err, jc.ErrorIsNil) 143 c.Assert(batches, gc.HasLen, 1) 144 batch := batches[0] 145 c.Assert(batch.CharmURL, gc.Equals, "local:precise/wordpress") 146 c.Assert(batch.UUID, gc.Not(gc.Equals), "") 147 c.Assert(batch.Metrics, gc.HasLen, 2) 148 c.Assert(batch.Metrics[0].Key, gc.Equals, "pings") 149 c.Assert(batch.Metrics[0].Value, gc.Equals, "5") 150 c.Assert(batch.Metrics[0].Labels, gc.HasLen, 0) 151 c.Assert(batch.Metrics[1].Key, gc.Equals, "pongs") 152 c.Assert(batch.Metrics[1].Value, gc.Equals, "10") 153 c.Assert(batch.Metrics[1].Labels, gc.DeepEquals, map[string]string{"foo": "bar"}) 154 c.Assert(batch.UnitTag, gc.Equals, s.unitTag) 155 156 err = r.Close() 157 c.Assert(err, jc.ErrorIsNil) 158 } 159 160 func (s *metricsRecorderSuite) TestMetricValidation(c *gc.C) { 161 tests := []struct { 162 about string 163 key string 164 value string 165 expectedError string 166 }{{ 167 about: "metric not declared", 168 key: "pings", 169 value: "5", 170 expectedError: `metric key "pings" not declared by the charm`, 171 }, { 172 about: "non float metrics", 173 key: "pongs", 174 value: "abcd", 175 expectedError: `invalid value type: expected float, got "abcd"`, 176 }, { 177 about: "negative value", 178 key: "pongs", 179 value: "-5.0", 180 expectedError: `invalid value: value must be greater or equal to zero, got -5.0`, 181 }, { 182 about: "large value", 183 key: "pongs", 184 value: "1234567890123456789012345678901234567890", 185 expectedError: `metric value is too large`, 186 }, 187 } 188 189 for _, test := range tests { 190 w, err := spool.NewJSONMetricRecorder( 191 spool.MetricRecorderConfig{ 192 SpoolDir: s.paths.GetMetricsSpoolDir(), 193 Metrics: map[string]corecharm.Metric{ 194 "juju-units": {}, 195 "pongs": { 196 Type: corecharm.MetricTypeAbsolute, 197 }, 198 }, 199 CharmURL: "local:precise/wordpress", 200 UnitTag: s.unitTag, 201 }) 202 c.Assert(err, jc.ErrorIsNil) 203 c.Assert(w, gc.NotNil) 204 205 c.Logf("running test: %s", test.about) 206 err = w.AddMetric(test.key, test.value, time.Now(), nil) 207 if test.expectedError != "" { 208 c.Assert(err, gc.ErrorMatches, test.expectedError) 209 err = w.Close() 210 c.Assert(err, jc.ErrorIsNil) 211 212 r, err := spool.NewJSONMetricReader(s.paths.GetMetricsSpoolDir()) 213 c.Assert(err, jc.ErrorIsNil) 214 batches, err := r.Read() 215 c.Assert(err, jc.ErrorIsNil) 216 c.Assert(batches, gc.HasLen, 0) 217 } else { 218 c.Assert(err, jc.ErrorIsNil) 219 err = w.Close() 220 c.Assert(err, jc.ErrorIsNil) 221 } 222 } 223 } 224 225 type metricsReaderSuite struct { 226 paths testPaths 227 unitTag string 228 229 w *spool.JSONMetricRecorder 230 } 231 232 var _ = gc.Suite(&metricsReaderSuite{}) 233 234 func (s *metricsReaderSuite) SetUpTest(c *gc.C) { 235 s.paths = newTestPaths(c) 236 s.unitTag = names.NewUnitTag("test-unit/0").String() 237 238 var err error 239 s.w, err = spool.NewJSONMetricRecorder( 240 spool.MetricRecorderConfig{ 241 SpoolDir: s.paths.GetMetricsSpoolDir(), 242 Metrics: map[string]corecharm.Metric{"pings": {}}, 243 CharmURL: "local:precise/wordpress", 244 UnitTag: s.unitTag, 245 }) 246 247 c.Assert(err, jc.ErrorIsNil) 248 err = s.w.AddMetric("pings", "5", time.Now(), nil) 249 c.Assert(err, jc.ErrorIsNil) 250 err = s.w.Close() 251 c.Assert(err, jc.ErrorIsNil) 252 } 253 254 func (s *metricsReaderSuite) TestTwoSimultaneousReaders(c *gc.C) { 255 r, err := spool.NewJSONMetricReader(s.paths.GetMetricsSpoolDir()) 256 c.Assert(err, jc.ErrorIsNil) 257 258 r2, err := spool.NewJSONMetricReader(c.MkDir()) 259 c.Assert(err, jc.ErrorIsNil) 260 c.Assert(r2, gc.NotNil) 261 err = r2.Close() 262 c.Assert(err, jc.ErrorIsNil) 263 err = r.Close() 264 c.Assert(err, jc.ErrorIsNil) 265 266 } 267 268 func (s *metricsReaderSuite) TestUnblockedReaders(c *gc.C) { 269 r, err := spool.NewJSONMetricReader(s.paths.GetMetricsSpoolDir()) 270 c.Assert(err, jc.ErrorIsNil) 271 err = r.Close() 272 c.Assert(err, jc.ErrorIsNil) 273 274 r2, err := spool.NewJSONMetricReader(s.paths.GetMetricsSpoolDir()) 275 c.Assert(err, jc.ErrorIsNil) 276 c.Assert(r2, gc.NotNil) 277 err = r2.Close() 278 c.Assert(err, jc.ErrorIsNil) 279 } 280 281 func (s *metricsReaderSuite) TestRemoval(c *gc.C) { 282 r, err := spool.NewJSONMetricReader(s.paths.GetMetricsSpoolDir()) 283 c.Assert(err, jc.ErrorIsNil) 284 285 batches, err := r.Read() 286 c.Assert(err, jc.ErrorIsNil) 287 for _, batch := range batches { 288 err := r.Remove(batch.UUID) 289 c.Assert(err, jc.ErrorIsNil) 290 } 291 err = r.Close() 292 c.Assert(err, jc.ErrorIsNil) 293 294 batches, err = r.Read() 295 c.Assert(err, jc.ErrorIsNil) 296 c.Assert(batches, gc.HasLen, 0) 297 err = r.Close() 298 c.Assert(err, jc.ErrorIsNil) 299 }