blob: 305aecdcf08aa4e130a275a7b1c6b2f51bf6eab8 [file] [log] [blame]
// Copyright (C) 2016 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package rpc
import (
"fmt"
"io"
"reflect"
"testing"
"android.googlesource.com/platform/tools/gpu/framework/assert"
"android.googlesource.com/platform/tools/gpu/framework/binary"
"android.googlesource.com/platform/tools/gpu/framework/log"
"android.googlesource.com/platform/tools/gpu/framework/multiplexer"
)
const mtu = 1024
type request struct {
binary.Generate
data string
}
type delay struct {
binary.Generate
data string
}
type response struct {
binary.Generate
data string
}
type err struct {
binary.Generate `implements:"rpc.Err"`
msg string
}
type splitter struct {
io.Reader
io.Writer
io.Closer
}
func (e err) Error() string { return e.msg }
func create(t *testing.T) Client {
ctx := assert.Context(t)
pass := make(chan string, 1)
sr, cw := io.Pipe()
cr, sw := io.Pipe()
Serve(ctx, splitter{sr, sw, sw}, mtu, func(ctx log.Context, call interface{}) (binary.Object, error) {
switch o := call.(type) {
case *request:
pass <- o.data
return &response{data: o.data}, nil
case *delay:
return &response{data: <-pass}, nil
default:
return nil, &err{msg: fmt.Sprintf("Invalid call type %T", o)}
}
})
return NewClient(multiplexer.New(ctx, splitter{cr, cw, cw}, mtu, nil), nil)
}
func simpleRequest(t *testing.T, c Client, v string) {
r, err := c.Send(&request{data: v})
if err != nil {
t.Fatalf("Unexpected error %s from rpc", err)
}
if r, ok := r.(*response); !ok {
t.Fatalf("Unexpected response type %T from rpc", r)
} else if string(r.data) != v {
t.Fatalf("expected %s got %s from rpc", v, r.data)
}
}
func delayRequest(t *testing.T, c Client, send string, expect string) {
r, err := c.Send(&delay{data: send})
if err != nil {
t.Fatalf("Unexpected error %s from rpc", err)
}
if r, ok := r.(*response); !ok {
t.Fatalf("Unexpected response type %T from rpc", r)
} else if string(r.data) != expect {
t.Fatalf("expected %s got %s from rpc", expect, r.data)
}
}
func TestSimpleRpc(t *testing.T) {
c := create(t)
simpleRequest(t, c, "hello")
}
func TestError(t *testing.T) {
c := create(t)
data, got := c.Send(&err{msg: "not an RPC method"})
if data != nil {
t.Fatalf("Expected no data. Got: %v", data)
}
expected := &err{msg: "Invalid call type *rpc.err"}
if !reflect.DeepEqual(got, expected) {
t.Fatalf("Unexpected error from rpc. Expected: %v, got: %v", expected, got)
}
}