~nskaggs/+junk/xenial-test

« back to all changes in this revision

Viewing changes to src/github.com/juju/juju/cmd/juju/application/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-2015 Canonical Ltd.
 
2
// Licensed under the AGPLv3, see LICENCE file for details.
 
3
 
 
4
package application_test
 
5
 
 
6
import (
 
7
        "bytes"
 
8
        "io/ioutil"
 
9
        "os"
 
10
        "strings"
 
11
        "unicode/utf8"
 
12
 
 
13
        "github.com/juju/cmd"
 
14
        jc "github.com/juju/testing/checkers"
 
15
        "github.com/juju/utils"
 
16
        gc "gopkg.in/check.v1"
 
17
 
 
18
        "github.com/juju/juju/apiserver/common"
 
19
        "github.com/juju/juju/cmd/juju/application"
 
20
        coretesting "github.com/juju/juju/testing"
 
21
)
 
22
 
 
23
type SetSuite struct {
 
24
        coretesting.FakeJujuXDGDataHomeSuite
 
25
        dir            string
 
26
        fakeServiceAPI *fakeServiceAPI
 
27
}
 
28
 
 
29
var _ = gc.Suite(&SetSuite{})
 
30
 
 
31
var (
 
32
        validSetTestValue   = "a value with spaces\nand newline\nand UTF-8 characters: \U0001F604 / \U0001F44D"
 
33
        invalidSetTestValue = "a value with an invalid UTF-8 sequence: " + string([]byte{0xFF, 0xFF})
 
34
        yamlConfigValue     = "dummy-application:\n  skill-level: 9000\n  username: admin001\n\n"
 
35
)
 
36
 
 
37
func (s *SetSuite) SetUpTest(c *gc.C) {
 
38
        s.FakeJujuXDGDataHomeSuite.SetUpTest(c)
 
39
        s.fakeServiceAPI = &fakeServiceAPI{serviceName: "dummy-application"}
 
40
 
 
41
        s.dir = c.MkDir()
 
42
        c.Assert(utf8.ValidString(validSetTestValue), jc.IsTrue)
 
43
        c.Assert(utf8.ValidString(invalidSetTestValue), jc.IsFalse)
 
44
        setupValueFile(c, s.dir, "valid.txt", validSetTestValue)
 
45
        setupValueFile(c, s.dir, "invalid.txt", invalidSetTestValue)
 
46
        setupBigFile(c, s.dir)
 
47
        setupConfigFile(c, s.dir)
 
48
}
 
49
 
 
50
func (s *SetSuite) TestSetCommandInit(c *gc.C) {
 
51
        // missing args
 
52
        err := coretesting.InitCommand(application.NewSetCommandForTest(s.fakeServiceAPI), []string{})
 
53
        c.Assert(err, gc.ErrorMatches, "no application name specified")
 
54
 
 
55
        // missing application name
 
56
        err = coretesting.InitCommand(application.NewSetCommandForTest(s.fakeServiceAPI), []string{"name=foo"})
 
57
        c.Assert(err, gc.ErrorMatches, "no application name specified")
 
58
 
 
59
        // --config path, but no application
 
60
        err = coretesting.InitCommand(application.NewSetCommandForTest(s.fakeServiceAPI), []string{"--config", "testconfig.yaml"})
 
61
        c.Assert(err, gc.ErrorMatches, "no application name specified")
 
62
 
 
63
        // --config and options specified
 
64
        err = coretesting.InitCommand(application.NewSetCommandForTest(s.fakeServiceAPI), []string{"application", "--config", "testconfig.yaml", "bees="})
 
65
        c.Assert(err, gc.ErrorMatches, "cannot specify --config when using key=value arguments")
 
66
 
 
67
        // --to-default and no config name provided
 
68
        err = coretesting.InitCommand(application.NewSetCommandForTest(s.fakeServiceAPI), []string{"application", "--to-default"})
 
69
        c.Assert(err, gc.ErrorMatches, "no configuration options specified")
 
70
 
 
71
}
 
