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

« back to all changes in this revision

Viewing changes to src/launchpad.net/juju-core/worker/instancepoller/updater_test.go

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2014-02-03 09:22:46 UTC
  • mfrom: (1.1.17)
  • Revision ID: package-import@ubuntu.com-20140203092246-e03vg402vztzo4qa
Tags: 1.17.2-0ubuntu1
New upstream release.

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
// TODO(wallyworld) - move to instancepoller_test
 
5
package instancepoller
 
6
 
 
7
import (
 
8
        "errors"
 
9
        stdtesting "testing"
 
10
        "time"
 
11
 
 
12
        gc "launchpad.net/gocheck"
 
13
 
 
14
        "launchpad.net/juju-core/state"
 
15
        coretesting "launchpad.net/juju-core/testing"
 
16
        jc "launchpad.net/juju-core/testing/checkers"
 
17
        "launchpad.net/juju-core/testing/testbase"
 
18
)
 
19
 
 
20
func TestPackage(t *stdtesting.T) {
 
21
        coretesting.MgoTestPackage(t)
 
22
}
 
23
 
 
24
var _ = gc.Suite(&updaterSuite{})
 
25
 
 
26
type updaterSuite struct {
 
27
        testbase.LoggingSuite
 
28
}
 
29
 
 
30
func (*updaterSuite) TestStopsWatcher(c *gc.C) {
 
31
        context := &testUpdaterContext{
 
32
                dyingc: make(chan struct{}),
 
33
        }
 
34
        expectErr := errors.New("some error")
 
35
        watcher := &testMachinesWatcher{
 
36
                changes: make(chan []string),
 
37
                err:     expectErr,
 
38
        }
 
39
        done := make(chan error)
 
40
        go func() {
 
41
                done <- watchMachinesLoop(context, watcher)
 
42
        }()
 
43
        close(context.dyingc)
 
44
        select {
 
45
        case err := <-done:
 
46
                c.Assert(err, gc.ErrorMatches, ".*"+expectErr.Error())
 
47
        case <-time.After(coretesting.LongWait):
 
48
                c.Fatalf("timed out waiting for watchMachinesLoop to terminate")
 
49
        }
 
50
        c.Assert(watcher.stopped, jc.IsTrue)
 
51
}
 
52
 
 
53
func (*updaterSuite) TestWatchMachinesWaitsForMachinePollers(c *gc.C) {
 
54
        // We can't see that the machine pollers are still alive directly,
 
55
        // but we can make the machine's Refresh method block,
 
56
        // and test that watchMachinesLoop only terminates
 
57
        // when it unblocks.
 
58
        waitRefresh := make(chan struct{})
 
59
        m := &testMachine{
 
60
                id:         "99",
 
61
                instanceId: "i1234",
 
62
                life:       state.Alive,
 
63
                refresh: func() error {
 
64
                        // Signal that we're in Refresh.
 
65
                        waitRefresh <- struct{}{}
 
66
                        // Wait to be unblocked.
 
67
                        <-waitRefresh
 
68
                        return nil
 
69
                },
 
70
        }
 
71
        dyingc := make(chan struct{})
 
72
        context := &testUpdaterContext{
 
73
                dyingc: dyingc,
 
74
                newMachineContextFunc: func() machineContext {
 
75
                        return &testMachineContext{
 
76
                                getInstanceInfo: instanceInfoGetter(c, "i1234", testAddrs, "running", nil),
 
77
                                dyingc:          dyingc,
 
78
                        }
 
79
                },
 
80
                getMachineFunc: func(id string) (machine, error) {
 
81
                        c.Check(id, gc.Equals, m.id)
 
82
                        return m, nil
 
83
                },
 
84
        }
 
85
        watcher := &testMachinesWatcher{
 
86
                changes: make(chan []string),
 
87
        }
 
88
        done := make(chan error)
 
89
        go func() {
 
90
                done <- watchMachinesLoop(context, watcher)
 
91
        }()
 
92
        // Send two changes; the first one should start the machineLoop;
 
93
        // the second should call Refresh.
 
94
        watcher.changes <- []string{"99"}
 
95
        watcher.changes <- []string{"99"}
 
96
        // Wait for the machineLoop to call Refresh
 
97
        select {
 
98
        case <-waitRefresh:
 
99
                c.Logf("poller called Refresh")
 
100
        case <-time.After(coretesting.LongWait):
 
101
                c.Fatalf("timed out waiting for machine to be refreshed")
 
102
        }
 
103
        close(context.dyingc)
 
104
        // Wait a little while to be sure that watchMachinesLoop is
 
105
        // actually waiting for its machine poller to finish.
 
106
        select {
 
107
        case err := <-done:
 
108
                c.Fatalf("watchMachinesLoop terminated prematurely: %v", err)
 
109
        case <-time.After(coretesting.ShortWait):
 
110
        }
 
111
 
 
112
        waitRefresh <- struct{}{}
 
113
        select {
 
114
        case err := <-done:
 
115
                c.Assert(err, gc.IsNil)
 
116
        case <-time.After(coretesting.LongWait):
 
117
                c.Fatalf("timed out waiting for watchMachinesLoop to terminate")
 
118
        }
 
119
        c.Assert(watcher.stopped, jc.IsTrue)
 
120
}
 
121
 
 
122
type testUpdaterContext struct {
 
123
        newMachineContextFunc func() machineContext
 
124
        getMachineFunc        func(id string) (machine, error)
 
125
        dyingc                chan struct{}
 
126
}
 
127
 
 
128
func (context *testUpdaterContext) newMachineContext() machineContext {
 
129
        return context.newMachineContextFunc()
 
130
}
 
131
 
 
132
func (context *testUpdaterContext) getMachine(id string) (machine, error) {
 
133
        return context.getMachineFunc(id)
 
134
}
 
135
 
 
136
func (context *testUpdaterContext) dying() <-chan struct{} {
 
137
        return context.dyingc
 
138
}
 
139
 
 
140
type testMachinesWatcher struct {
 
141
        stopped bool
 
142
        changes chan []string
 
143
        err     error
 
144
}
 
145
 
 
146
func (w *testMachinesWatcher) Changes() <-chan []string {
 
147
        return w.changes
 
148
}
 
149
 
 
150
func (w *testMachinesWatcher) Stop() error {
 
151
        w.stopped = true
 
152
        return w.err
 
153
}
 
154
 
 
155
func (w *testMachinesWatcher) Err() error {
 
156
        return w.err
 
157
}