1
// Copyright 2014-2015 Canonical Ltd.
2
// Licensed under the AGPLv3, see LICENCE file for details.
4
package leadership_test
7
Test that the service is translating incoming parameters to the
8
manager layer correctly, and also translates the results back into
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"
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"
27
type leadershipSuite struct {
28
testing.IsolationSuite
31
var _ = gc.Suite(&leadershipSuite{})
34
StubServiceNm = "stub-application"
35
StubUnitNm = "stub-application/0"
38
type stubClaimer struct {
39
ClaimLeadershipFn func(sid, uid string, duration time.Duration) error
40
BlockUntilLeadershipReleasedFn func(serviceId string) error
43
func (m *stubClaimer) ClaimLeadership(sid, uid string, duration time.Duration) error {
44
if m.ClaimLeadershipFn != nil {
45
return m.ClaimLeadershipFn(sid, uid, duration)
50
func (m *stubClaimer) BlockUntilLeadershipReleased(serviceId string) error {
51
if m.BlockUntilLeadershipReleasedFn != nil {
52
return m.BlockUntilLeadershipReleasedFn(serviceId)
57
type stubAuthorizer struct {
62
func (m stubAuthorizer) AuthUnitAgent() bool {
63
_, ok := m.tag.(names.UnitTag)
66
func (m stubAuthorizer) AuthOwner(tag names.Tag) bool {
70
func (m stubAuthorizer) GetAuthTag() names.Tag {
74
func checkDurationEquals(c *gc.C, actual, expect time.Duration) {
75
delta := actual - expect
79
c.Check(delta, jc.LessThan, time.Microsecond)
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)}
88
result, err := leadership.NewLeadershipService(claimer, authorizer)
89
c.Assert(err, jc.ErrorIsNil)
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)
104
ldrSvc := newLeadershipService(c, claimer, nil)
105
results, err := ldrSvc.ClaimLeadership(params.ClaimLeadershipBulkParams{
106
Params: []params.ClaimLeadershipParams{
108
ApplicationTag: names.NewApplicationTag(StubServiceNm).String(),
109
UnitTag: names.NewUnitTag(StubUnitNm).String(),
110
DurationSeconds: 299.9,
115
c.Check(err, jc.ErrorIsNil)
116
c.Assert(results.Results, gc.HasLen, 1)
117
c.Check(results.Results[0].Error, gc.IsNil)
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")
131
ldrSvc := newLeadershipService(c, claimer, nil)
132
results, err := ldrSvc.ClaimLeadership(params.ClaimLeadershipBulkParams{
133
Params: []params.ClaimLeadershipParams{
135
ApplicationTag: names.NewApplicationTag(StubServiceNm).String(),
136
UnitTag: names.NewUnitTag(StubUnitNm).String(),
137
DurationSeconds: 5.001,
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)
147
func (s *leadershipSuite) TestClaimLeadershipBadService(c *gc.C) {
148
ldrSvc := newLeadershipService(c, nil, nil)
150
results, err := ldrSvc.ClaimLeadership(params.ClaimLeadershipBulkParams{
151
Params: []params.ClaimLeadershipParams{
153
ApplicationTag: "application-bad/0",
154
UnitTag: names.NewUnitTag(StubUnitNm).String(),
155
DurationSeconds: 123.45,
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)
164
func (s *leadershipSuite) TestClaimLeadershipBadUnit(c *gc.C) {
165
ldrSvc := newLeadershipService(c, nil, nil)
167
results, err := ldrSvc.ClaimLeadership(params.ClaimLeadershipBulkParams{
168
Params: []params.ClaimLeadershipParams{
170
ApplicationTag: names.NewApplicationTag(StubServiceNm).String(),
172
DurationSeconds: 123.45,
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)
181
func (s *leadershipSuite) TestClaimLeadershipDurationTooShort(c *gc.C) {
182
ldrSvc := newLeadershipService(c, nil, nil)
184
results, err := ldrSvc.ClaimLeadership(params.ClaimLeadershipBulkParams{
185
Params: []params.ClaimLeadershipParams{
187
ApplicationTag: names.NewApplicationTag(StubServiceNm).String(),
188
UnitTag: names.NewUnitTag(StubUnitNm).String(),
189
DurationSeconds: 4.99,
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")
198
func (s *leadershipSuite) TestClaimLeadershipDurationTooLong(c *gc.C) {
199
ldrSvc := newLeadershipService(c, nil, nil)
201
results, err := ldrSvc.ClaimLeadership(params.ClaimLeadershipBulkParams{
202
Params: []params.ClaimLeadershipParams{
204
ApplicationTag: names.NewApplicationTag(StubServiceNm).String(),
205
UnitTag: names.NewUnitTag(StubUnitNm).String(),
206
DurationSeconds: 300.1,
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")
215
func (s *leadershipSuite) TestBlockUntilLeadershipReleasedTranslation(c *gc.C) {
216
claimer := &stubClaimer{
217
BlockUntilLeadershipReleasedFn: func(sid string) error {
218
c.Check(sid, gc.Equals, StubServiceNm)
223
ldrSvc := newLeadershipService(c, claimer, nil)
224
result, err := ldrSvc.BlockUntilLeadershipReleased(names.NewApplicationTag(StubServiceNm))
226
c.Check(err, jc.ErrorIsNil)
227
c.Check(result.Error, gc.IsNil)
230
func (s *leadershipSuite) TestClaimLeadershipFailBadUnit(c *gc.C) {
231
authorizer := &stubAuthorizer{
232
tag: names.NewUnitTag("lol-different/123"),
235
ldrSvc := newLeadershipService(c, nil, authorizer)
236
results, err := ldrSvc.ClaimLeadership(params.ClaimLeadershipBulkParams{
237
Params: []params.ClaimLeadershipParams{
239
ApplicationTag: names.NewApplicationTag(StubServiceNm).String(),
240
UnitTag: names.NewUnitTag(StubUnitNm).String(),
241
DurationSeconds: 123.45,
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)
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{
257
ApplicationTag: names.NewApplicationTag("lol-different").String(),
258
UnitTag: names.NewUnitTag(StubUnitNm).String(),
259
DurationSeconds: 123.45,
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)
270
func (s *leadershipSuite) TestCreateUnauthorized(c *gc.C) {
271
authorizer := &stubAuthorizer{
272
tag: names.NewMachineTag("123"),
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)