~nskaggs/+junk/xenial-test

« back to all changes in this revision

Viewing changes to src/github.com/juju/juju/worker/uniter/runner/jujuc/relation-set_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, 2013 Canonical Ltd.
 
2
// Copyright 2014 Cloudbase Solutions SRL
 
3
// Licensed under the AGPLv3, see LICENCE file for details.
 
4
 
 
5
package jujuc_test
 
6
 
 
7
import (
 
8
        "bytes"
 
9
        "fmt"
 
10
        "io/ioutil"
 
11
        "path/filepath"
 
12
 
 
13
        "github.com/juju/cmd"
 
14
        jc "github.com/juju/testing/checkers"
 
15
        gc "gopkg.in/check.v1"
 
16
 
 
17
        "github.com/juju/juju/testing"
 
18
        "github.com/juju/juju/worker/uniter/runner/jujuc"
 
19
        jujuctesting "github.com/juju/juju/worker/uniter/runner/jujuc/testing"
 
20
)
 
21
 
 
22
type RelationSetSuite struct {
 
23
        relationSuite
 
24
}
 
25
 
 
26
var _ = gc.Suite(&RelationSetSuite{})
 
27
 
 
28
var helpTests = []struct {
 
29
        relid  int
 
30
        expect string
 
31
}{{-1, ""}, {0, "peer0:0"}}
 
32
 
 
33
func (s *RelationSetSuite) TestHelp(c *gc.C) {
 
34
        for i, t := range helpTests {
 
35
                c.Logf("test %d", i)
 
36
                hctx, _ := s.newHookContext(t.relid, "")
 
37
                com, err := jujuc.NewCommand(hctx, cmdString("relation-set"))
 
38
                c.Assert(err, jc.ErrorIsNil)
 
39
                ctx := testing.Context(c)
 
40
                code := cmd.Main(com, ctx, []string{"--help"})
 
41
                c.Assert(code, gc.Equals, 0)
 
42
                c.Assert(bufferString(ctx.Stdout), gc.Equals, fmt.Sprintf(`
 
43
Usage: relation-set [options] key=value [key=value ...]
 
44
 
 
45
Summary:
 
46
set relation settings
 
47
 
 
48
Options:
 
49
--file  (= )
 
50
    file containing key-value pairs
 
51
--format (= "")
 
52
    deprecated format flag
 
53
-r, --relation  (= %s)
 
54
    specify a relation by id
 
55
 
 
56
Details:
 
57
"relation-set" writes the local unit's settings for some relation.
 
58
If no relation is specified then the current relation is used. The
 
59
setting values are not inspected and are stored as strings. Setting
 
60
an empty string causes the setting to be removed. Duplicate settings
 
61
are not allowed.
 
62
 
 
63
The --file option should be used when one or more key-value pairs are
 
64
too long to fit within the command length limit of the shell or
 
65
operating system. The file will contain a YAML map containing the
 
66
settings.  Settings in the file will be overridden by any duplicate
 
67
key-value arguments. A value of "-" for the filename means <stdin>.
 
68
`[1:], t.expect))
 
69
                c.Assert(bufferString(ctx.Stderr), gc.Equals, "")
 
70
        }
 
71
}
 
72
 
 
73
type relationSetInitTest struct {
 
74
        summary  string
 
75
        ctxrelid int
 
76
        args     []string
 
77
        content  string
 
78
        err      string
 
79
        relid    int
 
80
        settings map[string]string
 
81
}
 
82
 
 
83
func (t relationSetInitTest) log(c *gc.C, i int) {
 
84
        var summary string
 
85
        if t.summary != "" {
 
86
                summary = " - " + t.summary
 
87
        }
 
88
        c.Logf("test %d%s", i, summary)
 
89
}
 
90
 
 
91
func (t relationSetInitTest) filename() (string, int) {
 
92
        for i, arg := range t.args {
 
93
                next := i + 1
 
94
                if arg == "--file" && next < len(t.args) {
 
95
                        return t.args[next], next
 
96
                }
 
97
        }
 
98
        return "", -1
 
99
}
 
