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 }