github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/apiserver/facades/controller/modelupgrader/modelupgrader_test.go (about)

     1  // Copyright 2017 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package modelupgrader_test
     5  
     6  import (
     7  	"github.com/juju/errors"
     8  	"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/controller/modelupgrader"
    15  	"github.com/juju/juju/apiserver/params"
    16  	apiservertesting "github.com/juju/juju/apiserver/testing"
    17  	"github.com/juju/juju/cloud"
    18  	"github.com/juju/juju/environs"
    19  )
    20  
    21  var (
    22  	modelTag1 = names.NewModelTag("6e114b25-fc6d-448e-b58a-22fff690689e")
    23  	modelTag2 = names.NewModelTag("631d2cbe-1085-4b74-ab76-41badfc73d9a")
    24  )
    25  
    26  type ModelUpgraderSuite struct {
    27  	testing.IsolationSuite
    28  	backend      mockBackend
    29  	pool         mockPool
    30  	providers    mockProviderRegistry
    31  	watcher      mockWatcher
    32  	statusSetter mockStatusSetter
    33  	authorizer   apiservertesting.FakeAuthorizer
    34  }
    35  
    36  var _ = gc.Suite(&ModelUpgraderSuite{})
    37  
    38  func (s *ModelUpgraderSuite) SetUpTest(c *gc.C) {
    39  	s.IsolationSuite.SetUpTest(c)
    40  	s.authorizer = apiservertesting.FakeAuthorizer{
    41  		Controller: true,
    42  		Tag:        names.NewMachineTag("0"),
    43  	}
    44  	s.backend = mockBackend{
    45  		clouds: map[string]cloud.Cloud{
    46  			"foo": {Type: "foo-provider"},
    47  			"bar": {Type: "bar-provider"},
    48  		},
    49  	}
    50  	s.pool = mockPool{
    51  		models: map[string]*mockModel{
    52  			modelTag1.Id(): {cloud: "foo", v: 0},
    53  			modelTag2.Id(): {cloud: "bar", v: 1},
    54  		},
    55  	}
    56  	s.providers = mockProviderRegistry{
    57  		providers: map[string]*mockProvider{
    58  			"foo-provider": {version: 123},
    59  		},
    60  	}
    61  	s.watcher = mockWatcher{}
    62  	s.statusSetter = mockStatusSetter{}
    63  }
    64  
    65  func (s *ModelUpgraderSuite) TestAuthController(c *gc.C) {
    66  	_, err := modelupgrader.NewFacade(&s.backend, &s.pool, &s.providers, &s.watcher, &s.statusSetter, &s.authorizer)
    67  	c.Assert(err, jc.ErrorIsNil)
    68  }
    69  
    70  func (s *ModelUpgraderSuite) TestAuthNonController(c *gc.C) {
    71  	s.authorizer.Controller = false
    72  	s.authorizer.Tag = names.NewUserTag("admin")
    73  	_, err := modelupgrader.NewFacade(&s.backend, &s.pool, &s.providers, &s.watcher, &s.statusSetter, &s.authorizer)
    74  	c.Assert(err, gc.Equals, common.ErrPerm)
    75  }
    76  
    77  func (s *ModelUpgraderSuite) TestModelEnvironVersion(c *gc.C) {
    78  	facade, err := modelupgrader.NewFacade(&s.backend, &s.pool, &s.providers, &s.watcher, &s.statusSetter, &s.authorizer)
    79  	c.Assert(err, jc.ErrorIsNil)
    80  	results, err := facade.ModelEnvironVersion(params.Entities{
    81  		Entities: []params.Entity{
    82  			{Tag: modelTag1.String()},
    83  			{Tag: modelTag2.String()},
    84  			{Tag: "machine-0"},
    85  		},
    86  	})
    87  	c.Assert(err, jc.ErrorIsNil)
    88  	c.Assert(results, jc.DeepEquals, params.IntResults{
    89  		Results: []params.IntResult{{
    90  			Result: 0,
    91  		}, {
    92  			Result: 1,
    93  		}, {
    94  			Error: &params.Error{Message: `"machine-0" is not a valid model tag`},
    95  		}},
    96  	})
    97  	s.pool.CheckCalls(c, []testing.StubCall{
    98  		{"GetModel", []interface{}{modelTag1.Id()}},
    99  		{"GetModel", []interface{}{modelTag2.Id()}},
   100  	})
   101  	s.pool.models[modelTag1.Id()].CheckCallNames(c, "EnvironVersion")
   102  	s.pool.models[modelTag2.Id()].CheckCallNames(c, "EnvironVersion")
   103  }
   104  
   105  func (s *ModelUpgraderSuite) TestModelTargetEnvironVersion(c *gc.C) {
   106  	s.providers.SetErrors(nil, errors.New("blargh"))
   107  	facade, err := modelupgrader.NewFacade(&s.backend, &s.pool, &s.providers, &s.watcher, &s.statusSetter, &s.authorizer)
   108  	c.Assert(err, jc.ErrorIsNil)
   109  	results, err := facade.ModelTargetEnvironVersion(params.Entities{
   110  		Entities: []params.Entity{
   111  			{Tag: modelTag1.String()},
   112  			{Tag: modelTag2.String()},
   113  			{Tag: "machine-0"},
   114  		},
   115  	})
   116  	c.Assert(err, jc.ErrorIsNil)
   117  	c.Assert(results, jc.DeepEquals, params.IntResults{
   118  		Results: []params.IntResult{{
   119  			Result: 123,
   120  		}, {
   121  			Error: &params.Error{Message: `blargh`},
   122  		}, {
   123  			Error: &params.Error{Message: `"machine-0" is not a valid model tag`},
   124  		}},
   125  	})
   126  	s.backend.CheckCalls(c, []testing.StubCall{
   127  		{"Cloud", []interface{}{"foo"}},
   128  		{"Cloud", []interface{}{"bar"}},
   129  	})
   130  	s.pool.CheckCalls(c, []testing.StubCall{
   131  		{"GetModel", []interface{}{modelTag1.Id()}},
   132  		{"GetModel", []interface{}{modelTag2.Id()}},
   133  	})
   134  	s.pool.models[modelTag1.Id()].CheckCallNames(c, "Cloud")
   135  	s.pool.models[modelTag2.Id()].CheckCallNames(c, "Cloud")
   136  	s.providers.CheckCalls(c, []testing.StubCall{
   137  		{"Provider", []interface{}{"foo-provider"}},
   138  		{"Provider", []interface{}{"bar-provider"}},
   139  	})
   140  	s.providers.providers["foo-provider"].CheckCallNames(c, "Version")
   141  }
   142  
   143  func (s *ModelUpgraderSuite) TestSetModelEnvironVersion(c *gc.C) {
   144  	facade, err := modelupgrader.NewFacade(&s.backend, &s.pool, &s.providers, &s.watcher, &s.statusSetter, &s.authorizer)
   145  	c.Assert(err, jc.ErrorIsNil)
   146  	results, err := facade.SetModelEnvironVersion(params.SetModelEnvironVersions{
   147  		Models: []params.SetModelEnvironVersion{
   148  			{ModelTag: modelTag1.String(), Version: 1},
   149  			{ModelTag: "machine-0", Version: 0},
   150  		},
   151  	})
   152  	c.Assert(err, jc.ErrorIsNil)
   153  	c.Assert(results, jc.DeepEquals, params.ErrorResults{
   154  		Results: []params.ErrorResult{
   155  			{},
   156  			{&params.Error{Message: `"machine-0" is not a valid model tag`}},
   157  		},
   158  	})
   159  	s.pool.CheckCalls(c, []testing.StubCall{
   160  		{"GetModel", []interface{}{modelTag1.Id()}},
   161  	})
   162  	s.pool.models[modelTag1.Id()].CheckCalls(c, []testing.StubCall{
   163  		{"SetEnvironVersion", []interface{}{int(1)}},
   164  	})
   165  }
   166  
   167  func (s *ModelUpgraderSuite) TestSetModelStatus(c *gc.C) {
   168  	args := params.SetStatus{
   169  		Entities: []params.EntityStatusArgs{{
   170  			Tag:    "machine-0",
   171  			Status: "bar",
   172  			Info:   "baz",
   173  			Data: map[string]interface{}{
   174  				"qux": "quux",
   175  			},
   176  		}},
   177  	}
   178  	s.statusSetter.results = params.ErrorResults{
   179  		Results: []params.ErrorResult{
   180  			{&params.Error{Message: `"machine-0" is not a valid model tag`}},
   181  		},
   182  	}
   183  
   184  	facade, err := modelupgrader.NewFacade(&s.backend, &s.pool, &s.providers, &s.watcher, &s.statusSetter, &s.authorizer)
   185  	c.Assert(err, jc.ErrorIsNil)
   186  	results, err := facade.SetModelStatus(args)
   187  	c.Assert(err, jc.ErrorIsNil)
   188  	c.Assert(results, jc.DeepEquals, s.statusSetter.results)
   189  	s.backend.CheckNoCalls(c)
   190  	s.pool.models[modelTag1.Id()].CheckNoCalls(c)
   191  	s.statusSetter.CheckCalls(c, []testing.StubCall{
   192  		{"SetStatus", []interface{}{args}},
   193  	})
   194  }
   195  
   196  type mockBackend struct {
   197  	testing.Stub
   198  	clouds map[string]cloud.Cloud
   199  }
   200  
   201  func (b *mockBackend) Cloud(name string) (cloud.Cloud, error) {
   202  	b.MethodCall(b, "Cloud", name)
   203  	return b.clouds[name], b.NextErr()
   204  }
   205  
   206  type mockPool struct {
   207  	testing.Stub
   208  	models map[string]*mockModel
   209  }
   210  
   211  func (p *mockPool) GetModel(uuid string) (modelupgrader.Model, func(), error) {
   212  	p.MethodCall(p, "GetModel", uuid)
   213  	return p.models[uuid], func() {}, p.NextErr()
   214  }
   215  
   216  type mockModel struct {
   217  	testing.Stub
   218  	cloud string
   219  	v     int
   220  }
   221  
   222  func (m *mockModel) Cloud() string {
   223  	m.MethodCall(m, "Cloud")
   224  	m.PopNoErr()
   225  	return m.cloud
   226  }
   227  
   228  func (m *mockModel) EnvironVersion() int {
   229  	m.MethodCall(m, "EnvironVersion")
   230  	m.PopNoErr()
   231  	return m.v
   232  }
   233  
   234  func (m *mockModel) SetEnvironVersion(v int) error {
   235  	m.MethodCall(m, "SetEnvironVersion", v)
   236  	return m.NextErr()
   237  }
   238  
   239  type mockWatcher struct {
   240  	testing.Stub
   241  }
   242  
   243  func (m *mockWatcher) Watch(args params.Entities) (params.NotifyWatchResults, error) {
   244  	m.MethodCall(m, "Watch", args)
   245  	if err := m.NextErr(); err != nil {
   246  		return params.NotifyWatchResults{}, err
   247  	}
   248  	return params.NotifyWatchResults{}, errors.NotImplementedf("Watch")
   249  }
   250  
   251  type mockProviderRegistry struct {
   252  	testing.Stub
   253  	providers map[string]*mockProvider
   254  }
   255  
   256  func (m *mockProviderRegistry) Provider(name string) (environs.EnvironProvider, error) {
   257  	m.MethodCall(m, "Provider", name)
   258  	if err := m.NextErr(); err != nil {
   259  		return nil, err
   260  	}
   261  	return m.providers[name], nil
   262  }
   263  
   264  type mockProvider struct {
   265  	testing.Stub
   266  	environs.EnvironProvider
   267  	version int
   268  }
   269  
   270  func (m *mockProvider) Version() int {
   271  	m.MethodCall(m, "Version")
   272  	m.PopNoErr()
   273  	return m.version
   274  }
   275  
   276  type mockStatusSetter struct {
   277  	testing.Stub
   278  	results params.ErrorResults
   279  }
   280  
   281  func (m *mockStatusSetter) SetStatus(args params.SetStatus) (params.ErrorResults, error) {
   282  	m.MethodCall(m, "SetStatus", args)
   283  	return m.results, m.NextErr()
   284  }