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, &params.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, &params.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, &params.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, &params.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  }