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