~nskaggs/+junk/xenial-test

« back to all changes in this revision

Viewing changes to src/github.com/juju/juju/worker/migrationflag/util_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 LGPLv3, see LICENCE file for details.
 
3
 
 
4
package migrationflag_test
 
5
 
 
6
import (
 
7
        "github.com/juju/errors"
 
8
        "github.com/juju/testing"
 
9
        jc "github.com/juju/testing/checkers"
 
10
        gc "gopkg.in/check.v1"
 
11
        "gopkg.in/juju/names.v2"
 
12
 
 
13
        "github.com/juju/juju/api/base"
 
14
        "github.com/juju/juju/core/migration"
 
15
        "github.com/juju/juju/watcher"
 
16
        "github.com/juju/juju/worker"
 
17
        dt "github.com/juju/juju/worker/dependency/testing"
 
18
        "github.com/juju/juju/worker/migrationflag"
 
19
        "github.com/juju/juju/worker/workertest"
 
20
)
 
21
 
 
22
// newMockFacade returns a mock Facade that will add calls to the
 
23
// supplied testing.Stub, and return errors in the sequences it
 
24
// specifies; if any Phase call does not return an error, it will
 
25
// return a phase consumed from the head of the supplied list (or
 
26
// panic if it's empty).
 
27
func newMockFacade(stub *testing.Stub, phases ...migration.Phase) *mockFacade {
 
28
        return &mockFacade{
 
29
                stub:   stub,
 
30
                phases: phases,
 
31
        }
 
32
}
 
33
 
 
34
// mockFacade implements migrationflag.Facade for use in the tests.
 
35
type mockFacade struct {
 
36
        stub   *testing.Stub
 
37
        phases []migration.Phase
 
38
}
 
39
 
 
40
// Phase is part of the migrationflag.Facade interface.
 
41
func (mock *mockFacade) Phase(uuid string) (migration.Phase, error) {
 
42
        mock.stub.AddCall("Phase", uuid)
 
43
        if err := mock.stub.NextErr(); err != nil {
 
44
                return 0, err
 
45
        }
 
46
        return mock.nextPhase(), nil
 
47
}
 
48
 
 
49
// nextPhase consumes a phase and returns it, or panics.
 
50
func (mock *mockFacade) nextPhase() migration.Phase {
 
51
        phase := mock.phases[0]
 
52
        mock.phases = mock.phases[1:]
 
53
        return phase
 
54
}
 
55
 
 
56
// Watch is part of the migrationflag.Facade interface.
 
57
func (mock *mockFacade) Watch(uuid string) (watcher.NotifyWatcher, error) {
 
58
        mock.stub.AddCall("Watch", uuid)
 
59
        if err := mock.stub.NextErr(); err != nil {
 
60
                return nil, err
 
61
        }
 
62
        return newMockWatcher(), nil
 
63
}
 
64
 
 
65
// newMockWatcher returns a watcher.NotifyWatcher that always
 
66
// sends 3 changes and then sits quietly until killed.
 
67
func newMockWatcher() *mockWatcher {
 
68
        const count = 3
 
69
        changes := make(chan struct{}, count)
 
70
        for i := 0; i < count; i++ {
 
71
                changes <- struct{}{}
 
72
        }
 
73
        return &mockWatcher{
 
74
                Worker:  workertest.NewErrorWorker(nil),
 
75
                changes: changes,
 
76
        }
 
77
}
 
78
 
 
79
// mockWatcher implements watcher.NotifyWatcher for use in the tests.
 
80
type mockWatcher struct {
 
81
        worker.Worker
 
82
        changes chan struct{}
 
83
}
 
84
 
 
85
// Changes is part of the watcher.NotifyWatcher interface.
 
86
func (mock *mockWatcher) Changes() watcher.NotifyChannel {
 
87
        return mock.changes
 
88
}
 
89
 
 
90
// checkCalls checks that all the supplied call names were invoked
 
91
// in the supplied order, and that every one was passed [validUUID].
 