100
 
 
101
func (t relationSetInitTest) init(c *gc.C, s *RelationSetSuite) (cmd.Command, []string, *cmd.Context) {
 
102
        args := make([]string, len(t.args))
 
103
        copy(args, t.args)
 
104
 
 
105
        hctx, _ := s.newHookContext(t.ctxrelid, "")
 
106
        com, err := jujuc.NewCommand(hctx, cmdString("relation-set"))
 
107
        c.Assert(err, jc.ErrorIsNil)
 
108
 
 
109
        ctx := testing.Context(c)
 
110
 
 
111
        // Adjust the args and context for the filename.
 
112
        filename, i := t.filename()
 
113
        if filename == "-" {
 
114
                ctx.Stdin = bytes.NewBufferString(t.content)
 
115
        } else if filename != "" {
 
116
                filename = filepath.Join(c.MkDir(), filename)
 
117
                args[i] = filename
 
118
                err := ioutil.WriteFile(filename, []byte(t.content), 0644)
 
119
                c.Assert(err, jc.ErrorIsNil)
 
120
        }
 
121
 
 
122
        return com, args, ctx
 
123
}
 
124
 
 
125
func (t relationSetInitTest) check(c *gc.C, com cmd.Command, err error) {
 
126
        if t.err == "" {
 
127
                if !c.Check(err, jc.ErrorIsNil) {
 
128
                        return
 
129
                }
 
130
 
 
131
                rset := com.(*jujuc.RelationSetCommand)
 
132
                c.Check(rset.RelationId, gc.Equals, t.relid)
 
133
 
 
134
                settings := t.settings
 
135
                if settings == nil {
 
136
                        settings = map[string]string{}
 
137
                }
 
138
                c.Check(rset.Settings, jc.DeepEquals, settings)
 
139
        } else {
 
140
                c.Logf("%#v", com.(*jujuc.RelationSetCommand).Settings)
 
141
                c.Check(err, gc.ErrorMatches, t.err)
 
142
        }
 
143
}
 
