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 }