Fix nil-pointer panic in wspr.
When MethodSignature is called from Prepare, a nil ctx is passed in. We
have to check for ctx==nil, and pass nil into verror.Make.
This CL also adds tests for the case when MethodNotFound and
WrongNumberOfArg errors are returned, and cleans up the app_test a bit.
Change-Id: I907223d392012482802bdceb0b182c81e8933849
diff --git a/services/wsprd/app/app_test.go b/services/wsprd/app/app_test.go
index cf8cfb4..738c7cb 100644
--- a/services/wsprd/app/app_test.go
+++ b/services/wsprd/app/app_test.go
@@ -14,6 +14,7 @@
"v.io/core/veyron2/vdl"
"v.io/core/veyron2/vdl/vdlroot/src/signature"
"v.io/core/veyron2/verror2"
+ "v.io/wspr/veyron/services/wsprd/ipc/server"
"v.io/wspr/veyron/services/wsprd/lib"
"v.io/wspr/veyron/services/wsprd/lib/testwriter"
@@ -513,20 +514,23 @@
var err2 error
err = call.Finish(&result, &err2)
- if (err == nil && test.authError != nil) || (err != nil && test.authError == nil) {
- t.Errorf("unexpected err: %v, %v", err, test.authError)
+
+ // If err is nil and test.authErr is nil reflect.DeepEqual will return
+ // false because the types are different. Because of this, we only use
+ // reflect.DeepEqual if one of the values is non-nil. If both values
+ // are nil, then we consider them equal.
+ if (err != nil || test.authError != nil) && !verror2.Equal(err, test.authError) {
+ t.Errorf("unexpected err: got %#v, expected %#v", err, test.authError)
}
if err != nil {
return
}
+
if !reflect.DeepEqual(result, test.finalResponse) {
t.Errorf("unexected final response: got %v, expected %v", result, test.finalResponse)
}
- // If err2 is nil and test.err is nil reflect.DeepEqual will return false because the
- // types are different. Because of this, we only use reflect.DeepEqual if one of
- // the values is non-nil. If both values are nil, then we consider them equal.
if (err2 != nil || test.err != nil) && !verror2.Equal(err2, test.err) {
t.Errorf("unexpected error: got %#v, expected %#v", err2, test.err)
}
@@ -552,15 +556,14 @@
func TestJSServerWithError(t *testing.T) {
err := verror2.Make(verror2.Internal, nil)
runJsServerTestCase(t, jsServerTestCase{
- method: "Add",
- inArgs: []interface{}{int32(1), int32(2)},
- finalResponse: int32(3),
- err: err,
+ method: "Divide",
+ inArgs: []interface{}{int32(1), int32(0)},
+ err: err,
})
}
func TestJSServerWithAuthorizerAndAuthError(t *testing.T) {
- err := verror2.Make(verror2.Internal, nil)
+ err := verror2.Make(verror2.NoAccess, nil)
runJsServerTestCase(t, jsServerTestCase{
method: "Add",
inArgs: []interface{}{int32(1), int32(2)},
@@ -593,3 +596,22 @@
finalResponse: int32(10),
})
}
+
+func TestJSServerWithWrongNumberOfArgs(t *testing.T) {
+ err := verror2.Make(server.ErrWrongNumberOfArgs, nil, "Add", 3, 2)
+ runJsServerTestCase(t, jsServerTestCase{
+ method: "Add",
+ inArgs: []interface{}{int32(1), int32(2), int32(3)},
+ authError: err,
+ })
+}
+
+func TestJSServerWithMethodNotFound(t *testing.T) {
+ methodName := "UnknownMethod"
+ err := verror2.Make(server.ErrMethodNotFoundInSignature, nil, methodName)
+ runJsServerTestCase(t, jsServerTestCase{
+ method: methodName,
+ inArgs: []interface{}{int32(1), int32(2)},
+ authError: err,
+ })
+}
diff --git a/services/wsprd/ipc/server/invoker.go b/services/wsprd/ipc/server/invoker.go
index 0f871b4..5f92174 100644
--- a/services/wsprd/ipc/server/invoker.go
+++ b/services/wsprd/ipc/server/invoker.go
@@ -1,6 +1,7 @@
package server
import (
+ "v.io/core/veyron2/context"
"v.io/core/veyron2/ipc"
"v.io/core/veyron2/naming"
"v.io/core/veyron2/vdl"
@@ -14,8 +15,8 @@
// Errors.
var (
- errWrongNumberOfArgs = verror.Register(pkgPath+".errWrongNumberOfArgs", verror.NoRetry, "{1:}{2:} Method {3} got {4} args, want {5}{:_}")
- errMethodNotFoundInSignature = verror.Register(pkgPath+".errMethodNotFoundInSignature", verror.NoRetry, "{1:}{2:} Method {3} not found in signature{:_}")
+ ErrWrongNumberOfArgs = verror.Register(pkgPath+".ErrWrongNumberOfArgs", verror.NoRetry, "{1:}{2:} Method {3} got {4} args, want {5}{:_}")
+ ErrMethodNotFoundInSignature = verror.Register(pkgPath+".ErrMethodNotFoundInSignature", verror.NoRetry, "{1:}{2:} Method {3} not found in signature{:_}")
)
// invoker holds a delegate function to call on invoke and a list of methods that
@@ -44,7 +45,7 @@
return nil, nil, err
}
if got, want := numArgs, len(method.InArgs); got != want {
- return nil, nil, verror.Make(errWrongNumberOfArgs, nil, methodName, got, want)
+ return nil, nil, verror.Make(ErrWrongNumberOfArgs, nil, methodName, got, want)
}
argptrs := make([]interface{}, len(method.InArgs))
for ix, arg := range method.InArgs {
@@ -103,5 +104,11 @@
if methodSig, ok := signature.FirstMethod(i.signature, method); ok {
return methodSig, nil
}
- return signature.Method{}, verror.Make(errMethodNotFoundInSignature, ctx.Context(), method)
+
+ var innerContext *context.T
+ if ctx != nil {
+ innerContext = ctx.Context()
+ }
+
+ return signature.Method{}, verror.Make(ErrMethodNotFoundInSignature, innerContext, method)
}