Merge "veyron/google/rt/runtimex: Add preferred protocols to runtime init for profile to call."
diff --git a/lib/testutil/dispatcher.go b/lib/testutil/dispatcher.go
new file mode 100644
index 0000000..b7bb689
--- /dev/null
+++ b/lib/testutil/dispatcher.go
@@ -0,0 +1,26 @@
+package testutil
+
+import (
+	"v.io/core/veyron2/ipc"
+	"v.io/core/veyron2/security"
+	"v.io/core/veyron2/verror"
+)
+
+// LeafDispatcher returns a dispatcher for a single object obj, using
+// ReflectInvokerOrDie to invoke methods. Lookup only succeeds on the empty
+// suffix.  The provided auth is returned for successful lookups.
+func LeafDispatcher(obj interface{}, auth security.Authorizer) ipc.Dispatcher {
+	return &leafDispatcher{ipc.ReflectInvokerOrDie(obj), auth}
+}
+
+type leafDispatcher struct {
+	invoker ipc.Invoker
+	auth    security.Authorizer
+}
+
+func (d leafDispatcher) Lookup(suffix string) (interface{}, security.Authorizer, error) {
+	if suffix != "" {
+		return nil, nil, verror.NoExistf("ipc: LeafDispatcher lookup on non-empty suffix: " + suffix)
+	}
+	return d.invoker, d.auth, nil
+}
diff --git a/profiles/roaming/roaming_server.go b/profiles/roaming/roaming_server.go
index b36bfda..e49caa8 100644
--- a/profiles/roaming/roaming_server.go
+++ b/profiles/roaming/roaming_server.go
@@ -34,7 +34,7 @@
 	if ep != nil {
 		fmt.Println(ep)
 	}
-	if err := server.Serve("roamer", ipc.LeafDispatcher(&dispatcher{}, nil)); err != nil {
+	if err := server.Serve("roamer", &receiver{}, nil); err != nil {
 		log.Fatalf("unexpected error: %q", err)
 	}
 
@@ -42,8 +42,8 @@
 	<-done
 }
 
-type dispatcher struct{}
+type receiver struct{}
 
-func (d *dispatcher) Echo(call ipc.ServerContext, arg string) (string, error) {
+func (d *receiver) Echo(call ipc.ServerContext, arg string) (string, error) {
 	return arg, nil
 }
diff --git a/runtimes/google/ipc/full_test.go b/runtimes/google/ipc/full_test.go
index ff3f950..c3ad725 100644
--- a/runtimes/google/ipc/full_test.go
+++ b/runtimes/google/ipc/full_test.go
@@ -458,7 +458,7 @@
 	defer stopServer(t, server, ns, serverName)
 
 	// Start the discharge server.
-	_, dischargeServer := startServer(t, pdischarger, mgr, ns, dischargeServerName, ipc.LeafDispatcher(&dischargeServer{}, &acceptAllAuthorizer{}))
+	_, dischargeServer := startServer(t, pdischarger, mgr, ns, dischargeServerName, testutil.LeafDispatcher(&dischargeServer{}, &acceptAllAuthorizer{}))
 	defer stopServer(t, dischargeServer, ns, dischargeServerName)
 
 	// Make the client and server principals trust root certificates from pprovider
@@ -965,7 +965,7 @@
 	defer stopServer(t, server, ns, serverName)
 
 	// Start the discharge server.
-	_, dischargeServer := startServer(t, pdischarger, mgr, ns, dischargeServerName, ipc.LeafDispatcher(&dischargeServer{}, &acceptAllAuthorizer{}))
+	_, dischargeServer := startServer(t, pdischarger, mgr, ns, dischargeServerName, testutil.LeafDispatcher(&dischargeServer{}, &acceptAllAuthorizer{}))
 	defer stopServer(t, dischargeServer, ns, dischargeServerName)
 
 	// The server should recognize the client principal as an authority on "client/..." and "random/..." blessings.
diff --git a/runtimes/google/ipc/server.go b/runtimes/google/ipc/server.go
index 804225c..9994978 100644
--- a/runtimes/google/ipc/server.go
+++ b/runtimes/google/ipc/server.go
@@ -641,13 +641,23 @@
 }
 */
 
