~nskaggs/+junk/xenial-test

« back to all changes in this revision

Viewing changes to src/github.com/juju/juju/worker/uniter/runner/context/flush_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 2012-2014 Canonical Ltd.
 
2
// Licensed under the AGPLv3, see LICENCE file for details.
 
3
 
 
4
package context_test
 
5
 
 
6
import (
 
7
        "github.com/juju/errors"
 
8
        "github.com/juju/testing"
 
9
        jc "github.com/juju/testing/checkers"
 
10
        "github.com/juju/utils"
 
11
        gc "gopkg.in/check.v1"
 
12
 
 
13
        "github.com/juju/juju/apiserver/params"
 
14
        "github.com/juju/juju/network"
 
15
        "github.com/juju/juju/worker/metrics/spool"
 
16
        "github.com/juju/juju/worker/uniter/runner/context"
 
17
        runnertesting "github.com/juju/juju/worker/uniter/runner/testing"
 
18
)
 
19
 
 
20
type FlushContextSuite struct {
 
21
        HookContextSuite
 
22
        stub testing.Stub
 
23
}
 
24
 
 
25
var _ = gc.Suite(&FlushContextSuite{})
 
26
 
 
27
func (s *FlushContextSuite) SetUpTest(c *gc.C) {
 
28
        s.HookContextSuite.SetUpTest(c)
 
29
        s.stub.ResetCalls()
 
30
}
 
31
 
 
32
func (s *FlushContextSuite) TestRunHookRelationFlushingError(c *gc.C) {
 
33
        ctx := s.context(c)
 
34
 
 
35
        // Mess with multiple relation settings.
 
36
        relCtx0, err := ctx.Relation(0)
 
37
        c.Assert(err, jc.ErrorIsNil)
 
38
        node0, err := relCtx0.Settings()
 
39
        c.Assert(err, jc.ErrorIsNil)
 
40
        node0.Set("foo", "1")
 
41
        relCtx1, err := ctx.Relation(1)
 
42
        c.Assert(err, jc.ErrorIsNil)
 
43
        node1, err := relCtx1.Settings()
 
44
        c.Assert(err, jc.ErrorIsNil)
 
45
        node1.Set("bar", "2")
 
46
 
 
47
        // Flush the context with a failure.
 
48
        err = ctx.Flush("some badge", errors.New("blam pow"))
 
49
        c.Assert(err, gc.ErrorMatches, "blam pow")
 
50
 
 
51
        // Check that the changes have not been written to state.
 
52
        settings0, err := s.relunits[0].ReadSettings("u/0")
 
53
        c.Assert(err, jc.ErrorIsNil)
 
54
        c.Assert(settings0, gc.DeepEquals, map[string]interface{}{"relation-name": "db0"})
 
55
        settings1, err := s.relunits[1].ReadSettings("u/0")
 
56
        c.Assert(err, jc.ErrorIsNil)
 
57
        c.Assert(settings1, gc.DeepEquals, map[string]interface{}{"relation-name": "db1"})
 
58
}
 
59
 
 
60
func (s *FlushContextSuite) TestRunHookRelationFlushingSuccess(c *gc.C) {
 
61
        ctx := s.context(c)
 
62
 
 
63
        // Mess with multiple relation settings.
 
64
        relCtx0, err := ctx.Relation(0)
 
65
        c.Assert(err, jc.ErrorIsNil)
 
66
        node0, err := relCtx0.Settings()
 
67
        c.Assert(err, jc.ErrorIsNil)
 
68
        node0.Set("baz", "3")
 
69
        relCtx1, err := ctx.Relation(1)
 
70
        c.Assert(err, jc.ErrorIsNil)
 
71
        node1, err := relCtx1.Settings()
 
72
        c.Assert(err, jc.ErrorIsNil)
 
73
        node1.Set("qux", "4")
 
74
 
 
75
        // Flush the context with a success.
 
76
        err = ctx.Flush("some badge", nil)
 
77
        c.Assert(err, jc.ErrorIsNil)
 
78
 
 
79
        // Check that the changes have been written to state.
 
80
        settings0, err := s.relunits[0].ReadSettings("u/0")
 
81
        c.Assert(err, jc.ErrorIsNil)
 
82
        c.Assert(settings0, gc.DeepEquals, map[string]interface{}{
 
83
                "relation-name": "db0",
 
84
                "baz":           "3",
 
85
        })
 
86
        settings1, err := s.relunits[1].ReadSettings("u/0")
 
87
        c.Assert(err, jc.ErrorIsNil)
 
88
        c.Assert(settings1, gc.DeepEquals, map[string]interface{}{
 
89
                "relation-name": "db1",
 
90
                "qux":           "4",
 
91
        })
 
92
}
 
