github.com/altoros/juju-vmware@v0.0.0-20150312064031-f19ae857ccca/cmd/juju/destroyenvironment_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 9 "github.com/juju/cmd" 10 "github.com/juju/errors" 11 jc "github.com/juju/testing/checkers" 12 gc "gopkg.in/check.v1" 13 14 "github.com/juju/juju/cmd/envcmd" 15 cmdtesting "github.com/juju/juju/cmd/testing" 16 "github.com/juju/juju/environs" 17 "github.com/juju/juju/environs/configstore" 18 "github.com/juju/juju/instance" 19 "github.com/juju/juju/juju/testing" 20 "github.com/juju/juju/provider/dummy" 21 coretesting "github.com/juju/juju/testing" 22 ) 23 24 type destroyEnvSuite struct { 25 testing.JujuConnSuite 26 } 27 28 var _ = gc.Suite(&destroyEnvSuite{}) 29 30 func (s *destroyEnvSuite) TestDestroyEnvironmentCommand(c *gc.C) { 31 // Prepare the environment so we can destroy it. 32 _, err := environs.PrepareFromName("dummyenv", envcmd.BootstrapContext(cmdtesting.NullContext(c)), s.ConfigStore) 33 c.Assert(err, jc.ErrorIsNil) 34 35 // check environment is mandatory 36 opc, errc := cmdtesting.RunCommand(cmdtesting.NullContext(c), new(DestroyEnvironmentCommand)) 37 c.Check(<-errc, gc.Equals, NoEnvironmentError) 38 39 // normal destroy 40 opc, errc = cmdtesting.RunCommand(cmdtesting.NullContext(c), new(DestroyEnvironmentCommand), "dummyenv", "--yes") 41 c.Check(<-errc, gc.IsNil) 42 c.Check((<-opc).(dummy.OpDestroy).Env, gc.Equals, "dummyenv") 43 44 // Verify that the environment information has been removed. 45 _, err = s.ConfigStore.ReadInfo("dummyenv") 46 c.Assert(err, jc.Satisfies, errors.IsNotFound) 47 } 48 49 // startEnvironment prepare the environment so we can destroy it. 50 func (s *destroyEnvSuite) startEnvironment(c *gc.C, desiredEnvName string) { 51 _, err := environs.PrepareFromName(desiredEnvName, envcmd.BootstrapContext(cmdtesting.NullContext(c)), s.ConfigStore) 52 c.Assert(err, jc.ErrorIsNil) 53 } 54 55 func (s *destroyEnvSuite) checkDestroyEnvironment(c *gc.C, blocked, force bool) { 56 //Setup environment 57 envName := "dummyenv" 58 s.startEnvironment(c, envName) 59 s.AssertConfigParameterUpdated(c, "block-destroy-environment", blocked) 60 opc := make(chan dummy.Operation) 61 errc := make(chan error) 62 if force { 63 opc, errc = cmdtesting.RunCommand(cmdtesting.NullContext(c), new(DestroyEnvironmentCommand), envName, "--yes", "--force") 64 } else { 65 opc, errc = cmdtesting.RunCommand(cmdtesting.NullContext(c), new(DestroyEnvironmentCommand), envName, "--yes") 66 } 67 if force || !blocked { 68 c.Check(<-errc, gc.IsNil) 69 c.Check((<-opc).(dummy.OpDestroy).Env, gc.Equals, envName) 70 // Verify that the environment information has been removed. 71 _, err := s.ConfigStore.ReadInfo(envName) 72 c.Assert(err, jc.Satisfies, errors.IsNotFound) 73 } else { 74 c.Check(<-errc, gc.Not(gc.IsNil)) 75 c.Check((<-opc), gc.IsNil) 76 // Verify that the environment information has not been removed. 77 _, err := s.ConfigStore.ReadInfo(envName) 78 c.Assert(err, jc.ErrorIsNil) 79 } 80 } 81 82 func (s *destroyEnvSuite) TestDestroyLockedEnvironment(c *gc.C) { 83 // lock environment: can't destroy locked environment 84 s.checkDestroyEnvironment(c, true, false) 85 } 86 87 func (s *destroyEnvSuite) TestDestroyUnlockedEnvironment(c *gc.C) { 88 s.checkDestroyEnvironment(c, false, false) 89 } 90 91 func (s *destroyEnvSuite) TestForceDestroyLockedEnvironment(c *gc.C) { 92 s.checkDestroyEnvironment(c, true, true) 93 } 94 95 func (s *destroyEnvSuite) TestForceDestroyUnlockedEnvironment(c *gc.C) { 96 s.checkDestroyEnvironment(c, false, true) 97 } 98 99 func (s *destroyEnvSuite) TestDestroyEnvironmentCommandEFlag(c *gc.C) { 100 // Prepare the environment so we can destroy it. 101 _, err := environs.PrepareFromName("dummyenv", envcmd.BootstrapContext(cmdtesting.NullContext(c)), s.ConfigStore) 102 c.Assert(err, jc.ErrorIsNil) 103 104 // check that either environment or the flag is mandatory 105 opc, errc := cmdtesting.RunCommand(cmdtesting.NullContext(c), new(DestroyEnvironmentCommand)) 106 c.Check(<-errc, gc.Equals, NoEnvironmentError) 107 108 // We don't allow them to supply both entries at the same time 109 opc, errc = cmdtesting.RunCommand(cmdtesting.NullContext(c), new(DestroyEnvironmentCommand), "-e", "dummyenv", "dummyenv", "--yes") 110 c.Check(<-errc, gc.Equals, DoubleEnvironmentError) 111 // We treat --environment the same way 112 opc, errc = cmdtesting.RunCommand(cmdtesting.NullContext(c), new(DestroyEnvironmentCommand), "--environment", "dummyenv", "dummyenv", "--yes") 113 c.Check(<-errc, gc.Equals, DoubleEnvironmentError) 114 115 // destroy using the -e flag 116 opc, errc = cmdtesting.RunCommand(cmdtesting.NullContext(c), new(DestroyEnvironmentCommand), "-e", "dummyenv", "--yes") 117 c.Check(<-errc, gc.IsNil) 118 c.Check((<-opc).(dummy.OpDestroy).Env, gc.Equals, "dummyenv") 119 120 // Verify that the environment information has been removed. 121 _, err = s.ConfigStore.ReadInfo("dummyenv") 122 c.Assert(err, jc.Satisfies, errors.IsNotFound) 123 } 124 125 func (s *destroyEnvSuite) TestDestroyEnvironmentCommandEmptyJenv(c *gc.C) { 126 info := s.ConfigStore.CreateInfo("emptyenv") 127 err := info.Write() 128 c.Assert(err, jc.ErrorIsNil) 129 130 context, err := coretesting.RunCommand(c, new(DestroyEnvironmentCommand), "-e", "emptyenv") 131 c.Assert(err, jc.ErrorIsNil) 132 133 c.Assert(coretesting.Stderr(context), gc.Equals, "removing empty environment file\n") 134 } 135 136 func (s *destroyEnvSuite) TestDestroyEnvironmentCommandBroken(c *gc.C) { 137 oldinfo, err := s.ConfigStore.ReadInfo("dummyenv") 138 c.Assert(err, jc.ErrorIsNil) 139 bootstrapConfig := oldinfo.BootstrapConfig() 140 apiEndpoint := oldinfo.APIEndpoint() 141 apiCredentials := oldinfo.APICredentials() 142 err = oldinfo.Destroy() 143 c.Assert(err, jc.ErrorIsNil) 144 newinfo := s.ConfigStore.CreateInfo("dummyenv") 145 146 bootstrapConfig["broken"] = "Destroy" 147 newinfo.SetBootstrapConfig(bootstrapConfig) 148 newinfo.SetAPIEndpoint(apiEndpoint) 149 newinfo.SetAPICredentials(apiCredentials) 150 err = newinfo.Write() 151 c.Assert(err, jc.ErrorIsNil) 152 153 // Prepare the environment so we can destroy it. 154 _, err = environs.PrepareFromName("dummyenv", envcmd.BootstrapContext(cmdtesting.NullContext(c)), s.ConfigStore) 155 c.Assert(err, jc.ErrorIsNil) 156 157 // destroy with broken environment 158 opc, errc := cmdtesting.RunCommand(cmdtesting.NullContext(c), new(DestroyEnvironmentCommand), "dummyenv", "--yes") 159 op, ok := (<-opc).(dummy.OpDestroy) 160 c.Assert(ok, jc.IsTrue) 161 c.Assert(op.Error, gc.ErrorMatches, "dummy.Destroy is broken") 162 c.Check(<-errc, gc.Equals, op.Error) 163 c.Check(<-opc, gc.IsNil) 164 } 165 166 func (*destroyEnvSuite) TestDestroyEnvironmentCommandConfirmationFlag(c *gc.C) { 167 com := new(DestroyEnvironmentCommand) 168 c.Check(coretesting.InitCommand(com, []string{"dummyenv"}), gc.IsNil) 169 c.Check(com.assumeYes, jc.IsFalse) 170 171 com = new(DestroyEnvironmentCommand) 172 c.Check(coretesting.InitCommand(com, []string{"dummyenv", "-y"}), gc.IsNil) 173 c.Check(com.assumeYes, jc.IsTrue) 174 175 com = new(DestroyEnvironmentCommand) 176 c.Check(coretesting.InitCommand(com, []string{"dummyenv", "--yes"}), gc.IsNil) 177 c.Check(com.assumeYes, jc.IsTrue) 178 } 179 180 func (s *destroyEnvSuite) TestDestroyEnvironmentCommandConfirmation(c *gc.C) { 181 var stdin, stdout bytes.Buffer 182 ctx, err := cmd.DefaultContext() 183 c.Assert(err, jc.ErrorIsNil) 184 ctx.Stdout = &stdout 185 ctx.Stdin = &stdin 186 187 // Prepare the environment so we can destroy it. 188 env, err := environs.PrepareFromName("dummyenv", envcmd.BootstrapContext(cmdtesting.NullContext(c)), s.ConfigStore) 189 c.Assert(err, jc.ErrorIsNil) 190 191 assertEnvironNotDestroyed(c, env, s.ConfigStore) 192 193 // Ensure confirmation is requested if "-y" is not specified. 194 stdin.WriteString("n") 195 opc, errc := cmdtesting.RunCommand(ctx, new(DestroyEnvironmentCommand), "dummyenv") 196 c.Check(<-errc, gc.ErrorMatches, "environment destruction aborted") 197 c.Check(<-opc, gc.IsNil) 198 c.Check(stdout.String(), gc.Matches, "WARNING!.*dummyenv.*\\(type: dummy\\)(.|\n)*") 199 assertEnvironNotDestroyed(c, env, s.ConfigStore) 200 201 // EOF on stdin: equivalent to answering no. 202 stdin.Reset() 203 stdout.Reset() 204 opc, errc = cmdtesting.RunCommand(ctx, new(DestroyEnvironmentCommand), "dummyenv") 205 c.Check(<-opc, gc.IsNil) 206 c.Check(<-errc, gc.ErrorMatches, "environment destruction aborted") 207 assertEnvironNotDestroyed(c, env, s.ConfigStore) 208 209 // "--yes" passed: no confirmation request. 210 stdin.Reset() 211 stdout.Reset() 212 opc, errc = cmdtesting.RunCommand(ctx, new(DestroyEnvironmentCommand), "dummyenv", "--yes") 213 c.Check(<-errc, gc.IsNil) 214 c.Check((<-opc).(dummy.OpDestroy).Env, gc.Equals, "dummyenv") 215 c.Check(stdout.String(), gc.Equals, "") 216 assertEnvironDestroyed(c, env, s.ConfigStore) 217 218 // Any of casing of "y" and "yes" will confirm. 219 for _, answer := range []string{"y", "Y", "yes", "YES"} { 220 // Prepare the environment so we can destroy it. 221 s.Reset(c) 222 env, err := environs.PrepareFromName("dummyenv", envcmd.BootstrapContext(cmdtesting.NullContext(c)), s.ConfigStore) 223 c.Assert(err, jc.ErrorIsNil) 224 225 stdin.Reset() 226 stdout.Reset() 227 stdin.WriteString(answer) 228 opc, errc = cmdtesting.RunCommand(ctx, new(DestroyEnvironmentCommand), "dummyenv") 229 c.Check(<-errc, gc.IsNil) 230 c.Check((<-opc).(dummy.OpDestroy).Env, gc.Equals, "dummyenv") 231 c.Check(stdout.String(), gc.Matches, "WARNING!.*dummyenv.*\\(type: dummy\\)(.|\n)*") 232 assertEnvironDestroyed(c, env, s.ConfigStore) 233 } 234 } 235 236 func assertEnvironDestroyed(c *gc.C, env environs.Environ, store configstore.Storage) { 237 _, err := store.ReadInfo(env.Config().Name()) 238 c.Assert(err, jc.Satisfies, errors.IsNotFound) 239 240 _, err = env.Instances([]instance.Id{"invalid"}) 241 c.Assert(err, gc.ErrorMatches, "environment has been destroyed") 242 } 243 244 func assertEnvironNotDestroyed(c *gc.C, env environs.Environ, store configstore.Storage) { 245 info, err := store.ReadInfo(env.Config().Name()) 246 c.Assert(err, jc.ErrorIsNil) 247 c.Assert(info.Initialized(), jc.IsTrue) 248 249 _, err = environs.NewFromName(env.Config().Name(), store) 250 c.Assert(err, jc.ErrorIsNil) 251 }