github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/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  	"github.com/juju/cmd"
     8  	"github.com/juju/errors"
     9  	jc "github.com/juju/testing/checkers"
    10  	gc "gopkg.in/check.v1"
    11  	"gopkg.in/juju/charmrepo.v2-unstable"
    12  	"gopkg.in/macaroon-bakery.v1/httpbakery"
    13  
    14  	"github.com/juju/juju/api/annotations"
    15  	"github.com/juju/juju/api/application"
    16  	"github.com/juju/juju/api/charms"
    17  	"github.com/juju/juju/api/modelconfig"
    18  	"github.com/juju/juju/cmd/modelcmd"
    19  	jujutesting "github.com/juju/juju/juju/testing"
    20  	"github.com/juju/juju/rpc"
    21  	"github.com/juju/juju/state"
    22  	"github.com/juju/juju/testcharms"
    23  	"github.com/juju/juju/testing"
    24  	jutesting "github.com/juju/testing"
    25  )
    26  
    27  type RemoveServiceSuite struct {
    28  	jujutesting.RepoSuite
    29  	testing.CmdBlockHelper
    30  	stub            *jutesting.Stub
    31  	budgetAPIClient budgetAPIClient
    32  }
    33  
    34  var _ = gc.Suite(&RemoveServiceSuite{})
    35  
    36  func (s *RemoveServiceSuite) SetUpTest(c *gc.C) {
    37  	s.RepoSuite.SetUpTest(c)
    38  	s.CmdBlockHelper = testing.NewCmdBlockHelper(s.APIState)
    39  	c.Assert(s.CmdBlockHelper, gc.NotNil)
    40  	s.AddCleanup(func(*gc.C) { s.CmdBlockHelper.Close() })
    41  	s.stub = &jutesting.Stub{}
    42  	s.budgetAPIClient = &mockBudgetAPIClient{Stub: s.stub}
    43  	s.PatchValue(&getBudgetAPIClient, func(*httpbakery.Client) budgetAPIClient { return s.budgetAPIClient })
    44  }
    45  
    46  func runRemoveService(c *gc.C, args ...string) error {
    47  	_, err := testing.RunCommand(c, NewRemoveServiceCommand(), args...)
    48  	return err
    49  }
    50  
    51  func (s *RemoveServiceSuite) setupTestService(c *gc.C) {
    52  	// Destroy an application that exists.
    53  	ch := testcharms.Repo.CharmArchivePath(s.CharmsPath, "riak")
    54  	err := runDeploy(c, ch, "riak", "--series", "quantal")
    55  	c.Assert(err, jc.ErrorIsNil)
    56  }
    57  
    58  func (s *RemoveServiceSuite) TestSuccess(c *gc.C) {
    59  	s.setupTestService(c)
    60  	err := runRemoveService(c, "riak")
    61  	c.Assert(err, jc.ErrorIsNil)
    62  	riak, err := s.State.Application("riak")
    63  	c.Assert(err, jc.ErrorIsNil)
    64  	c.Assert(riak.Life(), gc.Equals, state.Dying)
    65  	s.stub.CheckNoCalls(c)
    66  }
    67  
    68  func (s *RemoveServiceSuite) TestRemoveLocalMetered(c *gc.C) {
    69  	ch := testcharms.Repo.CharmArchivePath(s.CharmsPath, "metered")
    70  	deploy := NewDefaultDeployCommand()
    71  	_, err := testing.RunCommand(c, deploy, ch, "--series", "quantal")
    72  	c.Assert(err, jc.ErrorIsNil)
    73  	err = runRemoveService(c, "metered")
    74  	c.Assert(err, jc.ErrorIsNil)
    75  	riak, err := s.State.Application("metered")
    76  	c.Assert(err, jc.ErrorIsNil)
    77  	c.Assert(riak.Life(), gc.Equals, state.Dying)
    78  	s.stub.CheckNoCalls(c)
    79  }
    80  
    81  func (s *RemoveServiceSuite) TestBlockRemoveService(c *gc.C) {
    82  	s.setupTestService(c)
    83  
    84  	// block operation
    85  	s.BlockRemoveObject(c, "TestBlockRemoveService")
    86  	err := runRemoveService(c, "riak")
    87  	s.AssertBlocked(c, err, ".*TestBlockRemoveService.*")
    88  	riak, err := s.State.Application("riak")
    89  	c.Assert(err, jc.ErrorIsNil)
    90  	c.Assert(riak.Life(), gc.Equals, state.Alive)
    91  	s.stub.CheckNoCalls(c)
    92  }
    93  
    94  func (s *RemoveServiceSuite) TestFailure(c *gc.C) {
    95  	// Destroy an application that does not exist.
    96  	err := runRemoveService(c, "gargleblaster")
    97  	c.Assert(errors.Cause(err), gc.DeepEquals, &rpc.RequestError{
    98  		Message: `application "gargleblaster" not found`,
    99  		Code:    "not found",
   100  	})
   101  	s.stub.CheckNoCalls(c)
   102  }
   103  
   104  func (s *RemoveServiceSuite) TestInvalidArgs(c *gc.C) {
   105  	err := runRemoveService(c)
   106  	c.Assert(err, gc.ErrorMatches, `no application specified`)
   107  	err = runRemoveService(c, "ping", "pong")
   108  	c.Assert(err, gc.ErrorMatches, `unrecognized args: \["pong"\]`)
   109  	err = runRemoveService(c, "invalid:name")
   110  	c.Assert(err, gc.ErrorMatches, `invalid application name "invalid:name"`)
   111  	s.stub.CheckNoCalls(c)
   112  }
   113  
   114  type RemoveCharmStoreCharmsSuite struct {
   115  	charmStoreSuite
   116  	stub            *jutesting.Stub
   117  	ctx             *cmd.Context
   118  	budgetAPIClient budgetAPIClient
   119  }
   120  
   121  var _ = gc.Suite(&RemoveCharmStoreCharmsSuite{})
   122  
   123  func (s *RemoveCharmStoreCharmsSuite) SetUpTest(c *gc.C) {
   124  	s.charmStoreSuite.SetUpTest(c)
   125  
   126  	s.ctx = testing.Context(c)
   127  	s.stub = &jutesting.Stub{}
   128  	s.budgetAPIClient = &mockBudgetAPIClient{Stub: s.stub}
   129  	s.PatchValue(&getBudgetAPIClient, func(*httpbakery.Client) budgetAPIClient { return s.budgetAPIClient })
   130  
   131  	testcharms.UploadCharm(c, s.client, "cs:quantal/metered-1", "metered")
   132  	deployCmd := &DeployCommand{}
   133  	cmd := modelcmd.Wrap(deployCmd)
   134  	deployCmd.NewAPIRoot = func() (DeployAPI, error) {
   135  		apiRoot, err := deployCmd.ModelCommandBase.NewAPIRoot()
   136  		if err != nil {
   137  			return nil, errors.Trace(err)
   138  		}
   139  		bakeryClient, err := deployCmd.BakeryClient()
   140  		if err != nil {
   141  			return nil, errors.Trace(err)
   142  		}
   143  		cstoreClient := newCharmStoreClient(bakeryClient).WithChannel(deployCmd.Channel)
   144  		return &deployAPIAdapter{
   145  			Connection:        apiRoot,
   146  			apiClient:         &apiClient{Client: apiRoot.Client()},
   147  			charmsClient:      &charmsClient{Client: charms.NewClient(apiRoot)},
   148  			applicationClient: &applicationClient{Client: application.NewClient(apiRoot)},
   149  			modelConfigClient: &modelConfigClient{Client: modelconfig.NewClient(apiRoot)},
   150  			charmstoreClient:  &charmstoreClient{Client: cstoreClient},
   151  			annotationsClient: &annotationsClient{Client: annotations.NewClient(apiRoot)},
   152  			charmRepoClient:   &charmRepoClient{CharmStore: charmrepo.NewCharmStoreFromClient(cstoreClient)},
   153  		}, nil
   154  	}
   155  
   156  	_, err := testing.RunCommand(c, cmd, "cs:quantal/metered-1")
   157  	c.Assert(err, jc.ErrorIsNil)
   158  
   159  }
   160  
   161  func (s *RemoveCharmStoreCharmsSuite) TestRemoveAllocation(c *gc.C) {
   162  	err := runRemoveService(c, "metered")
   163  	c.Assert(err, jc.ErrorIsNil)
   164  	s.stub.CheckCalls(c, []jutesting.StubCall{{
   165  		"DeleteAllocation", []interface{}{testing.ModelTag.Id(), "metered"}}})
   166  }
   167  
   168  type mockBudgetAPIClient struct {
   169  	*jutesting.Stub
   170  }
   171  
   172  // CreateAllocation implements apiClient.
   173  func (c *mockBudgetAPIClient) CreateAllocation(budget, limit, model string, services []string) (string, error) {
   174  	c.MethodCall(c, "CreateAllocation", budget, limit, model, services)
   175  	return "Allocation created.", c.NextErr()
   176  }
   177  
   178  // DeleteAllocation implements apiClient.
   179  func (c *mockBudgetAPIClient) DeleteAllocation(model, application string) (string, error) {
   180  	c.MethodCall(c, "DeleteAllocation", model, application)
   181  	return "Allocation removed.", c.NextErr()
   182  }