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: ¶ms.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: ¶ms.Error{Message: `blargh`}, 122 }, { 123 Error: ¶ms.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 {¶ms.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 {¶ms.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 }