Merge "profiles/internal: Refactor IPC tests."
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 d01c409..1918bfa 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)