blob: 8e7188e73a00393118d45dc2b9b1ea7b91e324a1 [file] [log] [blame]
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build fuchsia
package fidl_test
import (
"flag"
"fmt"
"syscall/zx"
"testing"
"time"
. "syscall/zx/fidl"
. "syscall/zx/fidl/bindingstest"
)
func init() { flag.CommandLine.Set("test.v", "true") }
type Test1Impl struct{}
func (t *Test1Impl) Echo(s *string) (*string, error) {
return s, nil
}
func (t *Test1Impl) NoResponse() error {
return nil
}
func (t *Test1Impl) EmptyResponse() error {
return nil
}
func TestBindingSize(t *testing.T) {
clientEnd, serverEnd, err := zx.NewChannel(0)
if err != nil {
t.Fatalf("could not create channel: %v", err)
}
defer func() {
clientEnd.Close()
serverEnd.Close()
}()
var server Test1Service
if got, want := server.Size(), 0; got != want {
t.Fatalf("got server.Size() = %d, want %d", got, want)
}
key, err := server.Add(&Test1Impl{}, serverEnd, nil)
if err != nil {
t.Fatalf("could not add to server: %v", err)
}
if got, want := server.Size(), 1; got != want {
t.Fatalf("got server.Size() = %d, want %d", got, want)
}
if got := server.Remove(key); !got {
t.Fatalf("got server.Remove(%v) = %t, want %t", key, got, true)
}
if got, want := server.Size(), 0; got != want {
t.Fatalf("got server.Size() = %d, want %d", got, want)
}
}
func TestEmptyWriteErrors(t *testing.T) {
t.Parallel()
chErr := make(chan error)
errFunc := func(err error) { chErr <- err }
chPanic := make(chan error)
go func() {
defer func() {
if r := recover(); r != nil {
chPanic <- fmt.Errorf("write panicked: %v", r)
}
}()
Serve()
}()
ch, sh, err := zx.NewChannel(0)
if err != nil {
t.Fatalf("could not create channel: %v", err)
}
if err := ch.Write([]byte{}, []zx.Handle{}, 0); err != nil {
t.Fatalf("could not write to channel: %v", err)
}
server := Test1Service{}
if _, err := server.Add(&Test1Impl{}, sh, errFunc); err != nil {
t.Fatalf("could not add to server: %v", err)
}
select {
case <-chErr:
// Everything went well.
case err := <-chPanic:
t.Fatal(err)
case <-time.After(time.Second * 5):
t.Fatal("test timed out")
}
ch.Close()
server.Close()
}
func TestEcho(t *testing.T) {
t.Parallel()
ch, sh, err := zx.NewChannel(0)
if err != nil {
t.Fatal(err)
}
client := Test1Interface(ChannelProxy{Channel: ch})
server := Test1Service{}
clientKey, err := server.Add(&Test1Impl{}, sh, nil)
if err != nil {
t.Fatal(err)
}
go Serve()
t.Run("Basic", func(t *testing.T) {
str := "Hello World!"
r, err := client.Echo(&str)
if err != nil {
t.Fatal(err)
}
if r == nil {
t.Fatal("unexpected nil result")
}
if *r != str {
t.Fatalf("expected %s, got %s", str, *r)
}
})
t.Run("NoResponse", func(t *testing.T) {
err := client.NoResponse()
if err != nil {
t.Fatal(err)
}
})
t.Run("EmptyResponse", func(t *testing.T) {
err := client.EmptyResponse()
if err != nil {
t.Fatal(err)
}
})
t.Run("Event", func(t *testing.T) {
str := "Surprise!"
done := make(chan struct{})
// Spin up goroutine with waiting client.
go func() {
s, err := client.ExpectSurprise()
if err != nil {
t.Fatal(err)
}
if s != str {
t.Fatalf("expected %s, got %s", str, s)
}
done <- struct{}{}
}()
// Spin up server goroutine which makes the call.
go func() {
pxy, ok := server.EventProxyFor(clientKey)
if !ok {
t.Fatalf("could not create proxy for key %d", clientKey)
}
if err := pxy.Surprise(str); err != nil {
t.Fatal(err)
}
}()
select {
case <-done:
return
case <-time.After(5 * time.Second):
t.Fatalf("test timed out")
}
})
}
func TestUnionStructFieldFactory(t *testing.T) {
b := TestSimple{X: 13}
union := Union1WithB(b)
if union.Which() != Union1B {
t.Error("expected union with tag Union1B")
}
if union.B != b {
t.Error("union has incorrect value")
}
}
func TestUnionPrimitiveFieldFactory(t *testing.T) {
union := Union1WithD(3.14)
if union.Which() != Union1D {
t.Error("expected union with tag Union1D")
}
if union.D != 3.14 {
t.Error("union has incorrect value")
}
}
func TestUnionOptionalFieldFactory(t *testing.T) {
union := Union1WithC(nil)
if union.Which() != Union1C {
t.Error("expected union with tag Union1C")
}
if union.C != nil {
t.Error("union has incorrect value")
}
}
func TestXUnionStructFieldFactory(t *testing.T) {
b := TestSimple{X: 13}
xunion := XUnion1WithB(b)
if xunion.Which() != XUnion1B {
t.Error("expected xunion with tag XUnion1B")
}
if xunion.B != b {
t.Error("xunion has incorrect value")
}
}
func TestXUnionPrimitiveFieldFactory(t *testing.T) {
xunion := XUnion1WithD(3.14)
if xunion.Which() != XUnion1D {
t.Error("expected xunion with tag XUnion1D")
}
if xunion.D != 3.14 {
t.Error("xunion has incorrect value")
}
}
func TestXUnionArrayFieldFactory(t *testing.T) {
a := [3]int8{1, 2, 3}
xunion := XUnion1WithA(a)
if xunion.Which() != XUnion1A {
t.Error("expected xunion with tag XUnion1A")
}
if xunion.A != a {
t.Error("xunion has incorrect value")
}
}