// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package test

import (
	"errors"
	"fmt"
	"io"
	"os"
	"path/filepath"
	"runtime"
	"strings"
	"sync"
	"testing"
	"time"

	"v.io/v23"
	"v.io/v23/context"
	"v.io/v23/flow"
	"v.io/v23/flow/message"
	"v.io/v23/naming"
	"v.io/v23/options"
	"v.io/v23/rpc"
	"v.io/v23/security"
	"v.io/v23/vdlroot/signature"
	"v.io/v23/verror"
	"v.io/x/lib/gosh"
	"v.io/x/ref"
	"v.io/x/ref/internal/logger"
	"v.io/x/ref/lib/signals"
	_ "v.io/x/ref/runtime/factories/generic"
	"v.io/x/ref/runtime/internal/flow/conn"
	irpc "v.io/x/ref/runtime/internal/rpc"
	"v.io/x/ref/runtime/protocols/debug"
	"v.io/x/ref/runtime/protocols/lib/tcputil"
	"v.io/x/ref/services/mounttable/mounttablelib"
	"v.io/x/ref/test"
	"v.io/x/ref/test/testutil"
	"v.io/x/ref/test/v23test"
)

func TestMain(m *testing.M) {
	v23test.TestMain(m)
}

// testInit creates a new v23test.Shell, starts a root mount table, and
// optionally starts a simple server.
func testInit(t *testing.T, startServer bool) (sh *v23test.Shell, ctx *context.T, name string, cleanup func()) {
	sh = v23test.NewShell(t, nil)
	ctx = sh.Ctx
	startRootMT(t, sh, false)
	var cleanupServer func()
	name, cleanupServer = startSimpleServer(t, ctx)
	cleanup = func() {
		cleanupServer()
		sh.Cleanup()
	}
	return
}

////////////////////////////////////////
// Root mount table

// TODO(sadovsky): Switch to using v23test.Shell.StartRootMountTable.
var rootMT = gosh.RegisterFunc("rootMT", func(deb bool) error {
	ctx, shutdown := test.V23Init()
	defer shutdown()
	if deb {
		p, a := debug.WrapAddress("tcp", "127.0.0.1:0")
		ctx = v23.WithListenSpec(ctx, rpc.ListenSpec{
			Addrs: rpc.ListenAddrs{{Protocol: p, Address: a}},
		})
	}
	mt, err := mounttablelib.NewMountTableDispatcher(ctx, "", "", "mounttable")
	if err != nil {
		return fmt.Errorf("mounttablelib.NewMountTableDispatcher failed: %s", err)
	}
	ctx, server, err := v23.WithNewDispatchingServer(ctx, "", mt, options.ServesMountTable(true))
	if err != nil {
		return fmt.Errorf("root failed: %v", err)
	}
	fmt.Printf("PID=%d\n", os.Getpid())
	for _, ep := range server.Status().Endpoints {
		fmt.Printf("MT_NAME=%s\n", ep.Name())
	}
	<-signals.ShutdownOnSignals(ctx)
	return nil
})

func startRootMT(t *testing.T, sh *v23test.Shell, deb bool) {
	cmd := sh.FuncCmd(rootMT, deb)
	cmd.Start()
	cmd.S.ExpectVar("PID")
	rootName := cmd.S.ExpectVar("MT_NAME")
	if len(rootName) == 0 {
		sh.HandleError(errors.New("no MT_NAME"))
		return
	}
	sh.Vars[ref.EnvNamespacePrefix] = rootName
	if err := v23.GetNamespace(sh.Ctx).SetRoots(rootName); err != nil {
		sh.HandleError(err)
		return
	}
}

////////////////////////////////////////
// Echo server

type treeDispatcher struct{ id string }

func (d treeDispatcher) Lookup(_ *context.T, suffix string) (interface{}, security.Authorizer, error) {
	return &echoServerObject{d.id, suffix}, nil, nil
}

type echoServerObject struct {
	id, suffix string
}

func (es *echoServerObject) Echo(_ *context.T, _ rpc.ServerCall, m string) (string, error) {
	if len(es.suffix) > 0 {
		return fmt.Sprintf("%s.%s: %s\n", es.id, es.suffix, m), nil
	}
	return fmt.Sprintf("%s: %s\n", es.id, m), nil
}

func (es *echoServerObject) Sleep(_ *context.T, _ rpc.ServerCall, d string) error {
	duration, err := time.ParseDuration(d)
	if err != nil {
		return err
	}
	time.Sleep(duration)
	return nil
}

