github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/api/metricsdebug/client_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  	"errors"
     8  	"time"
     9  
    10  	jc "github.com/juju/testing/checkers"
    11  	gc "gopkg.in/check.v1"
    12  
    13  	basetesting "github.com/juju/juju/api/base/testing"
    14  	"github.com/juju/juju/api/metricsdebug"
    15  	"github.com/juju/juju/apiserver/common"
    16  	"github.com/juju/juju/apiserver/params"
    17  	jujutesting "github.com/juju/juju/juju/testing"
    18  	"github.com/juju/juju/state"
    19  	"github.com/juju/juju/testing"
    20  	"github.com/juju/juju/testing/factory"
    21  )
    22  
    23  type metricsdebugSuiteMock struct {
    24  	testing.BaseSuite
    25  	manager *metricsdebug.Client
    26  }
    27  
    28  var _ = gc.Suite(&metricsdebugSuiteMock{})
    29  
    30  func (s *metricsdebugSuiteMock) TestGetMetrics(c *gc.C) {
    31  	var called bool
    32  	now := time.Now()
    33  	apiCaller := basetesting.APICallerFunc(
    34  		func(objType string,
    35  			version int,
    36  			id, request string,
    37  			a, response interface{},
    38  		) error {
    39  			c.Assert(request, gc.Equals, "GetMetrics")
    40  			result := response.(*params.MetricResults)
    41  			result.Results = []params.EntityMetrics{{
    42  				Metrics: []params.MetricResult{{
    43  					Key:   "pings",
    44  					Value: "5",
    45  					Time:  now,
    46  				}},
    47  				Error: nil,
    48  			}}
    49  			called = true
    50  			return nil
    51  		})
    52  	client := metricsdebug.NewClient(apiCaller)
    53  	metrics, err := client.GetMetrics("unit-wordpress/0")
    54  	c.Assert(err, jc.ErrorIsNil)
    55  	c.Assert(called, jc.IsTrue)
    56  	c.Assert(metrics, gc.HasLen, 1)
    57  	c.Assert(metrics[0].Key, gc.Equals, "pings")
    58  	c.Assert(metrics[0].Value, gc.Equals, "5")
    59  	c.Assert(metrics[0].Time, gc.Equals, now)
    60  }
    61  
    62  func (s *metricsdebugSuiteMock) TestGetMetricsFails(c *gc.C) {
    63  	var called bool
    64  	apiCaller := basetesting.APICallerFunc(
    65  		func(objType string,
    66  			version int,
    67  			id, request string,
    68  			a, response interface{},
    69  		) error {
    70  			c.Assert(request, gc.Equals, "GetMetrics")
    71  			result := response.(*params.MetricResults)
    72  			result.Results = []params.EntityMetrics{{
    73  				Error: common.ServerError(errors.New("an error")),
    74  			}}
    75  			called = true
    76  			return nil
    77  		})
    78  	client := metricsdebug.NewClient(apiCaller)
    79  	metrics, err := client.GetMetrics("unit-wordpress/0")
    80  	c.Assert(err, gc.ErrorMatches, "an error")
    81  	c.Assert(metrics, gc.IsNil)
    82  	c.Assert(called, jc.IsTrue)
    83  }
    84  
    85  func (s *metricsdebugSuiteMock) TestGetMetricsFacadeCallError(c *gc.C) {
    86  	var called bool
    87  	apiCaller := basetesting.APICallerFunc(
    88  		func(objType string,
    89  			version int,
    90  			id, request string,
    91  			a, result interface{},
    92  		) error {
    93  			called = true
    94  			return errors.New("an error")
    95  		})
    96  	client := metricsdebug.NewClient(apiCaller)
    97  	metrics, err := client.GetMetrics("unit-wordpress/0")
    98  	c.Assert(err, gc.ErrorMatches, "an error")
    99  	c.Assert(metrics, gc.IsNil)
   100  	c.Assert(called, jc.IsTrue)
   101  }
   102  
   103  func (s *metricsdebugSuiteMock) TestSetMeterStatus(c *gc.C) {
   104  	var called bool
   105  	apiCaller := basetesting.APICallerFunc(
   106  		func(objType string,
   107  			version int,
   108  			id, request string,
   109  			a, response interface{},
   110  		) error {
   111  			c.Assert(request, gc.Equals, "SetMeterStatus")
   112  			c.Assert(a, gc.DeepEquals, params.MeterStatusParams{
   113  				Statuses: []params.MeterStatusParam{{
   114  					Tag:  "unit-metered/0",
   115  					Code: "RED",
   116  					Info: "test"},
   117  				},
   118  			})
   119  			result := response.(*params.ErrorResults)
   120  			result.Results = []params.ErrorResult{{
   121  				Error: nil,
   122  			}}
   123  			called = true
   124  			return nil
   125  		})
   126  	client := metricsdebug.NewClient(apiCaller)
   127  	err := client.SetMeterStatus("unit-metered/0", "RED", "test")
   128  	c.Assert(err, jc.ErrorIsNil)
   129  	c.Assert(called, jc.IsTrue)
   130  }
   131  
   132  func (s *metricsdebugSuiteMock) TestSetMeterStatusAPIServerError(c *gc.C) {
   133  	var called bool
   134  	apiCaller := basetesting.APICallerFunc(
   135  		func(objType string,
   136  			version int,
   137  			id, request string,
   138  			a, response interface{},
   139  		) error {
   140  			c.Assert(request, gc.Equals, "SetMeterStatus")
   141  			c.Assert(a, gc.DeepEquals, params.MeterStatusParams{
   142  				Statuses: []params.MeterStatusParam{{
   143  					Tag:  "unit-metered/0",
   144  					Code: "RED",
   145  					Info: "test"},
   146  				},
   147  			})
   148  			result := response.(*params.ErrorResults)
   149  			result.Results = []params.ErrorResult{{
   150  				Error: common.ServerError(errors.New("an error")),
   151  			}}
   152  			called = true
   153  			return nil
   154  		})
   155  	client := metricsdebug.NewClient(apiCaller)
   156  	err := client.SetMeterStatus("unit-metered/0", "RED", "test")
   157  	c.Assert(err, gc.ErrorMatches, "an error")
   158  	c.Assert(called, jc.IsTrue)
   159  }
   160  
   161  func (s *metricsdebugSuiteMock) TestSetMeterStatusFacadeCallError(c *gc.C) {
   162  	var called bool
   163  	apiCaller := basetesting.APICallerFunc(
   164  		func(objType string,
   165  			version int,
   166  			id, request string,
   167  			a, response interface{},
   168  		) error {
   169  			called = true
   170  			return errors.New("an error")
   171  		})
   172  	client := metricsdebug.NewClient(apiCaller)
   173  	err := client.SetMeterStatus("unit-metered/0", "RED", "test")
   174  	c.Assert(err, gc.ErrorMatches, "an error")
   175  	c.Assert(called, jc.IsTrue)
   176  }
   177  
   178  type metricsdebugSuite struct {
   179  	jujutesting.JujuConnSuite
   180  	manager *metricsdebug.Client
   181  }
   182  
   183  var _ = gc.Suite(&metricsdebugSuite{})
   184  
   185  func (s *metricsdebugSuite) SetUpTest(c *gc.C) {
   186  	s.JujuConnSuite.SetUpTest(c)
   187  	s.manager = metricsdebug.NewClient(s.APIState)
   188  	c.Assert(s.manager, gc.NotNil)
   189  }
   190  
   191  func assertSameMetric(c *gc.C, a params.MetricResult, b *state.MetricBatch) {
   192  	c.Assert(a.Key, gc.Equals, b.Metrics()[0].Key)
   193  	c.Assert(a.Value, gc.Equals, b.Metrics()[0].Value)
   194  	c.Assert(a.Time, jc.TimeBetween(b.Metrics()[0].Time, b.Metrics()[0].Time))
   195  }
   196  
   197  func (s *metricsdebugSuite) TestFeatureGetMetrics(c *gc.C) {
   198  	meteredCharm := s.Factory.MakeCharm(c, &factory.CharmParams{Name: "metered", URL: "local:quantal/metered"})
   199  	meteredService := s.Factory.MakeService(c, &factory.ServiceParams{Charm: meteredCharm})
   200  	unit := s.Factory.MakeUnit(c, &factory.UnitParams{Service: meteredService, SetCharmURL: true})
   201  	metric := s.Factory.MakeMetric(c, &factory.MetricParams{Unit: unit})
   202  	metrics, err := s.manager.GetMetrics("unit-metered/0")
   203  	c.Assert(err, jc.ErrorIsNil)
   204  	c.Assert(metrics, gc.HasLen, 1)
   205  	assertSameMetric(c, metrics[0], metric)
   206  }
   207  
   208  func (s *metricsdebugSuite) TestFeatureGetMultipleMetrics(c *gc.C) {
   209  	meteredCharm := s.Factory.MakeCharm(c, &factory.CharmParams{Name: "metered", URL: "local:quantal/metered"})
   210  	meteredService := s.Factory.MakeService(c, &factory.ServiceParams{
   211  		Charm: meteredCharm,
   212  	})
   213  	unit0 := s.Factory.MakeUnit(c, &factory.UnitParams{Service: meteredService, SetCharmURL: true})
   214  	unit1 := s.Factory.MakeUnit(c, &factory.UnitParams{Service: meteredService, SetCharmURL: true})
   215  
   216  	metricUnit0 := s.Factory.MakeMetric(c, &factory.MetricParams{
   217  		Unit: unit0,
   218  	})
   219  	metricUnit1 := s.Factory.MakeMetric(c, &factory.MetricParams{
   220  		Unit: unit1,
   221  	})
   222  
   223  	metrics0, err := s.manager.GetMetrics("unit-metered/0")
   224  	c.Assert(err, jc.ErrorIsNil)
   225  	c.Assert(metrics0, gc.HasLen, 1)
   226  	assertSameMetric(c, metrics0[0], metricUnit0)
   227  
   228  	metrics1, err := s.manager.GetMetrics("unit-metered/1")
   229  	c.Assert(err, jc.ErrorIsNil)
   230  	c.Assert(metrics1, gc.HasLen, 1)
   231  	assertSameMetric(c, metrics1[0], metricUnit1)
   232  }
   233  
   234  func (s *metricsdebugSuite) TestFeatureGetMultipleMetricsWithService(c *gc.C) {
   235  	meteredCharm := s.Factory.MakeCharm(c, &factory.CharmParams{Name: "metered", URL: "local:quantal/metered"})
   236  	meteredService := s.Factory.MakeService(c, &factory.ServiceParams{
   237  		Charm: meteredCharm,
   238  	})
   239  	unit0 := s.Factory.MakeUnit(c, &factory.UnitParams{Service: meteredService, SetCharmURL: true})
   240  	unit1 := s.Factory.MakeUnit(c, &factory.UnitParams{Service: meteredService, SetCharmURL: true})
   241  
   242  	metricUnit0 := s.Factory.MakeMetric(c, &factory.MetricParams{
   243  		Unit: unit0,
   244  	})
   245  	metricUnit1 := s.Factory.MakeMetric(c, &factory.MetricParams{
   246  		Unit: unit1,
   247  	})
   248  
   249  	metrics, err := s.manager.GetMetrics("service-metered")
   250  	c.Assert(err, jc.ErrorIsNil)
   251  	c.Assert(metrics, gc.HasLen, 2)
   252  	assertSameMetric(c, metrics[0], metricUnit0)
   253  	assertSameMetric(c, metrics[1], metricUnit1)
   254  }
   255  
   256  func (s *metricsdebugSuite) TestSetMeterStatus(c *gc.C) {
   257  	testCharm := s.Factory.MakeCharm(c, &factory.CharmParams{Name: "metered", URL: "local:quantal/metered"})
   258  	testService := s.Factory.MakeService(c, &factory.ServiceParams{Charm: testCharm})
   259  	testUnit1 := s.Factory.MakeUnit(c, &factory.UnitParams{Service: testService, SetCharmURL: true})
   260  	testUnit2 := s.Factory.MakeUnit(c, &factory.UnitParams{Service: testService, SetCharmURL: true})
   261  
   262  	csCharm := s.Factory.MakeCharm(c, &factory.CharmParams{Name: "metered", URL: "cs:quantal/metered"})
   263  	csService := s.Factory.MakeService(c, &factory.ServiceParams{Name: "cs-service", Charm: csCharm})
   264  	csUnit1 := s.Factory.MakeUnit(c, &factory.UnitParams{Service: csService, SetCharmURL: true})
   265  
   266  	tests := []struct {
   267  		about  string
   268  		tag    string
   269  		code   string
   270  		info   string
   271  		err    string
   272  		assert func(*gc.C)
   273  	}{{
   274  		about: "set service meter status",
   275  		tag:   testService.Tag().String(),
   276  		code:  "RED",
   277  		info:  "test",
   278  		assert: func(c *gc.C) {
   279  			ms1, err := testUnit1.GetMeterStatus()
   280  			c.Assert(err, jc.ErrorIsNil)
   281  			c.Assert(ms1, gc.DeepEquals, state.MeterStatus{
   282  				Code: state.MeterRed,
   283  				Info: "test",
   284  			})
   285  			ms2, err := testUnit2.GetMeterStatus()
   286  			c.Assert(err, jc.ErrorIsNil)
   287  			c.Assert(ms2, gc.DeepEquals, state.MeterStatus{
   288  				Code: state.MeterRed,
   289  				Info: "test",
   290  			})
   291  		},
   292  	}, {
   293  		about: "set unit meter status",
   294  		tag:   testUnit1.Tag().String(),
   295  		code:  "AMBER",
   296  		info:  "test",
   297  		assert: func(c *gc.C) {
   298  			ms1, err := testUnit1.GetMeterStatus()
   299  			c.Assert(err, jc.ErrorIsNil)
   300  			c.Assert(ms1, gc.DeepEquals, state.MeterStatus{
   301  				Code: state.MeterAmber,
   302  				Info: "test",
   303  			})
   304  		},
   305  	}, {
   306  		about: "not a local charm - service",
   307  		tag:   csService.Tag().String(),
   308  		code:  "AMBER",
   309  		info:  "test",
   310  		err:   "not a local charm",
   311  	}, {
   312  		about: "not a local charm - unit",
   313  		tag:   csUnit1.Tag().String(),
   314  		code:  "AMBER",
   315  		info:  "test",
   316  		err:   "not a local charm",
   317  	}, {
   318  		about: "invalid meter status",
   319  		tag:   testUnit1.Tag().String(),
   320  		code:  "WRONG",
   321  		info:  "test",
   322  		err:   "invalid meter status \"NOT AVAILABLE\"",
   323  	}, {
   324  		about: "not such service",
   325  		tag:   "service-missing",
   326  		code:  "AMBER",
   327  		info:  "test",
   328  		err:   "service \"missing\" not found",
   329  	},
   330  	}
   331  
   332  	for i, test := range tests {
   333  		c.Logf("running test %d: %v", i, test.about)
   334  		err := s.manager.SetMeterStatus(test.tag, test.code, test.info)
   335  		if test.err == "" {
   336  			c.Assert(err, jc.ErrorIsNil)
   337  			test.assert(c)
   338  		} else {
   339  			c.Assert(err, gc.ErrorMatches, test.err)
   340  		}
   341  	}
   342  }