~nskaggs/+junk/xenial-test

« back to all changes in this revision

Viewing changes to src/github.com/juju/juju/worker/resumer/manifold_test.go

  • Committer: Nicholas Skaggs
  • Date: 2016-10-24 20:56:05 UTC
  • Revision ID: nicholas.skaggs@canonical.com-20161024205605-z8lta0uvuhtxwzwl
Initi with beta15

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright 2016 Canonical Ltd.
 
2
// Licensed under the AGPLv3, see LICENCE file for details.
 
3
 
 
4
package resumer_test
 
5
 
 
6
import (
 
7
        "errors"
 
8
        "time"
 
9
 
 
10
        "github.com/juju/testing"
 
11
        jc "github.com/juju/testing/checkers"
 
12
        "github.com/juju/utils/clock"
 
13
        gc "gopkg.in/check.v1"
 
14
        "gopkg.in/juju/names.v2"
 
15
 
 
16
        "github.com/juju/juju/agent"
 
17
        "github.com/juju/juju/api/base"
 
18
        "github.com/juju/juju/apiserver/params"
 
19
        "github.com/juju/juju/state/multiwatcher"
 
20
        "github.com/juju/juju/worker"
 
21
        "github.com/juju/juju/worker/dependency"
 
22
        dt "github.com/juju/juju/worker/dependency/testing"
 
23
        resumer "github.com/juju/juju/worker/resumer"
 
24
        "github.com/juju/juju/worker/workertest"
 
25
)
 
26
 
 
27
type ManifoldSuite struct {
 
28
        testing.IsolationSuite
 
29
}
 
30
 
 
31
var _ = gc.Suite(&ManifoldSuite{})
 
32
 
 
33
func (*ManifoldSuite) TestInputs(c *gc.C) {
 
34
        manifold := resumer.Manifold(resumer.ManifoldConfig{
 
35
                AgentName:     "bill",
 
36
                APICallerName: "ben",
 
37
        })
 
38
        expect := []string{"bill", "ben"}
 
39
        c.Check(manifold.Inputs, jc.DeepEquals, expect)
 
40
}
 
41
 
 
42
func (*ManifoldSuite) TestOutput(c *gc.C) {
 
43
        manifold := resumer.Manifold(resumer.ManifoldConfig{})
 
44
        c.Check(manifold.Output, gc.IsNil)
 
45
}
 
46
 
 
47
func (*ManifoldSuite) TestMissingAgent(c *gc.C) {
 
48
        manifold := resumer.Manifold(resumer.ManifoldConfig{
 
49
                AgentName:     "agent",
 
50
                APICallerName: "api-caller",
 
51
        })
 
52
 
 
53
        worker, err := manifold.Start(dt.StubContext(nil, map[string]interface{}{
 
54
                "agent":      dependency.ErrMissing,
 
55
                "api-caller": &fakeAPICaller{},
 
56
        }))
 
57
        workertest.CheckNilOrKill(c, worker)
 
58
        c.Check(err, gc.Equals, dependency.ErrMissing)
 
59
}
 
60
 
 
61
func (*ManifoldSuite) TestMissingAPICaller(c *gc.C) {
 
62
        manifold := resumer.Manifold(resumer.ManifoldConfig{
 
63
                AgentName:     "agent",
 
64
                APICallerName: "api-caller",
 
65
        })
 
66
 
 
67
        worker, err := manifold.Start(dt.StubContext(nil, map[string]interface{}{
 
68
                "agent":      &fakeAgent{},
 
69
                "api-caller": dependency.ErrMissing,
 
70
        }))
 
71
        workertest.CheckNilOrKill(c, worker)
 
72
        c.Check(err, gc.Equals, dependency.ErrMissing)
 
73
}
 
74
 
 
75
func (*ManifoldSuite) TestAgentEntity_Error(c *gc.C) {
 
76
        manifold := resumer.Manifold(resumer.ManifoldConfig{
 
77
                AgentName:     "agent",
 
78
                APICallerName: "api-caller",
 
79
        })
 
80
 
 
81
        stub := &testing.Stub{}
 
82
        stub.SetErrors(errors.New("zap"))
 
83
        apiCaller := &fakeAPICaller{stub: stub}
 
84
        worker, err := manifold.Start(dt.StubContext(nil, map[string]interface{}{
 
85
                "agent":      &fakeAgent{},
 
86
                "api-caller": apiCaller,
 
87
        }))
 
88
        workertest.CheckNilOrKill(c, worker)
 
89
        c.Check(err, gc.ErrorMatches, "zap")
 
90
 
 
91
        stub.CheckCalls(c, []testing.StubCall{{
 
92
                FuncName: "Agent.GetEntities",
 
93
                Args: []interface{}{params.Entities{
 
94
                        Entities: []params.Entity{{
 
95
                                Tag: "machine-123",
 
96
                        }},
 
97
                }},
 
98
        }})
 
99
}
 
