github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/apiserver/facades/agent/metricsadder/metricsadder_test.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package metricsadder_test
     5  
     6  import (
     7  	"time"
     8  
     9  	"github.com/juju/errors"
    10  	jc "github.com/juju/testing/checkers"
    11  	"github.com/juju/utils"
    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/facades/agent/metricsadder"
    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  	jujuFactory "github.com/juju/juju/testing/factory"
    22  )
    23  
    24  var _ = gc.Suite(&metricsAdderSuite{})
    25  
    26  type metricsAdderSuite struct {
    27  	jujutesting.JujuConnSuite
    28  
    29  	authorizer apiservertesting.FakeAuthorizer
    30  	resources  *common.Resources
    31  
    32  	machine0       *state.Machine
    33  	machine1       *state.Machine
    34  	mysqlService   *state.Application
    35  	mysql          *state.Application
    36  	mysqlUnit      *state.Unit
    37  	meteredService *state.Application
    38  	meteredCharm   *state.Charm
    39  	meteredUnit    *state.Unit
    40  
    41  	adder metricsadder.MetricsAdder
    42  }
    43  
    44  func (s *metricsAdderSuite) SetUpTest(c *gc.C) {
    45  	s.JujuConnSuite.SetUpTest(c)
    46  	s.machine0 = s.Factory.MakeMachine(c, &jujuFactory.MachineParams{
    47  		Series: "quantal",
    48  		Jobs:   []state.MachineJob{state.JobHostUnits, state.JobManageModel},
    49  	})
    50  	s.machine1 = s.Factory.MakeMachine(c, &jujuFactory.MachineParams{
    51  		Series: "quantal",
    52  		Jobs:   []state.MachineJob{state.JobHostUnits},
    53  	})
    54  	mysqlCharm := s.Factory.MakeCharm(c, &jujuFactory.CharmParams{
    55  		Name: "mysql",
    56  	})
    57  	s.mysql = s.Factory.MakeApplication(c, &jujuFactory.ApplicationParams{
    58  		Name:  "mysql",
    59  		Charm: mysqlCharm,
    60  	})
    61  	s.mysqlUnit = s.Factory.MakeUnit(c, &jujuFactory.UnitParams{
    62  		Application: s.mysql,
    63  		Machine:     s.machine0,
    64  	})
    65  
    66  	s.meteredCharm = s.Factory.MakeCharm(c, &jujuFactory.CharmParams{
    67  		Name: "metered",
    68  		URL:  "cs:quantal/metered",
    69  	})
    70  	s.meteredService = s.Factory.MakeApplication(c, &jujuFactory.ApplicationParams{
    71  		Charm: s.meteredCharm,
    72  	})
    73  	s.meteredUnit = s.Factory.MakeUnit(c, &jujuFactory.UnitParams{
    74  		Application: s.meteredService,
    75  		SetCharmURL: true,
    76  		Machine:     s.machine1,
    77  	})
    78  
    79  	// Create a FakeAuthorizer so we can check permissions,
    80  	// set up assuming unit 0 has logged in.
    81  	s.authorizer = apiservertesting.FakeAuthorizer{
    82  		Tag: names.NewMachineTag("1"),
    83  	}
    84  
    85  	// Create the resource registry separately to track invocations to
    86  	// Register.
    87  	s.resources = common.NewResources()
    88  	s.AddCleanup(func(_ *gc.C) { s.resources.StopAll() })
    89  
    90  	adder, err := metricsadder.NewMetricsAdderAPI(s.State, s.resources, s.authorizer)
    91  	c.Assert(err, jc.ErrorIsNil)
    92  	s.adder = adder
    93  }
    94  
    95  func (s *metricsAdderSuite) TestAddMetricsBatch(c *gc.C) {
    96  	metrics := []params.Metric{{
    97  		Key: "pings", Value: "5", Time: time.Now().UTC(),
    98  	}, {
    99  		Key: "pongs", Value: "6", Time: time.Now().UTC(), Labels: map[string]string{"foo": "bar"},
   100  	}}
   101  	uuid := utils.MustNewUUID().String()
   102  
   103  	result, err := s.adder.AddMetricBatches(params.MetricBatchParams{
   104  		Batches: []params.MetricBatchParam{{
   105  			Tag: s.meteredUnit.Tag().String(),
   106  			Batch: params.MetricBatch{
   107  				UUID:     uuid,
   108  				CharmURL: s.meteredCharm.URL().String(),
   109  				Created:  time.Now(),
   110  				Metrics:  metrics,
   111  			}}}},
   112  	)
   113  	c.Assert(err, jc.ErrorIsNil)
   114  	c.Assert(result, gc.DeepEquals, params.ErrorResults{
   115  		Results: []params.ErrorResult{{nil}},
   116  	})
   117  
   118  	batches, err := s.State.AllMetricBatches()
   119  	c.Assert(err, jc.ErrorIsNil)
   120  	c.Assert(batches, gc.HasLen, 1)
   121  	batch := batches[0]
   122  	c.Assert(batch.UUID(), gc.Equals, uuid)
   123  	c.Assert(batch.CharmURL(), gc.Equals, s.meteredCharm.URL().String())
   124  	c.Assert(batch.Unit(), gc.Equals, s.meteredUnit.Name())
   125  	storedMetrics := batch.Metrics()
   126  	c.Assert(storedMetrics, gc.HasLen, 2)
   127  	c.Assert(storedMetrics[0].Key, gc.Equals, metrics[0].Key)
   128  	c.Assert(storedMetrics[0].Value, gc.Equals, metrics[0].Value)
   129  	c.Assert(storedMetrics[0].Labels, gc.DeepEquals, metrics[0].Labels)
   130  	c.Assert(storedMetrics[1].Key, gc.Equals, metrics[1].Key)
   131  	c.Assert(storedMetrics[1].Value, gc.Equals, metrics[1].Value)
   132  	c.Assert(storedMetrics[1].Labels, gc.DeepEquals, metrics[1].Labels)
   133  }
   134  
   135  func (s *metricsAdderSuite) TestAddMetricsBatchNoCharmURL(c *gc.C) {
   136  	metrics := []params.Metric{{Key: "pings", Value: "5", Time: time.Now().UTC()}}
   137  	uuid := utils.MustNewUUID().String()
   138  
   139  	result, err := s.adder.AddMetricBatches(params.MetricBatchParams{
   140  		Batches: []params.MetricBatchParam{{
   141  			Tag: s.meteredUnit.Tag().String(),
   142  			Batch: params.MetricBatch{
   143  				UUID:     uuid,
   144  				CharmURL: s.meteredCharm.URL().String(),
   145  				Created:  time.Now(),
   146  				Metrics:  metrics,
   147  			}}}})
   148  	c.Assert(err, jc.ErrorIsNil)
   149  	c.Assert(result, gc.DeepEquals, params.ErrorResults{
   150  		Results: []params.ErrorResult{{nil}},
   151  	})
   152  
   153  	batches, err := s.State.AllMetricBatches()
   154  	c.Assert(err, jc.ErrorIsNil)
   155  	c.Assert(batches, gc.HasLen, 1)
   156  	batch := batches[0]
   157  	c.Assert(batch.UUID(), gc.Equals, uuid)
   158  	c.Assert(batch.CharmURL(), gc.Equals, s.meteredCharm.URL().String())
   159  	c.Assert(batch.Unit(), gc.Equals, s.meteredUnit.Name())
   160  	storedMetrics := batch.Metrics()
   161  	c.Assert(storedMetrics, gc.HasLen, 1)
   162  	c.Assert(storedMetrics[0].Key, gc.Equals, metrics[0].Key)
   163  	c.Assert(storedMetrics[0].Value, gc.Equals, metrics[0].Value)
   164  }
   165  
   166  func (s *metricsAdderSuite) TestAddMetricsBatchDiffTag(c *gc.C) {
   167  	metrics := []params.Metric{{Key: "pings", Value: "5", Time: time.Now().UTC()}}
   168  	uuid := utils.MustNewUUID().String()
   169  
   170  	tests := []struct {
   171  		about  string
   172  		tag    string
   173  		expect string
   174  	}{{
   175  		about:  "unknown unit",
   176  		tag:    names.NewUnitTag("unknownservice/11").String(),
   177  		expect: "unit \"unknownservice/11\" not found",
   178  	}, {
   179  		about:  "user tag",
   180  		tag:    names.NewLocalUserTag("admin").String(),
   181  		expect: `"user-admin" is not a valid unit tag`,
   182  	}, {
   183  		about:  "machine tag",
   184  		tag:    names.NewMachineTag("0").String(),
   185  		expect: `"machine-0" is not a valid unit tag`,
   186  	}}
   187  
   188  	for i, test := range tests {
   189  		c.Logf("test %d: %s -> %s", i, test.about, test.tag)
   190  		result, err := s.adder.AddMetricBatches(params.MetricBatchParams{
   191  			Batches: []params.MetricBatchParam{{
   192  				Tag: test.tag,
   193  				Batch: params.MetricBatch{
   194  					UUID:     uuid,
   195  					CharmURL: s.meteredCharm.URL().String(),
   196  					Created:  time.Now(),
   197  					Metrics:  metrics,
   198  				}}}})
   199  		c.Assert(err, jc.ErrorIsNil)
   200  		if test.expect == "" {
   201  			c.Assert(result.OneError(), jc.ErrorIsNil)
   202  		} else {
   203  			c.Assert(result.OneError(), gc.ErrorMatches, test.expect)
   204  		}
   205  
   206  		batches, err := s.State.AllMetricBatches()
   207  		c.Assert(err, jc.ErrorIsNil)
   208  		c.Assert(batches, gc.HasLen, 0)
   209  
   210  		_, err = s.State.MetricBatch(uuid)
   211  		c.Assert(err, jc.Satisfies, errors.IsNotFound)
   212  	}
   213  }
   214  
   215  func (s *metricsAdderSuite) TestNewMetricsAdderAPIRefusesNonAgent(c *gc.C) {
   216  	tests := []struct {
   217  		tag           names.Tag
   218  		controller    bool
   219  		expectedError string
   220  	}{
   221  		// TODO(cmars): unit agent should get permission denied when callers are
   222  		// moved to machine agent.
   223  		{names.NewUnitTag("mysql/0"), false, ""},
   224  
   225  		{names.NewLocalUserTag("admin"), true, "permission denied"},
   226  		{names.NewMachineTag("0"), false, ""},
   227  		{names.NewMachineTag("0"), true, ""},
   228  	}
   229  	for i, test := range tests {
   230  		c.Logf("test %d", i)
   231  
   232  		anAuthoriser := s.authorizer
   233  		anAuthoriser.Controller = test.controller
   234  		anAuthoriser.Tag = test.tag
   235  		endPoint, err := metricsadder.NewMetricsAdderAPI(s.State, nil, anAuthoriser)
   236  		if test.expectedError == "" {
   237  			c.Assert(err, jc.ErrorIsNil)
   238  			c.Assert(endPoint, gc.NotNil)
   239  		} else {
   240  			c.Assert(err, gc.ErrorMatches, test.expectedError)
   241  			c.Assert(endPoint, gc.IsNil)
   242  		}
   243  	}
   244  }