github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/apiserver/metricsdebug/metricsdebug_test.go (about) 1 // Copyright 2016 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package metricsdebug_test 5 6 import ( 7 "time" 8 9 jc "github.com/juju/testing/checkers" 10 gc "gopkg.in/check.v1" 11 12 "github.com/juju/juju/apiserver/metricsdebug" 13 "github.com/juju/juju/apiserver/params" 14 apiservertesting "github.com/juju/juju/apiserver/testing" 15 jujutesting "github.com/juju/juju/juju/testing" 16 "github.com/juju/juju/state" 17 "github.com/juju/juju/testing/factory" 18 ) 19 20 type metricsDebugSuite struct { 21 jujutesting.JujuConnSuite 22 23 metricsdebug *metricsdebug.MetricsDebugAPI 24 authorizer apiservertesting.FakeAuthorizer 25 unit *state.Unit 26 } 27 28 var _ = gc.Suite(&metricsDebugSuite{}) 29 30 func (s *metricsDebugSuite) SetUpTest(c *gc.C) { 31 s.JujuConnSuite.SetUpTest(c) 32 s.authorizer = apiservertesting.FakeAuthorizer{ 33 Tag: s.AdminUserTag(c), 34 } 35 debug, err := metricsdebug.NewMetricsDebugAPI(s.State, nil, s.authorizer) 36 c.Assert(err, jc.ErrorIsNil) 37 s.metricsdebug = debug 38 } 39 40 func (s *metricsDebugSuite) TestSetMeterStatus(c *gc.C) { 41 testCharm := s.Factory.MakeCharm(c, &factory.CharmParams{Name: "metered", URL: "local:quantal/metered"}) 42 testService := s.Factory.MakeApplication(c, &factory.ApplicationParams{Charm: testCharm}) 43 testUnit1 := s.Factory.MakeUnit(c, &factory.UnitParams{Application: testService, SetCharmURL: true}) 44 testUnit2 := s.Factory.MakeUnit(c, &factory.UnitParams{Application: testService, SetCharmURL: true}) 45 46 csCharm := s.Factory.MakeCharm(c, &factory.CharmParams{Name: "metered", URL: "cs:quantal/metered"}) 47 csService := s.Factory.MakeApplication(c, &factory.ApplicationParams{Name: "cs-service", Charm: csCharm}) 48 csUnit1 := s.Factory.MakeUnit(c, &factory.UnitParams{Application: csService, SetCharmURL: true}) 49 50 tests := []struct { 51 about string 52 params params.MeterStatusParams 53 err string 54 assert func(*gc.C, params.ErrorResults) 55 }{{ 56 about: "set application meter status", 57 params: params.MeterStatusParams{ 58 Statuses: []params.MeterStatusParam{{ 59 Tag: testService.Tag().String(), 60 Code: "RED", 61 Info: "test", 62 }, 63 }, 64 }, 65 assert: func(c *gc.C, results params.ErrorResults) { 66 err := results.OneError() 67 c.Assert(err, jc.ErrorIsNil) 68 ms1, err := testUnit1.GetMeterStatus() 69 c.Assert(err, jc.ErrorIsNil) 70 c.Assert(ms1, gc.DeepEquals, state.MeterStatus{ 71 Code: state.MeterRed, 72 Info: "test", 73 }) 74 ms2, err := testUnit2.GetMeterStatus() 75 c.Assert(err, jc.ErrorIsNil) 76 c.Assert(ms2, gc.DeepEquals, state.MeterStatus{ 77 Code: state.MeterRed, 78 Info: "test", 79 }) 80 }, 81 }, { 82 about: "set unit meter status", 83 params: params.MeterStatusParams{ 84 Statuses: []params.MeterStatusParam{{ 85 Tag: testUnit1.Tag().String(), 86 Code: "AMBER", 87 Info: "test", 88 }, 89 }, 90 }, 91 assert: func(c *gc.C, results params.ErrorResults) { 92 err := results.OneError() 93 c.Assert(err, jc.ErrorIsNil) 94 ms1, err := testUnit1.GetMeterStatus() 95 c.Assert(err, jc.ErrorIsNil) 96 c.Assert(ms1, gc.DeepEquals, state.MeterStatus{ 97 Code: state.MeterAmber, 98 Info: "test", 99 }) 100 }, 101 }, { 102 about: "not a local charm - application", 103 params: params.MeterStatusParams{ 104 Statuses: []params.MeterStatusParam{{ 105 Tag: csService.Tag().String(), 106 Code: "AMBER", 107 Info: "test", 108 }, 109 }, 110 }, 111 assert: func(c *gc.C, results params.ErrorResults) { 112 err := results.OneError() 113 c.Assert(err, gc.DeepEquals, ¶ms.Error{Message: "not a local charm"}) 114 }, 115 }, { 116 about: "not a local charm - unit", 117 params: params.MeterStatusParams{ 118 Statuses: []params.MeterStatusParam{{ 119 Tag: csUnit1.Tag().String(), 120 Code: "AMBER", 121 Info: "test", 122 }, 123 }, 124 }, 125 assert: func(c *gc.C, results params.ErrorResults) { 126 err := results.OneError() 127 c.Assert(err, gc.DeepEquals, ¶ms.Error{Message: "not a local charm"}) 128 }, 129 }, { 130 about: "invalid meter status", 131 params: params.MeterStatusParams{ 132 Statuses: []params.MeterStatusParam{{ 133 Tag: testUnit1.Tag().String(), 134 Code: "WRONG", 135 Info: "test", 136 }, 137 }, 138 }, 139 assert: func(c *gc.C, results params.ErrorResults) { 140 err := results.OneError() 141 c.Assert(err, gc.DeepEquals, ¶ms.Error{Message: "invalid meter status \"NOT AVAILABLE\""}) 142 }, 143 }, { 144 about: "not such application", 145 params: params.MeterStatusParams{ 146 Statuses: []params.MeterStatusParam{{ 147 Tag: "application-missing", 148 Code: "AMBER", 149 Info: "test", 150 }, 151 }, 152 }, 153 assert: func(c *gc.C, results params.ErrorResults) { 154 err := results.OneError() 155 c.Assert(err, gc.DeepEquals, ¶ms.Error{Message: "application \"missing\" not found", Code: "not found"}) 156 }, 157 }, 158 } 159 160 for i, test := range tests { 161 c.Logf("running test %d: %v", i, test.about) 162 result, err := s.metricsdebug.SetMeterStatus(test.params) 163 if test.err == "" { 164 c.Assert(err, jc.ErrorIsNil) 165 test.assert(c, result) 166 } else { 167 c.Assert(err, gc.ErrorMatches, test.err) 168 } 169 } 170 } 171 172 func (s *metricsDebugSuite) TestGetMetrics(c *gc.C) { 173 meteredCharm := s.Factory.MakeCharm(c, &factory.CharmParams{Name: "metered", URL: "local:quantal/metered"}) 174 meteredService := s.Factory.MakeApplication(c, &factory.ApplicationParams{Charm: meteredCharm}) 175 unit := s.Factory.MakeUnit(c, &factory.UnitParams{Application: meteredService, SetCharmURL: true}) 176 t0 := time.Now().Round(time.Second) 177 t1 := t0.Add(time.Second) 178 metricA := state.Metric{"pings", "5", t0} 179 metricB := state.Metric{"pings", "10.5", t1} 180 s.Factory.MakeMetric(c, &factory.MetricParams{Unit: unit, Metrics: []state.Metric{metricA}}) 181 s.Factory.MakeMetric(c, &factory.MetricParams{Unit: unit, Metrics: []state.Metric{metricA, metricB}}) 182 args := params.Entities{Entities: []params.Entity{ 183 {"unit-metered/0"}, 184 }} 185 result, err := s.metricsdebug.GetMetrics(args) 186 c.Assert(err, jc.ErrorIsNil) 187 c.Assert(result.Results, gc.HasLen, 1) 188 c.Assert(result.Results[0].Metrics, gc.HasLen, 1) 189 c.Assert(result.Results[0], jc.DeepEquals, params.EntityMetrics{ 190 Metrics: []params.MetricResult{ 191 { 192 Key: "pings", 193 Value: "10.5", 194 Time: t1, 195 Unit: "metered/0", 196 }, 197 }, 198 Error: nil, 199 }) 200 } 201 202 func (s *metricsDebugSuite) TestGetMetricsFiltersCorrectly(c *gc.C) { 203 meteredCharm := s.Factory.MakeCharm(c, &factory.CharmParams{Name: "metered", URL: "local:quantal/metered"}) 204 meteredService := s.Factory.MakeApplication(c, &factory.ApplicationParams{Charm: meteredCharm}) 205 unit0 := s.Factory.MakeUnit(c, &factory.UnitParams{Application: meteredService, SetCharmURL: true}) 206 unit1 := s.Factory.MakeUnit(c, &factory.UnitParams{Application: meteredService, SetCharmURL: true}) 207 t0 := time.Now().Round(time.Second) 208 t1 := t0.Add(time.Second) 209 metricA := state.Metric{"pings", "5", t1} 210 metricB := state.Metric{"pings", "10.5", t0} 211 metricC := state.Metric{"juju-units", "8", t1} 212 s.Factory.MakeMetric(c, &factory.MetricParams{Unit: unit0, Metrics: []state.Metric{metricA, metricB, metricC}}) 213 s.Factory.MakeMetric(c, &factory.MetricParams{Unit: unit1, Metrics: []state.Metric{metricA, metricB, metricC}}) 214 args := params.Entities{} 215 result, err := s.metricsdebug.GetMetrics(args) 216 c.Assert(err, jc.ErrorIsNil) 217 c.Assert(result.Results, gc.HasLen, 1) 218 c.Assert(result.Results[0].Metrics, gc.HasLen, 4) 219 c.Assert(result.Results[0].Metrics, jc.SameContents, []params.MetricResult{{ 220 Key: "pings", 221 Value: "5", 222 Time: t1, 223 Unit: "metered/0", 224 }, { 225 Key: "juju-units", 226 Value: "8", 227 Time: t1, 228 Unit: "metered/0", 229 }, { 230 Key: "pings", 231 Value: "5", 232 Time: t1, 233 Unit: "metered/1", 234 }, { 235 Key: "juju-units", 236 Value: "8", 237 Time: t1, 238 Unit: "metered/1", 239 }}, 240 ) 241 } 242 243 func (s *metricsDebugSuite) TestGetMetricsFiltersCorrectlyWhenNotAllMetricsInEachBatch(c *gc.C) { 244 meteredCharm := s.Factory.MakeCharm(c, &factory.CharmParams{Name: "metered", URL: "local:quantal/metered"}) 245 meteredService := s.Factory.MakeApplication(c, &factory.ApplicationParams{Charm: meteredCharm}) 246 unit0 := s.Factory.MakeUnit(c, &factory.UnitParams{Application: meteredService, SetCharmURL: true}) 247 unit1 := s.Factory.MakeUnit(c, &factory.UnitParams{Application: meteredService, SetCharmURL: true}) 248 t0 := time.Now().Round(time.Second) 249 t1 := t0.Add(time.Second) 250 metricA := state.Metric{"pings", "5", t1} 251 metricB := state.Metric{"pings", "10.5", t0} 252 metricC := state.Metric{"juju-units", "8", t1} 253 s.Factory.MakeMetric(c, &factory.MetricParams{Unit: unit0, Metrics: []state.Metric{metricA, metricB, metricC}}) 254 s.Factory.MakeMetric(c, &factory.MetricParams{Unit: unit1, Metrics: []state.Metric{metricA, metricB}}) 255 args := params.Entities{} 256 result, err := s.metricsdebug.GetMetrics(args) 257 c.Assert(err, jc.ErrorIsNil) 258 c.Assert(result.Results, gc.HasLen, 1) 259 c.Assert(result.Results[0].Metrics, gc.HasLen, 3) 260 c.Assert(result.Results[0].Metrics, jc.SameContents, []params.MetricResult{{ 261 Key: "pings", 262 Value: "5", 263 Time: t1, 264 Unit: "metered/0", 265 }, { 266 Key: "juju-units", 267 Value: "8", 268 Time: t1, 269 Unit: "metered/0", 270 }, { 271 Key: "pings", 272 Value: "5", 273 Time: t1, 274 Unit: "metered/1", 275 }}, 276 ) 277 } 278 279 func (s *metricsDebugSuite) TestGetMetricsFiltersCorrectlyWithMultipleBatchesPerUnit(c *gc.C) { 280 meteredCharm := s.Factory.MakeCharm(c, &factory.CharmParams{Name: "metered", URL: "local:quantal/metered"}) 281 meteredService := s.Factory.MakeApplication(c, &factory.ApplicationParams{Charm: meteredCharm}) 282 unit0 := s.Factory.MakeUnit(c, &factory.UnitParams{Application: meteredService, SetCharmURL: true}) 283 unit1 := s.Factory.MakeUnit(c, &factory.UnitParams{Application: meteredService, SetCharmURL: true}) 284 t0 := time.Now().Round(time.Second) 285 t1 := t0.Add(time.Second) 286 metricA := state.Metric{"pings", "5", t1} 287 metricB := state.Metric{"pings", "10.5", t0} 288 metricC := state.Metric{"juju-units", "8", t1} 289 s.Factory.MakeMetric(c, &factory.MetricParams{Unit: unit0, Metrics: []state.Metric{metricA, metricB}}) 290 s.Factory.MakeMetric(c, &factory.MetricParams{Unit: unit0, Metrics: []state.Metric{metricC}}) 291 s.Factory.MakeMetric(c, &factory.MetricParams{Unit: unit1, Metrics: []state.Metric{metricA, metricB}}) 292 args := params.Entities{} 293 result, err := s.metricsdebug.GetMetrics(args) 294 c.Assert(err, jc.ErrorIsNil) 295 c.Assert(result.Results, gc.HasLen, 1) 296 c.Assert(result.Results[0].Metrics, gc.HasLen, 3) 297 c.Assert(result.Results[0].Metrics, jc.SameContents, []params.MetricResult{{ 298 Key: "pings", 299 Value: "5", 300 Time: t1, 301 Unit: "metered/0", 302 }, { 303 Key: "juju-units", 304 Value: "8", 305 Time: t1, 306 Unit: "metered/0", 307 }, { 308 Key: "pings", 309 Value: "5", 310 Time: t1, 311 Unit: "metered/1", 312 }}, 313 ) 314 } 315 316 func (s *metricsDebugSuite) TestGetMultipleMetricsNoMocks(c *gc.C) { 317 meteredCharm := s.Factory.MakeCharm(c, &factory.CharmParams{Name: "metered", URL: "local:quantal/metered"}) 318 meteredService := s.Factory.MakeApplication(c, &factory.ApplicationParams{ 319 Charm: meteredCharm, 320 }) 321 unit0 := s.Factory.MakeUnit(c, &factory.UnitParams{Application: meteredService, SetCharmURL: true}) 322 unit1 := s.Factory.MakeUnit(c, &factory.UnitParams{Application: meteredService, SetCharmURL: true}) 323 324 metricUnit0 := s.Factory.MakeMetric(c, &factory.MetricParams{ 325 Unit: unit0, 326 }) 327 metricUnit1 := s.Factory.MakeMetric(c, &factory.MetricParams{ 328 Unit: unit1, 329 }) 330 331 args0 := params.Entities{Entities: []params.Entity{ 332 {"unit-metered/0"}, 333 }} 334 args1 := params.Entities{Entities: []params.Entity{ 335 {"unit-metered/1"}, 336 }} 337 338 metrics0, err := s.metricsdebug.GetMetrics(args0) 339 c.Assert(err, jc.ErrorIsNil) 340 c.Assert(metrics0.Results, gc.HasLen, 1) 341 c.Assert(metrics0.Results[0].Metrics[0].Key, gc.Equals, metricUnit0.Metrics()[0].Key) 342 c.Assert(metrics0.Results[0].Metrics[0].Value, gc.Equals, metricUnit0.Metrics()[0].Value) 343 c.Assert(metrics0.Results[0].Metrics[0].Time, jc.TimeBetween(metricUnit0.Metrics()[0].Time, metricUnit0.Metrics()[0].Time)) 344 345 metrics1, err := s.metricsdebug.GetMetrics(args1) 346 c.Assert(err, jc.ErrorIsNil) 347 c.Assert(metrics1.Results, gc.HasLen, 1) 348 c.Assert(metrics1.Results[0].Metrics[0].Key, gc.Equals, metricUnit1.Metrics()[0].Key) 349 c.Assert(metrics1.Results[0].Metrics[0].Value, gc.Equals, metricUnit1.Metrics()[0].Value) 350 c.Assert(metrics1.Results[0].Metrics[0].Time, jc.TimeBetween(metricUnit1.Metrics()[0].Time, metricUnit1.Metrics()[0].Time)) 351 } 352 353 func (s *metricsDebugSuite) TestGetMultipleMetricsNoMocksWithService(c *gc.C) { 354 meteredCharm := s.Factory.MakeCharm(c, &factory.CharmParams{Name: "metered", URL: "local:quantal/metered"}) 355 meteredService := s.Factory.MakeApplication(c, &factory.ApplicationParams{ 356 Charm: meteredCharm, 357 }) 358 unit0 := s.Factory.MakeUnit(c, &factory.UnitParams{Application: meteredService, SetCharmURL: true}) 359 unit1 := s.Factory.MakeUnit(c, &factory.UnitParams{Application: meteredService, SetCharmURL: true}) 360 361 metricUnit0 := s.Factory.MakeMetric(c, &factory.MetricParams{ 362 Unit: unit0, 363 }) 364 metricUnit1 := s.Factory.MakeMetric(c, &factory.MetricParams{ 365 Unit: unit1, 366 }) 367 368 args := params.Entities{Entities: []params.Entity{ 369 {"application-metered"}, 370 }} 371 372 metrics, err := s.metricsdebug.GetMetrics(args) 373 c.Assert(err, jc.ErrorIsNil) 374 c.Assert(metrics.Results, gc.HasLen, 1) 375 c.Assert(metrics.Results[0].Metrics, gc.HasLen, 2) 376 c.Assert(metrics.Results[0].Metrics[0].Key, gc.Equals, metricUnit0.Metrics()[0].Key) 377 c.Assert(metrics.Results[0].Metrics[0].Value, gc.Equals, metricUnit0.Metrics()[0].Value) 378 c.Assert(metrics.Results[0].Metrics[0].Time, jc.TimeBetween(metricUnit0.Metrics()[0].Time, metricUnit0.Metrics()[0].Time)) 379 380 c.Assert(metrics.Results[0].Metrics[1].Key, gc.Equals, metricUnit1.Metrics()[0].Key) 381 c.Assert(metrics.Results[0].Metrics[1].Value, gc.Equals, metricUnit1.Metrics()[0].Value) 382 c.Assert(metrics.Results[0].Metrics[1].Time, jc.TimeBetween(metricUnit1.Metrics()[0].Time, metricUnit1.Metrics()[0].Time)) 383 } 384 385 func (s *metricsDebugSuite) TestGetModelNoMocks(c *gc.C) { 386 meteredCharm := s.Factory.MakeCharm(c, &factory.CharmParams{Name: "metered", URL: "local:quantal/metered"}) 387 meteredService := s.Factory.MakeApplication(c, &factory.ApplicationParams{ 388 Charm: meteredCharm, 389 }) 390 unit0 := s.Factory.MakeUnit(c, &factory.UnitParams{Application: meteredService, SetCharmURL: true}) 391 unit1 := s.Factory.MakeUnit(c, &factory.UnitParams{Application: meteredService, SetCharmURL: true}) 392 393 metricUnit0 := s.Factory.MakeMetric(c, &factory.MetricParams{ 394 Unit: unit0, 395 }) 396 metricUnit1 := s.Factory.MakeMetric(c, &factory.MetricParams{ 397 Unit: unit1, 398 }) 399 400 args := params.Entities{Entities: []params.Entity{}} 401 metrics, err := s.metricsdebug.GetMetrics(args) 402 c.Assert(err, jc.ErrorIsNil) 403 c.Assert(metrics.Results, gc.HasLen, 1) 404 metric0 := metrics.Results[0].Metrics[0] 405 metric1 := metrics.Results[0].Metrics[1] 406 expected0 := metricUnit0.Metrics()[0] 407 expected1 := metricUnit1.Metrics()[0] 408 c.Assert(metric0.Key, gc.Equals, expected0.Key) 409 c.Assert(metric0.Value, gc.Equals, expected0.Value) 410 c.Assert(metric0.Time, jc.TimeBetween(expected0.Time, expected0.Time)) 411 c.Assert(metric0.Unit, gc.Equals, metricUnit0.Unit()) 412 c.Assert(metric1.Key, gc.Equals, expected1.Key) 413 c.Assert(metric1.Value, gc.Equals, expected1.Value) 414 c.Assert(metric1.Time, jc.TimeBetween(expected1.Time, expected1.Time)) 415 c.Assert(metric1.Unit, gc.Equals, metricUnit1.Unit()) 416 }