var echoServer = gosh.RegisterFunc("echoServer", func(id, mp, addr string) error {
	ctx, shutdown := test.V23Init()
	defer shutdown()

	if addr == "" {
		addr = "127.0.0.1:0"
	}
	ctx = v23.WithListenSpec(ctx, rpc.ListenSpec{Addrs: rpc.ListenAddrs{{Protocol: "tcp", Address: addr}}})

	disp := &treeDispatcher{id: id}
	ctx, server, err := v23.WithNewDispatchingServer(ctx, mp, disp)
	if err != nil {
		return err
	}
	fmt.Printf("PID=%d\n", os.Getpid())
	for _, ep := range server.Status().Endpoints {
		fmt.Printf("NAME=%s\n", ep.Name())
	}
	<-signals.ShutdownOnSignals(ctx)
	return nil
})

// Returns server Cmd and name.
func startEchoServer(t *testing.T, sh *v23test.Shell, id, mp, addr string) (*v23test.Cmd, string) {
	cmd := sh.FuncCmd(echoServer, id, mp, addr)
	cmd.Start()
	cmd.S.ExpectVar("PID")
	name := cmd.S.ExpectVar("NAME")
	return cmd, name
}

////////////////////////////////////////
// Echo client

var echoClient = gosh.RegisterFunc("echoClient", func(name string, args ...string) error {
	ctx, shutdown := test.V23Init()
	defer shutdown()

	client := v23.GetClient(ctx)
	for _, a := range args {
		var r string
		if err := client.Call(ctx, name, "Echo", []interface{}{a}, []interface{}{&r}); err != nil {
			return err
		}
		fmt.Printf(r)
	}
	return nil
})

func runEchoClient(t *testing.T, sh *v23test.Shell) {
	cmd := sh.FuncCmd(echoClient, "echoServer", "a message")
	cmd.Start()
	cmd.S.Expect("echoServer: a message")
	cmd.Wait()
}

////////////////////////////////////////
// Misc helpers

func numServers(t *testing.T, ctx *context.T, name string, expected int) int {
	for {
		me, err := v23.GetNamespace(ctx).Resolve(ctx, name)
		if err == nil && len(me.Servers) == expected {
			return expected
		}
		time.Sleep(10 * time.Millisecond)
	}
}

////////////////////////////////////////
// Tests

// TODO(cnicolaou): figure out how to test and see what the internals
// of tryCall are doing - e.g. using stats counters.
func TestMultipleEndpoints(t *testing.T) {
	sh, ctx, _, cleanup := testInit(t, false)
	defer cleanup()

	// Disable the cache so that the repeated lookups we do don't hang on
	// cached values.
	v23.GetNamespace(ctx).CacheCtl(naming.DisableCache(true))

	cmd, _ := startEchoServer(t, sh, "echoServer", "echoServer", "")

	// Verify that there is 1 entry for echoServer in the mount table.
	if got, want := numServers(t, ctx, "echoServer", 1), 1; got != want {
		t.Fatalf("got: %d, want: %d", got, want)
	}

	runEchoClient(t, sh)

	// Create a fake set of 100 entries in the mount table.
	for i := 0; i < 100; i++ {
		// 203.0.113.0 is TEST-NET-3 from RFC5737
		ep := naming.FormatEndpoint("tcp", fmt.Sprintf("203.0.113.%d:443", i))
		n := naming.JoinAddressName(ep, "")
		if err := v23.GetNamespace(ctx).Mount(ctx, "echoServer", n, time.Hour); err != nil {
			t.Fatalf("unexpected error: %s", err)
		}
	}

	// Verify that there are 101 entries for echoServer in the mount table.
	if got, want := numServers(t, ctx, "echoServer", 101), 101; got != want {
		t.Fatalf("got: %q, want: %q", got, want)
	}

	// TODO(cnicolaou): ok, so it works, but I'm not sure how
	// long it should take or if the parallel connection code
	// really works. Use counters to inspect it for example.
	runEchoClient(t, sh)

	cmd.Terminate(os.Interrupt)

	// Verify that there are 100 entries for echoServer in the mount table.
	if got, want := numServers(t, ctx, "echoServer", 100), 100; got != want {
		t.Fatalf("got: %d, want: %d", got, want)
	}
}

func TestTimeout(t *testing.T) {
	_, ctx, _, cleanup := testInit(t, false)
	defer cleanup()

	client := v23.GetClient(ctx)
	var cancel context.CancelFunc
	ctx, cancel = context.WithTimeout(ctx, 100*time.Millisecond)
	defer cancel()
	name := naming.JoinAddressName(naming.FormatEndpoint("tcp", "203.0.113.10:443"), "")
	_, err := client.StartCall(ctx, name, "echo", []interface{}{"args don't matter"})
	t.Log(err)
	if verror.ErrorID(err) != verror.ErrTimeout.ID {
		t.Fatalf("wrong error: %s", err)
	}
}

