github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/apiserver/common/modeldestroy_test.go (about)

     1  // Copyright 2012-2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package common_test
     5  
     6  import (
     7  	"github.com/juju/errors"
     8  	jtesting "github.com/juju/testing"
     9  	jc "github.com/juju/testing/checkers"
    10  	gc "gopkg.in/check.v1"
    11  	"gopkg.in/juju/names.v2"
    12  
    13  	"github.com/juju/juju/apiserver/common"
    14  	"github.com/juju/juju/apiserver/facades/agent/metricsender"
    15  	"github.com/juju/juju/state"
    16  	"github.com/juju/juju/testing"
    17  )
    18  
    19  type destroyModelSuite struct {
    20  	jtesting.IsolationSuite
    21  
    22  	modelManager *mockModelManager
    23  	metricSender *testMetricSender
    24  }
    25  
    26  var _ = gc.Suite(&destroyModelSuite{})
    27  
    28  func (s *destroyModelSuite) SetUpTest(c *gc.C) {
    29  	s.IsolationSuite.SetUpTest(c)
    30  
    31  	otherModelTag := names.NewModelTag("deadbeef-0bad-400d-8000-4b1d0d06f33d")
    32  	s.modelManager = &mockModelManager{
    33  		models: []*mockModel{
    34  			{tag: testing.ModelTag},
    35  			{tag: otherModelTag},
    36  		},
    37  	}
    38  	s.metricSender = &testMetricSender{}
    39  	s.PatchValue(common.SendMetrics, s.metricSender.SendMetrics)
    40  }
    41  
    42  func (s *destroyModelSuite) TestDestroyModelSendsMetrics(c *gc.C) {
    43  	err := common.DestroyModel(s.modelManager, nil)
    44  	c.Assert(err, jc.ErrorIsNil)
    45  	s.metricSender.CheckCalls(c, []jtesting.StubCall{
    46  		{"SendMetrics", []interface{}{s.modelManager}},
    47  	})
    48  }
    49  
    50  func (s *destroyModelSuite) TestDestroyModel(c *gc.C) {
    51  	true_ := true
    52  	false_ := false
    53  	s.testDestroyModel(c, nil)
    54  	s.testDestroyModel(c, &true_)
    55  	s.testDestroyModel(c, &false_)
    56  }
    57  
    58  func (s *destroyModelSuite) testDestroyModel(c *gc.C, destroyStorage *bool) {
    59  	s.modelManager.ResetCalls()
    60  	s.modelManager.models[0].ResetCalls()
    61  
    62  	err := common.DestroyModel(s.modelManager, destroyStorage)
    63  	c.Assert(err, jc.ErrorIsNil)
    64  
    65  	s.modelManager.CheckCalls(c, []jtesting.StubCall{
    66  		{"GetBlockForType", []interface{}{state.DestroyBlock}},
    67  		{"GetBlockForType", []interface{}{state.RemoveBlock}},
    68  		{"GetBlockForType", []interface{}{state.ChangeBlock}},
    69  		{"Model", nil},
    70  	})
    71  
    72  	s.modelManager.models[0].CheckCalls(c, []jtesting.StubCall{
    73  		{"Destroy", []interface{}{state.DestroyModelParams{
    74  			DestroyStorage: destroyStorage,
    75  		}}},
    76  	})
    77  }
    78  
    79  func (s *destroyModelSuite) TestDestroyModelBlocked(c *gc.C) {
    80  	s.modelManager.SetErrors(errors.New("nope"))
    81  
    82  	err := common.DestroyModel(s.modelManager, nil)
    83  	c.Assert(err, gc.ErrorMatches, "nope")
    84  
    85  	s.modelManager.CheckCallNames(c, "GetBlockForType")
    86  	s.modelManager.models[0].CheckNoCalls(c)
    87  }
    88  
    89  func (s *destroyModelSuite) TestDestroyControllerNonControllerModel(c *gc.C) {
    90  	s.modelManager.models[0].tag = s.modelManager.models[1].tag
    91  	err := common.DestroyController(s.modelManager, false, nil)
    92  	c.Assert(err, gc.ErrorMatches, `expected state for controller model UUID deadbeef-0bad-400d-8000-4b1d0d06f33d, got deadbeef-0bad-400d-8000-4b1d0d06f00d`)
    93  }
    94  
    95  func (s *destroyModelSuite) TestDestroyController(c *gc.C) {
    96  	err := common.DestroyController(s.modelManager, false, nil)
    97  	c.Assert(err, jc.ErrorIsNil)
    98  
    99  	s.modelManager.CheckCalls(c, []jtesting.StubCall{
   100  		{"ControllerModelTag", nil},
   101  		{"GetBlockForType", []interface{}{state.DestroyBlock}},
   102  		{"GetBlockForType", []interface{}{state.RemoveBlock}},
   103  		{"GetBlockForType", []interface{}{state.ChangeBlock}},
   104  		{"Model", nil},
   105  	})
   106  	s.modelManager.models[0].CheckCalls(c, []jtesting.StubCall{
   107  		{"Destroy", []interface{}{state.DestroyModelParams{}}},
   108  	})
   109  }
   110  
   111  func (s *destroyModelSuite) TestDestroyControllerReleaseStorage(c *gc.C) {
   112  	destroyStorage := false
   113  	err := common.DestroyController(s.modelManager, false, &destroyStorage)
   114  	c.Assert(err, jc.ErrorIsNil)
   115  
   116  	s.modelManager.CheckCalls(c, []jtesting.StubCall{
   117  		{"ControllerModelTag", nil},
   118  		{"GetBlockForType", []interface{}{state.DestroyBlock}},
   119  		{"GetBlockForType", []interface{}{state.RemoveBlock}},
   120  		{"GetBlockForType", []interface{}{state.ChangeBlock}},
   121  		{"Model", nil},
   122  	})
   123  	s.modelManager.models[0].CheckCalls(c, []jtesting.StubCall{
   124  		{"Destroy", []interface{}{state.DestroyModelParams{
   125  			DestroyStorage: &destroyStorage,
   126  		}}},
   127  	})
   128  }
   129  
   130  func (s *destroyModelSuite) TestDestroyControllerDestroyHostedModels(c *gc.C) {
   131  	err := common.DestroyController(s.modelManager, true, nil)
   132  	c.Assert(err, jc.ErrorIsNil)
   133  
   134  	s.modelManager.CheckCalls(c, []jtesting.StubCall{
   135  		{"ControllerModelTag", nil},
   136  		{"AllModelUUIDs", nil},
   137  
   138  		{"GetBackend", []interface{}{s.modelManager.models[0].tag.Id()}},
   139  		{"GetBlockForType", []interface{}{state.DestroyBlock}},
   140  		{"GetBlockForType", []interface{}{state.RemoveBlock}},
   141  		{"GetBlockForType", []interface{}{state.ChangeBlock}},
   142  
   143  		{"GetBackend", []interface{}{s.modelManager.models[1].tag.Id()}},
   144  		{"GetBlockForType", []interface{}{state.DestroyBlock}},
   145  		{"GetBlockForType", []interface{}{state.RemoveBlock}},
   146  		{"GetBlockForType", []interface{}{state.ChangeBlock}},
   147  
   148  		{"GetBlockForType", []interface{}{state.DestroyBlock}},
   149  		{"GetBlockForType", []interface{}{state.RemoveBlock}},
   150  		{"GetBlockForType", []interface{}{state.ChangeBlock}},
   151  		{"Model", nil},
   152  	})
   153  	s.modelManager.models[0].CheckCalls(c, []jtesting.StubCall{
   154  		{"Destroy", []interface{}{state.DestroyModelParams{
   155  			DestroyHostedModels: true,
   156  		}}},
   157  	})
   158  	s.metricSender.CheckCalls(c, []jtesting.StubCall{
   159  		// One call per hosted model, and one for the controller model.
   160  		{"SendMetrics", []interface{}{s.modelManager}},
   161  		{"SendMetrics", []interface{}{s.modelManager}},
   162  		{"SendMetrics", []interface{}{s.modelManager}},
   163  	})
   164  }
   165  
   166  func (s *destroyModelSuite) TestDestroyControllerModelErrs(c *gc.C) {
   167  	// This is similar to what we'd see if a model was destroyed
   168  	// but there are still some connections to it lingering.
   169  	s.modelManager.SetErrors(
   170  		nil, // for GetBackend, 1st model
   171  		nil, // for GetBlockForType, 1st model
   172  		nil, // for GetBlockForType, 1st model
   173  		nil, // for GetBlockForType, 1st model
   174  		errors.NotFoundf("pretend I am not here"), // for GetBackend, 2nd model
   175  	)
   176  	err := common.DestroyController(s.modelManager, true, nil)
   177  	// Processing continued despite one model erring out.
   178  	c.Assert(err, jc.ErrorIsNil)
   179  
   180  	s.modelManager.SetErrors(
   181  		nil,                            // for GetBackend, 1st model
   182  		nil,                            // for GetBlockForType, 1st model
   183  		nil,                            // for GetBlockForType, 1st model
   184  		nil,                            // for GetBlockForType, 1st model
   185  		errors.New("I have a problem"), // for GetBackend, 2nd model
   186  	)
   187  	err = common.DestroyController(s.modelManager, true, nil)
   188  	// Processing erred out since a model seriously failed.
   189  	c.Assert(err, gc.ErrorMatches, "I have a problem")
   190  }
   191  
   192  type testMetricSender struct {
   193  	jtesting.Stub
   194  }
   195  
   196  func (t *testMetricSender) SendMetrics(st metricsender.ModelBackend) error {
   197  	t.MethodCall(t, "SendMetrics", st)
   198  	return t.NextErr()
   199  }
   200  
   201  type mockModelManager struct {
   202  	common.ModelManagerBackend
   203  	jtesting.Stub
   204  
   205  	models []*mockModel
   206  }
   207  
   208  func (m *mockModelManager) ControllerModelUUID() string {
   209  	m.MethodCall(m, "ControllerModelUUID")
   210  	return m.models[0].UUID()
   211  }
   212  
   213  func (m *mockModelManager) ControllerModelTag() names.ModelTag {
   214  	m.MethodCall(m, "ControllerModelTag")
   215  	return m.models[0].ModelTag()
   216  }
   217  
   218  func (m *mockModelManager) ModelTag() names.ModelTag {
   219  	return testing.ModelTag
   220  }
   221  
   222  func (m *mockModelManager) GetBlockForType(t state.BlockType) (state.Block, bool, error) {
   223  	m.MethodCall(m, "GetBlockForType", t)
   224  	return nil, false, m.NextErr()
   225  }
   226  
   227  func (m *mockModelManager) AllModelUUIDs() ([]string, error) {
   228  	m.MethodCall(m, "AllModelUUIDs")
   229  	var out []string
   230  	for _, model := range m.models {
   231  		out = append(out, model.UUID())
   232  	}
   233  	return out, nil
   234  }
   235  
   236  func (m *mockModelManager) Model() (common.Model, error) {
   237  	m.MethodCall(m, "Model")
   238  	return m.models[0], m.NextErr()
   239  }
   240  
   241  func (m *mockModelManager) GetBackend(uuid string) (common.ModelManagerBackend, func() bool, error) {
   242  	m.MethodCall(m, "GetBackend", uuid)
   243  	return m, func() bool { return true }, m.NextErr()
   244  }
   245  
   246  func (m *mockModelManager) Close() error {
   247  	m.MethodCall(m, "Close")
   248  	return m.NextErr()
   249  }
   250  
   251  type mockModel struct {
   252  	common.Model
   253  	jtesting.Stub
   254  	tag names.ModelTag
   255  }
   256  
   257  func (m *mockModel) ModelTag() names.ModelTag {
   258  	return m.tag
   259  }
   260  
   261  func (m *mockModel) UUID() string {
   262  	return m.tag.Id()
   263  }
   264  
   265  func (m *mockModel) Destroy(args state.DestroyModelParams) error {
   266  	m.MethodCall(m, "Destroy", args)
   267  	return m.NextErr()
   268  }