+type leafDispatcher struct {
+	invoker ipc.Invoker
+	auth    security.Authorizer
+}
+
+func (d leafDispatcher) Lookup(suffix string) (interface{}, security.Authorizer, error) {
+	if suffix != "" {
+		return nil, nil, old_verror.NoExistf("ipc: dispatcher lookup on non-empty suffix not supported: " + suffix)
+	}
+	return d.invoker, d.auth, nil
+}
+
 func (s *server) Serve(name string, obj interface{}, authorizer security.Authorizer) error {
 	if obj == nil {
-		// The ReflectInvoker inside the LeafDispatcher will panic
-		// if called for a nil value.
 		return s.newBadArg("nil object")
 	}
-	return s.ServeDispatcher(name, ipc.LeafDispatcher(obj, authorizer))
+	return s.ServeDispatcher(name, &leafDispatcher{objectToInvoker(obj), authorizer})
 }
 
 func (s *server) ServeDispatcher(name string, disp ipc.Dispatcher) error {
diff --git a/runtimes/google/naming/namespace/all_test.go b/runtimes/google/naming/namespace/all_test.go
index e4b322f..debb6d9 100644
--- a/runtimes/google/naming/namespace/all_test.go
+++ b/runtimes/google/naming/namespace/all_test.go
@@ -493,7 +493,7 @@
 
 	globServer := &GlobbableServer{}
 	name := naming.JoinAddressName(mts["mt4/foo/bar"].name, "glob")
-	runningGlobServer := runServer(t, r, ipc.LeafDispatcher(globServer, nil), name)
+	runningGlobServer := runServer(t, r, testutil.LeafDispatcher(globServer, nil), name)
 	defer runningGlobServer.server.Stop()
 
 	ns := r.Namespace()
diff --git a/runtimes/google/naming/namespace/namespace.go b/runtimes/google/naming/namespace/namespace.go
index 6933430..92af50b 100644
--- a/runtimes/google/naming/namespace/namespace.go
+++ b/runtimes/google/naming/namespace/namespace.go
@@ -148,7 +148,7 @@
 		return true
 	case verror.NoExist:
 		// This should cover "ipc: unknown method", "ipc: dispatcher not
-		// found", and "ipc: LeafDispatcher lookup on non-empty suffix".
+		// found", and dispatcher Lookup not found errors.
 		return true
 	case verror.BadProtocol:
 		// This covers "ipc: response decoding failed: EOF".
diff --git a/tools/servicerunner/servicerunner_test.go b/tools/servicerunner/servicerunner_test.go
index 57cd8f7..4a559f5 100644
--- a/tools/servicerunner/servicerunner_test.go
+++ b/tools/servicerunner/servicerunner_test.go
@@ -13,31 +13,38 @@
 	"testing"
 )
 
-func check(t *testing.T, err error) {
+func TestMain(t *testing.T) {
+	tmpdir, err := ioutil.TempDir("", "servicerunner_test")
 	if err != nil {
 		t.Fatal(err)
 	}
-}
-
-func TestMain(t *testing.T) {
-	tmpdir, err := ioutil.TempDir("", "servicerunner_test")
-	check(t, err)
 	defer os.RemoveAll(tmpdir)
 	os.Setenv("TMPDIR", tmpdir)
 
 	bin := path.Join(tmpdir, "servicerunner")
 	fmt.Println("Building", bin)
-	check(t, exec.Command("v23", "go", "build", "-o", bin, "v.io/core/veyron/tools/servicerunner").Run())
+	err = exec.Command("v23", "go", "build", "-o", bin, "v.io/core/veyron/tools/servicerunner").Run()
+	if err != nil {
+		t.Fatal(err)
+	}
 
 	cmd := exec.Command(bin)
 	stdout, err := cmd.StdoutPipe()
-	check(t, err)
-	check(t, cmd.Start())
+	if err != nil {
+		t.Fatal(err)
+	}
+	if err = cmd.Start(); err != nil {
+		t.Fatal(err)
+	}
 
 	line, err := bufio.NewReader(stdout).ReadBytes('\n')
-	check(t, err)
+	if err != nil {
+		t.Fatal(err)
+	}
 	vars := map[string]string{}
-	check(t, json.Unmarshal(line, &vars))
+	if err = json.Unmarshal(line, &vars); err != nil {
+		t.Fatal(err)
+	}
 	fmt.Println(vars)
 	expectedVars := []string{
 		"VEYRON_CREDENTIALS",
@@ -53,5 +60,7 @@
 		}
 	}
 
-	check(t, cmd.Process.Kill())
+	if err != cmd.Process.Kill() {
+		t.Fatal(err)
+	}
 }