1
// Copyright 2014 Canonical Ltd.
2
// Licensed under the AGPLv3, see LICENCE file for details.
4
package metricsmanager_test
9
"github.com/juju/errors"
10
jc "github.com/juju/testing/checkers"
11
gc "gopkg.in/check.v1"
12
"gopkg.in/juju/names.v2"
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"
24
type metricsManagerSuite struct {
25
jujutesting.JujuConnSuite
27
metricsmanager *metricsmanager.MetricsManagerAPI
28
authorizer apiservertesting.FakeAuthorizer
32
var _ = gc.Suite(&metricsManagerSuite{})
34
func (s *metricsManagerSuite) SetUpTest(c *gc.C) {
35
s.JujuConnSuite.SetUpTest(c)
36
s.authorizer = apiservertesting.FakeAuthorizer{
37
Tag: names.NewMachineTag("0"),
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.MakeApplication(c, &factory.ApplicationParams{Charm: meteredCharm})
45
s.unit = s.Factory.MakeUnit(c, &factory.UnitParams{Application: meteredService, SetCharmURL: true})
48
func (s *metricsManagerSuite) TestNewMetricsManagerAPIRefusesNonMachine(c *gc.C) {
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, ""},
59
for i, test := range tests {
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)
70
c.Assert(err, gc.ErrorMatches, test.expectedError)
71
c.Assert(endPoint, gc.IsNil)
76
func (s *metricsManagerSuite) TestCleanupOldMetrics(c *gc.C) {
77
oldTime := time.Now().Add(-(time.Hour * 25))
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()},
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)
95
func (s *metricsManagerSuite) TestCleanupOldMetricsInvalidArg(c *gc.C) {
96
args := params.Entities{Entities: []params.Entity{
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})
106
func (s *metricsManagerSuite) TestCleanupArgsIndependent(c *gc.C) {
107
args := params.Entities{Entities: []params.Entity{
109
{s.State.ModelTag().String()},
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})
119
func (s *metricsManagerSuite) TestSendMetrics(c *gc.C) {
120
var sender testing.MockSender
121
metricsmanager.PatchSender(&sender)
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()},
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)
139
func (s *metricsManagerSuite) TestSendOldMetricsInvalidArg(c *gc.C) {
140
args := params.Entities{Entities: []params.Entity{
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)
150
func (s *metricsManagerSuite) TestSendArgsIndependent(c *gc.C) {
151
args := params.Entities{Entities: []params.Entity{
153
{s.State.ModelTag().String()},
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)
163
func (s *metricsManagerSuite) TestMeterStatusOnConsecutiveErrors(c *gc.C) {
164
var sender testing.ErrorSender
165
sender.Err = errors.New("an error")
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()},
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)
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()},
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)
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()},
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)