144
 
 
145
var relationSetInitTests = []relationSetInitTest{
 
146
        {
 
147
        // compatibility: 0 args is valid.
 
148
        }, {
 
149
                ctxrelid: -1,
 
150
                err:      `no relation id specified`,
 
151
        }, {
 
152
                ctxrelid: -1,
 
153
                args:     []string{"-r", "one"},
 
154
                err:      `invalid value "one" for flag -r: invalid relation id`,
 
155
        }, {
 
156
                ctxrelid: 1,
 
157
                args:     []string{"-r", "one"},
 
158
                err:      `invalid value "one" for flag -r: invalid relation id`,
 
159
        }, {
 
160
                ctxrelid: -1,
 
161
                args:     []string{"-r", "ignored:one"},
 
162
                err:      `invalid value "ignored:one" for flag -r: invalid relation id`,
 
163
        }, {
 
164
                ctxrelid: 1,
 
165
                args:     []string{"-r", "ignored:one"},
 
166
                err:      `invalid value "ignored:one" for flag -r: invalid relation id`,
 
167
        }, {
 
168
                ctxrelid: -1,
 
169
                args:     []string{"-r", "2"},
 
170
                err:      `invalid value "2" for flag -r: relation not found`,
 
171
        }, {
 
172
                ctxrelid: 1,
 
173
                args:     []string{"-r", "ignored:2"},
 
174
                err:      `invalid value "ignored:2" for flag -r: relation not found`,
 
175
        }, {
 
176
                ctxrelid: -1,
 
177
                err:      `no relation id specified`,
 
178
        }, {
 
179
                ctxrelid: 1,
 
180
                args:     []string{"-r", "ignored:0"},
 
181
                relid:    0,
 
182
        }, {
 
183
                ctxrelid: 1,
 
184
                args:     []string{"-r", "0"},
 
185
                relid:    0,
 
186
        }, {
 
187
                ctxrelid: -1,
 
188
                args:     []string{"-r", "1"},
 
189
                relid:    1,
 
190
        }, {
 
191
                ctxrelid: 0,
 
192
                args:     []string{"-r", "1"},
 
193
                relid:    1,
 
194
        }, {
 
195
                ctxrelid: 1,
 
196
                args:     []string{"haha"},
 
197
                err:      `expected "key=value", got "haha"`,
 
198
        }, {
 
199
                ctxrelid: 1,
 
200
                args:     []string{"=haha"},
 
201
                err:      `expected "key=value", got "=haha"`,
 
202
        }, {
 
203
                ctxrelid: 1,
 
204
                args:     []string{"foo="},
 
205
                relid:    1,
 
206
                settings: map[string]string{"foo": ""},
 
207
        }, {
 
208
                ctxrelid: 1,
 
209
                args:     []string{"foo='"},
 
210
                relid:    1,
 
211
                settings: map[string]string{"foo": "'"},
 
212
        }, {
 
213
                ctxrelid: 1,
 
214
                args:     []string{"foo=bar"},
 
215
                relid:    1,
 
216
                settings: map[string]string{"foo": "bar"},
 
217
        }, {
 
218
                ctxrelid: 1,
 
219
                args:     []string{"foo=bar=baz=qux"},
 
220
                relid:    1,
 
221
                settings: map[string]string{"foo": "bar=baz=qux"},
 
222
        }, {
 
223
                ctxrelid: 1,
 
224
                args:     []string{"foo=foo: bar"},
 
225
                relid:    1,
 
226
                settings: map[string]string{"foo": "foo: bar"},
 
227
        }, {
 
228
                ctxrelid: 0,
 
229
                args:     []string{"-r", "1", "foo=bar"},
 
230
                relid:    1,
 
231
                settings: map[string]string{"foo": "bar"},
 
232
        }, {
 
233
                ctxrelid: 1,
 
234
                args:     []string{"foo=123", "bar=true", "baz=4.5", "qux="},
 
235
                relid:    1,
 
236
                settings: map[string]string{"foo": "123", "bar": "true", "baz": "4.5", "qux": ""},
 
237
        }, {
 
238
                summary:  "file with a valid setting",
 
239
                args:     []string{"--file", "spam"},
 
240
                content:  "{foo: bar}",
 
241
                settings: map[string]string{"foo": "bar"},
 
242
        }, {
 
243
                summary:  "file with multiple settings on a line",
 
244
                args:     []string{"--file", "spam"},
 
245
                content:  "{foo: bar, spam: eggs}",
 
246
                settings: map[string]string{"foo": "bar", "spam": "eggs"},
 
247
        }, {
 
248
                summary:  "file with multiple lines",
 
249
                args:     []string{"--file", "spam"},
 
250
                content:  "{\n  foo: bar,\n  spam: eggs\n}",
 
251
                settings: map[string]string{"foo": "bar", "spam": "eggs"},
 
252
        }, {
 
253
                summary:  "an empty file",
 
254
                args:     []string{"--file", "spam"},
 
255
                content:  "",
 
256
                settings: map[string]string{},
 
257
        }, {
 
258
                summary:  "an empty map",
 
259
                args:     []string{"--file", "spam"},
 
260
                content:  "{}",
 
261
                settings: map[string]string{},
 
262
        }, {
 
263
                summary: "accidental same format as command-line",
 
264
                args:    []string{"--file", "spam"},
 
265
                content: "foo=bar ham=eggs good=bad",
 
266
                err:     "yaml: unmarshal errors:\n  line 1: cannot unmarshal !!str `foo=bar...` into map.*",
 
267
        }, {
 
268
                summary: "scalar instead of map",
 
269
                args:    []string{"--file", "spam"},
 
270
                content: "haha",
 
271
                err:     "yaml: unmarshal errors:\n  line 1: cannot unmarshal !!str `haha` into map.*",
 
272
        }, {
 
273
                summary: "sequence instead of map",
 
274
                args:    []string{"--file", "spam"},
 
275
                content: "[haha]",
 
276
                err:     "yaml: unmarshal errors:\n  line 1: cannot unmarshal !!seq into map.*",
 
277
        }, {
 
278
                summary: "multiple maps",
 
279
                args:    []string{"--file", "spam"},
 
280
                content: "{a: b}\n{c: d}",
 
281
                err:     `.*yaml: .*`,
 
282
        }, {
 
283
                summary:  "value with a space",
 
284
                args:     []string{"--file", "spam"},
 
285
                content:  "{foo: 'bar baz'}",
 
286
                settings: map[string]string{"foo": "bar baz"},
 
287
        }, {
 
288
                summary:  "value with an equal sign",
 
289
                args:     []string{"--file", "spam"},
 
290
                content:  "{foo: foo=bar, base64: YmFzZTY0IGV4YW1wbGU=}",
 
291
                settings: map[string]string{"foo": "foo=bar", "base64": "YmFzZTY0IGV4YW1wbGU="},
 
292
        }, {
 
293
                summary:  "values with brackets",
 
294
                args:     []string{"--file", "spam"},
 
295
                content:  "{foo: '[x]', bar: '{y}'}",
 
296
                settings: map[string]string{"foo": "[x]", "bar": "{y}"},
 
297
        }, {
 
298
                summary:  "a messy file",
 
299
                args:     []string{"--file", "spam"},
 
300
                content:  "\n {  \n # a comment \n\n  \nfoo: bar,  \nham: eggs,\n\n  good: bad,\nup: down, left: right\n}\n",
 
301
                settings: map[string]string{"foo": "bar", "ham": "eggs", "good": "bad", "up": "down", "left": "right"},
 
302
        }, {
 
303
                summary:  "file + settings",
 
304
                args:     []string{"--file", "spam", "foo=bar"},
 
305
                content:  "{ham: eggs}",
 
306
                settings: map[string]string{"ham": "eggs", "foo": "bar"},
 
307
        }, {
 
308
                summary:  "file overridden by settings",
 
309
                args:     []string{"--file", "spam", "foo=bar"},
 
310
                content:  "{foo: baz}",
 
311
                settings: map[string]string{"foo": "bar"},
 
312
        }, {
 
313
                summary:  "read from stdin",
 
314
                args:     []string{"--file", "-"},
 
315
                content:  "{foo: bar}",
 
316
                settings: map[string]string{"foo": "bar"},
 
317
        },
 
318
}
 
