~ubuntu-branches/ubuntu/trusty/juju-core/trusty-proposed

« back to all changes in this revision

Viewing changes to src/launchpad.net/juju-core/state/apiserver/firewaller/firewaller_test.go

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2014-01-29 11:40:20 UTC
  • mfrom: (23.1.1 trusty-proposed)
  • Revision ID: package-import@ubuntu.com-20140129114020-ejieitm8smtt5vln
Tags: 1.17.1-0ubuntu2
d/tests/local-provider: Don't fail tests if ~/.juju is present as its
created by the juju version command. 

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright 2013 Canonical Ltd.
 
2
// Licensed under the AGPLv3, see LICENCE file for details.
 
3
 
 
4
package firewaller_test
 
5
 
 
6
import (
 
7
        stdtesting "testing"
 
8
 
 
9
        gc "launchpad.net/gocheck"
 
10
 
 
11
        "launchpad.net/juju-core/errors"
 
12
        "launchpad.net/juju-core/instance"
 
13
        "launchpad.net/juju-core/juju/testing"
 
14
        "launchpad.net/juju-core/state"
 
15
        "launchpad.net/juju-core/state/api/params"
 
16
        "launchpad.net/juju-core/state/apiserver/common"
 
17
        commontesting "launchpad.net/juju-core/state/apiserver/common/testing"
 
18
        "launchpad.net/juju-core/state/apiserver/firewaller"
 
19
        apiservertesting "launchpad.net/juju-core/state/apiserver/testing"
 
20
        statetesting "launchpad.net/juju-core/state/testing"
 
21
        coretesting "launchpad.net/juju-core/testing"
 
22
        jc "launchpad.net/juju-core/testing/checkers"
 
23
)
 
24
 
 
25
func Test(t *stdtesting.T) {
 
26
        coretesting.MgoTestPackage(t)
 
27
}
 
28
 
 
29
type firewallerSuite struct {
 
30
        testing.JujuConnSuite
 
31
        *commontesting.EnvironWatcherTest
 
32
 
 
33
        machines []*state.Machine
 
34
        service  *state.Service
 
35
        charm    *state.Charm
 
36
        units    []*state.Unit
 
37
 
 
38
        authorizer apiservertesting.FakeAuthorizer
 
39
        resources  *common.Resources
 
40
        firewaller *firewaller.FirewallerAPI
 
41
}
 
42
 
 
43
var _ = gc.Suite(&firewallerSuite{})
 
44
 
 
45
func (s *firewallerSuite) SetUpTest(c *gc.C) {
 
46
        s.JujuConnSuite.SetUpTest(c)
 
47
 
 
48
        // Reset previous machines and units (if any) and create 3
 
49
        // machines for the tests.
 
50
        s.machines = nil
 
51
        s.units = nil
 
52
        // Note that the specific machine ids allocated are assumed
 
53
        // to be numerically consecutive from zero.
 
54
        for i := 0; i <= 2; i++ {
 
55
                machine, err := s.State.AddMachine("quantal", state.JobHostUnits)
 
56
                c.Check(err, gc.IsNil)
 
57
                s.machines = append(s.machines, machine)
 
58
        }
 
59
        // Create a service and three units for these machines.
 
60
        s.charm = s.AddTestingCharm(c, "wordpress")
 
61
        s.service = s.AddTestingService(c, "wordpress", s.charm)
 
62
        // Add the rest of the units and assign them.
 
63
        for i := 0; i <= 2; i++ {
 
64
                unit, err := s.service.AddUnit()
 
65
                c.Check(err, gc.IsNil)
 
66
                err = unit.AssignToMachine(s.machines[i])
 
67
                c.Check(err, gc.IsNil)
 
68
                s.units = append(s.units, unit)
 
69
        }
 
70
 
 
71
        // Create a FakeAuthorizer so we can check permissions,
 
72
        // set up assuming we logged in as the environment manager.
 
73
        s.authorizer = apiservertesting.FakeAuthorizer{
 
74
                LoggedIn:       true,
 
75
                EnvironManager: true,
 
76
        }
 
77
 
 
78
        // Create the resource registry separately to track invocations to
 
79
        // Register.
 
80
        s.resources = common.NewResources()
 
81
 
 
82
        // Create a firewaller API for the machine.
 
83
        firewallerAPI, err := firewaller.NewFirewallerAPI(
 
84
                s.State,
 
85
                s.resources,
 
86
                s.authorizer,
 
87
        )
 
88
        c.Assert(err, gc.IsNil)
 
89
        s.firewaller = firewallerAPI
 
90
        s.EnvironWatcherTest = commontesting.NewEnvironWatcherTest(s.firewaller, s.State, s.resources, commontesting.HasSecrets)
 
91
}
 