93
 
 
94
func (s *FlushContextSuite) TestRunHookOpensAndClosesPendingPorts(c *gc.C) {
 
95
        // Initially, no port ranges are open on the unit or its machine.
 
96
        unitRanges, err := s.unit.OpenedPorts()
 
97
        c.Assert(err, jc.ErrorIsNil)
 
98
        c.Assert(unitRanges, gc.HasLen, 0)
 
99
        machinePorts, err := s.machine.AllPorts()
 
100
        c.Assert(err, jc.ErrorIsNil)
 
101
        c.Assert(machinePorts, gc.HasLen, 0)
 
102
 
 
103
        // Add another unit on the same machine.
 
104
        otherUnit, err := s.service.AddUnit()
 
105
        c.Assert(err, jc.ErrorIsNil)
 
106
        err = otherUnit.AssignToMachine(s.machine)
 
107
        c.Assert(err, jc.ErrorIsNil)
 
108
 
 
109
        // Open some ports on both units.
 
110
        err = s.unit.OpenPorts("tcp", 100, 200)
 
111
        c.Assert(err, jc.ErrorIsNil)
 
112
        err = otherUnit.OpenPorts("udp", 200, 300)
 
113
        c.Assert(err, jc.ErrorIsNil)
 
114
 
 
115
        unitRanges, err = s.unit.OpenedPorts()
 
116
        c.Assert(err, jc.ErrorIsNil)
 
117
        c.Assert(unitRanges, jc.DeepEquals, []network.PortRange{
 
118
                {100, 200, "tcp"},
 
119
        })
 
120
 
 
121
        ctx := s.context(c)
 
122
 
 
123
        // Try opening some ports via the context.
 
124
        err = ctx.OpenPorts("tcp", 100, 200)
 
125
        c.Assert(err, jc.ErrorIsNil) // duplicates are ignored
 
126
        err = ctx.OpenPorts("udp", 200, 300)
 
127
        c.Assert(err, gc.ErrorMatches, `cannot open 200-300/udp \(unit "u/0"\): conflicts with existing 200-300/udp \(unit "u/1"\)`)
 
128
        err = ctx.OpenPorts("udp", 100, 200)
 
129
        c.Assert(err, gc.ErrorMatches, `cannot open 100-200/udp \(unit "u/0"\): conflicts with existing 200-300/udp \(unit "u/1"\)`)
 
130
        err = ctx.OpenPorts("udp", 10, 20)
 
131
        c.Assert(err, jc.ErrorIsNil)
 
132
        err = ctx.OpenPorts("tcp", 50, 100)
 
133
        c.Assert(err, gc.ErrorMatches, `cannot open 50-100/tcp \(unit "u/0"\): conflicts with existing 100-200/tcp \(unit "u/0"\)`)
 
134
        err = ctx.OpenPorts("tcp", 50, 80)
 
135
        c.Assert(err, jc.ErrorIsNil)
 
136
        err = ctx.OpenPorts("tcp", 40, 90)
 
137
        c.Assert(err, gc.ErrorMatches, `cannot open 40-90/tcp \(unit "u/0"\): conflicts with 50-80/tcp requested earlier`)
 
138
 
 
139
        // Now try closing some ports as well.
 
140
        err = ctx.ClosePorts("udp", 8080, 8088)
 
141
        c.Assert(err, jc.ErrorIsNil) // not existing -> ignored
 
142
        err = ctx.ClosePorts("tcp", 100, 200)
 
143
        c.Assert(err, jc.ErrorIsNil)
 
144
        err = ctx.ClosePorts("tcp", 100, 200)
 
145
        c.Assert(err, jc.ErrorIsNil) // duplicates are ignored
 
146
        err = ctx.ClosePorts("udp", 200, 300)
 
147
        c.Assert(err, gc.ErrorMatches, `cannot close 200-300/udp \(opened by "u/1"\) from "u/0"`)
 
148
        err = ctx.ClosePorts("tcp", 50, 80)
 
149
        c.Assert(err, jc.ErrorIsNil) // still pending -> no longer pending
 
150
 
 
151
        // Ensure the ports are not actually changed on the unit yet.
 
152
        unitRanges, err = s.unit.OpenedPorts()
 
153
        c.Assert(err, jc.ErrorIsNil)
 
154
        c.Assert(unitRanges, jc.DeepEquals, []network.PortRange{
 
155
                {100, 200, "tcp"},
 
156
        })
 
157
 
 
158
        // Flush the context with a success.
 
159
        err = ctx.Flush("some badge", nil)
 
160
        c.Assert(err, jc.ErrorIsNil)
 
161
 
 
162
        // Verify the unit ranges are now open.
 
163
        expectUnitRanges := []network.PortRange{
 
164
                {FromPort: 10, ToPort: 20, Protocol: "udp"},
 
165
        }
 
166
        unitRanges, err = s.unit.OpenedPorts()
 
167
        c.Assert(err, jc.ErrorIsNil)
 
168
        c.Assert(unitRanges, jc.DeepEquals, expectUnitRanges)
 
169
}
 
