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

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package meterstatus_test
     5  
     6  import (
     7  	"github.com/golang/mock/gomock"
     8  	jc "github.com/juju/testing/checkers"
     9  	gc "gopkg.in/check.v1"
    10  	names "gopkg.in/juju/names.v2"
    11  
    12  	"github.com/juju/juju/apiserver/common"
    13  	facademocks "github.com/juju/juju/apiserver/facade/mocks"
    14  	"github.com/juju/juju/apiserver/facades/agent/meterstatus"
    15  	"github.com/juju/juju/apiserver/facades/agent/meterstatus/mocks"
    16  	meterstatustesting "github.com/juju/juju/apiserver/facades/agent/meterstatus/testing"
    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(&meterStatusSuite{})
    25  
    26  type meterStatusSuite struct {
    27  	jujutesting.JujuConnSuite
    28  
    29  	authorizer apiservertesting.FakeAuthorizer
    30  	resources  *common.Resources
    31  
    32  	unit *state.Unit
    33  
    34  	status meterstatus.MeterStatus
    35  }
    36  
    37  func (s *meterStatusSuite) SetUpTest(c *gc.C) {
    38  	s.JujuConnSuite.SetUpTest(c)
    39  	s.unit = s.Factory.MakeUnit(c, nil)
    40  
    41  	// Create a FakeAuthorizer so we can check permissions,
    42  	// set up assuming unit 0 has logged in.
    43  	s.authorizer = apiservertesting.FakeAuthorizer{
    44  		Tag: s.unit.UnitTag(),
    45  	}
    46  
    47  	// Create the resource registry separately to track invocations to
    48  	// Register.
    49  	s.resources = common.NewResources()
    50  	s.AddCleanup(func(_ *gc.C) { s.resources.StopAll() })
    51  
    52  	status, err := meterstatus.NewMeterStatusAPI(s.State, s.resources, s.authorizer)
    53  	c.Assert(err, jc.ErrorIsNil)
    54  	s.status = status
    55  }
    56  
    57  func (s *meterStatusSuite) TestGetMeterStatusUnauthenticated(c *gc.C) {
    58  	application, err := s.unit.Application()
    59  	c.Assert(err, jc.ErrorIsNil)
    60  	otherunit := s.Factory.MakeUnit(c, &jujufactory.UnitParams{Application: application})
    61  	args := params.Entities{Entities: []params.Entity{{otherunit.Tag().String()}}}
    62  	result, err := s.status.GetMeterStatus(args)
    63  	c.Assert(err, jc.ErrorIsNil)
    64  	c.Assert(result.Results, gc.HasLen, 1)
    65  	c.Assert(result.Results[0].Error, gc.ErrorMatches, "permission denied")
    66  	c.Assert(result.Results[0].Code, gc.Equals, "")
    67  	c.Assert(result.Results[0].Info, gc.Equals, "")
    68  }
    69  
    70  func (s *meterStatusSuite) TestGetMeterStatusBadTag(c *gc.C) {
    71  	tags := []string{
    72  		"user-admin",
    73  		"unit-nosuchunit",
    74  		"thisisnotatag",
    75  		"machine-0",
    76  		"model-blah",
    77  	}
    78  	args := params.Entities{Entities: make([]params.Entity, len(tags))}
    79  	for i, tag := range tags {
    80  		args.Entities[i] = params.Entity{Tag: tag}
    81  	}
    82  	result, err := s.status.GetMeterStatus(args)
    83  	c.Assert(err, jc.ErrorIsNil)
    84  	c.Assert(result.Results, gc.HasLen, len(tags))
    85  	for i, result := range result.Results {
    86  		c.Logf("checking result %d", i)
    87  		c.Assert(result.Code, gc.Equals, "")
    88  		c.Assert(result.Info, gc.Equals, "")
    89  		c.Assert(result.Error, gc.ErrorMatches, "permission denied")
    90  	}
    91  }
    92  
    93  func (s *meterStatusSuite) TestGetMeterStatus(c *gc.C) {
    94  	meterstatustesting.TestGetMeterStatus(c, s.status, s.unit)
    95  }
    96  
    97  func (s *meterStatusSuite) TestWatchMeterStatus(c *gc.C) {
    98  	status, ctrl := s.setupMeterStatusAPI(c, func(mocks meterStatusAPIMocks) {
    99  		aExp := mocks.authorizer.EXPECT()
   100  		sExp := mocks.state.EXPECT()
   101  		rExp := mocks.resources.EXPECT()
   102  
   103  		tag := s.unit.UnitTag()
   104  		aExp.GetAuthTag().Return(tag)
   105  
   106  		aExp.AuthOwner(tag).Return(true)
   107  		sExp.Unit(tag.Id()).Return(s.unit, nil)
   108  		rExp.Register(gomock.Any()).Return("1")
   109  
   110  		aExp.AuthOwner(names.NewUnitTag("foo/42")).Return(false)
   111  	})
   112  	defer ctrl.Finish()
   113  
   114  	args := params.Entities{Entities: []params.Entity{
   115  		{Tag: s.unit.UnitTag().String()},
   116  		{Tag: "unit-foo-42"},
   117  	}}
   118  	result, err := status.WatchMeterStatus(args)
   119  	c.Assert(err, jc.ErrorIsNil)
   120  	c.Assert(result, gc.DeepEquals, params.NotifyWatchResults{
   121  		Results: []params.NotifyWatchResult{
   122  			{NotifyWatcherId: "1"},
   123  			{Error: apiservertesting.ErrUnauthorized},
   124  		},
   125  	})
   126  }
   127  
   128  func (s *meterStatusSuite) TestWatchMeterStatusWithStateChange(c *gc.C) {
   129  	status, ctrl := s.setupMeterStatusAPI(c, func(mocks meterStatusAPIMocks) {
   130  		aExp := mocks.authorizer.EXPECT()
   131  		sExp := mocks.state.EXPECT()
   132  		rExp := mocks.resources.EXPECT()
   133  
   134  		tag := s.unit.UnitTag()
   135  		aExp.GetAuthTag().Return(tag)
   136  
   137  		aExp.AuthOwner(tag).Return(true)
   138  		sExp.Unit(tag.Id()).Return(s.unit, nil)
   139  		rExp.Register(gomock.Any()).Return("1")
   140  	})
   141  	defer ctrl.Finish()
   142  
   143  	args := params.Entities{Entities: []params.Entity{
   144  		{Tag: s.unit.UnitTag().String()},
   145  	}}
   146  	result, err := status.WatchMeterStatus(args)
   147  	c.Assert(err, jc.ErrorIsNil)
   148  	c.Assert(result, gc.DeepEquals, params.NotifyWatchResults{
   149  		Results: []params.NotifyWatchResult{
   150  			{NotifyWatcherId: "1"},
   151  		},
   152  	})
   153  }
   154  
   155  func (s *meterStatusSuite) TestWatchMeterStatusWithApplicationTag(c *gc.C) {
   156  	app, err := s.unit.Application()
   157  	c.Assert(err, jc.ErrorIsNil)
   158  
   159  	units, err := app.AllUnits()
   160  	c.Assert(err, jc.ErrorIsNil)
   161  
   162  	unit := units[0]
   163  
   164  	status, ctrl := s.setupMeterStatusAPI(c, func(mocks meterStatusAPIMocks) {
   165  		aExp := mocks.authorizer.EXPECT()
   166  		sExp := mocks.state.EXPECT()
   167  		rExp := mocks.resources.EXPECT()
   168  
   169  		tag := names.ApplicationTag{
   170  			Name: "mysql",
   171  		}
   172  		aExp.GetAuthTag().Return(tag)
   173  
   174  		sExp.Application(tag.Name).Return(app, nil)
   175  		sExp.Unit(unit.Tag().Id()).Return(unit, nil)
   176  		rExp.Register(gomock.Any()).Return("1")
   177  	})
   178  	defer ctrl.Finish()
   179  
   180  	args := params.Entities{Entities: []params.Entity{
   181  		{Tag: unit.UnitTag().String()},
   182  	}}
   183  	result, err := status.WatchMeterStatus(args)
   184  	c.Assert(err, jc.ErrorIsNil)
   185  	c.Assert(result, gc.DeepEquals, params.NotifyWatchResults{
   186  		Results: []params.NotifyWatchResult{
   187  			{NotifyWatcherId: "1"},
   188  		},
   189  	})
   190  }
   191  
   192  type meterStatusAPIMocks struct {
   193  	state      *mocks.MockMeterStatusState
   194  	resources  *facademocks.MockResources
   195  	authorizer *facademocks.MockAuthorizer
   196  }
   197  
   198  func (s *meterStatusSuite) setupMeterStatusAPI(c *gc.C, fn func(meterStatusAPIMocks)) (*meterstatus.MeterStatusAPI, *gomock.Controller) {
   199  	ctrl := gomock.NewController(c)
   200  
   201  	mockState := mocks.NewMockMeterStatusState(ctrl)
   202  	mockResources := facademocks.NewMockResources(ctrl)
   203  	mockAuthorizer := facademocks.NewMockAuthorizer(ctrl)
   204  
   205  	mockAuthorizer.EXPECT().AuthUnitAgent().Return(true)
   206  
   207  	status, err := meterstatus.NewMeterStatusAPI(mockState, mockResources, mockAuthorizer)
   208  	c.Assert(err, jc.ErrorIsNil)
   209  
   210  	fn(meterStatusAPIMocks{
   211  		state:      mockState,
   212  		resources:  mockResources,
   213  		authorizer: mockAuthorizer,
   214  	})
   215  
   216  	return status, ctrl
   217  }