72
 
 
73
func (s *SetSuite) TestSetOptionSuccess(c *gc.C) {
 
74
        s.assertSetSuccess(c, s.dir, []string{
 
75
                "username=hello",
 
76
                "outlook=hello@world.tld",
 
77
        }, map[string]interface{}{
 
78
                "username": "hello",
 
79
                "outlook":  "hello@world.tld",
 
80
        })
 
81
        s.assertSetSuccess(c, s.dir, []string{
 
82
                "username=hello=foo",
 
83
        }, map[string]interface{}{
 
84
                "username": "hello=foo",
 
85
                "outlook":  "hello@world.tld",
 
86
        })
 
87
        s.assertSetSuccess(c, s.dir, []string{
 
88
                "username=@valid.txt",
 
89
        }, map[string]interface{}{
 
90
                "username": validSetTestValue,
 
91
                "outlook":  "hello@world.tld",
 
92
        })
 
93
        s.assertSetSuccess(c, s.dir, []string{
 
94
                "username=",
 
95
        }, map[string]interface{}{
 
96
                "username": "",
 
97
                "outlook":  "hello@world.tld",
 
98
        })
 
99
}
 
100
 
 
101
func (s *SetSuite) TestSetSameValue(c *gc.C) {
 
102
        s.assertSetSuccess(c, s.dir, []string{
 
103
                "username=hello",
 
104
                "outlook=hello@world.tld",
 
105
        }, map[string]interface{}{
 
106
                "username": "hello",
 
107
                "outlook":  "hello@world.tld",
 
108
        })
 
109
        s.assertSetWarning(c, s.dir, []string{
 
110
                "username=hello",
 
111
        }, "the configuration setting \"username\" already has the value \"hello\"")
 
112
        s.assertSetWarning(c, s.dir, []string{
 
113
                "outlook=hello@world.tld",
 
114
        }, "the configuration setting \"outlook\" already has the value \"hello@world.tld\"")
 
115
 
 
116
}
 
117
 
 
118
func (s *SetSuite) TestSetOptionFail(c *gc.C) {
 
119
        s.assertSetFail(c, s.dir, []string{"foo", "bar"}, "error: expected \"key=value\", got \"foo\"\n")
 
120
        s.assertSetFail(c, s.dir, []string{"=bar"}, "error: expected \"key=value\", got \"=bar\"\n")
 
121
        s.assertSetFail(c, s.dir, []string{
 
122
                "username=@missing.txt",
 
123
        }, "error: cannot read option from file \"missing.txt\": .* "+utils.NoSuchFileErrRegexp+"\n")
 
124
        s.assertSetFail(c, s.dir, []string{
 
125
                "username=@big.txt",
 
126
        }, "error: size of option file is larger than 5M\n")
 
127
        s.assertSetFail(c, s.dir, []string{
 
128
                "username=@invalid.txt",
 
129
        }, "error: value for option \"username\" contains non-UTF-8 sequences\n")
 
130
}
 
131
 
 
132
func (s *SetSuite) TestSetConfig(c *gc.C) {
 
133
        s.assertSetFail(c, s.dir, []string{
 
134
                "--config",
 
135
                "missing.yaml",
 
136
        }, "error.* "+utils.NoSuchFileErrRegexp+"\n")
 
137
 
 
138
        ctx := coretesting.ContextForDir(c, s.dir)
 
139
        code := cmd.Main(application.NewSetCommandForTest(s.fakeServiceAPI), ctx, []string{
 
140
                "dummy-application",
 
141
                "--config",
 
142
                "testconfig.yaml"})
 
143
 
 
144
        c.Check(code, gc.Equals, 0)
 
145
        c.Check(s.fakeServiceAPI.config, gc.Equals, yamlConfigValue)
 
146
}
 
147
 
 
148
func (s *SetSuite) TestSetConfigToDefault(c *gc.C) {
 
149
        s.fakeServiceAPI = &fakeServiceAPI{serviceName: "dummy-application", values: map[string]interface{}{
 
150
                "username": "hello",
 
151
        }}
 
152
        s.assertSetSuccess(c, s.dir, []string{
 
153
                "--to-default",
 
154
                "username",
 
155
        }, make(map[string]interface{}))
 
156
}
 
