profiles/internal: Refactor IPC tests.

There are three types of tests in package ipc.
(1) Unit tests in "package ipc".
(2) Tests in "package ipc_test" that rely on conditionally compiled
    code in "package ipc".
(3) Tests in "package ipc_test" that do no rely on the above.

This change does the following:
(a) Move (3) to a subpackage in ipc, "package test" instead.
(b) Introduce fake runtime injection to support tests for (2). Currently only
    resolve test.

This fake runtime injection allows us to use different runtimes for tests
in the same package. (i.e. we now have a easier way to mock out all the ipc
tests, stay tuned...)

Change-Id: I2d7fa36df3d3b3fc3d2221343e9ba0749195bdaa
diff --git a/profiles/fake/fake.go b/profiles/fake/fake.go
index 58ce2c8..68b2572 100644
--- a/profiles/fake/fake.go
+++ b/profiles/fake/fake.go
@@ -1,14 +1,56 @@
 package fake
 
 import (
+	"sync"
+
 	"v.io/v23"
 	"v.io/v23/context"
+	"v.io/v23/ipc"
+
+	_ "v.io/x/ref/profiles/internal/ipc/protocols/tcp"
+	_ "v.io/x/ref/profiles/internal/ipc/protocols/ws"
+	_ "v.io/x/ref/profiles/internal/ipc/protocols/wsh"
+	"v.io/x/ref/profiles/internal/lib/websocket"
+)
+
+var (
+	runtimeInfo struct {
+		mu       sync.Mutex
+		runtime  v23.Runtime  // GUARDED_BY mu
+		ctx      *context.T   // GUARDED_BY mu
+		shutdown v23.Shutdown // GUARDED_BY mu
+	}
 )
 
 func init() {
 	v23.RegisterProfileInit(Init)
+	ipc.RegisterUnknownProtocol("wsh", websocket.HybridDial, websocket.HybridListener)
 }
 
 func Init(ctx *context.T) (v23.Runtime, *context.T, v23.Shutdown, error) {
+	runtimeInfo.mu.Lock()
+	defer runtimeInfo.mu.Unlock()
+	if runtimeInfo.runtime != nil {
+		shutdown := func() {
+			runtimeInfo.mu.Lock()
+			runtimeInfo.shutdown()
+			runtimeInfo.runtime = nil
+			runtimeInfo.ctx = nil
+			runtimeInfo.shutdown = nil
+			runtimeInfo.mu.Unlock()
+		}
+		return runtimeInfo.runtime, runtimeInfo.ctx, shutdown, nil
+	}
 	return new(ctx)
 }
+
+// InjectRuntime allows packages to inject whichever runtime, ctx, and shutdown.
+// This allows a package that needs different runtimes in tests to swap them as needed.
+// The injected runtime will be valid until the shutdown returned from v23.Init is called.
+func InjectRuntime(runtime v23.Runtime, ctx *context.T, shutdown v23.Shutdown) {
+	runtimeInfo.mu.Lock()
+	runtimeInfo.runtime = runtime
+	runtimeInfo.ctx = ctx
+	runtimeInfo.shutdown = shutdown
+	runtimeInfo.mu.Unlock()
+}
diff --git a/profiles/internal/ipc/full_test.go b/profiles/internal/ipc/full_test.go
index a8e0077..b66b257 100644
--- a/profiles/internal/ipc/full_test.go
+++ b/profiles/internal/ipc/full_test.go
@@ -35,9 +35,12 @@
 	"v.io/x/ref/lib/testutil"
 	tsecurity "v.io/x/ref/lib/testutil/security"
 	_ "v.io/x/ref/profiles/internal/ipc/protocols/tcp"
+	_ "v.io/x/ref/profiles/internal/ipc/protocols/ws"
+	_ "v.io/x/ref/profiles/internal/ipc/protocols/wsh"
 	imanager "v.io/x/ref/profiles/internal/ipc/stream/manager"
 	"v.io/x/ref/profiles/internal/ipc/stream/vc"
 	"v.io/x/ref/profiles/internal/lib/publisher"
+	"v.io/x/ref/profiles/internal/lib/websocket"
 	inaming "v.io/x/ref/profiles/internal/naming"
 	tnaming "v.io/x/ref/profiles/internal/testing/mocks/naming"
 	ivtrace "v.io/x/ref/profiles/internal/vtrace"
