github.com/altoros/juju-vmware@v0.0.0-20150312064031-f19ae857ccca/rpc/reflect_test.go (about)

     1  // Copyright 2012, 2013 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package rpc_test
     5  
     6  import (
     7  	"reflect"
     8  
     9  	jc "github.com/juju/testing/checkers"
    10  	gc "gopkg.in/check.v1"
    11  
    12  	"github.com/juju/juju/rpc/rpcreflect"
    13  	"github.com/juju/juju/testing"
    14  )
    15  
    16  // We test rpcreflect in this package, so that the
    17  // tests can all share the same testing Root type.
    18  
    19  type reflectSuite struct {
    20  	testing.BaseSuite
    21  }
    22  
    23  var _ = gc.Suite(&reflectSuite{})
    24  
    25  func (*reflectSuite) TestTypeOf(c *gc.C) {
    26  	rtype := rpcreflect.TypeOf(reflect.TypeOf(&Root{}))
    27  	c.Assert(rtype.DiscardedMethods(), gc.DeepEquals, []string{
    28  		"Discard1",
    29  		"Discard2",
    30  		"Discard3",
    31  	})
    32  	expect := map[string]reflect.Type{
    33  		"CallbackMethods":  reflect.TypeOf(&CallbackMethods{}),
    34  		"ChangeAPIMethods": reflect.TypeOf(&ChangeAPIMethods{}),
    35  		"DelayedMethods":   reflect.TypeOf(&DelayedMethods{}),
    36  		"ErrorMethods":     reflect.TypeOf(&ErrorMethods{}),
    37  		"InterfaceMethods": reflect.TypeOf((*InterfaceMethods)(nil)).Elem(),
    38  		"SimpleMethods":    reflect.TypeOf(&SimpleMethods{}),
    39  	}
    40  	c.Assert(rtype.MethodNames(), gc.HasLen, len(expect))
    41  	for name, expectGoType := range expect {
    42  		m, err := rtype.Method(name)
    43  		c.Assert(err, jc.ErrorIsNil)
    44  		c.Assert(m, gc.NotNil)
    45  		c.Assert(m.Call, gc.NotNil)
    46  		c.Assert(m.ObjType, gc.Equals, rpcreflect.ObjTypeOf(expectGoType))
    47  		c.Assert(m.ObjType.GoType(), gc.Equals, expectGoType)
    48  	}
    49  	m, err := rtype.Method("not found")
    50  	c.Assert(err, gc.Equals, rpcreflect.ErrMethodNotFound)
    51  	c.Assert(m, gc.DeepEquals, rpcreflect.RootMethod{})
    52  }
    53  
    54  func (*reflectSuite) TestObjTypeOf(c *gc.C) {
    55  	objType := rpcreflect.ObjTypeOf(reflect.TypeOf(&SimpleMethods{}))
    56  	c.Check(objType.DiscardedMethods(), gc.DeepEquals, []string{
    57  		"Discard1",
    58  		"Discard2",
    59  		"Discard3",
    60  		"Discard4",
    61  	})
    62  	expect := map[string]*rpcreflect.ObjMethod{
    63  		"SliceArg": {
    64  			Params: reflect.TypeOf(struct{ X []string }{}),
    65  			Result: reflect.TypeOf(stringVal{}),
    66  		},
    67  	}
    68  	for narg := 0; narg < 2; narg++ {
    69  		for nret := 0; nret < 2; nret++ {
    70  			for nerr := 0; nerr < 2; nerr++ {
    71  				retErr := nerr != 0
    72  				var m rpcreflect.ObjMethod
    73  				if narg > 0 {
    74  					m.Params = reflect.TypeOf(stringVal{})
    75  				}
    76  				if nret > 0 {
    77  					m.Result = reflect.TypeOf(stringVal{})
    78  				}
    79  				expect[callName(narg, nret, retErr)] = &m
    80  			}
    81  		}
    82  	}
    83  	c.Assert(objType.MethodNames(), gc.HasLen, len(expect))
    84  	for name, expectMethod := range expect {
    85  		m, err := objType.Method(name)
    86  		c.Check(err, jc.ErrorIsNil)
    87  		c.Assert(m, gc.NotNil)
    88  		c.Check(m.Call, gc.NotNil)
    89  		c.Check(m.Params, gc.Equals, expectMethod.Params)
    90  		c.Check(m.Result, gc.Equals, expectMethod.Result)
    91  	}
    92  	m, err := objType.Method("not found")
    93  	c.Check(err, gc.Equals, rpcreflect.ErrMethodNotFound)
    94  	c.Check(m, gc.DeepEquals, rpcreflect.ObjMethod{})
    95  }
    96  
    97  func (*reflectSuite) TestValueOf(c *gc.C) {
    98  	v := rpcreflect.ValueOf(reflect.ValueOf(nil))
    99  	c.Check(v.IsValid(), jc.IsFalse)
   100  	c.Check(func() { v.FindMethod("foo", 0, "bar") }, gc.PanicMatches, "FindMethod called on invalid Value")
   101  
   102  	root := &Root{}
   103  	v = rpcreflect.ValueOf(reflect.ValueOf(root))
   104  	c.Check(v.IsValid(), jc.IsTrue)
   105  	c.Check(v.GoValue().Interface(), gc.Equals, root)
   106  }
   107  
   108  func (*reflectSuite) TestFindMethod(c *gc.C) {
   109  	// FindMethod is actually extensively tested because it's
   110  	// used in the implementation of the rpc server,
   111  	// so just a simple sanity check test here.
   112  	root := &Root{
   113  		simple: make(map[string]*SimpleMethods),
   114  	}
   115  	root.simple["a99"] = &SimpleMethods{root: root, id: "a99"}
   116  	v := rpcreflect.ValueOf(reflect.ValueOf(root))
   117  
   118  	m, err := v.FindMethod("foo", 0, "bar")
   119  	c.Assert(err, gc.ErrorMatches, `unknown object type "foo"`)
   120  	c.Assert(err, gc.FitsTypeOf, (*rpcreflect.CallNotImplementedError)(nil))
   121  	c.Assert(m, gc.IsNil)
   122  
   123  	m, err = v.FindMethod("SimpleMethods", 0, "bar")
   124  	c.Assert(err, gc.ErrorMatches, "no such request - method SimpleMethods.bar is not implemented")
   125  	c.Assert(err, gc.FitsTypeOf, (*rpcreflect.CallNotImplementedError)(nil))
   126  	c.Assert(m, gc.IsNil)
   127  
   128  	m, err = v.FindMethod("SimpleMethods", 0, "Call1r1e")
   129  	c.Assert(err, jc.ErrorIsNil)
   130  	c.Assert(m.ParamsType(), gc.Equals, reflect.TypeOf(stringVal{}))
   131  	c.Assert(m.ResultType(), gc.Equals, reflect.TypeOf(stringVal{}))
   132  
   133  	ret, err := m.Call("a99", reflect.ValueOf(stringVal{"foo"}))
   134  	c.Assert(err, jc.ErrorIsNil)
   135  	c.Assert(ret.Interface(), gc.Equals, stringVal{"Call1r1e ret"})
   136  }
   137  
   138  func (*reflectSuite) TestFindMethodRefusesVersionsNot0(c *gc.C) {
   139  	root := &Root{
   140  		simple: make(map[string]*SimpleMethods),
   141  	}
   142  	root.simple["a99"] = &SimpleMethods{root: root, id: "a99"}
   143  	v := rpcreflect.ValueOf(reflect.ValueOf(root))
   144  
   145  	m, err := v.FindMethod("SimpleMethods", 0, "Call1r1e")
   146  	c.Assert(err, jc.ErrorIsNil)
   147  	c.Assert(m.ParamsType(), gc.Equals, reflect.TypeOf(stringVal{}))
   148  	c.Assert(m.ResultType(), gc.Equals, reflect.TypeOf(stringVal{}))
   149  
   150  	m, err = v.FindMethod("SimpleMethods", 1, "Call1r1e")
   151  	c.Assert(err, gc.FitsTypeOf, (*rpcreflect.CallNotImplementedError)(nil))
   152  	c.Assert(err, gc.ErrorMatches, `unknown version \(1\) of interface "SimpleMethods"`)
   153  }