v23proxy: Add test for 0-in and out args
Change-Id: I86cc5c8c514df48e84c61fed2ff401e2e91c423c
diff --git a/go/src/v.io/x/mojo/proxy/clientproxy/clientproxy.go b/go/src/v.io/x/mojo/proxy/clientproxy/clientproxy.go
index 2cfd823..eb19c84 100644
--- a/go/src/v.io/x/mojo/proxy/clientproxy/clientproxy.go
+++ b/go/src/v.io/x/mojo/proxy/clientproxy/clientproxy.go
@@ -88,6 +88,16 @@
messageBytes := message.Payload
+ if methodSig.ResponseParams == nil {
+ // This may be complicated to support because of a race on the server side.
+ // When we send the no-response message through mojo we don't know when it has been received
+ // and we can close the pipe (one is opened per incoming message).
+
+ // Note that because the client expects no response, it will not receive the following
+ // error.
+ return fmt.Errorf("this error not received")
+ }
+
response, err := s.call(s.header.v23Name, methodName, messageBytes, methodSig.Parameters, methodSig.ResponseParams)
if err != nil {
return err
@@ -143,13 +153,6 @@
if err != nil {
return nil, err
}
- var outVType *vdl.Type
- if outParamsType != nil {
- outVType, err = transcoder.MojomStructToVDLType(*outParamsType, s.header.desc)
- if err != nil {
- return nil, err
- }
- }
// Decode the vdl.Value from the mojom bytes and mojom type.
var inVdlValue *vdl.Value
@@ -167,7 +170,11 @@
// We know that the v23serverproxy will give us back a bunch of
// data in []interface{}. so we'll want to decode them into *vdl.Value.
s.ctx.Infof("%s %v", method, outParamsType)
- outargs := make([]*vdl.Value, len(outParamsType.Fields))
+ var numParams int
+ if outParamsType != nil {
+ numParams = len(outParamsType.Fields)
+ }
+ outargs := make([]*vdl.Value, numParams)
outptrs := make([]interface{}, len(outargs))
for i := range outargs {
outptrs[i] = &outargs[i]
@@ -178,6 +185,15 @@
return nil, err
}
+ if outParamsType == nil {
+ return nil, nil
+ }
+
+ outVType, err := transcoder.MojomStructToVDLType(*outParamsType, s.header.desc)
+ if err != nil {
+ return nil, err
+ }
+
// Now convert the []interface{} into a *vdl.Value (struct).
outVdlValue := util.CombineVdlValueByMojomType(outargs, outVType)
diff --git a/go/src/v.io/x/mojo/proxy/serverproxy/serverproxy.go b/go/src/v.io/x/mojo/proxy/serverproxy/serverproxy.go
index f83b3f0..13ac37d 100644
--- a/go/src/v.io/x/mojo/proxy/serverproxy/serverproxy.go
+++ b/go/src/v.io/x/mojo/proxy/serverproxy/serverproxy.go
@@ -162,7 +162,7 @@
}
// A helper function that sends a remote message that expects a response.
-func (fs fakeService) callRemoteGeneric(ctx *context.T, message *bindings.Message) (outMessage *bindings.Message, err error) {
+func (fs fakeService) callRemoteWithResponse(ctx *context.T, message *bindings.Message) (outMessage *bindings.Message, err error) {
ctx.Infof("callRemoteGeneric: Send message along the router")
readResult := <-fs.router.AcceptWithResponse(message)
@@ -227,19 +227,10 @@
// A void function must have request id of 0, whereas one with response params
// should have a unique request id.
- var rqId uint64
- var flag uint32
- if mm.ResponseParams != nil {
- rqId = fs.ids.Count()
- flag = bindings.MessageExpectsResponseFlag
- } else {
- flag = bindings.MessageNoFlag
- }
-
header := bindings.MessageHeader{
Type: ordinal,
- Flags: flag,
- RequestId: rqId,
+ Flags: bindings.MessageExpectsResponseFlag,
+ RequestId: fs.ids.Count(),
}
// Now produce the *bindings.Message that we will send to the other side.
@@ -252,16 +243,8 @@
return nil, err
}
- // Handle the 0 out-arg case first.
- if mm.ResponseParams == nil {
- if err = fs.router.Accept(message); err != nil {
- return nil, err
- }
- return make([]*vdl.Value, 0), nil
- }
-
// Otherwise, make a generic call with the message.
- outMessage, err := fs.callRemoteGeneric(ctx, message)
+ outMessage, err := fs.callRemoteWithResponse(ctx, message)
if err != nil {
return nil, err
}
@@ -304,7 +287,7 @@
}
func (v23pd *dispatcher) Lookup(ctx *context.T, suffix string) (interface{}, security.Authorizer, error) {
- ctx.Infof("Dispatcher: %s", suffix)
+ ctx.Infof("dispatcher.Lookup for suffix: %s", suffix)
return fakeService{
appctx: v23pd.appctx,
suffix: suffix,
diff --git a/go/src/v.io/x/mojo/tests/client/test_client.go b/go/src/v.io/x/mojo/tests/client/test_client.go
index 8b1e816..1909ad5 100644
--- a/go/src/v.io/x/mojo/tests/client/test_client.go
+++ b/go/src/v.io/x/mojo/tests/client/test_client.go
@@ -63,7 +63,6 @@
}
func TestReuseProxy(t *testing.T, ctx application.Context) {
- fmt.Printf("in test reuse\n")
proxy := createProxy(ctx)
defer proxy.Close_Proxy()
@@ -74,12 +73,10 @@
if value != expected.SimpleResponseValue {
t.Errorf("expected %v, but got %v", expected.SimpleResponseValue, value)
}
- fmt.Printf("about to call second f\n")
x, y, err := proxy.MultiArgs(expected.MultiArgsRequestA, expected.MultiArgsRequestB, expected.MultiArgsRequestC, expected.MultiArgsRequestD)
if err != nil {
t.Fatal(err)
}
- fmt.Printf("called second f\n")
if !reflect.DeepEqual(x, expected.MultiArgsResponseX) {
t.Errorf("expected %v, but got %v", expected.MultiArgsResponseX, x)
}
@@ -88,6 +85,29 @@
}
}
+// This test stores a value on the server (through a no-out args RPC)
+// and calls a no-in args RPC to retrieve the value and confirm
+// it matches the value originally sent.
+func TestNoOutArgs(t *testing.T, ctx application.Context) {
+ const msg = "message-for-no-return"
+
+ proxy := createProxy(ctx)
+ defer proxy.Close_Proxy()
+
+ err := proxy.NoOutArgsPut(msg)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ outMsg, err := proxy.FetchMsgFromNoOutArgsPut()
+ if err != nil {
+ t.Fatal(err)
+ }
+ if outMsg != msg {
+ t.Errorf("expected %v, but got %v", msg, outMsg)
+ }
+}
+
func createProxy(ctx application.Context) *end_to_end_test.V23ProxyTest_Proxy {
// Parse arguments. Note: May panic if not enough args are given.
remoteName := ctx.Args()[1]
@@ -119,7 +139,7 @@
log.Printf("TestClientDelegate.Initialize...")
tests := []func(*testing.T, application.Context){
- TestSimple, TestMultiArgs, TestReuseProxy,
+ TestSimple, TestMultiArgs, TestReuseProxy, TestNoOutArgs,
}
matchAllTests := func(pat, str string) (bool, error) { return true, nil }
diff --git a/go/src/v.io/x/mojo/tests/server/test_server.go b/go/src/v.io/x/mojo/tests/server/test_server.go
index e8a7f1c..8fe8607 100644
--- a/go/src/v.io/x/mojo/tests/server/test_server.go
+++ b/go/src/v.io/x/mojo/tests/server/test_server.go
@@ -8,6 +8,7 @@
"fmt"
"log"
"reflect"
+ "time"
"mojo/public/go/application"
"mojo/public/go/bindings"
@@ -21,7 +22,15 @@
//#include "mojo/public/c/system/types.h"
import "C"
-type V23ProxyTestImpl struct{}
+const noReturnReceiveTimeout = 1 * time.Second
+
+type V23ProxyTestImpl struct {
+ noReturnMsgChan chan string
+}
+
+func NewV23ProxyTestImpl() *V23ProxyTestImpl {
+ return &V23ProxyTestImpl{noReturnMsgChan: make(chan string, 1)}
+}
func (i *V23ProxyTestImpl) Simple(a int32) (value string, err error) {
if a != expected.SimpleRequestA {
@@ -46,21 +55,37 @@
return expected.MultiArgsResponseX, expected.MultiArgsResponseY, nil
}
+func (i *V23ProxyTestImpl) NoOutArgsPut(storedMsg string) error {
+ i.noReturnMsgChan <- storedMsg
+ return nil
+}
+
+func (i *V23ProxyTestImpl) FetchMsgFromNoOutArgsPut() (string, error) {
+ select {
+ case msg := <-i.noReturnMsgChan:
+ return msg, nil
+ case <-time.After(noReturnReceiveTimeout):
+ return "", fmt.Errorf("timed out waiting for no return message")
+ }
+}
+
type V23ProxyTestServerDelegate struct {
factory V23ProxyTestFactory
}
type V23ProxyTestFactory struct {
- stubs []*bindings.Stub
+ stubs []*bindings.Stub
+ testImpl *V23ProxyTestImpl
}
func (delegate *V23ProxyTestServerDelegate) Initialize(context application.Context) {
log.Printf("V23ProxyTestServerDelegate.Initialize...")
+ delegate.factory.testImpl = NewV23ProxyTestImpl()
}
func (factory *V23ProxyTestFactory) Create(request end_to_end_test.V23ProxyTest_Request) {
log.Printf("V23ProxyTestServer's V23ProxyTestFactory.Create...")
- stub := end_to_end_test.NewV23ProxyTestStub(request, &V23ProxyTestImpl{}, bindings.GetAsyncWaiter())
+ stub := end_to_end_test.NewV23ProxyTestStub(request, factory.testImpl, bindings.GetAsyncWaiter())
factory.stubs = append(factory.stubs, stub)
go func() {
for {
diff --git a/mojom/mojom/tests/end_to_end_test.mojom b/mojom/mojom/tests/end_to_end_test.mojom
index 025c65b..c98db9f 100644
--- a/mojom/mojom/tests/end_to_end_test.mojom
+++ b/mojom/mojom/tests/end_to_end_test.mojom
@@ -19,4 +19,6 @@
interface V23ProxyTest {
Simple(int32 a) => (string value);
MultiArgs(bool a, array<float> b, map<string, uint8> c, AStruct d) => (AUnion x, string y);
+ NoOutArgsPut(string storedMsg) => ();
+ FetchMsgFromNoOutArgsPut() => (string storedMsg);
};