examples/hello:  Add simple integration tests meant to be used in regression tests.

This change adds helloserver and helloclient.  These binaries are used
in a series of integration tests that exercise various aspects of the ipc
protocol.  This is intended to be used in regression tests to prove that
new changes don't break wire compatibility with old binaries.

Change-Id: Iea2915262d0089795f021fee18f69850968cf886
diff --git a/examples/hello/doc.go b/examples/hello/doc.go
new file mode 100644
index 0000000..5713ac0
--- /dev/null
+++ b/examples/hello/doc.go
@@ -0,0 +1,9 @@
+// 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 hello defines a simple client and server and uses them in a series
+// of regression tests.  The idea is for these programs to have stable interfaces
+// (command line flags, output, etc) so that the test code won't need to change
+// as the underlying framework changes.
+package hello
diff --git a/examples/hello/hello_test.go b/examples/hello/hello_test.go
new file mode 100644
index 0000000..bd5a04b
--- /dev/null
+++ b/examples/hello/hello_test.go
@@ -0,0 +1,110 @@
+// 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 hello_test
+
+import (
+	"fmt"
+
+	"v.io/x/ref/envvar"
+	"v.io/x/ref/lib/security"
+	_ "v.io/x/ref/profiles"
+	"v.io/x/ref/test/testutil"
+	"v.io/x/ref/test/v23tests"
+)
+
+//go:generate v23 test generate
+
+// setupCredentials makes a bunch of credentials directories.
+// Note that I do this myself instead of allowing the test framework
+// to do it because I really want to use the agentd binary, not
+// the agent that is locally hosted inside v23Tests.T.
+// This is important for regression tests where we want to test against
+// old agent binaries.
+func setupCredentials(i *v23tests.T, names ...string) (map[string]string, error) {
+	idp := testutil.NewIDProvider("root")
+	out := make(map[string]string, len(names))
+	for _, name := range names {
+		dir := i.NewTempDir("")
+		p, err := security.CreatePersistentPrincipal(dir, nil)
+		if err != nil {
+			return nil, err
+		}
+		if err := idp.Bless(p, name); err != nil {
+			return nil, err
+		}
+		out[name] = fmt.Sprintf("%s=%s", envvar.Credentials, dir)
+	}
+	return out, nil
+}
+
+func V23TestHelloDirect(i *v23tests.T) {
+	creds, err := setupCredentials(i, "helloclient", "helloserver")
+	if err != nil {
+		i.Fatalf("Could not create credentials: %v", err)
+	}
+	clientbin := i.BuildGoPkg("v.io/x/ref/examples/hello/helloclient")
+	serverbin := i.BuildGoPkg("v.io/x/ref/examples/hello/helloserver")
+	server := serverbin.WithEnv(creds["helloserver"]).Start()
+	name := server.ExpectVar("SERVER_NAME")
+	clientbin.WithEnv(creds["helloclient"]).Run("--name", name)
+}
+
+func V23TestHelloAgentd(i *v23tests.T) {
+	creds, err := setupCredentials(i, "helloclient", "helloserver")
+	if err != nil {
+		i.Fatalf("Could not create credentials: %v", err)
+	}
+	agentdbin := i.BuildGoPkg("v.io/x/ref/services/agent/agentd")
+	serverbin := i.BuildGoPkg("v.io/x/ref/examples/hello/helloserver")
+	clientbin := i.BuildGoPkg("v.io/x/ref/examples/hello/helloclient")
+	server := agentdbin.WithEnv(creds["helloserver"]).Start(serverbin.Path())
+	name := server.ExpectVar("SERVER_NAME")
+	agentdbin.WithEnv(creds["helloclient"]).Run(clientbin.Path(), "--name", name)
+}
+
+func V23TestHelloMounttabled(i *v23tests.T) {
+	creds, err := setupCredentials(i, "helloclient", "helloserver", "mounttabled")
+	if err != nil {
+		i.Fatalf("Could not create credentials: %v", err)
+	}
+	agentdbin := i.BuildGoPkg("v.io/x/ref/services/agent/agentd")
+	mounttabledbin := i.BuildGoPkg("v.io/x/ref/services/mounttable/mounttabled")
+	serverbin := i.BuildGoPkg("v.io/x/ref/examples/hello/helloserver")
+	clientbin := i.BuildGoPkg("v.io/x/ref/examples/hello/helloclient")
+	name := "hello"
+	mounttabled := agentdbin.WithEnv(creds["mounttabled"]).Start(mounttabledbin.Path(),
+		"--v23.tcp.address", "127.0.0.1:0")
+	mt := fmt.Sprintf("%s=%s", envvar.NamespacePrefix, mounttabled.ExpectVar("NAME"))
+	agentdbin.WithEnv(creds["helloserver"], mt).Start(serverbin.Path(), "--name", name)
+	agentdbin.WithEnv(creds["helloclient"], mt).Run(clientbin.Path(), "--name", name)
+}
+
+func V23TestHelloProxy(i *v23tests.T) {
+	creds, err := setupCredentials(i, "helloclient", "helloserver",
+		"mounttabled", "proxyd")
+	if err != nil {
+		i.Fatalf("Could not create credentials: %v", err)
+	}
+	agentdbin := i.BuildGoPkg("v.io/x/ref/services/agent/agentd")
+	mounttabledbin := i.BuildGoPkg("v.io/x/ref/services/mounttable/mounttabled")
+	proxydbin := i.BuildGoPkg("v.io/x/ref/services/proxy/proxyd")
+	serverbin := i.BuildGoPkg("v.io/x/ref/examples/hello/helloserver")
+	clientbin := i.BuildGoPkg("v.io/x/ref/examples/hello/helloclient")
+	proxyname := "proxy"
+	name := "hello"
+	mounttabled := agentdbin.WithEnv(creds["mounttabled"]).Start(mounttabledbin.Path(),
+		"--v23.tcp.address", "127.0.0.1:0")
+	mt := fmt.Sprintf("%s=%s", envvar.NamespacePrefix, mounttabled.ExpectVar("NAME"))
+	agentdbin.WithEnv(creds["proxyd"], mt).Start(proxydbin.Path(),
+		"--name", proxyname, "--v23.tcp.address", "127.0.0.1:0",
+		"--access-list", "{\"In\":[\"root/*\"]}")
+	server := agentdbin.WithEnv(creds["helloserver"], mt).Start(serverbin.Path(),
+		"--name", name, "--v23.proxy", proxyname, "--v23.tcp.address", "")
+	// Prove that we're listening on a proxy.
+	if sn := server.ExpectVar("SERVER_NAME"); sn != "proxy" {
+		i.Fatalf("helloserver not listening through proxy: %s.", sn)
+	}
+	agentdbin.WithEnv(creds["helloclient"], mt).Run(clientbin.Path(), "--name", name)
+}
diff --git a/examples/hello/helloclient/helloclient.go b/examples/hello/helloclient/helloclient.go
new file mode 100644
index 0000000..7c7f199
--- /dev/null
+++ b/examples/hello/helloclient/helloclient.go
@@ -0,0 +1,38 @@
+// 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.
+
+// Command helloclient is the simplest possible client.  It is mainly used in simple
+// regression tests.
+package main
+
+import (
+	"flag"
+	"fmt"
+	"time"
+
+	"v.io/v23"
+	"v.io/v23/context"
+	"v.io/v23/verror"
+	_ "v.io/x/ref/profiles"
+)
+
+var name *string = flag.String("name", "", "Name of the hello server")
+
+func main() {
+	ctx, shutdown := v23.Init()
+	defer shutdown()
+
+	ctx, cancel := context.WithTimeout(ctx, 10*time.Second)
+	defer cancel()
+
+	var result string
+	err := v23.GetClient(ctx).Call(ctx, *name, "Hello", nil, []interface{}{&result})
+	if err != nil {
+		panic(verror.DebugString(err))
+	}
+
+	if result != "hello" {
+		panic(fmt.Sprintf("Unexpected result.  Wanted %q, got %q", "hello", result))
+	}
+}
diff --git a/examples/hello/helloserver/helloserver.go b/examples/hello/helloserver/helloserver.go
new file mode 100644
index 0000000..212ca64
--- /dev/null
+++ b/examples/hello/helloserver/helloserver.go
@@ -0,0 +1,58 @@
+// 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.
+
+// Daemon helloserver is the simplest possible server.  It is mainly
+// used in simple regression tests.
+package main
+
+import (
+	"flag"
+	"fmt"
+	"os"
+
+	"v.io/v23"
+	"v.io/v23/context"
+	"v.io/v23/rpc"
+	"v.io/v23/security"
+	"v.io/x/ref/lib/signals"
+	_ "v.io/x/ref/profiles"
+)
+
+var name *string = flag.String("name", "", "Name to publish under")
+
+type helloServer struct{}
+
+func (*helloServer) Hello(ctx *context.T, call rpc.ServerCall) (string, error) {
+	return "hello", nil
+}
+
+func run() error {
+	ctx, shutdown := v23.Init()
+	defer shutdown()
+
+	server, err := v23.NewServer(ctx)
+	if err != nil {
+		return fmt.Errorf("NewServer: %v", err)
+	}
+	eps, err := server.Listen(v23.GetListenSpec(ctx))
+	if err != nil {
+		return fmt.Errorf("Listen: %v", err)
+	}
+	if len(eps) > 0 {
+		fmt.Printf("SERVER_NAME=%s\n", eps[0].Name())
+	} else {
+		fmt.Println("SERVER_NAME=proxy")
+	}
+	if err := server.Serve(*name, &helloServer{}, security.AllowEveryone()); err != nil {
+		return fmt.Errorf("Serve: %v", err)
+	}
+	<-signals.ShutdownOnSignals(ctx)
+	return nil
+}
+
+func main() {
+	if err := run(); err != nil {
+		os.Exit(1)
+	}
+}
diff --git a/examples/hello/v23_test.go b/examples/hello/v23_test.go
new file mode 100644
index 0000000..515e1cd
--- /dev/null
+++ b/examples/hello/v23_test.go
@@ -0,0 +1,37 @@
+// 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.
+
+// This file was auto-generated via go generate.
+// DO NOT UPDATE MANUALLY
+package hello_test
+
+import "testing"
+import "os"
+
+import "v.io/x/ref/test"
+import "v.io/x/ref/test/v23tests"
+
+func TestMain(m *testing.M) {
+	test.Init()
+	cleanup := v23tests.UseSharedBinDir()
+	r := m.Run()
+	cleanup()
+	os.Exit(r)
+}
+
+func TestV23HelloDirect(t *testing.T) {
+	v23tests.RunTest(t, V23TestHelloDirect)
+}
+
+func TestV23HelloAgentd(t *testing.T) {
+	v23tests.RunTest(t, V23TestHelloAgentd)
+}
+
+func TestV23HelloMounttabled(t *testing.T) {
+	v23tests.RunTest(t, V23TestHelloMounttabled)
+}
+
+func TestV23HelloProxy(t *testing.T) {
+	v23tests.RunTest(t, V23TestHelloProxy)
+}