func TestStartCallErrors(t *testing.T) {
	sh, ctx, _, cleanup := testInit(t, false)
	defer cleanup()

	client := v23.GetClient(ctx)
	ns := v23.GetNamespace(ctx)
	ns.CacheCtl(naming.DisableCache(true))

	emptyCtx := &context.T{}
	emptyCtx = context.WithLogger(emptyCtx, logger.Global())
	_, err := client.StartCall(emptyCtx, "noname", "nomethod", nil)
	if verror.ErrorID(err) != verror.ErrBadArg.ID {
		t.Errorf("wrong error: %s", err)
	}

	// This will fail with NoServers, but because there is no mount table
	// to communicate with. The error message should include a
	// 'connection refused' string.
	ns.SetRoots("/127.0.0.1:8101")
	_, err = client.StartCall(ctx, "noname", "nomethod", nil, options.NoRetry{})
	if verror.ErrorID(err) != verror.ErrNoServers.ID {
		t.Errorf("wrong error: %s", err)
	}
	if want := "connection refused"; !strings.Contains(verror.DebugString(err), want) {
		t.Errorf("wrong error: %s - doesn't contain %q", err, want)
	}

	// This will fail with NoServers, but because there really is no
	// name registered with the mount table.
	startRootMT(t, sh, false)
	_, err = client.StartCall(ctx, "noname", "nomethod", nil, options.NoRetry{})
	if verror.ErrorID(err) != verror.ErrNoServers.ID {
		t.Errorf("wrong error: %s", err)
	}
	if unwanted := "connection refused"; strings.Contains(err.Error(), unwanted) {
		t.Errorf("wrong error: %s - does contain %q", err, unwanted)
	}

	// The following tests will fail with NoServers, but because there are
	// no protocols that the client and servers (mounttable, and "name") share.
	nctx, nclient, err := v23.WithNewClient(ctx, irpc.PreferredProtocols([]string{"boo"}))
	addr := naming.FormatEndpoint("nope", "127.0.0.1:1081")
	if err := ns.Mount(ctx, "name", addr, time.Minute); err != nil {
		t.Fatal(err)
	}
	// This will fail in its attempt to call ResolveStep to the mount table
	// because we are using both the new context and the new client.
	_, err = nclient.StartCall(nctx, "name", "nomethod", nil, options.NoRetry{})
	if verror.ErrorID(err) != verror.ErrNoServers.ID {
		t.Fatalf("wrong error: %s", err)
	}
	if want := "ResolveStep"; !strings.Contains(err.Error(), want) {
		t.Fatalf("wrong error: %s - doesn't contain %q", err, want)
	}
	// This will fail in its attempt to invoke the actual RPC because
	// we are using the old context (which supplies the context for the calls
	// to ResolveStep) and the new client.
	_, err = nclient.StartCall(ctx, "name", "nomethod", nil, options.NoRetry{})
	if verror.ErrorID(err) != verror.ErrNoServers.ID {
		t.Fatalf("wrong error: %s", err)
	}
	if want := "nope"; !strings.Contains(err.Error(), want) {
		t.Errorf("wrong error: %s - doesn't contain %q", err, want)
	}
	if unwanted := "ResolveStep"; strings.Contains(err.Error(), unwanted) {
		t.Errorf("wrong error: %s - does contain %q", err, unwanted)
	}

	// The following two tests will fail due to a timeout.
	ns.SetRoots("/203.0.113.10:8101")
	var cancel context.CancelFunc
	nctx, cancel = context.WithTimeout(ctx, 100*time.Millisecond)
	// This call will timeout talking to the mount table.
	call, err := client.StartCall(nctx, "name", "noname", nil, options.NoRetry{})
	if verror.ErrorID(err) != verror.ErrTimeout.ID {
		t.Errorf("wrong error: %s", err)
	}
	if call != nil {
		t.Errorf("expected call to be nil")
	}
	cancel()

	// This, second test, will fail due a timeout contacting the server itself.
	addr = naming.FormatEndpoint("tcp", "203.0.113.10:8101")

	nctx, cancel = context.WithTimeout(ctx, 100*time.Millisecond)
	new_name := naming.JoinAddressName(addr, "")
	call, err = client.StartCall(nctx, new_name, "noname", nil, options.NoRetry{})
	if verror.ErrorID(err) != verror.ErrTimeout.ID {
		t.Errorf("wrong error: %s", err)
	}
	if call != nil {
		t.Errorf("expected call to be nil")
	}
	cancel()
}

type closeConn struct {
	ctx *context.T
	flow.Conn
	wg *sync.WaitGroup
}

func (c *closeConn) ReadMsg() ([]byte, error) {
	buf, err := c.Conn.ReadMsg()
	if err == nil {
		if m, err := message.Read(c.ctx, buf); err == nil {
			if _, ok := m.(*message.Data); ok {
				c.Conn.Close()
				c.wg.Done()
				return nil, io.EOF
			}
		}
	}
	return buf, err
}

