github.com/Pankov404/juju@v0.0.0-20150703034450-be266991dceb/cmd/juju/environment/create_test.go (about) 1 // Copyright 2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package environment_test 5 6 import ( 7 "io/ioutil" 8 9 "github.com/juju/cmd" 10 "github.com/juju/errors" 11 jc "github.com/juju/testing/checkers" 12 "github.com/juju/utils" 13 gc "gopkg.in/check.v1" 14 "gopkg.in/yaml.v1" 15 16 "github.com/juju/juju/apiserver/params" 17 "github.com/juju/juju/cmd/envcmd" 18 "github.com/juju/juju/cmd/juju/environment" 19 "github.com/juju/juju/environs/configstore" 20 "github.com/juju/juju/feature" 21 "github.com/juju/juju/testing" 22 ) 23 24 type createSuite struct { 25 testing.FakeJujuHomeSuite 26 fake *fakeCreateClient 27 store configstore.Storage 28 serverUUID string 29 server configstore.EnvironInfo 30 } 31 32 var _ = gc.Suite(&createSuite{}) 33 34 func (s *createSuite) SetUpTest(c *gc.C) { 35 s.FakeJujuHomeSuite.SetUpTest(c) 36 s.SetFeatureFlags(feature.JES) 37 s.fake = &fakeCreateClient{} 38 store := configstore.Default 39 s.AddCleanup(func(*gc.C) { 40 configstore.Default = store 41 }) 42 s.store = configstore.NewMem() 43 configstore.Default = func() (configstore.Storage, error) { 44 return s.store, nil 45 } 46 // Set up the current environment, and write just enough info 47 // so we don't try to refresh 48 envName := "test-master" 49 s.serverUUID = "fake-server-uuid" 50 info := s.store.CreateInfo(envName) 51 info.SetAPIEndpoint(configstore.APIEndpoint{ 52 Addresses: []string{"localhost"}, 53 CACert: testing.CACert, 54 EnvironUUID: s.serverUUID, 55 ServerUUID: s.serverUUID, 56 }) 57 info.SetAPICredentials(configstore.APICredentials{User: "bob", Password: "sekrit"}) 58 err := info.Write() 59 c.Assert(err, jc.ErrorIsNil) 60 s.server = info 61 err = envcmd.WriteCurrentEnvironment(envName) 62 c.Assert(err, jc.ErrorIsNil) 63 } 64 65 func (s *createSuite) run(c *gc.C, args ...string) (*cmd.Context, error) { 66 command := environment.NewCreateCommand(s.fake) 67 return testing.RunCommand(c, envcmd.Wrap(command), args...) 68 } 69 70 func (s *createSuite) TestInit(c *gc.C) { 71 72 for i, test := range []struct { 73 args []string 74 err string 75 name string 76 path string 77 values map[string]string 78 }{ 79 { 80 err: "environment name is required", 81 }, { 82 args: []string{"new-env"}, 83 name: "new-env", 84 }, { 85 args: []string{"new-env", "key=value", "key2=value2"}, 86 name: "new-env", 87 values: map[string]string{"key": "value", "key2": "value2"}, 88 }, { 89 args: []string{"new-env", "key=value", "key=value2"}, 90 err: `key "key" specified more than once`, 91 }, { 92 args: []string{"new-env", "another"}, 93 err: `expected "key=value", got "another"`, 94 }, { 95 args: []string{"new-env", "--config", "some-file"}, 96 name: "new-env", 97 path: "some-file", 98 }, 99 } { 100 c.Logf("test %d", i) 101 create := &environment.CreateCommand{} 102 err := testing.InitCommand(create, test.args) 103 if test.err != "" { 104 c.Assert(err, gc.ErrorMatches, test.err) 105 } else { 106 c.Assert(err, jc.ErrorIsNil) 107 c.Assert(create.Name, gc.Equals, test.name) 108 c.Assert(create.ConfigFile.Path, gc.Equals, test.path) 109 // The config value parse method returns an empty map 110 // if there were no values 111 if len(test.values) == 0 { 112 c.Assert(create.ConfValues, gc.HasLen, 0) 113 } else { 114 c.Assert(create.ConfValues, jc.DeepEquals, test.values) 115 } 116 } 117 } 118 } 119 120 func (s *createSuite) TestCreateExistingName(c *gc.C) { 121 // Make a configstore entry with the same name. 122 info := s.store.CreateInfo("test") 123 err := info.Write() 124 c.Assert(err, jc.ErrorIsNil) 125 126 _, err = s.run(c, "test") 127 c.Assert(err, gc.ErrorMatches, `environment "test" already exists`) 128 } 129 130 func (s *createSuite) TestComandLineConfigPassedThrough(c *gc.C) { 131 _, err := s.run(c, "test", "account=magic", "cloud=special") 132 c.Assert(err, jc.ErrorIsNil) 133 134 c.Assert(s.fake.config["account"], gc.Equals, "magic") 135 c.Assert(s.fake.config["cloud"], gc.Equals, "special") 136 } 137 138 func (s *createSuite) TestConfigFileValuesPassedThrough(c *gc.C) { 139 config := map[string]string{ 140 "account": "magic", 141 "cloud": "9", 142 } 143 bytes, err := yaml.Marshal(config) 144 c.Assert(err, jc.ErrorIsNil) 145 file, err := ioutil.TempFile(c.MkDir(), "") 146 c.Assert(err, jc.ErrorIsNil) 147 file.Write(bytes) 148 file.Close() 149 150 _, err = s.run(c, "test", "--config", file.Name()) 151 c.Assert(err, jc.ErrorIsNil) 152 c.Assert(s.fake.config["account"], gc.Equals, "magic") 153 c.Assert(s.fake.config["cloud"], gc.Equals, "9") 154 } 155 156 func (s *createSuite) TestConfigFileFormatError(c *gc.C) { 157 file, err := ioutil.TempFile(c.MkDir(), "") 158 c.Assert(err, jc.ErrorIsNil) 159 file.Write(([]byte)("not: valid: yaml")) 160 file.Close() 161 162 _, err = s.run(c, "test", "--config", file.Name()) 163 c.Assert(err, gc.ErrorMatches, `YAML error: .*`) 164 } 165 166 func (s *createSuite) TestConfigFileDoesntExist(c *gc.C) { 167 _, err := s.run(c, "test", "--config", "missing-file") 168 errMsg := ".*" + utils.NoSuchFileErrRegexp 169 c.Assert(err, gc.ErrorMatches, errMsg) 170 } 171 172 func (s *createSuite) TestConfigValuePrecedence(c *gc.C) { 173 config := map[string]string{ 174 "account": "magic", 175 "cloud": "9", 176 } 177 bytes, err := yaml.Marshal(config) 178 c.Assert(err, jc.ErrorIsNil) 179 file, err := ioutil.TempFile(c.MkDir(), "") 180 c.Assert(err, jc.ErrorIsNil) 181 file.Write(bytes) 182 file.Close() 183 184 _, err = s.run(c, "test", "--config", file.Name(), "account=magic", "cloud=special") 185 c.Assert(err, jc.ErrorIsNil) 186 c.Assert(s.fake.config["account"], gc.Equals, "magic") 187 c.Assert(s.fake.config["cloud"], gc.Equals, "special") 188 } 189 190 func (s *createSuite) TestCreateErrorRemoveConfigstoreInfo(c *gc.C) { 191 s.fake.err = errors.New("bah humbug") 192 193 _, err := s.run(c, "test") 194 c.Assert(err, gc.ErrorMatches, "bah humbug") 195 196 _, err = s.store.ReadInfo("test") 197 c.Assert(err, gc.ErrorMatches, `environment "test" not found`) 198 } 199 200 func (s *createSuite) TestCreateStoresValues(c *gc.C) { 201 s.fake.env = params.Environment{ 202 Name: "test", 203 UUID: "fake-env-uuid", 204 OwnerTag: "ignored-for-now", 205 ServerUUID: s.serverUUID, 206 } 207 _, err := s.run(c, "test") 208 c.Assert(err, jc.ErrorIsNil) 209 210 info, err := s.store.ReadInfo("test") 211 c.Assert(err, jc.ErrorIsNil) 212 // Stores the credentials of the original environment 213 c.Assert(info.APICredentials(), jc.DeepEquals, s.server.APICredentials()) 214 endpoint := info.APIEndpoint() 215 expected := s.server.APIEndpoint() 216 c.Assert(endpoint.Addresses, jc.DeepEquals, expected.Addresses) 217 c.Assert(endpoint.Hostnames, jc.DeepEquals, expected.Hostnames) 218 c.Assert(endpoint.ServerUUID, gc.Equals, expected.ServerUUID) 219 c.Assert(endpoint.CACert, gc.Equals, expected.CACert) 220 c.Assert(endpoint.EnvironUUID, gc.Equals, "fake-env-uuid") 221 } 222 223 // fakeCreateClient is used to mock out the behavior of the real 224 // CreateEnvironment command. 225 type fakeCreateClient struct { 226 owner string 227 account map[string]interface{} 228 config map[string]interface{} 229 err error 230 env params.Environment 231 } 232 233 var _ environment.CreateEnvironmentAPI = (*fakeCreateClient)(nil) 234 235 func (*fakeCreateClient) Close() error { 236 return nil 237 } 238 239 func (*fakeCreateClient) ConfigSkeleton(provider, region string) (params.EnvironConfig, error) { 240 return params.EnvironConfig{ 241 "type": "dummy", 242 "state-server": false, 243 }, nil 244 } 245 func (f *fakeCreateClient) CreateEnvironment(owner string, account, config map[string]interface{}) (params.Environment, error) { 246 var env params.Environment 247 if f.err != nil { 248 return env, f.err 249 } 250 f.owner = owner 251 f.account = account 252 f.config = config 253 return f.env, nil 254 }