github.com/cloud-green/juju@v0.0.0-20151002100041-a00291338d3d/cmd/envcmd/environmentcommand_test.go (about) 1 // Copyright 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package envcmd_test 5 6 import ( 7 "io" 8 "os" 9 10 "github.com/juju/cmd" 11 "github.com/juju/cmd/cmdtesting" 12 "github.com/juju/errors" 13 gitjujutesting "github.com/juju/testing" 14 jc "github.com/juju/testing/checkers" 15 gc "gopkg.in/check.v1" 16 17 "github.com/juju/juju/cmd/envcmd" 18 "github.com/juju/juju/environs/config" 19 "github.com/juju/juju/environs/configstore" 20 "github.com/juju/juju/juju/osenv" 21 "github.com/juju/juju/testing" 22 "github.com/juju/juju/version" 23 ) 24 25 type EnvironmentCommandSuite struct { 26 testing.FakeJujuHomeSuite 27 } 28 29 func (s *EnvironmentCommandSuite) SetUpTest(c *gc.C) { 30 s.FakeJujuHomeSuite.SetUpTest(c) 31 s.PatchEnvironment("JUJU_CLI_VERSION", "") 32 } 33 34 var _ = gc.Suite(&EnvironmentCommandSuite{}) 35 36 func (s *EnvironmentCommandSuite) TestGetDefaultEnvironment(c *gc.C) { 37 env, err := envcmd.GetDefaultEnvironment() 38 c.Assert(env, gc.Equals, "erewhemos") 39 c.Assert(err, jc.ErrorIsNil) 40 } 41 42 func (s *EnvironmentCommandSuite) TestGetDefaultEnvironmentNothingSet(c *gc.C) { 43 envPath := gitjujutesting.HomePath(".juju", "environments.yaml") 44 err := os.Remove(envPath) 45 c.Assert(err, jc.ErrorIsNil) 46 env, err := envcmd.GetDefaultEnvironment() 47 c.Assert(env, gc.Equals, "") 48 c.Assert(err, jc.ErrorIsNil) 49 } 50 51 func (s *EnvironmentCommandSuite) TestGetDefaultEnvironmentCurrentEnvironmentSet(c *gc.C) { 52 err := envcmd.WriteCurrentEnvironment("fubar") 53 c.Assert(err, jc.ErrorIsNil) 54 env, err := envcmd.GetDefaultEnvironment() 55 c.Assert(env, gc.Equals, "fubar") 56 c.Assert(err, jc.ErrorIsNil) 57 } 58 59 func (s *EnvironmentCommandSuite) TestGetDefaultEnvironmentJujuEnvSet(c *gc.C) { 60 os.Setenv(osenv.JujuEnvEnvKey, "magic") 61 env, err := envcmd.GetDefaultEnvironment() 62 c.Assert(env, gc.Equals, "magic") 63 c.Assert(err, jc.ErrorIsNil) 64 } 65 66 func (s *EnvironmentCommandSuite) TestGetDefaultEnvironmentBothSet(c *gc.C) { 67 os.Setenv(osenv.JujuEnvEnvKey, "magic") 68 err := envcmd.WriteCurrentEnvironment("fubar") 69 c.Assert(err, jc.ErrorIsNil) 70 env, err := envcmd.GetDefaultEnvironment() 71 c.Assert(env, gc.Equals, "magic") 72 c.Assert(err, jc.ErrorIsNil) 73 } 74 75 func (s *EnvironmentCommandSuite) TestEnvironCommandInitExplicit(c *gc.C) { 76 // Take environment name from command line arg. 77 testEnsureEnvName(c, "explicit", "-e", "explicit") 78 } 79 80 func (s *EnvironmentCommandSuite) TestEnvironCommandInitMultipleConfigs(c *gc.C) { 81 // Take environment name from the default. 82 testing.WriteEnvironments(c, testing.MultipleEnvConfig) 83 testEnsureEnvName(c, testing.SampleEnvName) 84 } 85 86 func (s *EnvironmentCommandSuite) TestEnvironCommandInitSingleConfig(c *gc.C) { 87 // Take environment name from the one and only environment, 88 // even if it is not explicitly marked as default. 89 testing.WriteEnvironments(c, testing.SingleEnvConfigNoDefault) 90 testEnsureEnvName(c, testing.SampleEnvName) 91 } 92 93 func (s *EnvironmentCommandSuite) TestEnvironCommandInitEnvFile(c *gc.C) { 94 // If there is a current-environment file, use that. 95 err := envcmd.WriteCurrentEnvironment("fubar") 96 c.Assert(err, jc.ErrorIsNil) 97 testEnsureEnvName(c, "fubar") 98 } 99 100 func (s *EnvironmentCommandSuite) TestEnvironCommandInitSystemFile(c *gc.C) { 101 // If there is a current-system file, error raised. 102 err := envcmd.WriteCurrentSystem("fubar") 103 c.Assert(err, jc.ErrorIsNil) 104 _, err = initTestCommand(c) 105 c.Assert(err, gc.ErrorMatches, `not operating on an environment, using system "fubar"`) 106 } 107 108 func (s *EnvironmentCommandSuite) TestEnvironCommandInitNoEnvFile(c *gc.C) { 109 envPath := gitjujutesting.HomePath(".juju", "environments.yaml") 110 err := os.Remove(envPath) 111 c.Assert(err, jc.ErrorIsNil) 112 testEnsureEnvName(c, "") 113 } 114 115 func (s *EnvironmentCommandSuite) TestEnvironCommandInitMultipleConfigNoDefault(c *gc.C) { 116 // If there are multiple environments but no default, the connection name is empty. 117 testing.WriteEnvironments(c, testing.MultipleEnvConfigNoDefault) 118 testEnsureEnvName(c, "") 119 } 120 121 func (s *EnvironmentCommandSuite) TestBootstrapContext(c *gc.C) { 122 ctx := envcmd.BootstrapContext(&cmd.Context{}) 123 c.Assert(ctx.ShouldVerifyCredentials(), jc.IsTrue) 124 } 125 126 func (s *EnvironmentCommandSuite) TestBootstrapContextNoVerify(c *gc.C) { 127 ctx := envcmd.BootstrapContextNoVerify(&cmd.Context{}) 128 c.Assert(ctx.ShouldVerifyCredentials(), jc.IsFalse) 129 } 130 131 func (s *EnvironmentCommandSuite) TestCompatVersion(c *gc.C) { 132 s.PatchEnvironment(osenv.JujuCLIVersion, "2") 133 cmd, err := initTestCommand(c) 134 c.Assert(err, jc.ErrorIsNil) 135 c.Assert(cmd.CompatVersion(), gc.Equals, 2) 136 } 137 138 func (s *EnvironmentCommandSuite) TestCompatVersionDefault(c *gc.C) { 139 cmd, err := initTestCommand(c) 140 c.Assert(err, jc.ErrorIsNil) 141 c.Assert(cmd.CompatVersion(), gc.Equals, 1) 142 } 143 144 func (s *EnvironmentCommandSuite) TestCompatVersionInvalid(c *gc.C) { 145 s.PatchEnvironment(osenv.JujuCLIVersion, "invalid") 146 cmd, err := initTestCommand(c) 147 c.Assert(err, jc.ErrorIsNil) 148 c.Assert(cmd.CompatVersion(), gc.Equals, 1) 149 } 150 151 type testCommand struct { 152 envcmd.EnvCommandBase 153 } 154 155 func (c *testCommand) Info() *cmd.Info { 156 panic("should not be called") 157 } 158 159 func (c *testCommand) Run(ctx *cmd.Context) error { 160 panic("should not be called") 161 } 162 163 func initTestCommand(c *gc.C, args ...string) (*testCommand, error) { 164 cmd := new(testCommand) 165 wrapped := envcmd.Wrap(cmd) 166 return cmd, cmdtesting.InitCommand(wrapped, args) 167 } 168 169 func testEnsureEnvName(c *gc.C, expect string, args ...string) { 170 cmd, err := initTestCommand(c, args...) 171 c.Assert(err, jc.ErrorIsNil) 172 c.Assert(cmd.ConnectionName(), gc.Equals, expect) 173 } 174 175 type ConnectionEndpointSuite struct { 176 testing.FakeJujuHomeSuite 177 store configstore.Storage 178 endpoint configstore.APIEndpoint 179 } 180 181 var _ = gc.Suite(&ConnectionEndpointSuite{}) 182 183 func (s *ConnectionEndpointSuite) SetUpTest(c *gc.C) { 184 s.FakeHomeSuite.SetUpTest(c) 185 s.store = configstore.NewMem() 186 s.PatchValue(envcmd.GetConfigStore, func() (configstore.Storage, error) { 187 return s.store, nil 188 }) 189 newInfo := s.store.CreateInfo("env-name") 190 newInfo.SetAPICredentials(configstore.APICredentials{ 191 User: "foo", 192 Password: "foopass", 193 }) 194 s.endpoint = configstore.APIEndpoint{ 195 Addresses: []string{"0.1.2.3"}, 196 Hostnames: []string{"foo.invalid"}, 197 CACert: "certificated", 198 EnvironUUID: "fake-uuid", 199 } 200 newInfo.SetAPIEndpoint(s.endpoint) 201 err := newInfo.Write() 202 c.Assert(err, jc.ErrorIsNil) 203 } 204 205 func (s *ConnectionEndpointSuite) TestAPIEndpointInStoreCached(c *gc.C) { 206 cmd, err := initTestCommand(c, "-e", "env-name") 207 c.Assert(err, jc.ErrorIsNil) 208 endpoint, err := cmd.ConnectionEndpoint(false) 209 c.Assert(err, jc.ErrorIsNil) 210 c.Assert(endpoint, gc.DeepEquals, s.endpoint) 211 } 212 213 func (s *ConnectionEndpointSuite) TestAPIEndpointForEnvSuchName(c *gc.C) { 214 cmd, err := initTestCommand(c, "-e", "no-such-env") 215 c.Assert(err, jc.ErrorIsNil) 216 _, err = cmd.ConnectionEndpoint(false) 217 c.Assert(err, jc.Satisfies, errors.IsNotFound) 218 c.Assert(err, gc.ErrorMatches, `environment "no-such-env" not found`) 219 } 220 221 func (s *ConnectionEndpointSuite) TestAPIEndpointRefresh(c *gc.C) { 222 newEndpoint := configstore.APIEndpoint{ 223 Addresses: []string{"0.1.2.3"}, 224 Hostnames: []string{"foo.example.com"}, 225 CACert: "certificated", 226 EnvironUUID: "fake-uuid", 227 } 228 s.PatchValue(envcmd.EndpointRefresher, func(_ *envcmd.EnvCommandBase) (io.Closer, error) { 229 info, err := s.store.ReadInfo("env-name") 230 info.SetAPIEndpoint(newEndpoint) 231 err = info.Write() 232 c.Assert(err, jc.ErrorIsNil) 233 return new(closer), nil 234 }) 235 236 cmd, err := initTestCommand(c, "-e", "env-name") 237 c.Assert(err, jc.ErrorIsNil) 238 endpoint, err := cmd.ConnectionEndpoint(true) 239 c.Assert(err, jc.ErrorIsNil) 240 c.Assert(endpoint, gc.DeepEquals, newEndpoint) 241 } 242 243 type closer struct{} 244 245 func (*closer) Close() error { 246 return nil 247 } 248 249 type EnvironmentVersionSuite struct { 250 fake *fakeEnvGetter 251 } 252 253 var _ = gc.Suite(&EnvironmentVersionSuite{}) 254 255 type fakeEnvGetter struct { 256 agentVersion interface{} 257 err error 258 results map[string]interface{} 259 closeCalled bool 260 getCalled bool 261 } 262 263 func (g *fakeEnvGetter) EnvironmentGet() (map[string]interface{}, error) { 264 g.getCalled = true 265 if g.err != nil { 266 return nil, g.err 267 } else if g.results != nil { 268 return g.results, nil 269 } else if g.agentVersion == nil { 270 return map[string]interface{}{}, nil 271 } else { 272 return map[string]interface{}{ 273 "agent-version": g.agentVersion, 274 }, nil 275 } 276 } 277 278 func (g *fakeEnvGetter) Close() error { 279 g.closeCalled = true 280 return nil 281 } 282 283 func (s *EnvironmentVersionSuite) SetUpTest(*gc.C) { 284 s.fake = new(fakeEnvGetter) 285 } 286 287 func (s *EnvironmentVersionSuite) TestApiCallFails(c *gc.C) { 288 s.fake.err = errors.New("boom") 289 _, err := envcmd.GetEnvironmentVersion(s.fake) 290 c.Assert(err, gc.ErrorMatches, "unable to retrieve environment config: boom") 291 } 292 293 func (s *EnvironmentVersionSuite) TestNoVersion(c *gc.C) { 294 _, err := envcmd.GetEnvironmentVersion(s.fake) 295 c.Assert(err, gc.ErrorMatches, "version not found in environment config") 296 } 297 298 func (s *EnvironmentVersionSuite) TestInvalidVersionType(c *gc.C) { 299 s.fake.agentVersion = 99 300 _, err := envcmd.GetEnvironmentVersion(s.fake) 301 c.Assert(err, gc.ErrorMatches, "invalid environment version type in config") 302 } 303 304 func (s *EnvironmentVersionSuite) TestInvalidVersion(c *gc.C) { 305 s.fake.agentVersion = "a.b.c" 306 _, err := envcmd.GetEnvironmentVersion(s.fake) 307 c.Assert(err, gc.ErrorMatches, "unable to parse environment version: .+") 308 } 309 310 func (s *EnvironmentVersionSuite) TestSuccess(c *gc.C) { 311 vs := "1.22.1" 312 s.fake.agentVersion = vs 313 v, err := envcmd.GetEnvironmentVersion(s.fake) 314 c.Assert(err, jc.ErrorIsNil) 315 c.Assert(v.Compare(version.MustParse(vs)), gc.Equals, 0) 316 } 317 318 type EnvConfigSuite struct { 319 testing.FakeJujuHomeSuite 320 client *fakeEnvGetter 321 store configstore.Storage 322 envName string 323 } 324 325 var _ = gc.Suite(&EnvConfigSuite{}) 326 327 func createBootstrapInfo(c *gc.C, name string) map[string]interface{} { 328 bootstrapCfg, err := config.New(config.UseDefaults, map[string]interface{}{ 329 "type": "dummy", 330 "name": name, 331 "state-server": "true", 332 "state-id": "1", 333 }) 334 c.Assert(err, jc.ErrorIsNil) 335 return bootstrapCfg.AllAttrs() 336 } 337 338 func (s *EnvConfigSuite) SetUpTest(c *gc.C) { 339 s.FakeJujuHomeSuite.SetUpTest(c) 340 s.envName = "test-env" 341 s.client = &fakeEnvGetter{results: createBootstrapInfo(c, s.envName)} 342 343 var err error 344 s.store, err = configstore.Default() 345 c.Assert(err, jc.ErrorIsNil) 346 } 347 348 func (s *EnvConfigSuite) writeStore(c *gc.C, bootstrapInfo bool) { 349 info := s.store.CreateInfo(s.envName) 350 info.SetAPIEndpoint(configstore.APIEndpoint{ 351 Addresses: []string{"localhost"}, 352 CACert: testing.CACert, 353 EnvironUUID: s.envName + "-UUID", 354 ServerUUID: s.envName + "-UUID", 355 }) 356 357 if bootstrapInfo { 358 info.SetBootstrapConfig(createBootstrapInfo(c, s.envName)) 359 } 360 err := info.Write() 361 c.Assert(err, jc.ErrorIsNil) 362 } 363 364 func (s *EnvConfigSuite) TestConfigWithBootstrapInfo(c *gc.C) { 365 cmd := envcmd.NewEnvCommandBase(s.envName, s.client, nil) 366 s.writeStore(c, true) 367 368 cfg, err := cmd.Config(s.store, s.client) 369 c.Assert(err, jc.ErrorIsNil) 370 c.Check(cfg.Name(), gc.Equals, s.envName) 371 c.Check(s.client.getCalled, jc.IsFalse) 372 c.Check(s.client.closeCalled, jc.IsFalse) 373 } 374 375 func (s *EnvConfigSuite) TestConfigWithNoBootstrapWithClient(c *gc.C) { 376 cmd := envcmd.NewEnvCommandBase(s.envName, s.client, nil) 377 s.writeStore(c, false) 378 379 cfg, err := cmd.Config(s.store, s.client) 380 c.Assert(err, jc.ErrorIsNil) 381 c.Check(cfg.Name(), gc.Equals, s.envName) 382 c.Check(s.client.getCalled, jc.IsTrue) 383 c.Check(s.client.closeCalled, jc.IsFalse) 384 } 385 386 func (s *EnvConfigSuite) TestConfigWithNoBootstrapNoClient(c *gc.C) { 387 cmd := envcmd.NewEnvCommandBase(s.envName, s.client, nil) 388 s.writeStore(c, false) 389 390 cfg, err := cmd.Config(s.store, nil) 391 c.Assert(err, jc.ErrorIsNil) 392 c.Check(cfg.Name(), gc.Equals, s.envName) 393 c.Check(s.client.getCalled, jc.IsTrue) 394 c.Check(s.client.closeCalled, jc.IsTrue) 395 } 396 397 func (s *EnvConfigSuite) TestConfigWithNoBootstrapWithClientErr(c *gc.C) { 398 cmd := envcmd.NewEnvCommandBase(s.envName, s.client, errors.New("problem opening connection")) 399 s.writeStore(c, false) 400 401 _, err := cmd.Config(s.store, nil) 402 c.Assert(err, gc.ErrorMatches, "problem opening connection") 403 c.Check(s.client.getCalled, jc.IsFalse) 404 c.Check(s.client.closeCalled, jc.IsFalse) 405 } 406 407 func (s *EnvConfigSuite) TestConfigWithNoBootstrapWithEnvGetError(c *gc.C) { 408 cmd := envcmd.NewEnvCommandBase(s.envName, s.client, nil) 409 s.writeStore(c, false) 410 s.client.err = errors.New("problem getting environment attributes") 411 412 _, err := cmd.Config(s.store, nil) 413 c.Assert(err, gc.ErrorMatches, "problem getting environment attributes") 414 c.Check(s.client.getCalled, jc.IsTrue) 415 c.Check(s.client.closeCalled, jc.IsTrue) 416 } 417 418 func (s *EnvConfigSuite) TestConfigEnvDoesntExist(c *gc.C) { 419 cmd := envcmd.NewEnvCommandBase("dummy", s.client, nil) 420 s.writeStore(c, false) 421 422 _, err := cmd.Config(s.store, nil) 423 c.Assert(err, jc.Satisfies, errors.IsNotFound) 424 c.Check(s.client.getCalled, jc.IsFalse) 425 c.Check(s.client.closeCalled, jc.IsFalse) 426 }