github.com/altoros/juju-vmware@v0.0.0-20150312064031-f19ae857ccca/cmd/juju/set_test.go (about) 1 // Copyright 2012, 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package main 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 "gopkg.in/juju/charm.v4" 18 19 "github.com/juju/juju/cmd/envcmd" 20 "github.com/juju/juju/juju/testing" 21 "github.com/juju/juju/state" 22 coretesting "github.com/juju/juju/testing" 23 ) 24 25 type SetSuite struct { 26 testing.JujuConnSuite 27 svc *state.Service 28 dir string 29 } 30 31 var _ = gc.Suite(&SetSuite{}) 32 33 var ( 34 validSetTestValue = "a value with spaces\nand newline\nand UTF-8 characters: \U0001F604 / \U0001F44D" 35 invalidSetTestValue = "a value with an invalid UTF-8 sequence: " + string([]byte{0xFF, 0xFF}) 36 ) 37 38 func (s *SetSuite) SetUpTest(c *gc.C) { 39 s.JujuConnSuite.SetUpTest(c) 40 ch := s.AddTestingCharm(c, "dummy") 41 svc := s.AddTestingService(c, "dummy-service", ch) 42 s.svc = svc 43 s.dir = c.MkDir() 44 c.Assert(utf8.ValidString(validSetTestValue), jc.IsTrue) 45 c.Assert(utf8.ValidString(invalidSetTestValue), jc.IsFalse) 46 setupValueFile(c, s.dir, "valid.txt", validSetTestValue) 47 setupValueFile(c, s.dir, "invalid.txt", invalidSetTestValue) 48 setupBigFile(c, s.dir) 49 setupConfigFile(c, s.dir) 50 } 51 52 func (s *SetSuite) TestSetOptionSuccess(c *gc.C) { 53 assertSetSuccess(c, s.dir, s.svc, []string{ 54 "username=hello", 55 "outlook=hello@world.tld", 56 }, charm.Settings{ 57 "username": "hello", 58 "outlook": "hello@world.tld", 59 }) 60 assertSetSuccess(c, s.dir, s.svc, []string{ 61 "username=hello=foo", 62 }, charm.Settings{ 63 "username": "hello=foo", 64 "outlook": "hello@world.tld", 65 }) 66 assertSetSuccess(c, s.dir, s.svc, []string{ 67 "username=@valid.txt", 68 }, charm.Settings{ 69 "username": validSetTestValue, 70 "outlook": "hello@world.tld", 71 }) 72 assertSetSuccess(c, s.dir, s.svc, []string{ 73 "username=", 74 }, charm.Settings{ 75 "username": "", 76 "outlook": "hello@world.tld", 77 }) 78 } 79 80 func (s *SetSuite) TestSetSameValue(c *gc.C) { 81 assertSetSuccess(c, s.dir, s.svc, []string{ 82 "username=hello", 83 "outlook=hello@world.tld", 84 }, charm.Settings{ 85 "username": "hello", 86 "outlook": "hello@world.tld", 87 }) 88 assertSetWarning(c, s.dir, []string{ 89 "username=hello", 90 }, "the configuration setting \"username\" already has the value \"hello\"") 91 assertSetWarning(c, s.dir, []string{ 92 "outlook=hello@world.tld", 93 }, "the configuration setting \"outlook\" already has the value \"hello@world.tld\"") 94 95 } 96 97 func (s *SetSuite) TestSetOptionFail(c *gc.C) { 98 assertSetFail(c, s.dir, []string{"foo", "bar"}, "error: expected \"key=value\", got \"foo\"\n") 99 assertSetFail(c, s.dir, []string{"=bar"}, "error: expected \"key=value\", got \"=bar\"\n") 100 assertSetFail(c, s.dir, []string{ 101 "username=@missing.txt", 102 }, "error: cannot read option from file \"missing.txt\": .* "+utils.NoSuchFileErrRegexp+"\n") 103 assertSetFail(c, s.dir, []string{ 104 "username=@big.txt", 105 }, "error: size of option file is larger than 5M\n") 106 assertSetFail(c, s.dir, []string{ 107 "username=@invalid.txt", 108 }, "error: value for option \"username\" contains non-UTF-8 sequences\n") 109 } 110 111 func (s *SetSuite) TestSetConfig(c *gc.C) { 112 assertSetFail(c, s.dir, []string{ 113 "--config", 114 "missing.yaml", 115 }, "error.* "+utils.NoSuchFileErrRegexp+"\n") 116 117 assertSetSuccess(c, s.dir, s.svc, []string{ 118 "--config", 119 "testconfig.yaml", 120 }, charm.Settings{ 121 "username": "admin001", 122 "skill-level": int64(9000), 123 }) 124 } 125 126 func (s *SetSuite) TestBlockSetConfig(c *gc.C) { 127 // Block operation 128 s.AssertConfigParameterUpdated(c, "block-all-changes", true) 129 ctx := coretesting.ContextForDir(c, s.dir) 130 code := cmd.Main(envcmd.Wrap(&SetCommand{}), ctx, append([]string{"dummy-service"}, []string{ 131 "--config", 132 "testconfig.yaml", 133 }...)) 134 c.Check(code, gc.Equals, 1) 135 // msg is logged 136 stripped := strings.Replace(c.GetTestLog(), "\n", "", -1) 137 c.Check(stripped, gc.Matches, ".*To unblock changes.*") 138 } 139 140 // assertSetSuccess sets configuration options and checks the expected settings. 141 func assertSetSuccess(c *gc.C, dir string, svc *state.Service, args []string, expect charm.Settings) { 142 ctx := coretesting.ContextForDir(c, dir) 143 code := cmd.Main(envcmd.Wrap(&SetCommand{}), ctx, append([]string{"dummy-service"}, args...)) 144 c.Check(code, gc.Equals, 0) 145 settings, err := svc.ConfigSettings() 146 c.Assert(err, jc.ErrorIsNil) 147 c.Assert(settings, gc.DeepEquals, expect) 148 } 149 150 // assertSetFail sets configuration options and checks the expected error. 151 func assertSetFail(c *gc.C, dir string, args []string, err string) { 152 ctx := coretesting.ContextForDir(c, dir) 153 code := cmd.Main(envcmd.Wrap(&SetCommand{}), ctx, append([]string{"dummy-service"}, args...)) 154 c.Check(code, gc.Not(gc.Equals), 0) 155 c.Assert(ctx.Stderr.(*bytes.Buffer).String(), gc.Matches, err) 156 } 157 158 func assertSetWarning(c *gc.C, dir string, args []string, w string) { 159 ctx := coretesting.ContextForDir(c, dir) 160 code := cmd.Main(envcmd.Wrap(&SetCommand{}), ctx, append([]string{"dummy-service"}, args...)) 161 c.Check(code, gc.Equals, 0) 162 163 c.Assert(strings.Replace(c.GetTestLog(), "\n", " ", -1), gc.Matches, ".*WARNING.*"+w+".*") 164 } 165 166 // setupValueFile creates a file containing one value for testing 167 // set with name=@filename. 168 func setupValueFile(c *gc.C, dir, filename, value string) string { 169 ctx := coretesting.ContextForDir(c, dir) 170 path := ctx.AbsPath(filename) 171 content := []byte(value) 172 err := ioutil.WriteFile(path, content, 0666) 173 c.Assert(err, jc.ErrorIsNil) 174 return path 175 } 176 177 // setupBigFile creates a too big file for testing 178 // set with name=@filename. 179 func setupBigFile(c *gc.C, dir string) string { 180 ctx := coretesting.ContextForDir(c, dir) 181 path := ctx.AbsPath("big.txt") 182 file, err := os.Create(path) 183 c.Assert(err, jc.ErrorIsNil) 184 defer file.Close() 185 chunk := make([]byte, 1024) 186 for i := 0; i < cap(chunk); i++ { 187 chunk[i] = byte(i % 256) 188 } 189 for i := 0; i < 6000; i++ { 190 _, err = file.Write(chunk) 191 c.Assert(err, jc.ErrorIsNil) 192 } 193 return path 194 } 195 196 // setupConfigFile creates a configuration file for testing set 197 // with the --config argument specifying a configuration file. 198 func setupConfigFile(c *gc.C, dir string) string { 199 ctx := coretesting.ContextForDir(c, dir) 200 path := ctx.AbsPath("testconfig.yaml") 201 content := []byte("dummy-service:\n skill-level: 9000\n username: admin001\n\n") 202 err := ioutil.WriteFile(path, content, 0666) 203 c.Assert(err, jc.ErrorIsNil) 204 return path 205 }