92
func checkCalls(c *gc.C, stub *testing.Stub, names ...string) {
 
93
        stub.CheckCallNames(c, names...)
 
94
        for _, call := range stub.Calls() {
 
95
                c.Check(call.Args, jc.DeepEquals, []interface{}{validUUID})
 
96
        }
 
97
}
 
98
 
 
99
// validUUID is the model UUID we're using in the tests.
 
100
var validUUID = "01234567-89ab-cdef-0123-456789abcdef"
 
101
 
 
102
// panicCheck is a Config.Check value that should not be called.
 
103
func panicCheck(migration.Phase) bool { panic("unexpected") }
 
104
 
 
105
// neverCheck is a Config.Check value that always returns false.
 
106
func neverCheck(migration.Phase) bool { return false }
 
107
 
 
108
// panicFacade is a NewFacade that should not be called.
 
109
func panicFacade(base.APICaller) (migrationflag.Facade, error) {
 
110
        panic("panicFacade")
 
111
}
 
112
 
 
113
// panicWorker is a NewWorker that should not be called.
 
114
func panicWorker(migrationflag.Config) (worker.Worker, error) {
 
115
        panic("panicWorker")
 
116
}
 
117
 
 
118
// isQuiesce is a Config.Check value that returns whether the phase is QUIESCE.
 
119
func isQuiesce(p migration.Phase) bool { return p == migration.QUIESCE }
 
120
 
 
121
// validConfig returns a minimal config stuffed with dummy objects that
 
122
// will explode when used.
 
123
func validConfig() migrationflag.Config {
 
124
        return migrationflag.Config{
 
125
                Facade: struct{ migrationflag.Facade }{},
 
126
                Model:  validUUID,
 
127
                Check:  panicCheck,
 
128
        }
 
129
}
 
130
 
 
131
// checkNotValid checks that the supplied migrationflag.Config fails to
 
132
// Validate, and cannot be used to construct a migrationflag.Worker.
 
133
func checkNotValid(c *gc.C, config migrationflag.Config, expect string) {
 
134
        check := func(err error) {
 
135
                c.Check(err, gc.ErrorMatches, expect)
 
136
                c.Check(err, jc.Satisfies, errors.IsNotValid)
 
137
        }
 
138
 
 
139
        err := config.Validate()
 
140
        check(err)
 
141
 
 
142
        worker, err := migrationflag.New(config)
 
143
        c.Check(worker, gc.IsNil)
 
144
        check(err)
 
145
}
 
146
 
 
147
// validManifoldConfig returns a minimal config stuffed with dummy objects
 
148
// that will explode when used.
 
149
func validManifoldConfig() migrationflag.ManifoldConfig {
 
150
        return migrationflag.ManifoldConfig{
 
151
                APICallerName: "api-caller",
 
152
                Check:         panicCheck,
 
153
                NewFacade:     panicFacade,
 
154
                NewWorker:     panicWorker,
 
155
        }
 
156
}
 
157
 
 
158
// checkManifoldNotValid checks that the supplied ManifoldConfig creates
 
159
// a manifold that cannot be started.
 
160
func checkManifoldNotValid(c *gc.C, config migrationflag.ManifoldConfig, expect string) {
 
161
        manifold := migrationflag.Manifold(config)
 
162
        worker, err := manifold.Start(dt.StubContext(nil, nil))
 
163
        c.Check(worker, gc.IsNil)
 
164
        c.Check(err, gc.ErrorMatches, expect)
 
165
        c.Check(err, jc.Satisfies, errors.IsNotValid)
 
166
}
 
167
 
 
168
// stubCaller is a base.APICaller that only implements ModelTag.
 
169
type stubCaller struct {
 
170
        base.APICaller
 
171
}
 
172
 
 
173
// ModelTag is part of the base.APICaller interface.
 
174
func (*stubCaller) ModelTag() (names.ModelTag, error) {
 
175
        return names.NewModelTag(validUUID), nil
 
176
}