@@ -2010,6 +2013,7 @@
 }
 
 func init() {
+	ipc.RegisterUnknownProtocol("wsh", websocket.HybridDial, websocket.HybridListener)
 	security.RegisterCaveatValidator(fakeTimeCaveat, func(_ security.Call, _ security.CallSide, t int64) error {
 		if now := clock.Now(); now > t {
 			return fmt.Errorf("fakeTimeCaveat expired: now=%d > then=%d", now, t)
diff --git a/profiles/internal/ipc/resolve_test.go b/profiles/internal/ipc/resolve_test.go
index 91a1331..95a47db 100644
--- a/profiles/internal/ipc/resolve_test.go
+++ b/profiles/internal/ipc/resolve_test.go
@@ -1,23 +1,63 @@
 package ipc_test
 
 import (
+	"flag"
 	"fmt"
 	"testing"
 	"time"
 
 	"v.io/v23"
+	"v.io/v23/context"
+	"v.io/v23/ipc"
 	"v.io/v23/naming"
 
+	"v.io/x/ref/lib/flags"
 	"v.io/x/ref/lib/modules"
 	"v.io/x/ref/lib/modules/core"
 	"v.io/x/ref/lib/testutil"
 	"v.io/x/ref/lib/testutil/expect"
+	"v.io/x/ref/profiles/fake"
+	"v.io/x/ref/profiles/internal"
 	iipc "v.io/x/ref/profiles/internal/ipc"
+	"v.io/x/ref/profiles/internal/lib/appcycle"
 	inaming "v.io/x/ref/profiles/internal/naming"
+	grt "v.io/x/ref/profiles/internal/rt"
 )
 
+var commonFlags *flags.Flags
+
+func init() {
+	commonFlags = flags.CreateAndRegister(flag.CommandLine, flags.Runtime)
+	if err := internal.ParseFlags(commonFlags); err != nil {
+		panic(err)
+	}
+
+	ac := appcycle.New()
+
+	listenSpec := ipc.ListenSpec{Addrs: ipc.ListenAddrs{{"tcp", "127.0.0.1:0"}}}
+
+	rootctx, rootcancel := context.RootContext()
+	ctx, cancel := context.WithCancel(rootctx)
+	runtime, ctx, sd, err := grt.Init(ctx,
+		ac,
+		nil,
+		&listenSpec,
+		commonFlags.RuntimeFlags(),
+		nil)
+	if err != nil {
+		panic(err)
+	}
+	shutdown := func() {
+		ac.Shutdown()
+		cancel()
+		sd()
+		rootcancel()
+	}
+	fake.InjectRuntime(runtime, ctx, shutdown)
+}
+
 func startMT(t *testing.T, sh *modules.Shell) string {
-	h, err := sh.Start(core.RootMTCommand, nil, "--veyron.tcp.address=127.0.0.1:0")
+	h, err := sh.Start(core.RootMTCommand, nil)
 	if err != nil {
 		t.Fatalf("unexpected error for root mt: %s", err)
 	}
diff --git a/profiles/internal/ipc/client_test.go b/profiles/internal/ipc/test/client_test.go
similarity index 99%
rename from profiles/internal/ipc/client_test.go
rename to profiles/internal/ipc/test/client_test.go
index 01807eb..a5a2156 100644
--- a/profiles/internal/ipc/client_test.go
+++ b/profiles/internal/ipc/test/client_test.go
@@ -1,4 +1,4 @@
-package ipc_test
+package test
 
 import (
 	"fmt"
diff --git a/profiles/internal/ipc/test/doc.go b/profiles/internal/ipc/test/doc.go
new file mode 100644
index 0000000..0580f89
--- /dev/null
+++ b/profiles/internal/ipc/test/doc.go
@@ -0,0 +1,2 @@
+// package test contains test for ipc code that do not rely on unexposed ipc declarations.
+package test
diff --git a/profiles/internal/ipc/glob_test.go b/profiles/internal/ipc/test/glob_test.go
similarity index 96%
rename from profiles/internal/ipc/glob_test.go
rename to profiles/internal/ipc/test/glob_test.go
index 4ea0c1c..bbdabf2 100644
--- a/profiles/internal/ipc/glob_test.go
+++ b/profiles/internal/ipc/test/glob_test.go
@@ -1,4 +1,4 @@
-package ipc_test
+package test
 
 import (
 	"errors"
@@ -21,7 +21,7 @@
 	_ "v.io/x/ref/profiles"
 )
 
-func startServer(ctx *context.T, tree *node) (string, func(), error) {
+func startGlobServer(ctx *context.T, tree *node) (string, func(), error) {
 	server, err := v23.NewServer(ctx)
 	if err != nil {
 		return "", nil, fmt.Errorf("failed to start debug server: %v", err)
@@ -54,9 +54,9 @@
 		tree.find(strings.Split(p, "/"), true)
 	}
 
-	ep, stop, err := startServer(ctx, tree)
+	ep, stop, err := startGlobServer(ctx, tree)
 	if err != nil {
-		t.Fatalf("startServer: %v", err)
+		t.Fatalf("startGlobServer: %v", err)
 	}
 	defer stop()
 
@@ -205,9 +205,9 @@
 	tree := newNode()
 	tree.find([]string{"a", "b"}, true)
 	tree.find([]string{"a", "deny", "x"}, true)
-	ep, stop, err := startServer(ctx, tree)
+	ep, stop, err := startGlobServer(ctx, tree)
 	if err != nil {
-		t.Fatalf("startServer: %v", err)
+		t.Fatalf("startGlobServer: %v", err)
 	}
 	defer stop()
 
@@ -248,7 +248,7 @@
 			// We check the actual error string to make sure that we don't start
 			// leaking new information by accident.
 			expectedStr := fmt.Sprintf(
-				`ipc.test:"%s".__Glob: some matches might have been omitted`,
+				`test.test:"%s".__Glob: some matches might have been omitted`,
 				tc.name)
 			if got := gerr.Error.Error(); got != expectedStr {
 				t.Errorf("unexpected error string: Got %q, expected %q", got, expectedStr)
diff --git a/profiles/internal/ipc/proxy_test.go b/profiles/internal/ipc/test/proxy_test.go
similarity index 99%
rename from profiles/internal/ipc/proxy_test.go
rename to profiles/internal/ipc/test/proxy_test.go
index 6eed70a..95310b0 100644
--- a/profiles/internal/ipc/proxy_test.go
+++ b/profiles/internal/ipc/test/proxy_test.go
@@ -1,4 +1,4 @@
-package ipc_test
+package test
 
 import (
 	"fmt"
diff --git a/profiles/internal/ipc/signature_test.go b/profiles/internal/ipc/test/signature_test.go
similarity index 99%
rename from profiles/internal/ipc/signature_test.go
rename to profiles/internal/ipc/test/signature_test.go
index 5d35fd6..293f2f9 100644
--- a/profiles/internal/ipc/signature_test.go
+++ b/profiles/internal/ipc/test/signature_test.go
@@ -1,4 +1,4 @@
-package ipc_test
+package test
 
 import (
 	"fmt"
diff --git a/profiles/internal/ipc/simple_test.go b/profiles/internal/ipc/test/simple_test.go
similarity index 98%
rename from profiles/internal/ipc/simple_test.go
rename to profiles/internal/ipc/test/simple_test.go
index dff3463..ad75cb7 100644
--- a/profiles/internal/ipc/simple_test.go
+++ b/profiles/internal/ipc/test/simple_test.go
@@ -1,4 +1,4 @@
-package ipc_test
+package test
 
 import (
 	"io"
diff --git a/profiles/internal/ipc/v23_test.go b/profiles/internal/ipc/test/v23_test.go
similarity index 97%
rename from profiles/internal/ipc/v23_test.go
rename to profiles/internal/ipc/test/v23_test.go
index a5def16..3c00214 100644
--- a/profiles/internal/ipc/v23_test.go
+++ b/profiles/internal/ipc/test/v23_test.go
@@ -4,7 +4,7 @@
 
 // This file was auto-generated via go generate.
 // DO NOT UPDATE MANUALLY
-package ipc_test
+package test
 
 import "fmt"
 import "testing"
diff --git a/profiles/internal/ipc/v23_test.go b/profiles/internal/ipc/v23_internal_test.go
similarity index 80%
copy from profiles/internal/ipc/v23_test.go
copy to profiles/internal/ipc/v23_internal_test.go
index a5def16..20b059a 100644
--- a/profiles/internal/ipc/v23_test.go
+++ b/profiles/internal/ipc/v23_internal_test.go
@@ -4,7 +4,7 @@
 
 // This file was auto-generated via go generate.
 // DO NOT UPDATE MANUALLY
-package ipc_test
+package ipc
 
 import "fmt"
 import "testing"
@@ -13,11 +13,6 @@
 import "v.io/x/ref/lib/modules"
 import "v.io/x/ref/lib/testutil"
 
-func init() {
-	modules.RegisterChild("childPing", ``, childPing)
-	modules.RegisterChild("proxyServer", ``, proxyServer)
-}
-
 func TestMain(m *testing.M) {
 	testutil.Init()
 	if modules.IsModulesChildProcess() {
diff --git a/profiles/internal/rt/ipc_test.go b/profiles/internal/rt/ipc_test.go
index 36ec91f..60ff811 100644
--- a/profiles/internal/rt/ipc_test.go
+++ b/profiles/internal/rt/ipc_test.go
@@ -35,7 +35,7 @@
 	return nil
 }
 
-func newCtx(rootCtx *context.T) *context.T {
+func newCtxPrincipal(rootCtx *context.T) *context.T {
 	ctx, err := v23.SetPrincipal(rootCtx, tsecurity.NewPrincipal("defaultBlessings"))
 	if err != nil {
 		panic(err)
@@ -101,7 +101,7 @@
 
 	var (
 		rootAlpha, rootBeta, rootUnrecognized = tsecurity.NewIDProvider("alpha"), tsecurity.NewIDProvider("beta"), tsecurity.NewIDProvider("unrecognized")
-		clientCtx, serverCtx                  = newCtx(ctx), newCtx(ctx)
+		clientCtx, serverCtx                  = newCtxPrincipal(ctx), newCtxPrincipal(ctx)
 		pclient                               = v23.GetPrincipal(clientCtx)
 		pserver                               = v23.GetPrincipal(serverCtx)
 
@@ -285,7 +285,7 @@
 	defer shutdown()
 
 	var (
-		dischargerCtx, clientCtx, serverCtx = newCtx(ctx), newCtx(ctx), newCtx(ctx)
+		dischargerCtx, clientCtx, serverCtx = newCtxPrincipal(ctx), newCtxPrincipal(ctx), newCtxPrincipal(ctx)
 		pdischarger                         = v23.GetPrincipal(dischargerCtx)
 		pclient                             = v23.GetPrincipal(clientCtx)
 		pserver                             = v23.GetPrincipal(serverCtx)