github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/apiserver/metricsmanager/metricsmanager_test.go (about)

     1  // Copyright 2014 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package metricsmanager_test
     5  
     6  import (
     7  	"time"
     8  
     9  	"github.com/juju/errors"
    10  	"github.com/juju/names"
    11  	jc "github.com/juju/testing/checkers"
    12  	gc "gopkg.in/check.v1"
    13  
    14  	"github.com/juju/juju/apiserver/common"
    15  	"github.com/juju/juju/apiserver/metricsender/testing"
    16  	"github.com/juju/juju/apiserver/metricsmanager"
    17  	"github.com/juju/juju/apiserver/params"
    18  	apiservertesting "github.com/juju/juju/apiserver/testing"
    19  	jujutesting "github.com/juju/juju/juju/testing"
    20  	"github.com/juju/juju/state"
    21  	"github.com/juju/juju/testing/factory"
    22  )
    23  
    24  type metricsManagerSuite struct {
    25  	jujutesting.JujuConnSuite
    26  
    27  	metricsmanager *metricsmanager.MetricsManagerAPI
    28  	authorizer     apiservertesting.FakeAuthorizer
    29  	unit           *state.Unit
    30  }
    31  
    32  var _ = gc.Suite(&metricsManagerSuite{})
    33  
    34  func (s *metricsManagerSuite) SetUpTest(c *gc.C) {
    35  	s.JujuConnSuite.SetUpTest(c)
    36  	s.authorizer = apiservertesting.FakeAuthorizer{
    37  		Tag:            names.NewMachineTag("0"),
    38  		EnvironManager: true,
    39  	}
    40  	manager, err := metricsmanager.NewMetricsManagerAPI(s.State, nil, s.authorizer)
    41  	c.Assert(err, jc.ErrorIsNil)
    42  	s.metricsmanager = manager
    43  	meteredCharm := s.Factory.MakeCharm(c, &factory.CharmParams{Name: "metered", URL: "cs:quantal/metered"})
    44  	meteredService := s.Factory.MakeService(c, &factory.ServiceParams{Charm: meteredCharm})
    45  	s.unit = s.Factory.MakeUnit(c, &factory.UnitParams{Service: meteredService, SetCharmURL: true})
    46  }
    47  
    48  func (s *metricsManagerSuite) TestNewMetricsManagerAPIRefusesNonMachine(c *gc.C) {
    49  	tests := []struct {
    50  		tag            names.Tag
    51  		environManager bool
    52  		expectedError  string
    53  	}{
    54  		{names.NewUnitTag("mysql/0"), true, "permission denied"},
    55  		{names.NewLocalUserTag("admin"), true, "permission denied"},
    56  		{names.NewMachineTag("0"), false, "permission denied"},
    57  		{names.NewMachineTag("0"), true, ""},
    58  	}
    59  	for i, test := range tests {
    60  		c.Logf("test %d", i)
    61  
    62  		anAuthoriser := s.authorizer
    63  		anAuthoriser.EnvironManager = test.environManager
    64  		anAuthoriser.Tag = test.tag
    65  		endPoint, err := metricsmanager.NewMetricsManagerAPI(s.State, nil, anAuthoriser)
    66  		if test.expectedError == "" {
    67  			c.Assert(err, jc.ErrorIsNil)
    68  			c.Assert(endPoint, gc.NotNil)
    69  		} else {
    70  			c.Assert(err, gc.ErrorMatches, test.expectedError)
    71  			c.Assert(endPoint, gc.IsNil)
    72  		}
    73  	}
    74  }
    75  
    76  func (s *metricsManagerSuite) TestCleanupOldMetrics(c *gc.C) {
    77  	oldTime := time.Now().Add(-(time.Hour * 25))
    78  	newTime := time.Now()
    79  	metric := state.Metric{"pings", "5", newTime}
    80  	oldMetric := s.Factory.MakeMetric(c, &factory.MetricParams{Unit: s.unit, Sent: true, DeleteTime: &oldTime, Metrics: []state.Metric{metric}})
    81  	newMetric := s.Factory.MakeMetric(c, &factory.MetricParams{Unit: s.unit, Sent: true, DeleteTime: &newTime, Metrics: []state.Metric{metric}})
    82  	args := params.Entities{Entities: []params.Entity{
    83  		{s.State.ModelTag().String()},
    84  	}}
    85  	result, err := s.metricsmanager.CleanupOldMetrics(args)
    86  	c.Assert(err, jc.ErrorIsNil)
    87  	c.Assert(result.Results, gc.HasLen, 1)
    88  	c.Assert(result.Results[0], gc.DeepEquals, params.ErrorResult{Error: nil})
    89  	_, err = s.State.MetricBatch(oldMetric.UUID())
    90  	c.Assert(err, jc.Satisfies, errors.IsNotFound)
    91  	_, err = s.State.MetricBatch(newMetric.UUID())
    92  	c.Assert(err, jc.ErrorIsNil)
    93  }
    94  
    95  func (s *metricsManagerSuite) TestCleanupOldMetricsInvalidArg(c *gc.C) {
    96  	args := params.Entities{Entities: []params.Entity{
    97  		{"invalid"},
    98  	}}
    99  	result, err := s.metricsmanager.CleanupOldMetrics(args)
   100  	c.Assert(result.Results, gc.HasLen, 1)
   101  	c.Assert(err, jc.ErrorIsNil)
   102  	expectedError := common.ServerError(common.ErrPerm)
   103  	c.Assert(result.Results[0], gc.DeepEquals, params.ErrorResult{Error: expectedError})
   104  }
   105  
   106  func (s *metricsManagerSuite) TestCleanupArgsIndependent(c *gc.C) {
   107  	args := params.Entities{Entities: []params.Entity{
   108  		{"invalid"},
   109  		{s.State.ModelTag().String()},
   110  	}}
   111  	result, err := s.metricsmanager.CleanupOldMetrics(args)
   112  	c.Assert(result.Results, gc.HasLen, 2)
   113  	c.Assert(err, jc.ErrorIsNil)
   114  	expectedError := common.ServerError(common.ErrPerm)
   115  	c.Assert(result.Results[0], gc.DeepEquals, params.ErrorResult{Error: expectedError})
   116  	c.Assert(result.Results[1], gc.DeepEquals, params.ErrorResult{Error: nil})
   117  }
   118  
   119  func (s *metricsManagerSuite) TestSendMetrics(c *gc.C) {
   120  	var sender testing.MockSender
   121  	metricsmanager.PatchSender(&sender)
   122  	now := time.Now()
   123  	metric := state.Metric{"pings", "5", now}
   124  	s.Factory.MakeMetric(c, &factory.MetricParams{Unit: s.unit, Sent: true, Time: &now, Metrics: []state.Metric{metric}})
   125  	unsent := s.Factory.MakeMetric(c, &factory.MetricParams{Unit: s.unit, Sent: false, Time: &now, Metrics: []state.Metric{metric}})
   126  	args := params.Entities{Entities: []params.Entity{
   127  		{s.State.ModelTag().String()},
   128  	}}
   129  	result, err := s.metricsmanager.SendMetrics(args)
   130  	c.Assert(err, jc.ErrorIsNil)
   131  	c.Assert(result.Results, gc.HasLen, 1)
   132  	c.Assert(result.Results[0], gc.DeepEquals, params.ErrorResult{Error: nil})
   133  	c.Assert(sender.Data, gc.HasLen, 1)
   134  	m, err := s.State.MetricBatch(unsent.UUID())
   135  	c.Assert(err, jc.ErrorIsNil)
   136  	c.Assert(m.Sent(), jc.IsTrue)
   137  }
   138  
   139  func (s *metricsManagerSuite) TestSendOldMetricsInvalidArg(c *gc.C) {
   140  	args := params.Entities{Entities: []params.Entity{
   141  		{"invalid"},
   142  	}}
   143  	result, err := s.metricsmanager.SendMetrics(args)
   144  	c.Assert(result.Results, gc.HasLen, 1)
   145  	c.Assert(err, jc.ErrorIsNil)
   146  	expectedError := `"invalid" is not a valid tag`
   147  	c.Assert(result.Results[0].Error, gc.ErrorMatches, expectedError)
   148  }
   149  
   150  func (s *metricsManagerSuite) TestSendArgsIndependent(c *gc.C) {
   151  	args := params.Entities{Entities: []params.Entity{
   152  		{"invalid"},
   153  		{s.State.ModelTag().String()},
   154  	}}
   155  	result, err := s.metricsmanager.SendMetrics(args)
   156  	c.Assert(result.Results, gc.HasLen, 2)
   157  	c.Assert(err, jc.ErrorIsNil)
   158  	expectedError := `"invalid" is not a valid tag`
   159  	c.Assert(result.Results[0].Error, gc.ErrorMatches, expectedError)
   160  	c.Assert(result.Results[1].Error, gc.IsNil)
   161  }
   162  
   163  func (s *metricsManagerSuite) TestMeterStatusOnConsecutiveErrors(c *gc.C) {
   164  	var sender testing.ErrorSender
   165  	sender.Err = errors.New("an error")
   166  	now := time.Now()
   167  	metric := state.Metric{"pings", "5", now}
   168  	s.Factory.MakeMetric(c, &factory.MetricParams{Unit: s.unit, Sent: false, Time: &now, Metrics: []state.Metric{metric}})
   169  	metricsmanager.PatchSender(&sender)
   170  	args := params.Entities{Entities: []params.Entity{
   171  		{s.State.ModelTag().String()},
   172  	}}
   173  	result, err := s.metricsmanager.SendMetrics(args)
   174  	c.Assert(err, jc.ErrorIsNil)
   175  	expectedError := params.ErrorResult{Error: apiservertesting.PrefixedError("failed to send metrics: ", "an error")}
   176  	c.Assert(result.Results[0], jc.DeepEquals, expectedError)
   177  	mm, err := s.State.MetricsManager()
   178  	c.Assert(err, jc.ErrorIsNil)
   179  	c.Assert(mm.ConsecutiveErrors(), gc.Equals, 1)
   180  }
   181  
   182  func (s *metricsManagerSuite) TestMeterStatusSuccessfulSend(c *gc.C) {
   183  	var sender testing.MockSender
   184  	pastTime := time.Now().Add(-time.Second)
   185  	metric := state.Metric{"pings", "5", pastTime}
   186  	s.Factory.MakeMetric(c, &factory.MetricParams{Unit: s.unit, Sent: false, Time: &pastTime, Metrics: []state.Metric{metric}})
   187  	metricsmanager.PatchSender(&sender)
   188  	args := params.Entities{Entities: []params.Entity{
   189  		{s.State.ModelTag().String()},
   190  	}}
   191  	result, err := s.metricsmanager.SendMetrics(args)
   192  	c.Assert(err, jc.ErrorIsNil)
   193  	c.Assert(result.Results[0].Error, gc.IsNil)
   194  	mm, err := s.State.MetricsManager()
   195  	c.Assert(err, jc.ErrorIsNil)
   196  	c.Assert(mm.LastSuccessfulSend().After(pastTime), jc.IsTrue)
   197  }
   198  
   199  func (s *metricsManagerSuite) TestLastSuccessfulNotChangedIfNothingToSend(c *gc.C) {
   200  	var sender testing.MockSender
   201  	metricsmanager.PatchSender(&sender)
   202  	args := params.Entities{Entities: []params.Entity{
   203  		{s.State.ModelTag().String()},
   204  	}}
   205  	result, err := s.metricsmanager.SendMetrics(args)
   206  	c.Assert(err, jc.ErrorIsNil)
   207  	c.Assert(result.Results[0].Error, gc.IsNil)
   208  	mm, err := s.State.MetricsManager()
   209  	c.Assert(err, jc.ErrorIsNil)
   210  	c.Assert(mm.LastSuccessfulSend().Equal(time.Time{}), jc.IsTrue)
   211  }