func TestStartCallBadProtocol(t *testing.T) {
	sh := v23test.NewShell(t, nil)
	ctx := sh.Ctx
	defer sh.Cleanup()
	startRootMT(t, sh, true)

	client := v23.GetClient(ctx)

	wg := &sync.WaitGroup{}
	nctx := debug.WithFilter(ctx, func(c flow.Conn) flow.Conn {
		wg.Add(1)
		return &closeConn{ctx: ctx, Conn: c, wg: wg}
	})
	call, err := client.StartCall(nctx, "name", "noname", nil, options.NoRetry{})
	if verror.ErrorID(err) != verror.ErrNoServers.ID {
		t.Errorf("wrong error: %s", verror.DebugString(err))
	}
	if call != nil {
		t.Errorf("expected call to be nil")
	}

	// Make sure we failed because we really did close the connection
	// with our filter
	wg.Wait()
}

func TestStartCallSecurity(t *testing.T) {
	_, ctx, name, cleanup := testInit(t, true)
	defer cleanup()

	client := v23.GetClient(ctx)

	// Create a context with a new principal that doesn't match the server,
	// so that the client will not trust the server.
	ctx1, err := v23.WithPrincipal(ctx, testutil.NewPrincipal("test-blessing"))
	if err != nil {
		t.Fatal(err)
	}
	call, err := client.StartCall(ctx1, name, "noname", nil, options.NoRetry{})
	if verror.ErrorID(err) != verror.ErrNotTrusted.ID {
		t.Fatalf("wrong error: %s", err)
	}
	if call != nil {
		t.Fatalf("expected call to be nil")
	}
}

var childPing = gosh.RegisterFunc("childPing", func(name string) error {
	ctx, shutdown := test.V23Init()
	defer shutdown()

	got := ""
	if err := v23.GetClient(ctx).Call(ctx, name, "Ping", nil, []interface{}{&got}); err != nil {
		return fmt.Errorf("unexpected error: %s", err)
	}
	fmt.Printf("RESULT=%s\n", got)
	return nil
})

func TestTimeoutResponse(t *testing.T) {
	_, ctx, name, cleanup := testInit(t, true)
	defer cleanup()

	ctx, cancel := context.WithTimeout(ctx, time.Millisecond)
	err := v23.GetClient(ctx).Call(ctx, name, "Sleep", nil, nil)
	if got, want := verror.ErrorID(err), verror.ErrTimeout.ID; got != want {
		t.Fatalf("got %v, want %v", verror.DebugString(err), want)
	}
	cancel()
}

func TestArgsAndResponses(t *testing.T) {
	_, ctx, name, cleanup := testInit(t, true)
	defer cleanup()

	call, err := v23.GetClient(ctx).StartCall(ctx, name, "Sleep", []interface{}{"too many args"})
	if err != nil {
		t.Fatalf("unexpected error: %s", err)
	}
	err = call.Finish()
	if got, want := verror.ErrorID(err), verror.ErrBadProtocol.ID; got != want {
		t.Fatalf("got %v, want %v", got, want)
	}

	call, err = v23.GetClient(ctx).StartCall(ctx, name, "Ping", nil)
	if err != nil {
		t.Fatalf("unexpected error: %s", err)
	}
	pong := ""
	dummy := ""
	err = call.Finish(&pong, &dummy)
	if got, want := verror.ErrorID(err), verror.ErrBadProtocol.ID; got != want {
		t.Fatalf("got %v, want %v", got, want)
	}
}

func TestAccessDenied(t *testing.T) {
	_, ctx, name, cleanup := testInit(t, true)
	defer cleanup()

	ctx1, err := v23.WithPrincipal(ctx, testutil.NewPrincipal("test-blessing"))
	// Client must recognize the server, otherwise it won't even send the request.
	bserver, _ := v23.GetPrincipal(ctx).BlessingStore().Default()
	security.AddToRoots(v23.GetPrincipal(ctx1), bserver)
	if err != nil {
		t.Fatal(err)
	}
	call, err := v23.GetClient(ctx1).StartCall(ctx1, name, "Sleep", nil)
	if err != nil {
		t.Fatalf("unexpected error: %s", err)
	}
	err = call.Finish()
	if got, want := verror.ErrorID(err), verror.ErrNoAccess.ID; got != want {
		t.Fatalf("got %v, want %v", got, want)
	}
}

func TestCanceledBeforeFinish(t *testing.T) {
	_, ctx, name, cleanup := testInit(t, true)
	defer cleanup()

	ctx, cancel := context.WithCancel(ctx)
	call, err := v23.GetClient(ctx).StartCall(ctx, name, "Sleep", nil)
	if err != nil {
		t.Fatalf("unexpected error: %s", err)
	}
	// Cancel before we call finish.
	cancel()
	err = call.Finish()
	if got, want := verror.ErrorID(err), verror.ErrCanceled.ID; got != want {
		t.Fatalf("got %v, want %v", got, want)
	}
}