92
 
 
93
func (s *firewallerSuite) TestFirewallerFailsWithNonEnvironManagerUser(c *gc.C) {
 
94
        anAuthorizer := s.authorizer
 
95
        anAuthorizer.MachineAgent = true
 
96
        anAuthorizer.EnvironManager = false
 
97
        aFirewaller, err := firewaller.NewFirewallerAPI(s.State, s.resources, anAuthorizer)
 
98
        c.Assert(err, gc.NotNil)
 
99
        c.Assert(err, gc.ErrorMatches, "permission denied")
 
100
        c.Assert(aFirewaller, gc.IsNil)
 
101
}
 
102
 
 
103
func (s *firewallerSuite) TestLife(c *gc.C) {
 
104
        // Unassign unit 1 from its machine, so we can change its life cycle.
 
105
        err := s.units[1].UnassignFromMachine()
 
106
        c.Assert(err, gc.IsNil)
 
107
 
 
108
        err = s.machines[1].EnsureDead()
 
109
        c.Assert(err, gc.IsNil)
 
110
        s.assertLife(c, 0, state.Alive)
 
111
        s.assertLife(c, 1, state.Dead)
 
112
        s.assertLife(c, 2, state.Alive)
 
113
 
 
114
        args := addFakeEntities(params.Entities{Entities: []params.Entity{
 
115
                {Tag: s.machines[0].Tag()},
 
116
                {Tag: s.machines[1].Tag()},
 
117
                {Tag: s.machines[2].Tag()},
 
118
        }})
 
119
        result, err := s.firewaller.Life(args)
 
120
        c.Assert(err, gc.IsNil)
 
121
        c.Assert(result, jc.DeepEquals, params.LifeResults{
 
122
                Results: []params.LifeResult{
 
123
                        {Life: "alive"},
 
124
                        {Life: "dead"},
 
125
                        {Life: "alive"},
 
126
                        {Error: apiservertesting.NotFoundError("machine 42")},
 
127
                        {Error: apiservertesting.NotFoundError(`unit "foo/0"`)},
 
128
                        {Error: apiservertesting.NotFoundError(`service "bar"`)},
 
129
                        {Error: apiservertesting.ErrUnauthorized},
 
130
                        {Error: apiservertesting.ErrUnauthorized},
 
131
                        {Error: apiservertesting.ErrUnauthorized},
 
132
                },
 
133
        })
 
134
 
 
135
        // Remove a machine and make sure it's detected.
 
136
        err = s.machines[1].Remove()
 
137
        c.Assert(err, gc.IsNil)
 
138
        err = s.machines[1].Refresh()
 
139
        c.Assert(err, jc.Satisfies, errors.IsNotFoundError)
 
140
 
 
141
        args = params.Entities{
 
142
                Entities: []params.Entity{
 
143
                        {Tag: s.machines[1].Tag()},
 
144
                },
 
145
        }
 
146
        result, err = s.firewaller.Life(args)
 
147
        c.Assert(err, gc.IsNil)
 
148
        c.Assert(result, jc.DeepEquals, params.LifeResults{
 
149
                Results: []params.LifeResult{
 
150
                        {Error: apiservertesting.NotFoundError("machine 1")},
 
151
                },
 
152
        })
 
153
}
 
154
 
 
155
func (s *firewallerSuite) TestInstanceId(c *gc.C) {
 
156
        // Provision 2 machines first.
 
157
        err := s.machines[0].SetProvisioned("i-am", "fake_nonce", nil)
 
158
        c.Assert(err, gc.IsNil)
 
159
        hwChars := instance.MustParseHardware("arch=i386", "mem=4G")
 
160
        err = s.machines[1].SetProvisioned("i-am-not", "fake_nonce", &hwChars)
 
161
        c.Assert(err, gc.IsNil)
 
162
 
 
163
        args := addFakeEntities(params.Entities{Entities: []params.Entity{
 
164
                {Tag: s.machines[0].Tag()},
 
165
                {Tag: s.machines[1].Tag()},
 
166
                {Tag: s.machines[2].Tag()},
 
167
                {Tag: s.service.Tag()},
 
168
                {Tag: s.units[2].Tag()},
 
169
        }})
 
170
        result, err := s.firewaller.InstanceId(args)
 
171
        c.Assert(err, gc.IsNil)
 
172
        c.Assert(result, jc.DeepEquals, params.StringResults{
 
173
                Results: []params.StringResult{
 
174
                        {Result: "i-am"},
 
175
                        {Result: "i-am-not"},
 
176
                        {Error: apiservertesting.NotProvisionedError("2")},
 
177
                        {Error: apiservertesting.ErrUnauthorized},
 
178
                        {Error: apiservertesting.ErrUnauthorized},
 
179
                        {Error: apiservertesting.NotFoundError("machine 42")},
 
180
                        {Error: apiservertesting.ErrUnauthorized},
 
181
                        {Error: apiservertesting.ErrUnauthorized},
 
182
                        {Error: apiservertesting.ErrUnauthorized},
 
183
                        {Error: apiservertesting.ErrUnauthorized},
 
184
                        {Error: apiservertesting.ErrUnauthorized},
 
185
                },
 
186
        })
 
187
}
 
