chat: Change test/modules registration mechanism.

Previously modules registration and usage looked like this:

func foo(stdin io.Reader, stdout, stderr io.Writer, env map[string]string, args ...string) error {
...
}

func init() {
modules.RegisterChild("foo", "", foo)
}

func TestFoo(t *testing.T) {
sh, err := modules.NewShell(...)
h, err := sh.Start("foo", nil, ...)
...
}

The new modules registration and usage looks like this:

var foo = modules.Register(func(env *modules.Env, args ...string) error {
...
}, "foo")

func TestFoo(t *testing.T) {
sh, err := modules.NewShell(...)
h, err := sh.Start(nil, foo, ...)
...
}

The main change is that Register now returns a modules.Program,
which is typically captured in a global variable, and is used as
the argument to Shell.Start.  This makes it easy to write the
registration manually, and we also have a more obvious linkage
between program registration and the Start call through the
program variable, rather than using strings.

Since registration was annoying to write manually, we used to
have 'v23 test generate' detect the functions and automatically
add the modules.RegisterChild call.  With the new mechanism, the
registration is simple to write manually, so 'v23 test generate'
has been simplified to remove the detection logic.

In fact the Program returned by modules.Register now must be
captured, so that it can be passed to Shell.Start; this forces
the linkage between Register and Start to be obvious.

Also removed the modules Help mechanism, since it wasn't being
used, and has questionable utility.  In its place, added logic to
dump all registered programs when program lookups fail.

MultiPart: 5/5

Change-Id: I7ea0a0b08a82a5fe93dc65124e8a723f6d1131eb
diff --git a/clients/shell/go/src/v.io/x/chat/channel_test.go b/clients/shell/go/src/v.io/x/chat/channel_test.go
index d65cd02..84bd900 100644
--- a/clients/shell/go/src/v.io/x/chat/channel_test.go
+++ b/clients/shell/go/src/v.io/x/chat/channel_test.go
@@ -6,7 +6,6 @@
 
 import (
 	"fmt"
-	"io"
 	"os"
 	"testing"
 	"time"
@@ -21,7 +20,7 @@
 
 //go:generate v23 test generate
 
-func rootMT(stdin io.Reader, stdout, stderr io.Writer, env map[string]string, args ...string) error {
+var rootMT = modules.Register(func(env *modules.Env, args ...string) error {
 	ctx, shutdown := v23.Init()
 	defer shutdown()
 
@@ -41,13 +40,13 @@
 	if err := server.ServeDispatcher("", mt); err != nil {
 		return fmt.Errorf("root failed: %s", err)
 	}
-	fmt.Fprintf(stdout, "PID=%d\n", os.Getpid())
+	fmt.Fprintf(env.Stdout, "PID=%d\n", os.Getpid())
 	for _, ep := range eps {
-		fmt.Fprintf(stdout, "MT_NAME=%s\n", ep.Name())
+		fmt.Fprintf(env.Stdout, "MT_NAME=%s\n", ep.Name())
 	}
-	modules.WaitForEOF(stdin)
+	modules.WaitForEOF(env.Stdin)
 	return nil
-}
+}, "rootMT")
 
 // Starts a mounttable.  Returns the name and a stop function.
 func startMountTable(t *testing.T, ctx *context.T) (string, func()) {
@@ -56,16 +55,16 @@
 		t.Fatalf("unexpected error: %s", err)
 	}
 
-	rootMT, err := sh.Start("rootMT", nil, "--v23.tcp.address=127.0.0.1:0")
+	mt, err := sh.Start(nil, rootMT, "--v23.tcp.address=127.0.0.1:0")
 	if err != nil {
 		t.Fatalf("failed to start root mount table: %s", err)
 	}
-	rootMT.ExpectVar("PID")
-	rootName := rootMT.ExpectVar("MT_NAME")
+	mt.ExpectVar("PID")
+	rootName := mt.ExpectVar("MT_NAME")
 
 	return rootName, func() {
 		if err := sh.Cleanup(nil, nil); err != nil {
-			t.Fatalf("failed to cleanup shell: %s", rootMT.Error())
+			t.Fatalf("failed to cleanup shell: %s", mt.Error())
 		}
 	}
 }
@@ -108,7 +107,7 @@
 	// Create a new channel.
 	channel, err := newChannel(ctx, mounttable, proxy, path)
 	if err != nil {
-		t.Fatal("newChannel(%v, %v, %v) failed: %v", ctx, mounttable, proxy, path)
+		t.Fatalf("newChannel(%v, %v, %v, %v) failed: %v", ctx, mounttable, proxy, path, err)
 	}
 
 	// New channel should be empty.
@@ -129,7 +128,7 @@
 	// Create and join the channel a second time.
 	channel2, err := newChannel(ctx, mounttable, proxy, path)
 	if err != nil {
-		t.Fatal("newChannel(%v, %v, %v) failed: %v", ctx, mounttable, proxy, path)
+		t.Fatalf("newChannel(%v, %v, %v, %v) failed: %v", ctx, mounttable, proxy, path, err)
 	}
 	if err := channel2.join(); err != nil {
 		t.Fatalf("channel2.join() failed: %v", err)
@@ -174,7 +173,7 @@
 
 	channel, err := newChannel(ctx, mounttable, proxy, path)
 	if err != nil {
-		t.Fatalf("newChannel(%v, %v, %v) failed: %v", ctx, mounttable, proxy, path, err)
+		t.Fatalf("newChannel(%v, %v, %v, %v) failed: %v", ctx, mounttable, proxy, path, err)
 	}
 
 	defer channel.leave()
diff --git a/clients/shell/go/src/v.io/x/chat/v23_internal_test.go b/clients/shell/go/src/v.io/x/chat/v23_internal_test.go
index e8fff94..a80e0ec 100644
--- a/clients/shell/go/src/v.io/x/chat/v23_internal_test.go
+++ b/clients/shell/go/src/v.io/x/chat/v23_internal_test.go
@@ -4,27 +4,19 @@
 
 // This file was auto-generated via go generate.
 // DO NOT UPDATE MANUALLY
+
 package main
 
-import "fmt"
-import "testing"
-import "os"
+import (
+	"os"
+	"testing"
 
-import "v.io/x/ref/test"
-import "v.io/x/ref/test/modules"
-
-func init() {
-	modules.RegisterChild("rootMT", ``, rootMT)
-}
+	"v.io/x/ref/test"
+	"v.io/x/ref/test/modules"
+)
 
 func TestMain(m *testing.M) {
 	test.Init()
-	if modules.IsModulesChildProcess() {
-		if err := modules.Dispatch(); err != nil {
-			fmt.Fprintf(os.Stderr, "modules.Dispatch failed: %v\n", err)
-			os.Exit(1)
-		}
-		return
-	}
+	modules.DispatchAndExitIfChild()
 	os.Exit(m.Run())
 }