func TestCanceledDuringFinish(t *testing.T) {
	_, ctx, name, cleanup := testInit(t, true)
	defer cleanup()

	ctx, cancel := context.WithCancel(ctx)
	call, err := v23.GetClient(ctx).StartCall(ctx, name, "Sleep", nil)
	if err != nil {
		t.Fatalf("unexpected error: %s", err)
	}
	// Cancel whilst the RPC is running.
	go func() {
		time.Sleep(100 * time.Millisecond)
		cancel()
	}()
	err = call.Finish()
	if got, want := verror.ErrorID(err), verror.ErrCanceled.ID; got != want {
		t.Fatalf("got %v, want %v", got, want)
	}
}

func TestRendezvous(t *testing.T) {
	sh, ctx, _, cleanup := testInit(t, false)
	defer cleanup()

	// We start the client before we start the server, StartCall will reresolve
	// the name until it finds an entry or times out after an exponential
	// backoff of some minutes.
	name := "echoServer"
	go func() {
		time.Sleep(100 * time.Millisecond)
		startEchoServer(t, sh, "message", name, "")
	}()

	call, err := v23.GetClient(ctx).StartCall(ctx, name, "Echo", []interface{}{"hello"})
	if err != nil {
		t.Fatalf("unexpected error: %s", err)
	}

	response := ""
	if err := call.Finish(&response); err != nil {
		if got, want := verror.ErrorID(err), verror.ErrCanceled.ID; got != want {
			t.Fatalf("got %v, want %v", got, want)
		}
	}
	if got, want := response, "message: hello\n"; got != want {
		t.Errorf("got %q, want %q", got, want)
	}
}

func TestCallback(t *testing.T) {
	sh, _, name, cleanup := testInit(t, true)
	defer cleanup()

	cmd := sh.FuncCmd(childPing, name)
	cmd.Start()
	if got, want := cmd.S.ExpectVar("RESULT"), "pong"; got != want {
		t.Errorf("got %q, want %q", got, want)
	}
	cmd.Wait()
}

func TestStreamTimeout(t *testing.T) {
	_, ctx, name, cleanup := testInit(t, true)
	defer cleanup()

	want := 10
	var cancel context.CancelFunc
	ctx, cancel = context.WithTimeout(ctx, 300*time.Millisecond)
	defer cancel()
	call, err := v23.GetClient(ctx).StartCall(ctx, name, "Source", []interface{}{want})
	if err != nil {
		if verror.ErrorID(err) != verror.ErrTimeout.ID {
			t.Fatalf("verror should be a timeout not %s: stack %s",
				err, verror.Stack(err))
		}
		return
	}

	for {
		got := 0
		err := call.Recv(&got)
		if err == nil {
			if got != want {
				t.Fatalf("got %d, want %d", got, want)
			}
			want++
			continue
		}
		if got, want := verror.ErrorID(err), verror.ErrTimeout.ID; got != want {
			t.Fatalf("got %v, want %v", got, want)
		}
		break
	}
	err = call.Finish()
	if got, want := verror.ErrorID(err), verror.ErrTimeout.ID; got != want {
		t.Fatalf("got %v, want %v", got, want)
	}
}

func TestStreamAbort(t *testing.T) {
	_, ctx, name, cleanup := testInit(t, true)
	defer cleanup()

	call, err := v23.GetClient(ctx).StartCall(ctx, name, "Sink", nil)
	if err != nil {
		t.Fatalf("unexpected error: %s", err)
	}

	want := 10
	for i := 0; i <= want; i++ {
		if err := call.Send(i); err != nil {
			t.Fatalf("unexpected error: %s", err)
		}
	}
	call.CloseSend()
	err = call.Send(100)
	if got, want := verror.ErrorID(err), verror.ErrAborted.ID; got != want {
		t.Fatalf("got %v, want %v", got, want)
	}

	result := 0
	err = call.Finish(&result)
	if err != nil {
		t.Errorf("unexpected error: %#v", err)
	}
	if got := result; got != want {
		t.Errorf("got %d, want %d", got, want)
	}
}

func TestNoServersAvailable(t *testing.T) {
	_, ctx, _, cleanup := testInit(t, false)
	defer cleanup()

	name := "noservers"
	call, err := v23.GetClient(ctx).StartCall(ctx, name, "Sleep", nil, options.NoRetry{})
	if err != nil {
		if got, want := verror.ErrorID(err), verror.ErrNoServers.ID; got != want {
			t.Fatalf("got %v, want %v", got, want)
		}
		return
	}
	err = call.Finish()
	if got, want := verror.ErrorID(err), verror.ErrNoServers.ID; got != want {
		t.Fatalf("got %v, want %v", got, want)
	}

}

