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 }