188
 
 
189
func (s *firewallerSuite) TestWatchEnvironMachines(c *gc.C) {
 
190
        c.Assert(s.resources.Count(), gc.Equals, 0)
 
191
 
 
192
        result, err := s.firewaller.WatchEnvironMachines()
 
193
        c.Assert(err, gc.IsNil)
 
194
        c.Assert(result, jc.DeepEquals, params.StringsWatchResult{
 
195
                StringsWatcherId: "1",
 
196
                Changes:          []string{"0", "1", "2"},
 
197
        })
 
198
 
 
199
        // Verify the resources were registered and stop them when done.
 
200
        c.Assert(s.resources.Count(), gc.Equals, 1)
 
201
        resource := s.resources.Get("1")
 
202
        defer statetesting.AssertStop(c, resource)
 
203
 
 
204
        // Check that the Watch has consumed the initial event ("returned"
 
205
        // in the Watch call)
 
206
        wc := statetesting.NewStringsWatcherC(c, s.State, resource.(state.StringsWatcher))
 
207
        wc.AssertNoChange()
 
208
}
 
209
 
 
210
func (s *firewallerSuite) TestWatch(c *gc.C) {
 
211
        c.Assert(s.resources.Count(), gc.Equals, 0)
 
212
 
 
213
        args := addFakeEntities(params.Entities{Entities: []params.Entity{
 
214
                {Tag: s.machines[0].Tag()},
 
215
                {Tag: s.service.Tag()},
 
216
                {Tag: s.units[0].Tag()},
 
217
        }})
 
218
        result, err := s.firewaller.Watch(args)
 
219
        c.Assert(err, gc.IsNil)
 
220
        c.Assert(result, jc.DeepEquals, params.NotifyWatchResults{
 
221
                Results: []params.NotifyWatchResult{
 
222
                        {Error: apiservertesting.ErrUnauthorized},
 
223
                        {NotifyWatcherId: "1"},
 
224
                        {NotifyWatcherId: "2"},
 
225
                        {Error: apiservertesting.ErrUnauthorized},
 
226
                        {Error: apiservertesting.NotFoundError(`unit "foo/0"`)},
 
227
                        {Error: apiservertesting.NotFoundError(`service "bar"`)},
 
228
                        {Error: apiservertesting.ErrUnauthorized},
 
229
                        {Error: apiservertesting.ErrUnauthorized},
 
230
                        {Error: apiservertesting.ErrUnauthorized},
 
231
                },
 
232
        })
 
233
 
 
234
        // Verify the resources were registered and stop when done.
 
235
        c.Assert(s.resources.Count(), gc.Equals, 2)
 
236
        c.Assert(result.Results[1].NotifyWatcherId, gc.Equals, "1")
 
237
        watcher1 := s.resources.Get("1")
 
238
        defer statetesting.AssertStop(c, watcher1)
 
239
        c.Assert(result.Results[2].NotifyWatcherId, gc.Equals, "2")
 
240
        watcher2 := s.resources.Get("2")
 
241
        defer statetesting.AssertStop(c, watcher2)
 
242
 
 
243
        // Check that the Watch has consumed the initial event ("returned" in
 
244
        // the Watch call)
 
245
        wc1 := statetesting.NewNotifyWatcherC(c, s.State, watcher1.(state.NotifyWatcher))
 
246
        wc1.AssertNoChange()
 
247
        wc2 := statetesting.NewNotifyWatcherC(c, s.State, watcher2.(state.NotifyWatcher))
 
248
        wc2.AssertNoChange()
 
249
}
 
