github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/apiserver/facade/registry_test.go (about) 1 // Copyright 2014-2016 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package facade_test 5 6 import ( 7 "reflect" 8 9 "github.com/juju/errors" 10 jc "github.com/juju/testing/checkers" 11 gc "gopkg.in/check.v1" 12 13 "github.com/juju/juju/apiserver/common" 14 "github.com/juju/juju/apiserver/facade" 15 "github.com/juju/juju/apiserver/facade/facadetest" 16 apiservertesting "github.com/juju/juju/apiserver/testing" 17 "github.com/juju/juju/state" 18 "github.com/juju/juju/testing" 19 ) 20 21 type RegistrySuite struct { 22 testing.BaseSuite 23 } 24 25 var _ = gc.Suite(&RegistrySuite{}) 26 27 var ( 28 interfaceType = reflect.TypeOf((*interface{})(nil)).Elem() 29 intPtrType = reflect.TypeOf((*int)(nil)) 30 ) 31 32 func (s *RegistrySuite) TestRegister(c *gc.C) { 33 registry := &facade.Registry{} 34 err := registry.Register("myfacade", 123, testFacade, interfaceType) 35 c.Assert(err, jc.ErrorIsNil) 36 37 factory, err := registry.GetFactory("myfacade", 123) 38 c.Assert(err, jc.ErrorIsNil) 39 val, err := factory(nil) 40 c.Assert(err, jc.ErrorIsNil) 41 c.Check(val, gc.Equals, "myobject") 42 } 43 44 func (s *RegistrySuite) TestListDetails(c *gc.C) { 45 registry := &facade.Registry{} 46 err := registry.Register("f2", 6, testFacade, interfaceType) 47 c.Assert(err, jc.ErrorIsNil) 48 49 err = registry.Register("f1", 9, validIdFactory, intPtrType) 50 c.Assert(err, jc.ErrorIsNil) 51 52 details := registry.ListDetails() 53 c.Assert(details, gc.HasLen, 2) 54 c.Assert(details[0].Name, gc.Equals, "f1") 55 c.Assert(details[0].Version, gc.Equals, 9) 56 v, _ := details[0].Factory(nil) 57 c.Assert(v, gc.FitsTypeOf, new(int)) 58 c.Assert(details[0].Type, gc.Equals, intPtrType) 59 60 c.Assert(details[1].Name, gc.Equals, "f2") 61 c.Assert(details[1].Version, gc.Equals, 6) 62 v, _ = details[1].Factory(nil) 63 c.Assert(v, gc.Equals, "myobject") 64 c.Assert(details[1].Type, gc.Equals, interfaceType) 65 } 66 67 func (*RegistrySuite) TestGetFactoryUnknown(c *gc.C) { 68 registry := &facade.Registry{} 69 factory, err := registry.GetFactory("name", 0) 70 c.Check(err, jc.Satisfies, errors.IsNotFound) 71 c.Check(err, gc.ErrorMatches, `name\(0\) not found`) 72 c.Check(factory, gc.IsNil) 73 } 74 75 func (*RegistrySuite) TestGetFactoryUnknownVersion(c *gc.C) { 76 registry := &facade.Registry{} 77 assertRegister(c, registry, "name", 0) 78 79 factory, err := registry.GetFactory("name", 1) 80 c.Check(err, jc.Satisfies, errors.IsNotFound) 81 c.Check(err, gc.ErrorMatches, `name\(1\) not found`) 82 c.Check(factory, gc.IsNil) 83 } 84 85 func (*RegistrySuite) TestRegisterAndList(c *gc.C) { 86 registry := &facade.Registry{} 87 assertRegister(c, registry, "name", 0) 88 89 c.Check(registry.List(), jc.DeepEquals, []facade.Description{ 90 {Name: "name", Versions: []int{0}}, 91 }) 92 } 93 94 func (*RegistrySuite) TestRegisterAndListSorted(c *gc.C) { 95 registry := &facade.Registry{} 96 assertRegister(c, registry, "name", 10) 97 assertRegister(c, registry, "name", 0) 98 assertRegister(c, registry, "name", 101) 99 100 c.Check(registry.List(), jc.DeepEquals, []facade.Description{ 101 {Name: "name", Versions: []int{0, 10, 101}}, 102 }) 103 } 104 105 func (*RegistrySuite) TestRegisterAndListMultiple(c *gc.C) { 106 registry := &facade.Registry{} 107 assertRegister(c, registry, "other", 0) 108 assertRegister(c, registry, "name", 0) 109 assertRegister(c, registry, "third", 2) 110 assertRegister(c, registry, "third", 3) 111 112 c.Check(registry.List(), jc.DeepEquals, []facade.Description{ 113 {Name: "name", Versions: []int{0}}, 114 {Name: "other", Versions: []int{0}}, 115 {Name: "third", Versions: []int{2, 3}}, 116 }) 117 } 118 119 func (*RegistrySuite) TestRegisterAlreadyPresent(c *gc.C) { 120 registry := &facade.Registry{} 121 assertRegister(c, registry, "name", 0) 122 secondIdFactory := func(context facade.Context) (facade.Facade, error) { 123 var i = 200 124 return &i, nil 125 } 126 err := registry.Register("name", 0, secondIdFactory, intPtrType) 127 c.Assert(err, gc.ErrorMatches, `object "name\(0\)" already registered`) 128 129 factory, err := registry.GetFactory("name", 0) 130 c.Assert(err, jc.ErrorIsNil) 131 c.Assert(factory, gc.NotNil) 132 val, err := factory(nil) 133 c.Assert(err, jc.ErrorIsNil) 134 asIntPtr := val.(*int) 135 c.Check(*asIntPtr, gc.Equals, 100) 136 } 137 138 func (*RegistrySuite) TestGetFactory(c *gc.C) { 139 registry := &facade.Registry{} 140 assertRegister(c, registry, "name", 0) 141 142 factory, err := registry.GetFactory("name", 0) 143 c.Assert(err, jc.ErrorIsNil) 144 c.Assert(factory, gc.NotNil) 145 res, err := factory(nil) 146 c.Assert(err, jc.ErrorIsNil) 147 c.Assert(res, gc.NotNil) 148 asIntPtr := res.(*int) 149 c.Check(*asIntPtr, gc.Equals, 100) 150 } 151 152 func (*RegistrySuite) TestGetType(c *gc.C) { 153 registry := &facade.Registry{} 154 assertRegister(c, registry, "name", 0) 155 156 typ, err := registry.GetType("name", 0) 157 c.Assert(err, jc.ErrorIsNil) 158 c.Check(typ, gc.Equals, intPtrType) 159 } 160 161 func (*RegistrySuite) TestDiscardHandlesNotPresent(c *gc.C) { 162 registry := &facade.Registry{} 163 registry.Discard("name", 1) 164 } 165 166 func (*RegistrySuite) TestDiscardRemovesEntry(c *gc.C) { 167 registry := &facade.Registry{} 168 assertRegister(c, registry, "name", 0) 169 _, err := registry.GetFactory("name", 0) 170 c.Assert(err, jc.ErrorIsNil) 171 172 registry.Discard("name", 0) 173 factory, err := registry.GetFactory("name", 0) 174 c.Check(err, jc.Satisfies, errors.IsNotFound) 175 c.Check(err, gc.ErrorMatches, `name\(0\) not found`) 176 c.Check(factory, gc.IsNil) 177 c.Check(registry.List(), jc.DeepEquals, []facade.Description{}) 178 } 179 180 func (*RegistrySuite) TestDiscardLeavesOtherVersions(c *gc.C) { 181 registry := &facade.Registry{} 182 assertRegister(c, registry, "name", 0) 183 assertRegister(c, registry, "name", 1) 184 185 registry.Discard("name", 0) 186 _, err := registry.GetFactory("name", 1) 187 c.Check(err, jc.ErrorIsNil) 188 c.Check(registry.List(), jc.DeepEquals, []facade.Description{ 189 {Name: "name", Versions: []int{1}}, 190 }) 191 } 192 193 func (*RegistrySuite) TestWrapNewFacadeFailure(c *gc.C) { 194 _, _, err := facade.WrapNewFacade("notafunc") 195 c.Check(err, gc.ErrorMatches, `wrong type "string" is not a function`) 196 } 197 198 func (*RegistrySuite) TestWrapNewFacadeHandlesId(c *gc.C) { 199 wrapped, _, err := facade.WrapNewFacade(validFactory) 200 c.Assert(err, jc.ErrorIsNil) 201 val, err := wrapped(facadetest.Context{ 202 ID_: "badId", 203 }) 204 c.Check(err, gc.ErrorMatches, "id not expected") 205 c.Check(val, gc.Equals, nil) 206 } 207 208 func (*RegistrySuite) TestWrapNewFacadeCallsFunc(c *gc.C) { 209 for _, function := range []interface{}{validFactory, validContextFactory} { 210 wrapped, _, err := facade.WrapNewFacade(function) 211 c.Assert(err, jc.ErrorIsNil) 212 val, err := wrapped(facadetest.Context{}) 213 c.Assert(err, jc.ErrorIsNil) 214 c.Check(*(val.(*int)), gc.Equals, 100) 215 } 216 } 217 218 func (*RegistrySuite) TestWrapNewFacadeCallsWithRightParams(c *gc.C) { 219 authorizer := apiservertesting.FakeAuthorizer{} 220 resources := common.NewResources() 221 testFunc := func( 222 st *state.State, 223 resources facade.Resources, 224 authorizer facade.Authorizer, 225 ) (*myResult, error) { 226 return &myResult{st, resources, authorizer}, nil 227 } 228 wrapped, facadeType, err := facade.WrapNewFacade(testFunc) 229 c.Assert(err, jc.ErrorIsNil) 230 c.Check(facadeType, gc.Equals, reflect.TypeOf((*myResult)(nil))) 231 232 val, err := wrapped(facadetest.Context{ 233 Resources_: resources, 234 Auth_: authorizer, 235 }) 236 c.Assert(err, jc.ErrorIsNil) 237 asResult := val.(*myResult) 238 c.Check(asResult.st, gc.IsNil) 239 c.Check(asResult.resources, gc.Equals, resources) 240 c.Check(asResult.auth, gc.Equals, authorizer) 241 } 242 243 func (s *RegistrySuite) TestRegisterStandard(c *gc.C) { 244 registry := &facade.Registry{} 245 registry.RegisterStandard("testing", 0, validFactory) 246 wrapped, err := registry.GetFactory("testing", 0) 247 c.Assert(err, jc.ErrorIsNil) 248 val, err := wrapped(facadetest.Context{}) 249 c.Assert(err, jc.ErrorIsNil) 250 c.Check(*(val.(*int)), gc.Equals, 100) 251 } 252 253 func (s *RegistrySuite) TestRegisterStandardError(c *gc.C) { 254 registry := &facade.Registry{} 255 err := registry.RegisterStandard("badtest", 0, noArgs) 256 c.Assert(err, gc.ErrorMatches, 257 `function ".*noArgs" does not have the signature .* or .*`) 258 259 _, err = registry.GetFactory("badtest", 0) 260 c.Assert(err, jc.Satisfies, errors.IsNotFound) 261 c.Assert(err, gc.ErrorMatches, `badtest\(0\) not found`) 262 } 263 264 func assertRegister(c *gc.C, registry *facade.Registry, name string, version int) { 265 assertRegisterFlag(c, registry, name, version) 266 } 267 268 func assertRegisterFlag(c *gc.C, registry *facade.Registry, name string, version int) { 269 err := registry.Register(name, version, validIdFactory, intPtrType) 270 c.Assert(err, gc.IsNil) 271 } 272 273 func testFacade(_ facade.Context) (facade.Facade, error) { 274 return "myobject", nil 275 } 276 277 func validIdFactory(_ facade.Context) (facade.Facade, error) { 278 var i = 100 279 return &i, nil 280 } 281 282 type myResult struct { 283 st *state.State 284 resources facade.Resources 285 auth facade.Authorizer 286 } 287 288 func noArgs() { 289 } 290 291 func validFactory(_ *state.State, _ facade.Resources, _ facade.Authorizer) (*int, error) { 292 var i = 100 293 return &i, nil 294 } 295 296 func validContextFactory(_ facade.Context) (*int, error) { 297 var i = 100 298 return &i, nil 299 }