319
 
 
320
func (s *RelationSetSuite) TestInit(c *gc.C) {
 
321
        for i, t := range relationSetInitTests {
 
322
                t.log(c, i)
 
323
                com, args, ctx := t.init(c, s)
 
324
 
 
325
                err := testing.InitCommand(com, args)
 
326
                if err == nil {
 
327
                        err = jujuc.HandleSettingsFile(com.(*jujuc.RelationSetCommand), ctx)
 
328
                }
 
329
                t.check(c, com, err)
 
330
        }
 
331
}
 
332
 
 
333
// Tests start with a relation with the settings {"base": "value"}
 
334
var relationSetRunTests = []struct {
 
335
        change map[string]string
 
336
        expect jujuctesting.Settings
 
337
}{
 
338
        {
 
339
                map[string]string{"base": ""},
 
340
                jujuctesting.Settings{},
 
341
        }, {
 
342
                map[string]string{"foo": "bar"},
 
343
                jujuctesting.Settings{"base": "value", "foo": "bar"},
 
344
        }, {
 
345
                map[string]string{"base": "changed"},
 
346
                jujuctesting.Settings{"base": "changed"},
 
347
        },
 
348
}
 
349
 
 
350
func (s *RelationSetSuite) TestRun(c *gc.C) {
 
351
        hctx, info := s.newHookContext(0, "")
 
352
        for i, t := range relationSetRunTests {
 
353
                c.Logf("test %d", i)
 
354
 
 
355
                pristine := jujuctesting.Settings{"pristine": "untouched"}
 
356
                info.rels[0].Units["u/0"] = pristine
 
357
                basic := jujuctesting.Settings{"base": "value"}
 
358
                info.rels[1].Units["u/0"] = basic
 
359
 
 
360
                // Run the command.
 
361
                com, err := jujuc.NewCommand(hctx, cmdString("relation-set"))
 
362
                c.Assert(err, jc.ErrorIsNil)
 
363
                rset := com.(*jujuc.RelationSetCommand)
 
364
                rset.RelationId = 1
 
365
                rset.Settings = t.change
 
366
                ctx := testing.Context(c)
 
367
                err = com.Run(ctx)
 
368
                c.Assert(err, jc.ErrorIsNil)
 
369
 
 
370
                // Check changes.
 
371
                c.Assert(info.rels[0].Units["u/0"], gc.DeepEquals, pristine)
 
372
                c.Assert(info.rels[1].Units["u/0"], gc.DeepEquals, t.expect)
 
373
        }
 
374
}
 
375
 
 
376
func (s *RelationSetSuite) TestRunDeprecationWarning(c *gc.C) {
 
377
        hctx, _ := s.newHookContext(0, "")
 
378
        com, _ := jujuc.NewCommand(hctx, cmdString("relation-set"))
 
379
 
 
380
        // The rel= is needed to make this a valid command.
 
381
        ctx, err := testing.RunCommand(c, com, "--format", "foo", "rel=")
 
382
 
 
383
        c.Assert(err, jc.ErrorIsNil)
 
384
        c.Assert(testing.Stdout(ctx), gc.Equals, "")
 
385
        c.Assert(testing.Stderr(ctx), gc.Equals, "--format flag deprecated for command \"relation-set\"")
 
386
}