github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/cmd/juju/application/removeapplication_test.go (about) 1 // Copyright 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package application 5 6 import ( 7 "fmt" 8 9 "github.com/juju/cmd" 10 "github.com/juju/cmd/cmdtesting" 11 "github.com/juju/errors" 12 jc "github.com/juju/testing/checkers" 13 gc "gopkg.in/check.v1" 14 "gopkg.in/juju/charmrepo.v3" 15 16 "github.com/juju/juju/api/annotations" 17 "github.com/juju/juju/api/application" 18 "github.com/juju/juju/api/charms" 19 "github.com/juju/juju/api/modelconfig" 20 "github.com/juju/juju/cmd/modelcmd" 21 jujutesting "github.com/juju/juju/juju/testing" 22 "github.com/juju/juju/state" 23 "github.com/juju/juju/testcharms" 24 "github.com/juju/juju/testing" 25 ) 26 27 type RemoveApplicationSuite struct { 28 jujutesting.RepoSuite 29 testing.CmdBlockHelper 30 } 31 32 var _ = gc.Suite(&RemoveApplicationSuite{}) 33 34 func (s *RemoveApplicationSuite) SetUpTest(c *gc.C) { 35 s.RepoSuite.SetUpTest(c) 36 s.CmdBlockHelper = testing.NewCmdBlockHelper(s.APIState) 37 c.Assert(s.CmdBlockHelper, gc.NotNil) 38 s.AddCleanup(func(*gc.C) { s.CmdBlockHelper.Close() }) 39 } 40 41 func runRemoveApplication(c *gc.C, args ...string) (*cmd.Context, error) { 42 return cmdtesting.RunCommand(c, NewRemoveApplicationCommand(), args...) 43 } 44 45 func (s *RemoveApplicationSuite) setupTestApplication(c *gc.C) { 46 // Destroy an application that exists. 47 ch := testcharms.Repo.CharmArchivePath(s.CharmsPath, "multi-series") 48 err := runDeploy(c, ch, "multi-series") 49 c.Assert(err, jc.ErrorIsNil) 50 } 51 52 func (s *RemoveApplicationSuite) TestLocalApplication(c *gc.C) { 53 s.setupTestApplication(c) 54 ctx, err := runRemoveApplication(c, "multi-series") 55 c.Assert(err, jc.ErrorIsNil) 56 stderr := cmdtesting.Stderr(ctx) 57 c.Assert(stderr, gc.Equals, "removing application multi-series\n") 58 multiSeries, err := s.State.Application("multi-series") 59 c.Assert(err, jc.ErrorIsNil) 60 c.Assert(multiSeries.Life(), gc.Equals, state.Dying) 61 } 62 63 func (s *RemoveApplicationSuite) TestDetachStorage(c *gc.C) { 64 s.testStorageRemoval(c, false) 65 } 66 67 func (s *RemoveApplicationSuite) TestDestroyStorage(c *gc.C) { 68 s.testStorageRemoval(c, true) 69 } 70 71 func (s *RemoveApplicationSuite) testStorageRemoval(c *gc.C, destroy bool) { 72 ch := testcharms.Repo.CharmArchivePath(s.CharmsPath, "storage-filesystem-multi-series") 73 err := runDeploy(c, ch, "storage-filesystem-multi-series", "-n2", "--storage", "data=2,modelscoped") 74 c.Assert(err, jc.ErrorIsNil) 75 76 // Materialise the storage by assigning units to machines. 77 for _, id := range []string{"storage-filesystem-multi-series/0", "storage-filesystem-multi-series/1"} { 78 u, err := s.State.Unit(id) 79 c.Assert(err, jc.ErrorIsNil) 80 err = s.State.AssignUnit(u, state.AssignCleanEmpty) 81 c.Assert(err, jc.ErrorIsNil) 82 } 83 84 args := []string{"storage-filesystem-multi-series"} 85 action := "detach" 86 if destroy { 87 args = append(args, "--destroy-storage") 88 action = "remove" 89 } 90 ctx, err := runRemoveApplication(c, args...) 91 c.Assert(err, jc.ErrorIsNil) 92 stderr := cmdtesting.Stderr(ctx) 93 c.Assert(stderr, gc.Equals, fmt.Sprintf(` 94 removing application storage-filesystem-multi-series 95 - will %[1]s storage data/0 96 - will %[1]s storage data/1 97 - will %[1]s storage data/2 98 - will %[1]s storage data/3 99 `[1:], action)) 100 } 101 102 func (s *RemoveApplicationSuite) TestRemoveLocalMetered(c *gc.C) { 103 ch := testcharms.Repo.CharmArchivePath(s.CharmsPath, "metered-multi-series") 104 deploy := NewDeployCommand() 105 _, err := cmdtesting.RunCommand(c, deploy, ch) 106 c.Assert(err, jc.ErrorIsNil) 107 _, err = runRemoveApplication(c, "metered-multi-series") 108 c.Assert(err, jc.ErrorIsNil) 109 multiSeries, err := s.State.Application("metered-multi-series") 110 c.Assert(err, jc.ErrorIsNil) 111 c.Assert(multiSeries.Life(), gc.Equals, state.Dying) 112 } 113 114 func (s *RemoveApplicationSuite) TestBlockRemoveApplication(c *gc.C) { 115 s.setupTestApplication(c) 116 117 // block operation 118 s.BlockRemoveObject(c, "TestBlockRemoveApplication") 119 _, err := runRemoveApplication(c, "multi-series") 120 s.AssertBlocked(c, err, ".*TestBlockRemoveApplication.*") 121 multiSeries, err := s.State.Application("multi-series") 122 c.Assert(err, jc.ErrorIsNil) 123 c.Assert(multiSeries.Life(), gc.Equals, state.Alive) 124 } 125 126 func (s *RemoveApplicationSuite) TestFailure(c *gc.C) { 127 // Destroy an application that does not exist. 128 ctx, err := runRemoveApplication(c, "gargleblaster") 129 c.Assert(err, gc.Equals, cmd.ErrSilent) 130 131 stderr := cmdtesting.Stderr(ctx) 132 c.Assert(stderr, gc.Equals, ` 133 removing application gargleblaster failed: application "gargleblaster" not found 134 `[1:]) 135 } 136 137 func (s *RemoveApplicationSuite) TestInvalidArgs(c *gc.C) { 138 _, err := runRemoveApplication(c) 139 c.Assert(err, gc.ErrorMatches, `no application specified`) 140 _, err = runRemoveApplication(c, "invalid:name") 141 c.Assert(err, gc.ErrorMatches, `invalid application name "invalid:name"`) 142 } 143 144 type RemoveCharmStoreCharmsSuite struct { 145 charmStoreSuite 146 ctx *cmd.Context 147 } 148 149 var _ = gc.Suite(&RemoveCharmStoreCharmsSuite{}) 150 151 func (s *RemoveCharmStoreCharmsSuite) SetUpTest(c *gc.C) { 152 s.charmStoreSuite.SetUpTest(c) 153 154 s.ctx = cmdtesting.Context(c) 155 156 testcharms.UploadCharm(c, s.client, "cs:quantal/metered-1", "metered") 157 deployCmd := &DeployCommand{} 158 cmd := modelcmd.Wrap(deployCmd) 159 deployCmd.NewAPIRoot = func() (DeployAPI, error) { 160 apiRoot, err := deployCmd.ModelCommandBase.NewAPIRoot() 161 if err != nil { 162 return nil, errors.Trace(err) 163 } 164 bakeryClient, err := deployCmd.BakeryClient() 165 if err != nil { 166 return nil, errors.Trace(err) 167 } 168 cstoreClient := newCharmStoreClient(bakeryClient, s.srv.URL).WithChannel(deployCmd.Channel) 169 return &deployAPIAdapter{ 170 Connection: apiRoot, 171 apiClient: &apiClient{Client: apiRoot.Client()}, 172 charmsClient: &charmsClient{Client: charms.NewClient(apiRoot)}, 173 applicationClient: &applicationClient{Client: application.NewClient(apiRoot)}, 174 modelConfigClient: &modelConfigClient{Client: modelconfig.NewClient(apiRoot)}, 175 charmstoreClient: &charmstoreClient{Client: cstoreClient}, 176 annotationsClient: &annotationsClient{Client: annotations.NewClient(apiRoot)}, 177 charmRepoClient: &charmRepoClient{CharmStore: charmrepo.NewCharmStoreFromClient(cstoreClient)}, 178 }, nil 179 } 180 181 _, err := cmdtesting.RunCommand(c, cmd, "cs:quantal/metered-1") 182 c.Assert(err, jc.ErrorIsNil) 183 184 }