func TestNoMountTable(t *testing.T) {
	_, ctx, _, cleanup := testInit(t, false)
	defer cleanup()

	v23.GetNamespace(ctx).SetRoots()
	name := "a_mount_table_entry"

	// If there is no mount table, then we'll get a NoServers error message.
	var cancel context.CancelFunc
	ctx, cancel = context.WithTimeout(ctx, 300*time.Millisecond)
	defer cancel()
	_, err := v23.GetClient(ctx).StartCall(ctx, name, "Sleep", nil)
	if got, want := verror.ErrorID(err), verror.ErrNoServers.ID; got != want {
		t.Fatalf("got %v, want %v", got, want)
	}
}

// TestReconnect verifies that the client transparently re-establishes the
// connection to the server if the server dies and comes back (on the same
// endpoint).
func TestReconnect(t *testing.T) {
	sh, ctx, _, cleanup := testInit(t, false)
	defer cleanup()

	cmd, serverName := startEchoServer(t, sh, "mymessage", "", "")
	serverEP, _ := naming.SplitAddressName(serverName)
	ep, _ := naming.ParseEndpoint(serverEP)
	// create a serverName of just the host:port format so that it will work with
	// servers on the same host port but with different routing ids.
	ep.RoutingID = naming.NullRoutingID
	serverName = ep.Name()

	makeCall := func(ctx *context.T, opts ...rpc.CallOpt) (string, error) {
		var cancel context.CancelFunc
		ctx, cancel = context.WithDeadline(ctx, time.Now().Add(10*time.Second))
		defer cancel()
		call, err := v23.GetClient(ctx).StartCall(ctx, serverName, "Echo", []interface{}{"bratman"}, opts...)
		if err != nil {
			return "", fmt.Errorf("START: %s", err)
		}
		var result string
		if err := call.Finish(&result); err != nil {
			return "", err
		}
		return result, nil
	}

	expected := "mymessage: bratman\n"
	if result, err := makeCall(ctx); err != nil || result != expected {
		t.Errorf("Got (%q, %v) want (%q, nil)", result, err, expected)
	}

	// Kill the server, verify client can't talk to it anymore.
	cmd.Terminate(os.Interrupt)
	if _, err := makeCall(ctx, options.NoRetry{}); err == nil || (!strings.HasPrefix(err.Error(), "START") && !strings.Contains(err.Error(), "EOF")) {
		t.Fatalf(`Got (%v) want ("START: <err>" or "EOF") as server is down`, err)
	}

	// Resurrect the server with the same address, verify client
	// re-establishes the connection. This is racy if another
	// process grabs the port.
	cmd, _ = startEchoServer(t, sh, "mymessage again", "", ep.Address)
	defer cmd.Terminate(os.Interrupt)
	expected = "mymessage again: bratman\n"
	if result, err := makeCall(ctx); err != nil || result != expected {
		t.Errorf("Got (%q, %v) want (%q, nil)", result, err, expected)
	}
}

func TestMethodErrors(t *testing.T) {
	_, ctx, name, cleanup := testInit(t, true)
	defer cleanup()

	var (
		i, j int
		s    string
	)

	testCases := []struct {
		testName, objectName, method string
		args, results                []interface{}
		wantID                       verror.ID
		wantMessage                  string
	}{
		{
			testName:   "unknown method",
			objectName: name,
			method:     "NoMethod",
			wantID:     verror.ErrUnknownMethod.ID,
		},
		{
			testName:   "unknown suffix",
			objectName: name + "/NoSuffix",
			method:     "Ping",
			wantID:     verror.ErrUnknownSuffix.ID,
		},
		{
			testName:    "too many args",
			objectName:  name,
			method:      "Ping",
			args:        []interface{}{1, 2},
			results:     []interface{}{&i},
			wantID:      verror.ErrBadProtocol.ID,
			wantMessage: "wrong number of input arguments",
		},
		{
			testName:    "wrong number of results",
			objectName:  name,
			method:      "Ping",
			results:     []interface{}{&i, &j},
			wantID:      verror.ErrBadProtocol.ID,
			wantMessage: "results, but want",
		},
		{
			testName:    "wrong number of results",
			objectName:  name,
			method:      "Ping",
			results:     []interface{}{&i, &j},
			wantID:      verror.ErrBadProtocol.ID,
			wantMessage: "results, but want",
		},
		{
			testName:    "incompatible arg types",
			objectName:  name,
			method:      "Echo",
			args:        []interface{}{1},
			results:     []interface{}{&s},
			wantID:      verror.ErrBadProtocol.ID,
			wantMessage: "incompatible",
		},
		{
			testName:    "incompatible result types",
			objectName:  name,
			method:      "Ping",
			results:     []interface{}{&i},
			wantID:      verror.ErrBadProtocol.ID,
			wantMessage: "incompatible",
		},
	}

	clt := v23.GetClient(ctx)
	for _, test := range testCases {
		testPrefix := fmt.Sprintf("test(%s) failed", test.testName)
		call, err := clt.StartCall(ctx, test.objectName, test.method, test.args)
		if err != nil {
			t.Fatalf("%s: %v", testPrefix, err)
		}
		verr := call.Finish(test.results...)
		if verror.ErrorID(verr) != test.wantID {
			t.Errorf("%s: wrong error: %v", testPrefix, verr)
		} else if got, want := verr.Error(), test.wantMessage; !strings.Contains(got, want) {
			t.Errorf("%s: want %q to contain %q", testPrefix, got, want)
		}
		logErrors(t, test.testName, false, false, false, verr)
	}
}

