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  }