github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/cmd/juju/application/removeunit_test.go (about)

     1  // Copyright 2012, 2013 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package application_test
     5  
     6  import (
     7  	"strings"
     8  
     9  	"github.com/juju/cmd"
    10  	"github.com/juju/cmd/cmdtesting"
    11  	jc "github.com/juju/testing/checkers"
    12  	gc "gopkg.in/check.v1"
    13  
    14  	apiapplication "github.com/juju/juju/api/application"
    15  	"github.com/juju/juju/apiserver/common"
    16  	"github.com/juju/juju/apiserver/params"
    17  	"github.com/juju/juju/cmd/juju/application"
    18  	"github.com/juju/juju/core/model"
    19  	"github.com/juju/juju/jujuclient"
    20  	"github.com/juju/juju/jujuclient/jujuclienttesting"
    21  	"github.com/juju/juju/testing"
    22  )
    23  
    24  type RemoveUnitSuite struct {
    25  	testing.FakeJujuXDGDataHomeSuite
    26  	fake *fakeApplicationRemoveUnitAPI
    27  
    28  	store *jujuclient.MemStore
    29  }
    30  
    31  var _ = gc.Suite(&RemoveUnitSuite{})
    32  
    33  type fakeApplicationRemoveUnitAPI struct {
    34  	application.RemoveApplicationAPI
    35  
    36  	units          []string
    37  	scale          int
    38  	destroyStorage bool
    39  	bestAPIVersion int
    40  	err            error
    41  }
    42  
    43  func (f *fakeApplicationRemoveUnitAPI) BestAPIVersion() int {
    44  	return f.bestAPIVersion
    45  }
    46  
    47  func (f *fakeApplicationRemoveUnitAPI) Close() error {
    48  	return nil
    49  }
    50  
    51  func (f *fakeApplicationRemoveUnitAPI) ModelUUID() string {
    52  	return "fake-uuid"
    53  }
    54  
    55  func (f *fakeApplicationRemoveUnitAPI) DestroyUnits(args apiapplication.DestroyUnitsParams) ([]params.DestroyUnitResult, error) {
    56  	if f.err != nil {
    57  		return nil, f.err
    58  	}
    59  	f.units = args.Units
    60  	f.destroyStorage = args.DestroyStorage
    61  	var result []params.DestroyUnitResult
    62  	for _, u := range args.Units {
    63  		var info *params.DestroyUnitInfo
    64  		var err *params.Error
    65  		switch u {
    66  		case "unit/0":
    67  			st := []params.Entity{{Tag: "storage-data-0"}}
    68  			info = &params.DestroyUnitInfo{}
    69  			if f.destroyStorage {
    70  				info.DestroyedStorage = st
    71  			} else {
    72  				info.DetachedStorage = st
    73  			}
    74  		case "unit/1":
    75  			st := []params.Entity{{Tag: "storage-data-1"}}
    76  			info = &params.DestroyUnitInfo{}
    77  			if f.destroyStorage {
    78  				info.DestroyedStorage = st
    79  			} else {
    80  				info.DetachedStorage = st
    81  			}
    82  		case "unit/2":
    83  			err = &params.Error{Code: params.CodeNotFound, Message: `unit "unit/2" does not exist`}
    84  		}
    85  		result = append(result, params.DestroyUnitResult{
    86  			Info:  info,
    87  			Error: err,
    88  		})
    89  	}
    90  	return result, nil
    91  }
    92  
    93  func (f *fakeApplicationRemoveUnitAPI) ScaleApplication(args apiapplication.ScaleApplicationParams) (params.ScaleApplicationResult, error) {
    94  	if f.err != nil {
    95  		return params.ScaleApplicationResult{}, f.err
    96  	}
    97  	f.scale += args.ScaleChange
    98  	return params.ScaleApplicationResult{
    99  		Info: &params.ScaleApplicationInfo{
   100  			Scale: f.scale,
   101  		},
   102  	}, nil
   103  }
   104  
   105  func (s *RemoveUnitSuite) SetUpTest(c *gc.C) {
   106  	s.FakeJujuXDGDataHomeSuite.SetUpTest(c)
   107  	s.fake = &fakeApplicationRemoveUnitAPI{
   108  		bestAPIVersion: 5,
   109  		scale:          5,
   110  	}
   111  	s.store = jujuclienttesting.MinimalStore()
   112  }
   113  
   114  func (s *RemoveUnitSuite) runRemoveUnit(c *gc.C, args ...string) (*cmd.Context, error) {
   115  	return cmdtesting.RunCommand(c, application.NewRemoveUnitCommandForTest(s.fake, s.store), args...)
   116  }
   117  
   118  func (s *RemoveUnitSuite) TestRemoveUnit(c *gc.C) {
   119  	ctx, err := s.runRemoveUnit(c, "unit/0", "unit/1", "unit/2")
   120  	c.Assert(err, gc.Equals, cmd.ErrSilent)
   121  	c.Assert(s.fake.units, jc.DeepEquals, []string{"unit/0", "unit/1", "unit/2"})
   122  	c.Assert(s.fake.destroyStorage, jc.IsFalse)
   123  
   124  	stderr := cmdtesting.Stderr(ctx)
   125  	c.Assert(stderr, gc.Equals, `
   126  removing unit unit/0
   127  - will detach storage data/0
   128  removing unit unit/1
   129  - will detach storage data/1
   130  removing unit unit/2 failed: unit "unit/2" does not exist
   131  `[1:])
   132  }
   133  
   134  func (s *RemoveUnitSuite) TestRemoveUnitDestroyStorage(c *gc.C) {
   135  	ctx, err := s.runRemoveUnit(c, "unit/0", "unit/1", "unit/2", "--destroy-storage")
   136  	c.Assert(err, gc.Equals, cmd.ErrSilent)
   137  	c.Assert(s.fake.units, jc.DeepEquals, []string{"unit/0", "unit/1", "unit/2"})
   138  	c.Assert(s.fake.destroyStorage, jc.IsTrue)
   139  
   140  	stderr := cmdtesting.Stderr(ctx)
   141  	c.Assert(stderr, gc.Equals, `
   142  removing unit unit/0
   143  - will remove storage data/0
   144  removing unit unit/1
   145  - will remove storage data/1
   146  removing unit unit/2 failed: unit "unit/2" does not exist
   147  `[1:])
   148  }
   149  
   150  func (s *RemoveUnitSuite) TestBlockRemoveUnit(c *gc.C) {
   151  	// Block operation
   152  	s.fake.err = common.OperationBlockedError("TestBlockRemoveUnit")
   153  	s.runRemoveUnit(c, "some-unit-name/0")
   154  
   155  	// msg is logged
   156  	stripped := strings.Replace(c.GetTestLog(), "\n", "", -1)
   157  	c.Check(stripped, gc.Matches, ".*TestBlockRemoveUnit.*")
   158  }
   159  
   160  func (s *RemoveUnitSuite) TestCAASRemoveUnit(c *gc.C) {
   161  	m := s.store.Models["arthur"].Models["king/sword"]
   162  	m.ModelType = model.CAAS
   163  	s.store.Models["arthur"].Models["king/sword"] = m
   164  
   165  	ctx, err := s.runRemoveUnit(c, "some-application-name", "--num-units", "2")
   166  	c.Assert(err, jc.ErrorIsNil)
   167  
   168  	stderr := cmdtesting.Stderr(ctx)
   169  	c.Assert(stderr, gc.Equals, `
   170  scaling down to 3 units
   171  `[1:])
   172  }
   173  
   174  func (s *RemoveUnitSuite) TestCAASAllowsNumUnitsOnly(c *gc.C) {
   175  	m := s.store.Models["arthur"].Models["king/sword"]
   176  	m.ModelType = model.CAAS
   177  	s.store.Models["arthur"].Models["king/sword"] = m
   178  
   179  	_, err := s.runRemoveUnit(c, "some-application-name")
   180  	c.Assert(err, gc.ErrorMatches, "removing 0 units not valid")
   181  
   182  	_, err = s.runRemoveUnit(c, "some-application-name", "--destroy-storage")
   183  	c.Assert(err, gc.ErrorMatches, "Kubernetes models only support --num-units")
   184  
   185  	_, err = s.runRemoveUnit(c, "some-application-name/0", "--num-units", "2")
   186  	c.Assert(err, gc.ErrorMatches, "application name \"some-application-name/0\" not valid")
   187  
   188  	_, err = s.runRemoveUnit(c, "some-application-name", "another-application", "--num-units", "2")
   189  	c.Assert(err, gc.ErrorMatches, "only single application supported")
   190  
   191  	_, err = s.runRemoveUnit(c, "some-application-name", "--num-units", "2")
   192  	c.Assert(err, jc.ErrorIsNil)
   193  }