github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/apiserver/facades/client/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/facades/client/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-1"}) 42 testApplication := s.Factory.MakeApplication(c, &factory.ApplicationParams{Charm: testCharm}) 43 testUnit1 := s.Factory.MakeUnit(c, &factory.UnitParams{Application: testApplication, SetCharmURL: true}) 44 testUnit2 := s.Factory.MakeUnit(c, &factory.UnitParams{Application: testApplication, SetCharmURL: true}) 45 46 csCharm := s.Factory.MakeCharm(c, &factory.CharmParams{Name: "metered", URL: "cs:quantal/metered-1"}) 47 csApplication := s.Factory.MakeApplication(c, &factory.ApplicationParams{Name: "cs-application", Charm: csCharm}) 48 csUnit1 := s.Factory.MakeUnit(c, &factory.UnitParams{Application: csApplication, 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: testApplication.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: csApplication.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: "meter status \"NOT AVAILABLE\" not valid"}) 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-1"}) 174 meteredApplication := s.Factory.MakeApplication(c, &factory.ApplicationParams{Charm: meteredCharm}) 175 unit := s.Factory.MakeUnit(c, &factory.UnitParams{Application: meteredApplication, SetCharmURL: true}) 176 t0 := time.Now().Round(time.Second) 177 t1 := t0.Add(time.Second) 178 metricA := state.Metric{Key: "pings", Value: "5", Time: t0} 179 metricB := state.Metric{Key: "pings", Value: "10.5", Time: 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) TestGetMetricsLabelOrdering(c *gc.C) { 203 meteredCharm := s.Factory.MakeCharm(c, &factory.CharmParams{Name: "metered", URL: "local:quantal/metered-1"}) 204 meteredApplication := s.Factory.MakeApplication(c, &factory.ApplicationParams{Charm: meteredCharm}) 205 unit := s.Factory.MakeUnit(c, &factory.UnitParams{Application: meteredApplication, SetCharmURL: true}) 206 t0 := time.Now().Round(time.Second) 207 s.Factory.MakeMetric(c, &factory.MetricParams{Unit: unit, Metrics: []state.Metric{{ 208 Key: "pings", Value: "6", Time: t0, 209 }, { 210 Key: "pings", Value: "2", Time: t0, Labels: map[string]string{"quux": "baz"}, 211 }, { 212 Key: "pings", Value: "3", Time: t0, Labels: map[string]string{"foo": "bar"}, 213 }, { 214 Key: "pings", Value: "1", Time: t0, Labels: map[string]string{"abc": "123"}, 215 }}}) 216 args := params.Entities{Entities: []params.Entity{ 217 {"unit-metered/0"}, 218 }} 219 result, err := s.metricsdebug.GetMetrics(args) 220 c.Assert(err, jc.ErrorIsNil) 221 c.Assert(result.Results, gc.HasLen, 1) 222 c.Assert(result.Results[0].Metrics, gc.HasLen, 4) 223 c.Assert(result.Results[0], jc.DeepEquals, params.EntityMetrics{ 224 Metrics: []params.MetricResult{{ 225 Unit: "metered/0", Key: "pings", Value: "6", Time: t0, 226 }, { 227 Unit: "metered/0", Key: "pings", Value: "1", Time: t0, Labels: map[string]string{"abc": "123"}, 228 }, { 229 Unit: "metered/0", Key: "pings", Value: "3", Time: t0, Labels: map[string]string{"foo": "bar"}, 230 }, { 231 Unit: "metered/0", Key: "pings", Value: "2", Time: t0, Labels: map[string]string{"quux": "baz"}, 232 }}, 233 Error: nil, 234 }) 235 } 236 237 func (s *metricsDebugSuite) TestGetMetricsFiltersCorrectly(c *gc.C) { 238 meteredCharm := s.Factory.MakeCharm(c, &factory.CharmParams{Name: "metered", URL: "local:quantal/metered-1"}) 239 meteredApplication := s.Factory.MakeApplication(c, &factory.ApplicationParams{Charm: meteredCharm}) 240 unit0 := s.Factory.MakeUnit(c, &factory.UnitParams{Application: meteredApplication, SetCharmURL: true}) 241 unit1 := s.Factory.MakeUnit(c, &factory.UnitParams{Application: meteredApplication, SetCharmURL: true}) 242 t0 := time.Now().Round(time.Second) 243 t1 := t0.Add(time.Second) 244 metricA := state.Metric{Key: "pings", Value: "5", Time: t1} 245 metricB := state.Metric{Key: "pings", Value: "10.5", Time: t0} 246 metricC := state.Metric{Key: "juju-units", Value: "8", Time: t1} 247 s.Factory.MakeMetric(c, &factory.MetricParams{Unit: unit0, Metrics: []state.Metric{metricA, metricB, metricC}}) 248 s.Factory.MakeMetric(c, &factory.MetricParams{Unit: unit1, Metrics: []state.Metric{metricA, metricB, metricC}}) 249 args := params.Entities{} 250 result, err := s.metricsdebug.GetMetrics(args) 251 c.Assert(err, jc.ErrorIsNil) 252 c.Assert(result.Results, gc.HasLen, 1) 253 c.Assert(result.Results[0].Metrics, gc.HasLen, 4) 254 c.Assert(result.Results[0].Metrics, gc.DeepEquals, []params.MetricResult{{ 255 Key: "juju-units", 256 Value: "8", 257 Time: t1, 258 Unit: "metered/0", 259 }, { 260 Key: "pings", 261 Value: "5", 262 Time: t1, 263 Unit: "metered/0", 264 }, { 265 Key: "juju-units", 266 Value: "8", 267 Time: t1, 268 Unit: "metered/1", 269 }, { 270 Key: "pings", 271 Value: "5", 272 Time: t1, 273 Unit: "metered/1", 274 }}, 275 ) 276 } 277 278 func (s *metricsDebugSuite) TestGetMetricsFiltersCorrectlyWhenNotAllMetricsInEachBatch(c *gc.C) { 279 meteredCharm := s.Factory.MakeCharm(c, &factory.CharmParams{Name: "metered", URL: "local:quantal/metered-1"}) 280 meteredApplication := s.Factory.MakeApplication(c, &factory.ApplicationParams{Charm: meteredCharm}) 281 unit0 := s.Factory.MakeUnit(c, &factory.UnitParams{Application: meteredApplication, SetCharmURL: true}) 282 unit1 := s.Factory.MakeUnit(c, &factory.UnitParams{Application: meteredApplication, SetCharmURL: true}) 283 t0 := time.Now().Round(time.Second) 284 t1 := t0.Add(time.Second) 285 metricA := state.Metric{Key: "pings", Value: "5", Time: t1} 286 metricB := state.Metric{Key: "pings", Value: "10.5", Time: t0} 287 metricC := state.Metric{Key: "juju-units", Value: "8", Time: t1} 288 s.Factory.MakeMetric(c, &factory.MetricParams{Unit: unit0, Metrics: []state.Metric{metricA, metricB, metricC}}) 289 s.Factory.MakeMetric(c, &factory.MetricParams{Unit: unit1, Metrics: []state.Metric{metricA, metricB}}) 290 args := params.Entities{} 291 result, err := s.metricsdebug.GetMetrics(args) 292 c.Assert(err, jc.ErrorIsNil) 293 c.Assert(result.Results, gc.HasLen, 1) 294 c.Assert(result.Results[0].Metrics, gc.HasLen, 3) 295 c.Assert(result.Results[0].Metrics, gc.DeepEquals, []params.MetricResult{{ 296 Key: "juju-units", 297 Value: "8", 298 Time: t1, 299 Unit: "metered/0", 300 }, { 301 Key: "pings", 302 Value: "5", 303 Time: t1, 304 Unit: "metered/0", 305 }, { 306 Key: "pings", 307 Value: "5", 308 Time: t1, 309 Unit: "metered/1", 310 }}, 311 ) 312 } 313 314 func (s *metricsDebugSuite) TestGetMetricsFiltersCorrectlyWithMultipleBatchesPerUnit(c *gc.C) { 315 meteredCharm := s.Factory.MakeCharm(c, &factory.CharmParams{Name: "metered", URL: "local:quantal/metered-1"}) 316 meteredApplication := s.Factory.MakeApplication(c, &factory.ApplicationParams{Charm: meteredCharm}) 317 unit0 := s.Factory.MakeUnit(c, &factory.UnitParams{Application: meteredApplication, SetCharmURL: true}) 318 unit1 := s.Factory.MakeUnit(c, &factory.UnitParams{Application: meteredApplication, SetCharmURL: true}) 319 t0 := time.Now().Round(time.Second) 320 t1 := t0.Add(time.Second) 321 metricA := state.Metric{Key: "pings", Value: "5", Time: t1} 322 metricB := state.Metric{Key: "pings", Value: "10.5", Time: t0} 323 metricC := state.Metric{Key: "juju-units", Value: "8", Time: t1} 324 s.Factory.MakeMetric(c, &factory.MetricParams{Unit: unit0, Metrics: []state.Metric{metricA, metricB}}) 325 s.Factory.MakeMetric(c, &factory.MetricParams{Unit: unit0, Metrics: []state.Metric{metricC}}) 326 s.Factory.MakeMetric(c, &factory.MetricParams{Unit: unit1, Metrics: []state.Metric{metricA, metricB}}) 327 args := params.Entities{} 328 result, err := s.metricsdebug.GetMetrics(args) 329 c.Assert(err, jc.ErrorIsNil) 330 c.Assert(result.Results, gc.HasLen, 1) 331 c.Assert(result.Results[0].Metrics, gc.HasLen, 3) 332 c.Assert(result.Results[0].Metrics, jc.DeepEquals, []params.MetricResult{{ 333 Key: "juju-units", 334 Value: "8", 335 Time: t1, 336 Unit: "metered/0", 337 }, { 338 Key: "pings", 339 Value: "5", 340 Time: t1, 341 Unit: "metered/0", 342 }, { 343 Key: "pings", 344 Value: "5", 345 Time: t1, 346 Unit: "metered/1", 347 }}, 348 ) 349 } 350 351 func (s *metricsDebugSuite) TestGetMultipleMetricsNoMocks(c *gc.C) { 352 meteredCharm := s.Factory.MakeCharm(c, &factory.CharmParams{Name: "metered", URL: "local:quantal/metered-1"}) 353 meteredApplication := s.Factory.MakeApplication(c, &factory.ApplicationParams{ 354 Charm: meteredCharm, 355 }) 356 unit0 := s.Factory.MakeUnit(c, &factory.UnitParams{Application: meteredApplication, SetCharmURL: true}) 357 unit1 := s.Factory.MakeUnit(c, &factory.UnitParams{Application: meteredApplication, SetCharmURL: true}) 358 359 metricUnit0 := s.Factory.MakeMetric(c, &factory.MetricParams{ 360 Unit: unit0, 361 }) 362 metricUnit1 := s.Factory.MakeMetric(c, &factory.MetricParams{ 363 Unit: unit1, 364 }) 365 366 args0 := params.Entities{Entities: []params.Entity{ 367 {"unit-metered/0"}, 368 }} 369 args1 := params.Entities{Entities: []params.Entity{ 370 {"unit-metered/1"}, 371 }} 372 373 metrics0, err := s.metricsdebug.GetMetrics(args0) 374 c.Assert(err, jc.ErrorIsNil) 375 c.Assert(metrics0.Results, gc.HasLen, 1) 376 c.Assert(metrics0.Results[0].Metrics[0].Key, gc.Equals, metricUnit0.Metrics()[0].Key) 377 c.Assert(metrics0.Results[0].Metrics[0].Value, gc.Equals, metricUnit0.Metrics()[0].Value) 378 c.Assert(metrics0.Results[0].Metrics[0].Time, jc.TimeBetween(metricUnit0.Metrics()[0].Time, metricUnit0.Metrics()[0].Time)) 379 380 metrics1, err := s.metricsdebug.GetMetrics(args1) 381 c.Assert(err, jc.ErrorIsNil) 382 c.Assert(metrics1.Results, gc.HasLen, 1) 383 c.Assert(metrics1.Results[0].Metrics[0].Key, gc.Equals, metricUnit1.Metrics()[0].Key) 384 c.Assert(metrics1.Results[0].Metrics[0].Value, gc.Equals, metricUnit1.Metrics()[0].Value) 385 c.Assert(metrics1.Results[0].Metrics[0].Time, jc.TimeBetween(metricUnit1.Metrics()[0].Time, metricUnit1.Metrics()[0].Time)) 386 } 387 388 func (s *metricsDebugSuite) TestGetMultipleMetricsNoMocksWithApplication(c *gc.C) { 389 meteredCharm := s.Factory.MakeCharm(c, &factory.CharmParams{Name: "metered", URL: "local:quantal/metered-1"}) 390 meteredApplication := s.Factory.MakeApplication(c, &factory.ApplicationParams{ 391 Charm: meteredCharm, 392 }) 393 unit0 := s.Factory.MakeUnit(c, &factory.UnitParams{Application: meteredApplication, SetCharmURL: true}) 394 unit1 := s.Factory.MakeUnit(c, &factory.UnitParams{Application: meteredApplication, SetCharmURL: true}) 395 396 metricUnit0 := s.Factory.MakeMetric(c, &factory.MetricParams{ 397 Unit: unit0, 398 }) 399 metricUnit1 := s.Factory.MakeMetric(c, &factory.MetricParams{ 400 Unit: unit1, 401 }) 402 403 args := params.Entities{Entities: []params.Entity{ 404 {"application-metered"}, 405 }} 406 407 metrics, err := s.metricsdebug.GetMetrics(args) 408 c.Assert(err, jc.ErrorIsNil) 409 c.Assert(metrics.Results, gc.HasLen, 1) 410 c.Assert(metrics.Results[0].Metrics, gc.HasLen, 2) 411 c.Assert(metrics.Results[0].Metrics[0].Key, gc.Equals, metricUnit0.Metrics()[0].Key) 412 c.Assert(metrics.Results[0].Metrics[0].Value, gc.Equals, metricUnit0.Metrics()[0].Value) 413 c.Assert(metrics.Results[0].Metrics[0].Time, jc.TimeBetween(metricUnit0.Metrics()[0].Time, metricUnit0.Metrics()[0].Time)) 414 415 c.Assert(metrics.Results[0].Metrics[1].Key, gc.Equals, metricUnit1.Metrics()[0].Key) 416 c.Assert(metrics.Results[0].Metrics[1].Value, gc.Equals, metricUnit1.Metrics()[0].Value) 417 c.Assert(metrics.Results[0].Metrics[1].Time, jc.TimeBetween(metricUnit1.Metrics()[0].Time, metricUnit1.Metrics()[0].Time)) 418 } 419 420 func (s *metricsDebugSuite) TestGetModelNoMocks(c *gc.C) { 421 meteredCharm := s.Factory.MakeCharm(c, &factory.CharmParams{Name: "metered", URL: "local:quantal/metered-1"}) 422 meteredApplication := s.Factory.MakeApplication(c, &factory.ApplicationParams{ 423 Charm: meteredCharm, 424 }) 425 unit0 := s.Factory.MakeUnit(c, &factory.UnitParams{Application: meteredApplication, SetCharmURL: true}) 426 unit1 := s.Factory.MakeUnit(c, &factory.UnitParams{Application: meteredApplication, SetCharmURL: true}) 427 428 metricUnit0 := s.Factory.MakeMetric(c, &factory.MetricParams{ 429 Unit: unit0, 430 }) 431 metricUnit1 := s.Factory.MakeMetric(c, &factory.MetricParams{ 432 Unit: unit1, 433 }) 434 435 args := params.Entities{Entities: []params.Entity{}} 436 metrics, err := s.metricsdebug.GetMetrics(args) 437 c.Assert(err, jc.ErrorIsNil) 438 c.Assert(metrics.Results, gc.HasLen, 1) 439 metric0 := metrics.Results[0].Metrics[0] 440 metric1 := metrics.Results[0].Metrics[1] 441 expected0 := metricUnit0.Metrics()[0] 442 expected1 := metricUnit1.Metrics()[0] 443 c.Assert(metric0.Key, gc.Equals, expected0.Key) 444 c.Assert(metric0.Value, gc.Equals, expected0.Value) 445 c.Assert(metric0.Time, jc.TimeBetween(expected0.Time, expected0.Time)) 446 c.Assert(metric0.Unit, gc.Equals, metricUnit0.Unit()) 447 c.Assert(metric1.Key, gc.Equals, expected1.Key) 448 c.Assert(metric1.Value, gc.Equals, expected1.Value) 449 c.Assert(metric1.Time, jc.TimeBetween(expected1.Time, expected1.Time)) 450 c.Assert(metric1.Unit, gc.Equals, metricUnit1.Unit()) 451 }