100
 
 
101
func (s *ManifoldSuite) TestAgentEntity_NoJob(c *gc.C) {
 
102
        manifold := resumer.Manifold(resumer.ManifoldConfig{
 
103
                AgentName:     "agent",
 
104
                APICallerName: "api-caller",
 
105
        })
 
106
 
 
107
        worker, err := manifold.Start(dt.StubContext(nil, map[string]interface{}{
 
108
                "agent":      &fakeAgent{},
 
109
                "api-caller": &fakeAPICaller{},
 
110
        }))
 
111
        workertest.CheckNilOrKill(c, worker)
 
112
        c.Check(err, gc.Equals, dependency.ErrMissing)
 
113
}
 
114
 
 
115
func (s *ManifoldSuite) TestAgentEntity_NotModelManager(c *gc.C) {
 
116
        manifold := resumer.Manifold(resumer.ManifoldConfig{
 
117
                AgentName:     "agent",
 
118
                APICallerName: "api-caller",
 
119
        })
 
120
 
 
121
        worker, err := manifold.Start(dt.StubContext(nil, map[string]interface{}{
 
122
                "agent":      &fakeAgent{},
 
123
                "api-caller": newFakeAPICaller(multiwatcher.JobHostUnits),
 
124
        }))
 
125
        workertest.CheckNilOrKill(c, worker)
 
126
        c.Check(err, gc.Equals, dependency.ErrMissing)
 
127
}
 
128
 
 
129
func (s *ManifoldSuite) TestNewFacade_Missing(c *gc.C) {
 
130
        manifold := resumer.Manifold(resumer.ManifoldConfig{
 
131
                AgentName:     "agent",
 
132
                APICallerName: "api-caller",
 
133
        })
 
134
 
 
135
        worker, err := manifold.Start(dt.StubContext(nil, map[string]interface{}{
 
136
                "agent":      &fakeAgent{},
 
137
                "api-caller": newFakeAPICaller(multiwatcher.JobManageModel),
 
138
        }))
 
139
        workertest.CheckNilOrKill(c, worker)
 
140
        c.Check(err, gc.Equals, dependency.ErrUninstall)
 
141
}
 
142
 
 
143
func (s *ManifoldSuite) TestNewFacade_Error(c *gc.C) {
 
144
        apiCaller := newFakeAPICaller(multiwatcher.JobManageModel)
 
145
        manifold := resumer.Manifold(resumer.ManifoldConfig{
 
146
                AgentName:     "agent",
 
147
                APICallerName: "api-caller",
 
148
                NewFacade: func(actual base.APICaller) (resumer.Facade, error) {
 
149
                        c.Check(actual, gc.Equals, apiCaller)
 
150
                        return nil, errors.New("pow")
 
151
                },
 
152
        })
 
153
 
 
154
        worker, err := manifold.Start(dt.StubContext(nil, map[string]interface{}{
 
155
                "agent":      &fakeAgent{},
 
156
                "api-caller": apiCaller,
 
157
        }))
 
158
        workertest.CheckNilOrKill(c, worker)
 
159
        c.Check(err, gc.ErrorMatches, "pow")
 
160
}
 
161
 
 
162
func (s *ManifoldSuite) TestNewWorker_Missing(c *gc.C) {
 
163
        manifold := resumer.Manifold(resumer.ManifoldConfig{
 
164
                AgentName:     "agent",
 
165
                APICallerName: "api-caller",
 
166
                NewFacade: func(base.APICaller) (resumer.Facade, error) {
 
167
                        return &fakeFacade{}, nil
 
168
                },
 
169
        })
 
170
 
 
171
        worker, err := manifold.Start(dt.StubContext(nil, map[string]interface{}{
 
172
                "agent":      &fakeAgent{},
 
173
                "api-caller": newFakeAPICaller(multiwatcher.JobManageModel),
 
174
        }))
 
175
        workertest.CheckNilOrKill(c, worker)
 
176
        c.Check(err, gc.Equals, dependency.ErrUninstall)
 
177
}
 
178
 
 
179
func (s *ManifoldSuite) TestNewWorker_Error(c *gc.C) {
 
180
        clock := &fakeClock{}
 
181
        facade := &fakeFacade{}
 
182
        manifold := resumer.Manifold(resumer.ManifoldConfig{
 
183
                AgentName:     "agent",
 
184
                APICallerName: "api-caller",
 
185
                Clock:         clock,
 
186
                Interval:      time.Hour,
 
187
                NewFacade: func(base.APICaller) (resumer.Facade, error) {
 
188
                        return facade, nil
 
189
                },
 
190
                NewWorker: func(actual resumer.Config) (worker.Worker, error) {
 
191
                        c.Check(actual, jc.DeepEquals, resumer.Config{
 
192
                                Facade:   facade,
 
193
                                Clock:    clock,
 
194
                                Interval: time.Hour,
 
195
                        })
 
196
                        return nil, errors.New("blam")
 
197
                },
 
198
        })
 
199
 
 
200
        worker, err := manifold.Start(dt.StubContext(nil, map[string]interface{}{
 
201
                "agent":      &fakeAgent{},
 
202
                "api-caller": newFakeAPICaller(multiwatcher.JobManageModel),
 
203
        }))
 
204
        workertest.CheckNilOrKill(c, worker)
 
205
        c.Check(err, gc.ErrorMatches, "blam")
 
206
}
 
