github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/apiserver/leadership/leadership_test.go (about) 1 // Copyright 2014-2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package leadership_test 5 6 /* 7 Test that the service is translating incoming parameters to the 8 manager layer correctly, and also translates the results back into 9 network parameters. 10 */ 11 12 import ( 13 "time" 14 15 "github.com/juju/errors" 16 "github.com/juju/testing" 17 jc "github.com/juju/testing/checkers" 18 gc "gopkg.in/check.v1" 19 "gopkg.in/juju/names.v2" 20 21 "github.com/juju/juju/apiserver/facade" 22 "github.com/juju/juju/apiserver/leadership" 23 "github.com/juju/juju/apiserver/params" 24 coreleadership "github.com/juju/juju/core/leadership" 25 ) 26 27 type leadershipSuite struct { 28 testing.IsolationSuite 29 } 30 31 var _ = gc.Suite(&leadershipSuite{}) 32 33 const ( 34 StubServiceNm = "stub-application" 35 StubUnitNm = "stub-application/0" 36 ) 37 38 type stubClaimer struct { 39 ClaimLeadershipFn func(sid, uid string, duration time.Duration) error 40 BlockUntilLeadershipReleasedFn func(serviceId string) error 41 } 42 43 func (m *stubClaimer) ClaimLeadership(sid, uid string, duration time.Duration) error { 44 if m.ClaimLeadershipFn != nil { 45 return m.ClaimLeadershipFn(sid, uid, duration) 46 } 47 return nil 48 } 49 50 func (m *stubClaimer) BlockUntilLeadershipReleased(serviceId string) error { 51 if m.BlockUntilLeadershipReleasedFn != nil { 52 return m.BlockUntilLeadershipReleasedFn(serviceId) 53 } 54 return nil 55 } 56 57 type stubAuthorizer struct { 58 facade.Authorizer 59 tag names.Tag 60 } 61 62 func (m stubAuthorizer) AuthUnitAgent() bool { 63 _, ok := m.tag.(names.UnitTag) 64 return ok 65 } 66 func (m stubAuthorizer) AuthOwner(tag names.Tag) bool { 67 return tag == m.tag 68 } 69 70 func (m stubAuthorizer) GetAuthTag() names.Tag { 71 return m.tag 72 } 73 74 func checkDurationEquals(c *gc.C, actual, expect time.Duration) { 75 delta := actual - expect 76 if delta < 0 { 77 delta = -delta 78 } 79 c.Check(delta, jc.LessThan, time.Microsecond) 80 } 81 82 func newLeadershipService( 83 c *gc.C, claimer coreleadership.Claimer, authorizer facade.Authorizer, 84 ) leadership.LeadershipService { 85 if authorizer == nil { 86 authorizer = stubAuthorizer{tag: names.NewUnitTag(StubUnitNm)} 87 } 88 result, err := leadership.NewLeadershipService(claimer, authorizer) 89 c.Assert(err, jc.ErrorIsNil) 90 return result 91 } 92 93 func (s *leadershipSuite) TestClaimLeadershipTranslation(c *gc.C) { 94 claimer := &stubClaimer{ 95 ClaimLeadershipFn: func(sid, uid string, duration time.Duration) error { 96 c.Check(sid, gc.Equals, StubServiceNm) 97 c.Check(uid, gc.Equals, StubUnitNm) 98 expectDuration := time.Duration(299.9 * float64(time.Second)) 99 checkDurationEquals(c, duration, expectDuration) 100 return nil 101 }, 102 } 103 104 ldrSvc := newLeadershipService(c, claimer, nil) 105 results, err := ldrSvc.ClaimLeadership(params.ClaimLeadershipBulkParams{ 106 Params: []params.ClaimLeadershipParams{ 107 { 108 ApplicationTag: names.NewApplicationTag(StubServiceNm).String(), 109 UnitTag: names.NewUnitTag(StubUnitNm).String(), 110 DurationSeconds: 299.9, 111 }, 112 }, 113 }) 114 115 c.Check(err, jc.ErrorIsNil) 116 c.Assert(results.Results, gc.HasLen, 1) 117 c.Check(results.Results[0].Error, gc.IsNil) 118 } 119 120 func (s *leadershipSuite) TestClaimLeadershipDeniedError(c *gc.C) { 121 claimer := &stubClaimer{ 122 ClaimLeadershipFn: func(sid, uid string, duration time.Duration) error { 123 c.Check(sid, gc.Equals, StubServiceNm) 124 c.Check(uid, gc.Equals, StubUnitNm) 125 expectDuration := time.Duration(5.001 * float64(time.Second)) 126 checkDurationEquals(c, duration, expectDuration) 127 return errors.Annotatef(coreleadership.ErrClaimDenied, "obfuscated") 128 }, 129 } 130 131 ldrSvc := newLeadershipService(c, claimer, nil) 132 results, err := ldrSvc.ClaimLeadership(params.ClaimLeadershipBulkParams{ 133 Params: []params.ClaimLeadershipParams{ 134 { 135 ApplicationTag: names.NewApplicationTag(StubServiceNm).String(), 136 UnitTag: names.NewUnitTag(StubUnitNm).String(), 137 DurationSeconds: 5.001, 138 }, 139 }, 140 }) 141 142 c.Check(err, jc.ErrorIsNil) 143 c.Assert(results.Results, gc.HasLen, 1) 144 c.Check(results.Results[0].Error, jc.Satisfies, params.IsCodeLeadershipClaimDenied) 145 } 146 147 func (s *leadershipSuite) TestClaimLeadershipBadService(c *gc.C) { 148 ldrSvc := newLeadershipService(c, nil, nil) 149 150 results, err := ldrSvc.ClaimLeadership(params.ClaimLeadershipBulkParams{ 151 Params: []params.ClaimLeadershipParams{ 152 { 153 ApplicationTag: "application-bad/0", 154 UnitTag: names.NewUnitTag(StubUnitNm).String(), 155 DurationSeconds: 123.45, 156 }, 157 }, 158 }) 159 c.Check(err, jc.ErrorIsNil) 160 c.Assert(results.Results, gc.HasLen, 1) 161 c.Check(results.Results[0].Error, jc.Satisfies, params.IsCodeUnauthorized) 162 } 163 164 func (s *leadershipSuite) TestClaimLeadershipBadUnit(c *gc.C) { 165 ldrSvc := newLeadershipService(c, nil, nil) 166 167 results, err := ldrSvc.ClaimLeadership(params.ClaimLeadershipBulkParams{ 168 Params: []params.ClaimLeadershipParams{ 169 { 170 ApplicationTag: names.NewApplicationTag(StubServiceNm).String(), 171 UnitTag: "unit-bad", 172 DurationSeconds: 123.45, 173 }, 174 }, 175 }) 176 c.Check(err, jc.ErrorIsNil) 177 c.Assert(results.Results, gc.HasLen, 1) 178 c.Check(results.Results[0].Error, jc.Satisfies, params.IsCodeUnauthorized) 179 } 180 181 func (s *leadershipSuite) TestClaimLeadershipDurationTooShort(c *gc.C) { 182 ldrSvc := newLeadershipService(c, nil, nil) 183 184 results, err := ldrSvc.ClaimLeadership(params.ClaimLeadershipBulkParams{ 185 Params: []params.ClaimLeadershipParams{ 186 { 187 ApplicationTag: names.NewApplicationTag(StubServiceNm).String(), 188 UnitTag: names.NewUnitTag(StubUnitNm).String(), 189 DurationSeconds: 4.99, 190 }, 191 }, 192 }) 193 c.Check(err, jc.ErrorIsNil) 194 c.Assert(results.Results, gc.HasLen, 1) 195 c.Check(results.Results[0].Error, gc.ErrorMatches, "invalid duration") 196 } 197 198 func (s *leadershipSuite) TestClaimLeadershipDurationTooLong(c *gc.C) { 199 ldrSvc := newLeadershipService(c, nil, nil) 200 201 results, err := ldrSvc.ClaimLeadership(params.ClaimLeadershipBulkParams{ 202 Params: []params.ClaimLeadershipParams{ 203 { 204 ApplicationTag: names.NewApplicationTag(StubServiceNm).String(), 205 UnitTag: names.NewUnitTag(StubUnitNm).String(), 206 DurationSeconds: 300.1, 207 }, 208 }, 209 }) 210 c.Check(err, jc.ErrorIsNil) 211 c.Assert(results.Results, gc.HasLen, 1) 212 c.Check(results.Results[0].Error, gc.ErrorMatches, "invalid duration") 213 } 214 215 func (s *leadershipSuite) TestBlockUntilLeadershipReleasedTranslation(c *gc.C) { 216 claimer := &stubClaimer{ 217 BlockUntilLeadershipReleasedFn: func(sid string) error { 218 c.Check(sid, gc.Equals, StubServiceNm) 219 return nil 220 }, 221 } 222 223 ldrSvc := newLeadershipService(c, claimer, nil) 224 result, err := ldrSvc.BlockUntilLeadershipReleased(names.NewApplicationTag(StubServiceNm)) 225 226 c.Check(err, jc.ErrorIsNil) 227 c.Check(result.Error, gc.IsNil) 228 } 229 230 func (s *leadershipSuite) TestClaimLeadershipFailBadUnit(c *gc.C) { 231 authorizer := &stubAuthorizer{ 232 tag: names.NewUnitTag("lol-different/123"), 233 } 234 235 ldrSvc := newLeadershipService(c, nil, authorizer) 236 results, err := ldrSvc.ClaimLeadership(params.ClaimLeadershipBulkParams{ 237 Params: []params.ClaimLeadershipParams{ 238 { 239 ApplicationTag: names.NewApplicationTag(StubServiceNm).String(), 240 UnitTag: names.NewUnitTag(StubUnitNm).String(), 241 DurationSeconds: 123.45, 242 }, 243 }, 244 }) 245 246 c.Check(err, jc.ErrorIsNil) 247 c.Assert(results.Results, gc.HasLen, 1) 248 c.Check(results.Results[0].Error, gc.ErrorMatches, "permission denied") 249 c.Check(results.Results[0].Error, jc.Satisfies, params.IsCodeUnauthorized) 250 } 251 252 func (s *leadershipSuite) TestClaimLeadershipFailBadService(c *gc.C) { 253 ldrSvc := newLeadershipService(c, nil, nil) 254 results, err := ldrSvc.ClaimLeadership(params.ClaimLeadershipBulkParams{ 255 Params: []params.ClaimLeadershipParams{ 256 { 257 ApplicationTag: names.NewApplicationTag("lol-different").String(), 258 UnitTag: names.NewUnitTag(StubUnitNm).String(), 259 DurationSeconds: 123.45, 260 }, 261 }, 262 }) 263 264 c.Check(err, jc.ErrorIsNil) 265 c.Assert(results.Results, gc.HasLen, 1) 266 c.Check(results.Results[0].Error, gc.ErrorMatches, "permission denied") 267 c.Check(results.Results[0].Error, jc.Satisfies, params.IsCodeUnauthorized) 268 } 269 270 func (s *leadershipSuite) TestCreateUnauthorized(c *gc.C) { 271 authorizer := &stubAuthorizer{ 272 tag: names.NewMachineTag("123"), 273 } 274 275 ldrSvc, err := leadership.NewLeadershipService(nil, authorizer) 276 c.Check(ldrSvc, gc.IsNil) 277 c.Check(err, gc.ErrorMatches, "permission denied") 278 c.Check(err, jc.Satisfies, errors.IsUnauthorized) 279 }