170
 
 
171
func (s *FlushContextSuite) TestRunHookAddStorageOnFailure(c *gc.C) {
 
172
        ctx := s.context(c)
 
173
        c.Assert(ctx.UnitName(), gc.Equals, "u/0")
 
174
 
 
175
        size := uint64(1)
 
176
        ctx.AddUnitStorage(
 
177
                map[string]params.StorageConstraints{
 
178
                        "allecto": params.StorageConstraints{Size: &size},
 
179
                })
 
180
 
 
181
        // Flush the context with an error.
 
182
        msg := "test fail run hook"
 
183
        err := ctx.Flush("test fail run hook", errors.New(msg))
 
184
        c.Assert(errors.Cause(err), gc.ErrorMatches, msg)
 
185
 
 
186
        all, err := s.State.AllStorageInstances()
 
187
        c.Assert(err, jc.ErrorIsNil)
 
188
        c.Assert(all, gc.HasLen, 0)
 
189
}
 
190
 
 
191
func (s *FlushContextSuite) TestRunHookAddUnitStorageOnSuccess(c *gc.C) {
 
192
        ctx := s.context(c)
 
193
        c.Assert(ctx.UnitName(), gc.Equals, "u/0")
 
194
 
 
195
        size := uint64(1)
 
196
        ctx.AddUnitStorage(
 
197
                map[string]params.StorageConstraints{
 
198
                        "allecto": params.StorageConstraints{Size: &size},
 
199
                })
 
200
 
 
201
        // Flush the context with a success.
 
202
        err := ctx.Flush("success", nil)
 
203
        c.Assert(errors.Cause(err), gc.ErrorMatches, `.*storage "allecto" not found.*`)
 
204
 
 
205
        all, err := s.State.AllStorageInstances()
 
206
        c.Assert(err, jc.ErrorIsNil)
 
207
        c.Assert(all, gc.HasLen, 0)
 
208
}
 
209
 
 
210
func (s *HookContextSuite) context(c *gc.C) *context.HookContext {
 
211
        uuid, err := utils.NewUUID()
 
212
        c.Assert(err, jc.ErrorIsNil)
 
213
        return s.getHookContext(c, uuid.String(), -1, "", noProxies)
 
214
}
 
215
 
 
216
func (s *FlushContextSuite) TestBuiltinMetricNotGeneratedIfNotDefined(c *gc.C) {
 
217
        uuid := utils.MustNewUUID()
 
218
        paths := runnertesting.NewRealPaths(c)
 
219
        ctx := s.getMeteredHookContext(c, uuid.String(), -1, "", noProxies, true, s.metricsDefinition("pings"), paths)
 
220
        reader, err := spool.NewJSONMetricReader(
 
221
                paths.GetMetricsSpoolDir(),
 
222
        )
 
223
 
 
224
        err = ctx.Flush("some badge", nil)
 
225
        c.Assert(err, jc.ErrorIsNil)
 
226
        batches, err := reader.Read()
 
227
        c.Assert(err, jc.ErrorIsNil)
 
228
        c.Assert(batches, gc.HasLen, 0)
 
229
}