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