250
 
 
251
func (s *firewallerSuite) TestWatchUnits(c *gc.C) {
 
252
        c.Assert(s.resources.Count(), gc.Equals, 0)
 
253
 
 
254
        args := addFakeEntities(params.Entities{Entities: []params.Entity{
 
255
                {Tag: s.machines[0].Tag()},
 
256
                {Tag: s.service.Tag()},
 
257
                {Tag: s.units[0].Tag()},
 
258
        }})
 
259
        result, err := s.firewaller.WatchUnits(args)
 
260
        c.Assert(err, gc.IsNil)
 
261
        c.Assert(result, jc.DeepEquals, params.StringsWatchResults{
 
262
                Results: []params.StringsWatchResult{
 
263
                        {Changes: []string{"wordpress/0"}, StringsWatcherId: "1"},
 
264
                        {Error: apiservertesting.ErrUnauthorized},
 
265
                        {Error: apiservertesting.ErrUnauthorized},
 
266
                        {Error: apiservertesting.NotFoundError("machine 42")},
 
267
                        {Error: apiservertesting.ErrUnauthorized},
 
268
                        {Error: apiservertesting.ErrUnauthorized},
 
269
                        {Error: apiservertesting.ErrUnauthorized},
 
270
                        {Error: apiservertesting.ErrUnauthorized},
 
271
                        {Error: apiservertesting.ErrUnauthorized},
 
272
                },
 
273
        })
 
274
 
 
275
        // Verify the resource was registered and stop when done
 
276
        c.Assert(s.resources.Count(), gc.Equals, 1)
 
277
        c.Assert(result.Results[0].StringsWatcherId, gc.Equals, "1")
 
278
        resource := s.resources.Get("1")
 
279
        defer statetesting.AssertStop(c, resource)
 
280
 
 
281
        // Check that the Watch has consumed the initial event ("returned" in
 
282
        // the Watch call)
 
283
        wc := statetesting.NewStringsWatcherC(c, s.State, resource.(state.StringsWatcher))
 
284
        wc.AssertNoChange()
 
285
}
 
286
 
 
287
func (s *firewallerSuite) TestGetExposed(c *gc.C) {
 
288
        // Set the service to exposed first.
 
289
        err := s.service.SetExposed()
 
290
        c.Assert(err, gc.IsNil)
 
291
 
 
292
        args := addFakeEntities(params.Entities{Entities: []params.Entity{
 
293
                {Tag: s.service.Tag()},
 
294
        }})
 
295
        result, err := s.firewaller.GetExposed(args)
 
296
        c.Assert(err, gc.IsNil)
 
297
        c.Assert(result, jc.DeepEquals, params.BoolResults{
 
298
                Results: []params.BoolResult{
 
299
                        {Result: true},
 
300
                        {Error: apiservertesting.ErrUnauthorized},
 
301
                        {Error: apiservertesting.ErrUnauthorized},
 
302
                        {Error: apiservertesting.NotFoundError(`service "bar"`)},
 
303
                        {Error: apiservertesting.ErrUnauthorized},
 
304
                        {Error: apiservertesting.ErrUnauthorized},
 
305
                        {Error: apiservertesting.ErrUnauthorized},
 
306
                },
 
307
        })
 
308
 
 
309
        // Now reset the exposed flag for the service and check again.
 
310
        err = s.service.ClearExposed()
 
311
        c.Assert(err, gc.IsNil)
 
312
 
 
313
        args = params.Entities{Entities: []params.Entity{
 
314
                {Tag: s.service.Tag()},
 
315
        }}
 
316
        result, err = s.firewaller.GetExposed(args)
 
317
        c.Assert(err, gc.IsNil)
 
318
        c.Assert(result, jc.DeepEquals, params.BoolResults{
 
319
                Results: []params.BoolResult{
 
320
                        {Result: false},
 
321
                },
 
322
        })
 
323
}
 
