Merge "examples/hello:  Add simple integration tests meant to be used in regression tests."
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)
+}