func logErrors(t *testing.T, msg string, logerr, logstack, debugString bool, err error) {
	_, file, line, _ := runtime.Caller(2)
	loc := fmt.Sprintf("%s:%d", filepath.Base(file), line)
	if logerr {
		t.Logf("%s: %s: %v", loc, msg, err)
	}
	if logstack {
		t.Logf("%s: %s: %v", loc, msg, verror.Stack(err).String())
	}
	if debugString {
		t.Logf("%s: %s: %v", loc, msg, verror.DebugString(err))
	}
}

func TestReservedMethodErrors(t *testing.T) {
	_, ctx, name, cleanup := testInit(t, true)
	defer cleanup()

	// This call will fail because the __xx suffix is not supported by
	// the dispatcher implementing Signature.
	clt := v23.GetClient(ctx)
	call, err := clt.StartCall(ctx, name+"/__xx", "__Signature", nil)
	if err != nil {
		t.Fatal(err)
	}
	sig := []signature.Interface{}
	verr := call.Finish(&sig)
	if verror.ErrorID(verr) != verror.ErrUnknownSuffix.ID {
		t.Fatalf("wrong error: %s", verr)
	}

	// This call will fail for the same reason, but with a different error,
	// saying that MethodSignature is an unknown method.
	call, err = clt.StartCall(ctx, name+"/__xx", "__MethodSignature", []interface{}{"dummy"})
	if err != nil {
		t.Fatal(err)
	}
	verr = call.Finish(&sig)
	if verror.ErrorID(verr) != verror.ErrUnknownMethod.ID {
		t.Fatalf("wrong error: %s", verr)
	}
}

type changeProtocol struct {
	tcp tcputil.TCP

	mu      sync.Mutex
	count   int
	address string
}

func (c *changeProtocol) Dial(ctx *context.T, protocol, address string, timeout time.Duration) (flow.Conn, error) {
	return c.tcp.Dial(ctx, "tcp", c.address, timeout)
}
func (c *changeProtocol) Resolve(ctx *context.T, proctocol, address string) (string, []string, error) {
	defer c.mu.Unlock()
	c.mu.Lock()
	// Return a new resolved address everytime to disallow cache hits based on resolved address.
	c.count++
	return "tcp", []string{fmt.Sprintf("resolved%d", c.count)}, nil
}
func (c *changeProtocol) Listen(ctx *context.T, protocol, address string) (flow.Listener, error) {
	protocol = "tcp"
	address = "127.0.0.1:0"
	l, err := c.tcp.Listen(ctx, protocol, address)
	if err != nil {
		return nil, err
	}
	c.mu.Lock()
	c.address = l.Addr().String()
	c.mu.Unlock()
	return l, nil
}

func TestDNSResolutionChange(t *testing.T) {
	// Scenario: A DNS Resolution changes the ip address a hostname resolves to. It
	// is important that we make sure that the flow and type flow dialed are still on
	// the same connection or the rpc will never succeed.
	flow.RegisterProtocol("change", &changeProtocol{})
	ctx, shutdown := test.V23Init()
	defer shutdown()

	ctx, cancel := context.WithCancel(ctx)
	ctx = v23.WithListenSpec(ctx, rpc.ListenSpec{
		Addrs: rpc.ListenAddrs{{Protocol: "change", Address: "hostname"}},
	})
	_, server, err := v23.WithNewServer(ctx, "", &testServer{}, nil)
	if err != nil {
		t.Fatal(err)
	}
	defer func() { <-server.Closed() }()
	defer cancel()

	// The call should succeed.
	if err := v23.GetClient(ctx).Call(ctx, "/@6@change@hostname@@00000000000000000000000000000000@s@@@", "Closure", nil, nil); err != nil {
		t.Error(err)
	}
}