207
 
 
208
func (s *ManifoldSuite) TestNewWorker_Success(c *gc.C) {
 
209
        expect := &fakeWorker{}
 
210
        manifold := resumer.Manifold(resumer.ManifoldConfig{
 
211
                AgentName:     "agent",
 
212
                APICallerName: "api-caller",
 
213
                NewFacade: func(base.APICaller) (resumer.Facade, error) {
 
214
                        return &fakeFacade{}, nil
 
215
                },
 
216
                NewWorker: func(actual resumer.Config) (worker.Worker, error) {
 
217
                        return expect, nil
 
218
                },
 
219
        })
 
220
 
 
221
        actual, err := manifold.Start(dt.StubContext(nil, map[string]interface{}{
 
222
                "agent":      &fakeAgent{},
 
223
                "api-caller": newFakeAPICaller(multiwatcher.JobManageModel),
 
224
        }))
 
225
        c.Check(err, jc.ErrorIsNil)
 
226
        c.Check(actual, gc.Equals, expect)
 
227
}
 
228
 
 
229
// fakeFacade should not be called.
 
230
type fakeFacade struct {
 
231
        resumer.Facade
 
232
}
 
233
 
 
234
// fakeClock should not be called.
 
235
type fakeClock struct {
 
236
        clock.Clock
 
237
}
 
238
 
 
239
// fakeWorker should not be called.
 
240
type fakeWorker struct {
 
241
        worker.Worker
 
242
}
 
243
 
 
244
// fakeAgent exists to expose a tag via CurrentConfig().Tag().
 
245
type fakeAgent struct {
 
246
        agent.Agent
 
247
}
 
248
 
 
249
// CurrentConfig returns an agent.Config with a working Tag() method.
 
250
func (a *fakeAgent) CurrentConfig() agent.Config {
 
251
        return &fakeConfig{}
 
252
}
 
253
 
 
254
// fakeConfig exists to expose Tag.
 
255
type fakeConfig struct {
 
256
        agent.Config
 
257
}
 
258
 
 
259
// Tag returns a Tag.
 
260
func (c *fakeConfig) Tag() names.Tag {
 
261
        return names.NewMachineTag("123")
 
262
}
 
263
 
 
264
func newFakeAPICaller(jobs ...multiwatcher.MachineJob) *fakeAPICaller {
 
265
        return &fakeAPICaller{jobs: jobs}
 
266
}
 
267
 
 
268
// fakeAPICaller exists to handle the hackish checkModelManager's api
 
269
// call directly, because it shouldn't happen in this context at all
 
270
// and we don't want it leaking into the config.
 
271
type fakeAPICaller struct {
 
272
        base.APICaller
 
273
        stub *testing.Stub
 
274
        jobs []multiwatcher.MachineJob
 
275
}
 
276
 
 
277
// APICall is part of the base.APICaller interface.
 
278
func (f *fakeAPICaller) APICall(objType string, version int, id, request string, args interface{}, response interface{}) error {
 
279
        if f.stub != nil {
 
280
                // We don't usually set the stub here, most of the time
 
281
                // the APICall hack is just an unwanted distraction from
 
282
                // the NewFacade/NewWorker bits that *should* exist long-
 
283
                // term. This makes it easier to just delete the broken
 
284
                // tests, and most of this type, including all of the
 
285
                // methods, when we drop the job check.
 
286
                f.stub.AddCall(objType+"."+request, args)
 
287
                if err := f.stub.NextErr(); err != nil {
 
288
                        return err
 
289
                }
 
290
        }
 
291
 
 
292
        if res, ok := response.(*params.AgentGetEntitiesResults); ok {
 
293
                jobs := make([]multiwatcher.MachineJob, 0, len(f.jobs))
 
294
                jobs = append(jobs, f.jobs...)
 
295
                res.Entities = []params.AgentGetEntitiesResult{
 
296
                        {Jobs: jobs},
 
297
                }
 
298
        }
 
299
        return nil
 
300
}
 
301
 
 
302
// BestFacadeVersion is part of the base.APICaller interface.
 
303
func (*fakeAPICaller) BestFacadeVersion(facade string) int {
 
304
        return 42
 
305
}