157
 
 
158
func (s *SetSuite) TestBlockSetConfig(c *gc.C) {
 
159
        // Block operation
 
160
        s.fakeServiceAPI.err = common.OperationBlockedError("TestBlockSetConfig")
 
161
        ctx := coretesting.ContextForDir(c, s.dir)
 
162
        code := cmd.Main(application.NewSetCommandForTest(s.fakeServiceAPI), ctx, []string{
 
163
                "dummy-application",
 
164
                "--config",
 
165
                "testconfig.yaml"})
 
166
        c.Check(code, gc.Equals, 1)
 
167
        // msg is logged
 
168
        stripped := strings.Replace(c.GetTestLog(), "\n", "", -1)
 
169
        c.Check(stripped, gc.Matches, ".*TestBlockSetConfig.*")
 
170
}
 
171
 
 
172
// assertSetSuccess sets configuration options and checks the expected settings.
 
173
func (s *SetSuite) assertSetSuccess(c *gc.C, dir string, args []string, expect map[string]interface{}) {
 
174
        ctx := coretesting.ContextForDir(c, dir)
 
175
        code := cmd.Main(application.NewSetCommandForTest(s.fakeServiceAPI), ctx, append([]string{"dummy-application"}, args...))
 
176
        c.Assert(code, gc.Equals, 0)
 
177
}
 
178
 
 
179
// assertSetFail sets configuration options and checks the expected error.
 
180
func (s *SetSuite) assertSetFail(c *gc.C, dir string, args []string, err string) {
 
181
        ctx := coretesting.ContextForDir(c, dir)
 
182
        code := cmd.Main(application.NewSetCommandForTest(s.fakeServiceAPI), ctx, append([]string{"dummy-application"}, args...))
 
183
        c.Check(code, gc.Not(gc.Equals), 0)
 
184
        c.Assert(ctx.Stderr.(*bytes.Buffer).String(), gc.Matches, err)
 
185
}
 
186
 
 
187
func (s *SetSuite) assertSetWarning(c *gc.C, dir string, args []string, w string) {
 
188
        ctx := coretesting.ContextForDir(c, dir)
 
189
        code := cmd.Main(application.NewSetCommandForTest(s.fakeServiceAPI), ctx, append([]string{"dummy-application"}, args...))
 
190
        c.Check(code, gc.Equals, 0)
 
191
 
 
192
        c.Assert(strings.Replace(c.GetTestLog(), "\n", " ", -1), gc.Matches, ".*WARNING.*"+w+".*")
 
193
}
 
194
 
 
195
// setupValueFile creates a file containing one value for testing
 
196
// set with name=@filename.
 
197
func setupValueFile(c *gc.C, dir, filename, value string) string {
 
198
        ctx := coretesting.ContextForDir(c, dir)
 
199
        path := ctx.AbsPath(filename)
 
200
        content := []byte(value)
 
201
        err := ioutil.WriteFile(path, content, 0666)
 
202
        c.Assert(err, jc.ErrorIsNil)
 
203
        return path
 
204
}
 
205
 
 
206
// setupBigFile creates a too big file for testing
 
207
// set with name=@filename.
 
208
func setupBigFile(c *gc.C, dir string) string {
 
209
        ctx := coretesting.ContextForDir(c, dir)
 
210
        path := ctx.AbsPath("big.txt")
 
211
        file, err := os.Create(path)
 
212
        c.Assert(err, jc.ErrorIsNil)
 
213
        defer file.Close()
 
214
        chunk := make([]byte, 1024)
 
215
        for i := 0; i < cap(chunk); i++ {
 
216
                chunk[i] = byte(i % 256)
 
217
        }
 
218
        for i := 0; i < 6000; i++ {
 
219
                _, err = file.Write(chunk)
 
220
                c.Assert(err, jc.ErrorIsNil)
 
221
        }
 
222
        return path
 
223
}
 
224
 
 
225
// setupConfigFile creates a configuration file for testing set
 
226
// with the --config argument specifying a configuration file.
 
227
func setupConfigFile(c *gc.C, dir string) string {
 
228
        ctx := coretesting.ContextForDir(c, dir)
 
229
        path := ctx.AbsPath("testconfig.yaml")
 
230
        content := []byte(yamlConfigValue)
 
231
        err := ioutil.WriteFile(path, content, 0666)
 
232
        c.Assert(err, jc.ErrorIsNil)
 
233
        return path
 
234
}