blob: 8ae788380854952a7f88d2af237e6e8b4c920c46 [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 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("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")
}
})
}