324
 
 
325
func (s *firewallerSuite) TestOpenedPorts(c *gc.C) {
 
326
        // Open some ports on two of the units.
 
327
        err := s.units[0].OpenPort("foo", 1234)
 
328
        c.Assert(err, gc.IsNil)
 
329
        err = s.units[0].OpenPort("bar", 4321)
 
330
        c.Assert(err, gc.IsNil)
 
331
        err = s.units[2].OpenPort("baz", 1111)
 
332
        c.Assert(err, gc.IsNil)
 
333
 
 
334
        args := addFakeEntities(params.Entities{Entities: []params.Entity{
 
335
                {Tag: s.units[0].Tag()},
 
336
                {Tag: s.units[1].Tag()},
 
337
                {Tag: s.units[2].Tag()},
 
338
        }})
 
339
        result, err := s.firewaller.OpenedPorts(args)
 
340
        c.Assert(err, gc.IsNil)
 
341
        c.Assert(result, jc.DeepEquals, params.PortsResults{
 
342
                Results: []params.PortsResult{
 
343
                        {Ports: []instance.Port{{"bar", 4321}, {"foo", 1234}}},
 
344
                        {Ports: []instance.Port{}},
 
345
                        {Ports: []instance.Port{{"baz", 1111}}},
 
346
                        {Error: apiservertesting.ErrUnauthorized},
 
347
                        {Error: apiservertesting.NotFoundError(`unit "foo/0"`)},
 
348
                        {Error: apiservertesting.ErrUnauthorized},
 
349
                        {Error: apiservertesting.ErrUnauthorized},
 
350
                        {Error: apiservertesting.ErrUnauthorized},
 
351
                        {Error: apiservertesting.ErrUnauthorized},
 
352
                },
 
353
        })
 
354
 
 
355
        // Now close unit 2's port and check again.
 
356
        err = s.units[2].ClosePort("baz", 1111)
 
357
        c.Assert(err, gc.IsNil)
 
358
 
 
359
        args = params.Entities{Entities: []params.Entity{
 
360
                {Tag: s.units[2].Tag()},
 
361
        }}
 
362
        result, err = s.firewaller.OpenedPorts(args)
 
363
        c.Assert(err, gc.IsNil)
 
364
        c.Assert(result, jc.DeepEquals, params.PortsResults{
 
365
                Results: []params.PortsResult{
 
366
                        {Ports: []instance.Port{}},
 
367
                },
 
368
        })
 
369
}
 
370
 
 
371
func (s *firewallerSuite) TestGetAssignedMachine(c *gc.C) {
 
372
        // Unassign a unit first.
 
373
        err := s.units[2].UnassignFromMachine()
 
374
        c.Assert(err, gc.IsNil)
 
375
 
 
376
        args := addFakeEntities(params.Entities{Entities: []params.Entity{
 
377
                {Tag: s.units[0].Tag()},
 
378
                {Tag: s.units[1].Tag()},
 
379
                {Tag: s.units[2].Tag()},
 
380
        }})
 
381
        result, err := s.firewaller.GetAssignedMachine(args)
 
382
        c.Assert(err, gc.IsNil)
 
383
        c.Assert(result, jc.DeepEquals, params.StringResults{
 
384
                Results: []params.StringResult{
 
385
                        {Result: s.machines[0].Tag()},
 
386
                        {Result: s.machines[1].Tag()},
 
387
                        {Error: apiservertesting.NotAssignedError("wordpress/2")},
 
388
                        {Error: apiservertesting.ErrUnauthorized},
 
389
                        {Error: apiservertesting.NotFoundError(`unit "foo/0"`)},
 
390
                        {Error: apiservertesting.ErrUnauthorized},
 
391
                        {Error: apiservertesting.ErrUnauthorized},
 
392
                        {Error: apiservertesting.ErrUnauthorized},
 
393
                        {Error: apiservertesting.ErrUnauthorized},
 
394
                },
 
395
        })
 
396
 
 
397
        // Now reset assign unit 2 again and check.
 
398
        err = s.units[2].AssignToMachine(s.machines[0])
 
399
        c.Assert(err, gc.IsNil)
 
400
 
 
401
        args = params.Entities{Entities: []params.Entity{
 
402
                {Tag: s.units[2].Tag()},
 
403
        }}
 
404
        result, err = s.firewaller.GetAssignedMachine(args)
 
405
        c.Assert(err, gc.IsNil)
 
406
        c.Assert(result, jc.DeepEquals, params.StringResults{
 
407
                Results: []params.StringResult{
 
408
                        {Result: s.machines[0].Tag()},
 
409
                },
 
410
        })
 
411
}
 
412
 
 
413
func (s *firewallerSuite) assertLife(c *gc.C, index int, expectLife state.Life) {
 
414
        err := s.machines[index].Refresh()
 
415
        c.Assert(err, gc.IsNil)
 
416
        c.Assert(s.machines[index].Life(), gc.Equals, expectLife)
 
417
}
 
418
 
 
419
var commonFakeEntities = []params.Entity{
 
420
        {Tag: "machine-42"},
 
421
        {Tag: "unit-foo-0"},
 
422
        {Tag: "service-bar"},
 
423
        {Tag: "user-foo"},
 
424
        {Tag: "foo-bar"},
 
425
        {Tag: ""},
 
426
}
 
427
 
 
428
func addFakeEntities(actual params.Entities) params.Entities {
 
429
        for _, entity := range commonFakeEntities {
 
430
                actual.Entities = append(actual.Entities, entity)
 
431
        }
 
432
        return actual
 
433
}