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  }