func TestPinConnection(t *testing.T) {
	ctx, shutdown := test.V23InitWithMounttable()
	defer shutdown()

	ctx, cancel := context.WithCancel(ctx)
	name := "mountpoint/server"
	_, server, err := v23.WithNewServer(ctx, name, &testServer{}, nil, options.LameDuckTimeout(0))
	if err != nil {
		t.Fatal(err)
	}
	defer func() { <-server.Closed() }()
	defer cancel()

	client := v23.GetClient(ctx)

	pinnedConn, err := client.PinConnection(ctx, name)
	if err != nil {
		t.Error(err)
	}

	// StartCall should use the same connection that was just created.
	call, err := client.StartCall(ctx, name, "Closure", nil)
	if err != nil {
		t.Error(err)
	}
	if got, want := call.Security().LocalEndpoint().String(), pinnedConn.Conn().LocalEndpoint().String(); got != want {
		t.Errorf("got %v, want %v", got, want)
	}
	call.Finish()

	// Closing the original conn should automatically reconnect to the server.
	origConn := pinnedConn.Conn()
	origConn.(*conn.Conn).Close(ctx, nil)
	<-origConn.Closed()
	for {
		if origConn != pinnedConn.Conn() {
			break
		}
		time.Sleep(20 * time.Millisecond)
	}

	// Closing an unpinned conn should not reconnect.
	pinnedConn.Unpin()
	origConn = pinnedConn.Conn()
	origConn.(*conn.Conn).Close(ctx, nil)
	<-origConn.Closed()
	time.Sleep(300 * time.Millisecond)
	if origConn != pinnedConn.Conn() {
		t.Errorf("Conn should not have reconnected.")
	}
	// The pinned conn should also become idle.
	if !origConn.(*conn.Conn).IsIdle(ctx, time.Millisecond) {
		t.Errorf("Conn should have been idle.")
	}
}

func TestConnectionTimeout(t *testing.T) {
	ctx, shutdown := test.V23InitWithMounttable()
	defer shutdown()

	ctx, cancel := context.WithCancel(ctx)
	name := "mountpoint/server"
	_, server, err := v23.WithNewServer(ctx, name, &testServer{}, nil)
	if err != nil {
		t.Fatal(err)
	}
	defer func() { <-server.Closed() }()
	defer cancel()

	client := v23.GetClient(ctx)

	// A connection timeout of zero should fail since the a connection to the server
	// doesn't yet exist in the the client's manager's cache.
	if err := client.Call(ctx, name, "Closure", nil, nil, options.ConnectionTimeout(0)); err == nil {
		t.Errorf("got err = <nil>, wanted call to fail")
	}
	// Making a rpc with a non-zero connection timeout should work.
	if err := client.Call(ctx, name, "Closure", nil, nil, options.ConnectionTimeout(5*time.Second)); err != nil {
		t.Error(err)
	}
	// Now the connection should be in the cache so connection timeout of zero should work.
	if err := client.Call(ctx, name, "Closure", nil, nil, options.ConnectionTimeout(0)); err != nil {
		t.Error(err)
	}
}

func TestIdleConnectionExpiry(t *testing.T) {
	ctx, shutdown := test.V23InitWithMounttable()
	defer shutdown()

	ctx, cancel := context.WithCancel(ctx)
	name := "mountpoint/server"
	_, server, err := v23.WithNewServer(ctx, name, &testServer{}, nil)
	if err != nil {
		t.Fatal(err)
	}
	defer func() { <-server.Closed() }()
	defer cancel()

	// Creating a client with no idle expiry should keep connection cached.
	ctx, client, err := v23.WithNewClient(ctx)
	if err := client.Call(ctx, name, "Closure", nil, nil); err != nil {
		t.Error(err)
	}
	// Now the connection should be in the cache so connection timeout of zero should work.
	if err := client.Call(ctx, name, "Closure", nil, nil, options.ConnectionTimeout(0)); err != nil {
		t.Error(err)
	}

	// Creating a client with a very low idle expiry should quickly close idle connections.
	ctx, client, err = v23.WithNewClient(ctx, irpc.IdleConnectionExpiry(1))
	if err := client.Call(ctx, name, "Closure", nil, nil); err != nil {
		t.Error(err)
	}
	time.Sleep(20 * time.Millisecond)
	// Now the connection should no longer be in the cache so connection timeout of zero should fail.
	if err := client.Call(ctx, name, "Closure", nil, nil, options.ConnectionTimeout(0)); err == nil {
		t.Errorf("expected call to fail, got success")
	}

	// Creating a client with a very high idle expiry should keep connection cached.
	ctx, client, err = v23.WithNewClient(ctx, irpc.IdleConnectionExpiry(time.Hour))
	if err := client.Call(ctx, name, "Closure", nil, nil); err != nil {
		t.Error(err)
	}
	// Now the connection should be in the cache so connection timeout of zero should work.
	if err := client.Call(ctx, name, "Closure", nil, nil, options.ConnectionTimeout(0)); err != nil {
		t.Error(err)
	}
}
