core: Remove the Principal method of the Runtime interface.

This is part of the runtimeX migration.

Change-Id: Id7747624f46663ee0b793eed248063aa39f864a5
diff --git a/services/identity/identityd/main.go b/services/identity/identityd/main.go
index 8c173ed..63a25ca 100644
--- a/services/identity/identityd/main.go
+++ b/services/identity/identityd/main.go
@@ -12,6 +12,7 @@
 
 	_ "github.com/go-sql-driver/mysql"
 
+	"v.io/core/veyron2/rt"
 	"v.io/core/veyron2/vlog"
 
 	"v.io/core/veyron/profiles/static"
@@ -71,6 +72,13 @@
 		vlog.Fatalf("Failed to start RevocationManager: %v", err)
 	}
 
+	runtime, err := rt.New()
+	if err != nil {
+		vlog.Fatalf("Failed to create Runtime: %v", err)
+	}
+	defer runtime.Cleanup()
+	ctx := runtime.NewContext()
+
 	s := server.NewIdentityServer(
 		googleoauth,
 		auditor,
@@ -78,7 +86,7 @@
 		revocationManager,
 		googleOAuthBlesserParams(googleoauth, revocationManager),
 		caveats.NewBrowserCaveatSelector())
-	s.Serve(&static.ListenSpec, *host, *httpaddr, *tlsconfig)
+	s.Serve(ctx, &static.ListenSpec, *host, *httpaddr, *tlsconfig)
 }
 
 func usage() {
diff --git a/services/identity/identityd_test/main.go b/services/identity/identityd_test/main.go
index f1d2e07..63ab350 100644
--- a/services/identity/identityd_test/main.go
+++ b/services/identity/identityd_test/main.go
@@ -7,6 +7,7 @@
 	"os"
 	"time"
 
+	"v.io/core/veyron2/rt"
 	"v.io/core/veyron2/vlog"
 
 	"v.io/core/veyron/profiles/static"
@@ -57,6 +58,13 @@
 		RevocationManager: revocationManager,
 	}
 
+	runtime, err := rt.New()
+	if err != nil {
+		vlog.Fatalf("Failed to create Runtime: %v", err)
+	}
+	defer runtime.Cleanup()
+	ctx := runtime.NewContext()
+
 	s := server.NewIdentityServer(
 		oauthProvider,
 		auditor,
@@ -64,7 +72,7 @@
 		revocationManager,
 		params,
 		caveats.NewMockCaveatSelector())
-	s.Serve(&static.ListenSpec, *host, *httpaddr, *tlsconfig)
+	s.Serve(ctx, &static.ListenSpec, *host, *httpaddr, *tlsconfig)
 }
 
 func usage() {
diff --git a/services/identity/oauth/handler.go b/services/identity/oauth/handler.go
index 0cec987..b8170f5 100644
--- a/services/identity/oauth/handler.go
+++ b/services/identity/oauth/handler.go
@@ -34,7 +34,6 @@
 	"v.io/core/veyron/services/identity/caveats"
 	"v.io/core/veyron/services/identity/revocation"
 	"v.io/core/veyron/services/identity/util"
-	"v.io/core/veyron2"
 	"v.io/core/veyron2/security"
 	"v.io/core/veyron2/vlog"
 	"v.io/core/veyron2/vom2"
@@ -52,8 +51,8 @@
 )
 
 type HandlerArgs struct {
-	// The Veyron runtime to use
-	R veyron2.Runtime
+	// The principal to use.
+	Principal security.Principal
 	// The Key that is used for creating and verifying macaroons.
 	// This needs to be common between the handler and the MacaroonBlesser service.
 	MacaroonKey []byte
@@ -392,7 +391,7 @@
 	caveatFactories := caveats.NewCaveatFactory()
 	for _, caveatInfo := range caveatInfos {
 		if caveatInfo.Type == "Revocation" {
-			caveatInfo.Args = []interface{}{h.args.RevocationManager, h.args.R.Principal().PublicKey(), h.args.DischargerLocation}
+			caveatInfo.Args = []interface{}{h.args.RevocationManager, h.args.Principal.PublicKey(), h.args.DischargerLocation}
 		}
 		cav, err := caveatFactories.New(caveatInfo)
 		if err != nil {
diff --git a/services/identity/revocation/revocation_test.go b/services/identity/revocation/revocation_test.go
index 3911150..9e45e33 100644
--- a/services/identity/revocation/revocation_test.go
+++ b/services/identity/revocation/revocation_test.go
@@ -8,15 +8,16 @@
 	"v.io/core/veyron/services/security/discharger"
 
 	"v.io/core/veyron2"
+	"v.io/core/veyron2/context"
 	"v.io/core/veyron2/naming"
 	"v.io/core/veyron2/rt"
 	"v.io/core/veyron2/security"
 	"v.io/core/veyron2/vom2"
 )
 
-func revokerSetup(t *testing.T, r veyron2.Runtime) (dischargerKey security.PublicKey, dischargerEndpoint string, revoker RevocationManager, closeFunc func(), runtime veyron2.Runtime) {
+func revokerSetup(t *testing.T, ctx *context.T) (dischargerKey security.PublicKey, dischargerEndpoint string, revoker RevocationManager, closeFunc func()) {
 	revokerService := NewMockRevocationManager()
-	dischargerServer, err := r.NewServer()
+	dischargerServer, err := veyron2.NewServer(ctx)
 	if err != nil {
 		t.Fatalf("r.NewServer: %s", err)
 	}
@@ -28,13 +29,12 @@
 	if err := dischargerServer.Serve("", dischargerServiceStub, nil); err != nil {
 		t.Fatalf("dischargerServer.Serve revoker: %s", err)
 	}
-	return r.Principal().PublicKey(),
+	return veyron2.GetPrincipal(ctx).PublicKey(),
 		naming.JoinAddressName(dischargerEPs[0].String(), ""),
 		revokerService,
 		func() {
 			dischargerServer.Stop()
-		},
-		r
+		}
 }
 
 func TestDischargeRevokeDischargeRevokeDischarge(t *testing.T) {
@@ -43,8 +43,9 @@
 		t.Fatalf("Could not initialize runtime: %v", err)
 	}
 	defer r.Cleanup()
+	ctx := r.NewContext()
 
-	dcKey, dc, revoker, closeFunc, r := revokerSetup(t, r)
+	dcKey, dc, revoker, closeFunc := revokerSetup(t, ctx)
 	defer closeFunc()
 
 	discharger := services.DischargerClient(dc)
diff --git a/services/identity/server/identityd.go b/services/identity/server/identityd.go
index 49c087b..5eb3938 100644
--- a/services/identity/server/identityd.go
+++ b/services/identity/server/identityd.go
@@ -11,10 +11,9 @@
 	"strings"
 
 	"v.io/core/veyron2"
+	"v.io/core/veyron2/context"
 	"v.io/core/veyron2/ipc"
 	"v.io/core/veyron2/naming"
-	"v.io/core/veyron2/options"
-	"v.io/core/veyron2/rt"
 	"v.io/core/veyron2/security"
 	verror "v.io/core/veyron2/verror2"
 	"v.io/core/veyron2/vlog"
@@ -68,34 +67,29 @@
 	}
 }
 
-func (s *identityd) Serve(listenSpec *ipc.ListenSpec, host, httpaddr, tlsconfig string) {
-	p, r := providerPrincipal(s.auditor)
-	defer r.Cleanup()
-
-	runtime, err := rt.New(options.RuntimePrincipal{p})
+func (s *identityd) Serve(ctx *context.T, listenSpec *ipc.ListenSpec, host, httpaddr, tlsconfig string) {
+	ctx, err := veyron2.SetPrincipal(ctx, audit.NewPrincipal(
+		veyron2.GetPrincipal(ctx), s.auditor))
 	if err != nil {
-		vlog.Fatal(err)
+		vlog.Panic(err)
 	}
-	defer runtime.Cleanup()
-
-	ctx := runtime.NewContext()
-
-	ipcServer, _, _ := s.Listen(runtime, listenSpec, host, httpaddr, tlsconfig)
-	defer ipcServer.Stop()
-
+	s.Listen(ctx, listenSpec, host, httpaddr, tlsconfig)
 	<-signals.ShutdownOnSignals(ctx)
 }
 
-func (s *identityd) Listen(runtime veyron2.Runtime, listenSpec *ipc.ListenSpec, host, httpaddr, tlsconfig string) (ipc.Server, []string, string) {
+func (s *identityd) Listen(ctx *context.T, listenSpec *ipc.ListenSpec, host, httpaddr, tlsconfig string) (ipc.Server, []string, string) {
 	// Setup handlers
-	http.Handle("/blessing-root", handlers.BlessingRoot{runtime.Principal()}) // json-encoded public key and blessing names of this server
+
+	// json-encoded public key and blessing names of this server
+	principal := veyron2.GetPrincipal(ctx)
+	http.Handle("/blessing-root", handlers.BlessingRoot{principal})
 
 	macaroonKey := make([]byte, 32)
 	if _, err := rand.Read(macaroonKey); err != nil {
 		vlog.Fatalf("macaroonKey generation failed: %v", err)
 	}
 
-	ipcServer, published, err := s.setupServices(runtime, listenSpec, macaroonKey)
+	ipcServer, published, err := s.setupServices(ctx, listenSpec, macaroonKey)
 	if err != nil {
 		vlog.Fatalf("Failed to setup veyron services for blessing: %v", err)
 	}
@@ -104,7 +98,7 @@
 
 	n := "/google/"
 	h, err := oauth.NewHandler(oauth.HandlerArgs{
-		R:                       runtime,
+		Principal:               principal,
 		MacaroonKey:             macaroonKey,
 		Addr:                    fmt.Sprintf("%s%s", externalHttpaddr, n),
 		BlessingLogReader:       s.blessingLogReader,
@@ -125,7 +119,7 @@
 			GoogleServers, DischargeServers []string
 			ListBlessingsRoute              string
 		}{
-			Self: runtime.Principal().BlessingStore().Default(),
+			Self: principal.BlessingStore().Default(),
 		}
 		if s.revocationManager != nil {
 			args.DischargeServers = appendSuffixTo(published, dischargerService)
@@ -155,8 +149,8 @@
 }
 
 // Starts the blessing services and the discharging service on the same port.
-func (s *identityd) setupServices(runtime veyron2.Runtime, listenSpec *ipc.ListenSpec, macaroonKey []byte) (ipc.Server, []string, error) {
-	server, err := runtime.NewServer()
+func (s *identityd) setupServices(ctx *context.T, listenSpec *ipc.ListenSpec, macaroonKey []byte) (ipc.Server, []string, error) {
+	server, err := veyron2.NewServer(ctx)
 	if err != nil {
 		return nil, nil, fmt.Errorf("failed to create new ipc.Server: %v", err)
 	}
@@ -167,7 +161,8 @@
 	ep := eps[0]
 
 	dispatcher := newDispatcher(macaroonKey, oauthBlesserParams(s.oauthBlesserParams, s.revocationManager, ep))
-	objectname := naming.Join("identity", fmt.Sprintf("%v", runtime.Principal().BlessingStore().Default()))
+	principal := veyron2.GetPrincipal(ctx)
+	objectname := naming.Join("identity", fmt.Sprintf("%v", principal.BlessingStore().Default()))
 	if err := server.ServeDispatcher(objectname, dispatcher); err != nil {
 		return nil, nil, fmt.Errorf("failed to start Veyron services: %v", err)
 	}
@@ -223,24 +218,6 @@
 	}
 }
 
-// providerPrincipal returns the Principal to use for the identity provider (i.e., this program).
-//
-// TODO(ataly, suharhs, mattr): HACK!!! This method also returns the runtime that it creates
-// internally to read the principal supplied by the environment. This runtime must be cleaned up
-// whenever identity server is shutdown. The runtime cannot be cleaned up here as the server may
-// be running under an agent in which case cleaning up the runtime closes the connection to the
-// agent. Therefore we return the runtime so that it can be cleaned up eventually. This problem
-// would hopefully go away once we change the runtime to a context.T and have mechanisms for
-// constructing and managing derived context.Ts.
-func providerPrincipal(auditor audit.Auditor) (security.Principal, veyron2.Runtime) {
-	// TODO(ashankar): Somewhat silly to have to create a runtime, but oh-well.
-	r, err := rt.New()
-	if err != nil {
-		vlog.Fatal(err)
-	}
-	return audit.NewPrincipal(r.Principal(), auditor), r
-}
-
 func httpaddress(host, httpaddr string) string {
 	_, port, err := net.SplitHostPort(httpaddr)
 	if err != nil {
diff --git a/services/mgmt/application/impl/acl_test.go b/services/mgmt/application/impl/acl_test.go
index 736e67e..4f1a558 100644
--- a/services/mgmt/application/impl/acl_test.go
+++ b/services/mgmt/application/impl/acl_test.go
@@ -33,8 +33,8 @@
 	repoCmd = "repository"
 )
 
-var globalRT veyron2.Runtime
 var globalCtx *context.T
+var globalCancel context.CancelFunc
 
 // This is also a modules world.
 // Insert necessary code here to be a modules test.
@@ -45,11 +45,12 @@
 	modules.RegisterChild(repoCmd, "", appRepository)
 	testutil.Init()
 
-	var err error
-	if globalRT, err = rt.New(); err != nil {
+	globalRT, err := rt.New()
+	if err != nil {
 		panic(err)
 	}
 	globalCtx = globalRT.NewContext()
+	globalCancel = globalRT.Cleanup
 	veyron2.GetNamespace(globalCtx).CacheCtl(naming.DisableCache(true))
 }
 
@@ -69,7 +70,7 @@
 
 	defer fmt.Fprintf(stdout, "%v terminating\n", publishName)
 	defer vlog.VI(1).Infof("%v terminating", publishName)
-	defer globalRT.Cleanup()
+	defer globalCancel()
 	server, endpoint := mgmttest.NewServer(globalCtx)
 	defer server.Stop()
 
@@ -98,9 +99,8 @@
 	storedir, cleanup := mgmttest.SetupRootDir(t, "application")
 	defer cleanup()
 
-	otherRT := mgmttest.NewRuntime(t, globalCtx)
-	defer otherRT.Cleanup()
-	otherCtx := otherRT.NewContext()
+	otherCtx, otherCancel := mgmttest.NewRuntime(t, globalCtx)
+	defer otherCancel()
 
 	idp := tsecurity.NewIDProvider("root")
 
@@ -228,9 +228,8 @@
 	storedir, cleanup := mgmttest.SetupRootDir(t, "application")
 	defer cleanup()
 
-	otherRT := mgmttest.NewRuntime(t, globalCtx)
-	defer otherRT.Cleanup()
-	otherCtx := otherRT.NewContext()
+	otherCtx, otherCancel := mgmttest.NewRuntime(t, globalCtx)
+	defer otherCancel()
 	idp := tsecurity.NewIDProvider("root")
 
 	// By default, globalRT and otherRT will have blessings generated based on the
diff --git a/services/mgmt/device/deviced/server.go b/services/mgmt/device/deviced/server.go
index 5ab0693..8c79307 100644
--- a/services/mgmt/device/deviced/server.go
+++ b/services/mgmt/device/deviced/server.go
@@ -9,6 +9,7 @@
 	"v.io/core/veyron/profiles/roaming"
 	"v.io/core/veyron/services/mgmt/device/config"
 	"v.io/core/veyron/services/mgmt/device/impl"
+	"v.io/core/veyron2"
 	"v.io/core/veyron2/naming"
 	"v.io/core/veyron2/rt"
 	"v.io/core/veyron2/vlog"
@@ -55,7 +56,7 @@
 	// implementation detail).
 
 	var exitErr error
-	dispatcher, err := impl.NewDispatcher(runtime.Principal(), configState, func() { exitErr = cmdline.ErrExitCode(*stopExitCode) })
+	dispatcher, err := impl.NewDispatcher(veyron2.GetPrincipal(ctx), configState, func() { exitErr = cmdline.ErrExitCode(*stopExitCode) })
 	if err != nil {
 		vlog.Errorf("Failed to create dispatcher: %v", err)
 		return err
diff --git a/services/mgmt/device/impl/impl_test.go b/services/mgmt/device/impl/impl_test.go
index 641bdcd..4d3904c 100644
--- a/services/mgmt/device/impl/impl_test.go
+++ b/services/mgmt/device/impl/impl_test.go
@@ -84,16 +84,17 @@
 	initRT(options.RuntimePrincipal{tsecurity.NewPrincipal("test-principal")})
 }
 
-var globalRT veyron2.Runtime
 var globalCtx *context.T
+var globalCancel context.CancelFunc
 
 func initRT(opts ...veyron2.ROpt) {
-	var err error
-	if globalRT, err = rt.New(opts...); err != nil {
+	globalRT, err := rt.New(opts...)
+	if err != nil {
 		panic(err)
 	}
 
 	globalCtx = globalRT.NewContext()
+	globalCancel = globalRT.Cleanup
 
 	// Disable the cache because we will be manipulating/using the namespace
 	// across multiple processes and want predictable behaviour without
@@ -156,7 +157,7 @@
 	args = args[1:]
 	defer fmt.Fprintf(stdout, "%v terminating\n", publishName)
 	defer vlog.VI(1).Infof("%v terminating", publishName)
-	defer globalRT.Cleanup()
+	defer globalCancel()
 	server, endpoint := mgmttest.NewServer(globalCtx)
 	defer server.Stop()
 	name := naming.JoinAddressName(endpoint, "")
@@ -252,7 +253,7 @@
 	}
 	publishName := args[0]
 
-	defer globalRT.Cleanup()
+	defer globalCancel()
 	server, _ := mgmttest.NewServer(globalCtx)
 	defer server.Stop()
 	if err := server.Serve(publishName, new(appService), nil); err != nil {
@@ -571,15 +572,15 @@
 	*envelope = envelopeFromShell(sh, nil, appCmd, "google naps", "appV1")
 
 	// Install the app.
-	appID := installApp(t)
+	appID := installApp(t, globalCtx)
 
 	// Start requires the caller to grant a blessing for the app instance.
-	if _, err := startAppImpl(t, appID, ""); err == nil || !verror.Is(err, impl.ErrInvalidBlessing.ID) {
+	if _, err := startAppImpl(t, globalCtx, appID, ""); err == nil || !verror.Is(err, impl.ErrInvalidBlessing.ID) {
 		t.Fatalf("Start(%v) expected to fail with %v, got %v instead", appID, impl.ErrInvalidBlessing.ID, err)
 	}
 
 	// Start an instance of the app.
-	instance1ID := startApp(t, appID)
+	instance1ID := startApp(t, globalCtx, appID)
 
 	// Wait until the app pings us that it's ready.
 	verifyHelperArgs(t, pingCh, userName(t))
@@ -587,10 +588,10 @@
 	v1EP1 := resolve(t, "appV1", 1)[0]
 
 	// Suspend the app instance.
-	suspendApp(t, appID, instance1ID)
+	suspendApp(t, globalCtx, appID, instance1ID)
 	resolveExpectNotFound(t, "appV1")
 
-	resumeApp(t, appID, instance1ID)
+	resumeApp(t, globalCtx, appID, instance1ID)
 	verifyHelperArgs(t, pingCh, userName(t)) // Wait until the app pings us that it's ready.
 	oldV1EP1 := v1EP1
 	if v1EP1 = resolve(t, "appV1", 1)[0]; v1EP1 == oldV1EP1 {
@@ -598,7 +599,7 @@
 	}
 
 	// Start a second instance.
-	instance2ID := startApp(t, appID)
+	instance2ID := startApp(t, globalCtx, appID)
 	verifyHelperArgs(t, pingCh, userName(t)) // Wait until the app pings us that it's ready.
 
 	// There should be two endpoints mounted as "appV1", one for each
@@ -619,7 +620,7 @@
 	// running; stop while suspended).
 
 	// Suspend the first instance.
-	suspendApp(t, appID, instance1ID)
+	suspendApp(t, globalCtx, appID, instance1ID)
 	// Only the second instance should still be running and mounted.
 	if want, got := v1EP2, resolve(t, "appV1", 1)[0]; want != got {
 		t.Fatalf("Resolve(%v): want: %v, got %v", "appV1", want, got)
@@ -636,7 +637,7 @@
 	// Create a second version of the app and update the app to it.
 	*envelope = envelopeFromShell(sh, nil, appCmd, "google naps", "appV2")
 
-	updateApp(t, appID)
+	updateApp(t, globalCtx, appID)
 
 	// Second instance should still be running.
 	if want, got := v1EP2, resolve(t, "appV1", 1)[0]; want != got {
@@ -644,7 +645,7 @@
 	}
 
 	// Resume first instance.
-	resumeApp(t, appID, instance1ID)
+	resumeApp(t, globalCtx, appID, instance1ID)
 	verifyHelperArgs(t, pingCh, userName(t)) // Wait until the app pings us that it's ready.
 	// Both instances should still be running the first version of the app.
 	// Check that the mounttable contains two endpoints, one of which is
@@ -659,7 +660,7 @@
 	}
 
 	// Stop first instance.
-	stopApp(t, appID, instance1ID)
+	stopApp(t, globalCtx, appID, instance1ID)
 	verifyAppWorkspace(t, root, appID, instance1ID)
 
 	// Only second instance is still running.
@@ -668,28 +669,28 @@
 	}
 
 	// Start a third instance.
-	instance3ID := startApp(t, appID)
+	instance3ID := startApp(t, globalCtx, appID)
 	// Wait until the app pings us that it's ready.
 	verifyHelperArgs(t, pingCh, userName(t))
 
 	resolve(t, "appV2", 1)
 
 	// Stop second instance.
-	stopApp(t, appID, instance2ID)
+	stopApp(t, globalCtx, appID, instance2ID)
 	resolveExpectNotFound(t, "appV1")
 
 	// Stop third instance.
-	stopApp(t, appID, instance3ID)
+	stopApp(t, globalCtx, appID, instance3ID)
 	resolveExpectNotFound(t, "appV2")
 
 	// Revert the app.
 	revertApp(t, appID)
 
 	// Start a fourth instance.  It should be started from version 1.
-	instance4ID := startApp(t, appID)
+	instance4ID := startApp(t, globalCtx, appID)
 	verifyHelperArgs(t, pingCh, userName(t)) // Wait until the app pings us that it's ready.
 	resolve(t, "appV1", 1)
-	stopApp(t, appID, instance4ID)
+	stopApp(t, globalCtx, appID, instance4ID)
 	resolveExpectNotFound(t, "appV1")
 
 	// We are already on the first version, no further revert possible.
@@ -705,7 +706,7 @@
 	revertAppExpectError(t, appID, impl.ErrInvalidOperation.ID)
 
 	// Starting new instances should no longer be allowed.
-	startAppExpectError(t, appID, impl.ErrInvalidOperation.ID)
+	startAppExpectError(t, globalCtx, appID, impl.ErrInvalidOperation.ID)
 
 	// Cleanly shut down the device manager.
 	syscall.Kill(dmh.Pid(), syscall.SIGINT)
@@ -786,12 +787,10 @@
 	*envelope = envelopeFromShell(sh, nil, appCmd, "google naps", "trapp")
 
 	deviceStub := device.DeviceClient("dm/device")
-	claimantRT := mgmttest.NewRuntime(t, globalCtx, options.RuntimePrincipal{tsecurity.NewPrincipal("claimant")})
-	defer claimantRT.Cleanup()
-	otherRT := mgmttest.NewRuntime(t, globalCtx, options.RuntimePrincipal{tsecurity.NewPrincipal("other")})
-	defer otherRT.Cleanup()
-
-	octx := otherRT.NewContext()
+	claimantCtx, claimantCancel := mgmttest.NewRuntime(t, globalCtx, options.RuntimePrincipal{tsecurity.NewPrincipal("claimant")})
+	defer claimantCancel()
+	octx, otherCancel := mgmttest.NewRuntime(t, globalCtx, options.RuntimePrincipal{tsecurity.NewPrincipal("other")})
+	defer otherCancel()
 
 	// Devicemanager should have open ACLs before we claim it and so an
 	// Install from otherRT should succeed.
@@ -799,13 +798,13 @@
 		t.Errorf("Failed to install: %s", err)
 	}
 	// Claim the devicemanager with claimantRT as <defaultblessing>/mydevice
-	if err := deviceStub.Claim(claimantRT.NewContext(), &granter{p: claimantRT.Principal(), extension: "mydevice"}); err != nil {
+	if err := deviceStub.Claim(claimantCtx, &granter{p: veyron2.GetPrincipal(claimantCtx), extension: "mydevice"}); err != nil {
 		t.Fatal(err)
 	}
 
 	// Installation should succeed since claimantRT is now the "owner" of
 	// the devicemanager.
-	appID := installApp(t, claimantRT)
+	appID := installApp(t, claimantCtx)
 
 	// otherRT should be unable to install though, since the ACLs have
 	// changed now.
@@ -818,7 +817,7 @@
 	defer cleanup()
 
 	// Start an instance of the app.
-	instanceID := startApp(t, appID, claimantRT)
+	instanceID := startApp(t, claimantCtx, appID)
 
 	// Wait until the app pings us that it's ready.
 	select {
@@ -827,7 +826,7 @@
 		t.Fatalf("failed to get ping")
 	}
 	resolve(t, "trapp", 1)
-	suspendApp(t, appID, instanceID, claimantRT)
+	suspendApp(t, claimantCtx, appID, instanceID)
 
 	// TODO(gauthamt): Test that ACLs persist across devicemanager restarts
 }
@@ -847,18 +846,17 @@
 		idp = tsecurity.NewIDProvider("root")
 		// The two "processes"/runtimes which will act as IPC clients to
 		// the devicemanager process.
-		selfRT  = globalRT
-		otherRT = mgmttest.NewRuntime(t, globalCtx)
+		selfCtx       = globalCtx
+		octx, ocancel = mgmttest.NewRuntime(t, globalCtx)
 	)
-	defer otherRT.Cleanup()
-	octx := otherRT.NewContext()
+	defer ocancel()
 	// By default, selfRT and otherRT will have blessings generated based on
 	// the username/machine name running this process. Since these blessings
 	// will appear in ACLs, give them recognizable names.
-	if err := idp.Bless(selfRT.Principal(), "self"); err != nil {
+	if err := idp.Bless(veyron2.GetPrincipal(selfCtx), "self"); err != nil {
 		t.Fatal(err)
 	}
-	if err := idp.Bless(otherRT.Principal(), "other"); err != nil {
+	if err := idp.Bless(veyron2.GetPrincipal(octx), "other"); err != nil {
 		t.Fatal(err)
 	}
 
@@ -875,7 +873,7 @@
 	*envelope = envelopeFromShell(sh, nil, appCmd, "google naps")
 
 	deviceStub := device.DeviceClient("dm//device")
-	acl, etag, err := deviceStub.GetACL(selfRT.NewContext())
+	acl, etag, err := deviceStub.GetACL(selfCtx)
 	if err != nil {
 		t.Fatalf("GetACL failed:%v", err)
 	}
@@ -884,7 +882,7 @@
 	}
 
 	// Claim the devicemanager as "root/self/mydevice"
-	if err := deviceStub.Claim(selfRT.NewContext(), &granter{p: selfRT.Principal(), extension: "mydevice"}); err != nil {
+	if err := deviceStub.Claim(selfCtx, &granter{p: veyron2.GetPrincipal(selfCtx), extension: "mydevice"}); err != nil {
 		t.Fatal(err)
 	}
 	expectedACL := make(access.TaggedACLMap)
@@ -897,7 +895,7 @@
 	}
 	md5hash := md5.Sum(b.Bytes())
 	expectedETAG := hex.EncodeToString(md5hash[:])
-	if acl, etag, err = deviceStub.GetACL(selfRT.NewContext()); err != nil {
+	if acl, etag, err = deviceStub.GetACL(selfCtx); err != nil {
 		t.Fatal(err)
 	}
 	if etag != expectedETAG {
@@ -911,15 +909,15 @@
 	for _, tag := range access.AllTypicalTags() {
 		newACL.Add("root/other", string(tag))
 	}
-	if err := deviceStub.SetACL(selfRT.NewContext(), newACL, "invalid"); err == nil {
+	if err := deviceStub.SetACL(selfCtx, newACL, "invalid"); err == nil {
 		t.Fatalf("SetACL should have failed with invalid etag")
 	}
-	if err := deviceStub.SetACL(selfRT.NewContext(), newACL, etag); err != nil {
+	if err := deviceStub.SetACL(selfCtx, newACL, etag); err != nil {
 		t.Fatal(err)
 	}
 	// Install should now fail with selfRT, which no longer matches the ACLs
 	// but succeed with otherRT, which does.
-	if err := tryInstall(selfRT.NewContext()); err == nil {
+	if err := tryInstall(selfCtx); err == nil {
 		t.Errorf("Install should have failed with selfRT since it should no longer match the ACL")
 	}
 	if err := tryInstall(octx); err != nil {
@@ -1026,11 +1024,11 @@
 	*envelope = envelopeFromShell(sh, nil, appCmd, "google naps", "appV1")
 
 	// Install the app.
-	appID := installApp(t)
+	appID := installApp(t, globalCtx)
 	install1ID := path.Base(appID)
 
 	// Start an instance of the app.
-	instance1ID := startApp(t, appID)
+	instance1ID := startApp(t, globalCtx, appID)
 
 	// Wait until the app pings us that it's ready.
 	select {
@@ -1039,7 +1037,7 @@
 		t.Fatalf("failed to get ping")
 	}
 
-	app2ID := installApp(t)
+	app2ID := installApp(t, globalCtx)
 	install2ID := path.Base(app2ID)
 
 	testcases := []struct {
@@ -1195,10 +1193,10 @@
 	}
 
 	// Install the app.
-	appID := installApp(t)
+	appID := installApp(t, globalCtx)
 
 	// Start an instance of the app.
-	startApp(t, appID)
+	startApp(t, globalCtx, appID)
 
 	// Wait until the app pings us that it's ready.
 	select {
@@ -1219,8 +1217,8 @@
 	}
 }
 
-func listAndVerifyAssociations(t *testing.T, stub device.DeviceClientMethods, run veyron2.Runtime, expected []device.Association) {
-	assocs, err := stub.ListAssociations(run.NewContext())
+func listAndVerifyAssociations(t *testing.T, ctx *context.T, stub device.DeviceClientMethods, expected []device.Association) {
+	assocs, err := stub.ListAssociations(ctx)
 	if err != nil {
 		t.Fatalf("ListAssociations failed %v", err)
 	}
@@ -1240,17 +1238,17 @@
 		idp = tsecurity.NewIDProvider("root")
 		// The two "processes"/runtimes which will act as IPC clients to
 		// the devicemanager process.
-		selfRT  = globalRT
-		otherRT = mgmttest.NewRuntime(t, globalCtx)
+		selfCtx               = globalCtx
+		otherCtx, otherCancel = mgmttest.NewRuntime(t, globalCtx)
 	)
-	defer otherRT.Cleanup()
+	defer otherCancel()
 	// By default, selfRT and otherRT will have blessings generated based on
 	// the username/machine name running this process. Since these blessings
 	// will appear in test expecations, give them readable names.
-	if err := idp.Bless(selfRT.Principal(), "self"); err != nil {
+	if err := idp.Bless(veyron2.GetPrincipal(selfCtx), "self"); err != nil {
 		t.Fatal(err)
 	}
-	if err := idp.Bless(otherRT.Principal(), "other"); err != nil {
+	if err := idp.Bless(veyron2.GetPrincipal(otherCtx), "other"); err != nil {
 		t.Fatal(err)
 	}
 	crFile, crEnv := mgmttest.CredentialsForChild(globalCtx, "devicemanager")
@@ -1264,23 +1262,23 @@
 
 	// Attempt to list associations on the device manager without having
 	// claimed it.
-	if list, err := deviceStub.ListAssociations(otherRT.NewContext()); err != nil || list != nil {
+	if list, err := deviceStub.ListAssociations(otherCtx); err != nil || list != nil {
 		t.Fatalf("ListAssociations should fail on unclaimed device manager but did not: %v", err)
 	}
 
 	// self claims the device manager.
-	if err := deviceStub.Claim(selfRT.NewContext(), &granter{p: selfRT.Principal(), extension: "alice"}); err != nil {
+	if err := deviceStub.Claim(selfCtx, &granter{p: veyron2.GetPrincipal(selfCtx), extension: "alice"}); err != nil {
 		t.Fatalf("Claim failed: %v", err)
 	}
 
 	vlog.VI(2).Info("Verify that associations start out empty.")
-	listAndVerifyAssociations(t, deviceStub, selfRT, []device.Association(nil))
+	listAndVerifyAssociations(t, selfCtx, deviceStub, []device.Association(nil))
 
-	if err := deviceStub.AssociateAccount(selfRT.NewContext(), []string{"root/self", "root/other"}, "alice_system_account"); err != nil {
+	if err := deviceStub.AssociateAccount(selfCtx, []string{"root/self", "root/other"}, "alice_system_account"); err != nil {
 		t.Fatalf("ListAssociations failed %v", err)
 	}
 	vlog.VI(2).Info("Added association should appear.")
-	listAndVerifyAssociations(t, deviceStub, selfRT, []device.Association{
+	listAndVerifyAssociations(t, selfCtx, deviceStub, []device.Association{
 		{
 			"root/self",
 			"alice_system_account",
@@ -1291,11 +1289,11 @@
 		},
 	})
 
-	if err := deviceStub.AssociateAccount(selfRT.NewContext(), []string{"root/self", "root/other"}, "alice_other_account"); err != nil {
+	if err := deviceStub.AssociateAccount(selfCtx, []string{"root/self", "root/other"}, "alice_other_account"); err != nil {
 		t.Fatalf("AssociateAccount failed %v", err)
 	}
 	vlog.VI(2).Info("Change the associations and the change should appear.")
-	listAndVerifyAssociations(t, deviceStub, selfRT, []device.Association{
+	listAndVerifyAssociations(t, selfCtx, deviceStub, []device.Association{
 		{
 			"root/self",
 			"alice_other_account",
@@ -1306,11 +1304,11 @@
 		},
 	})
 
-	if err := deviceStub.AssociateAccount(selfRT.NewContext(), []string{"root/other"}, ""); err != nil {
+	if err := deviceStub.AssociateAccount(selfCtx, []string{"root/other"}, ""); err != nil {
 		t.Fatalf("AssociateAccount failed %v", err)
 	}
 	vlog.VI(2).Info("Verify that we can remove an association.")
-	listAndVerifyAssociations(t, deviceStub, selfRT, []device.Association{
+	listAndVerifyAssociations(t, selfCtx, deviceStub, []device.Association{
 		{
 			"root/self",
 			"alice_other_account",
@@ -1343,18 +1341,18 @@
 		idp = tsecurity.NewIDProvider("root")
 		// The two "processes"/runtimes which will act as IPC clients to
 		// the devicemanager process.
-		selfRT  = globalRT
-		otherRT = mgmttest.NewRuntime(t, globalCtx)
+		selfCtx               = globalCtx
+		otherCtx, otherCancel = mgmttest.NewRuntime(t, globalCtx)
 	)
-	defer otherRT.Cleanup()
+	defer otherCancel()
 
 	// By default, selfRT and otherRT will have blessings generated based on
 	// the username/machine name running this process. Since these blessings
 	// can appear in debugging output, give them recognizable names.
-	if err := idp.Bless(selfRT.Principal(), "self"); err != nil {
+	if err := idp.Bless(veyron2.GetPrincipal(selfCtx), "self"); err != nil {
 		t.Fatal(err)
 	}
-	if err := idp.Bless(otherRT.Principal(), "other"); err != nil {
+	if err := idp.Bless(veyron2.GetPrincipal(otherCtx), "other"); err != nil {
 		t.Fatal(err)
 	}
 
@@ -1383,40 +1381,40 @@
 	*envelope = envelopeFromShell(sh, nil, appCmd, "google naps", "appV1")
 
 	// Install and start the app as root/self.
-	appID := installApp(t, selfRT)
+	appID := installApp(t, selfCtx)
 
 	// Claim the devicemanager with selfRT as root/self/alice
-	if err := deviceStub.Claim(selfRT.NewContext(), &granter{p: selfRT.Principal(), extension: "alice"}); err != nil {
+	if err := deviceStub.Claim(selfCtx, &granter{p: veyron2.GetPrincipal(selfCtx), extension: "alice"}); err != nil {
 		t.Fatal(err)
 	}
 
 	// Start an instance of the app but this time it should fail: we do not
 	// have an associated uname for the invoking identity.
-	startAppExpectError(t, appID, verror.NoAccess.ID, selfRT)
+	startAppExpectError(t, selfCtx, appID, verror.NoAccess.ID)
 
 	// Create an association for selfRT
-	if err := deviceStub.AssociateAccount(selfRT.NewContext(), []string{"root/self"}, testUserName); err != nil {
+	if err := deviceStub.AssociateAccount(selfCtx, []string{"root/self"}, testUserName); err != nil {
 		t.Fatalf("AssociateAccount failed %v", err)
 	}
 
-	instance1ID := startApp(t, appID, selfRT)
+	instance1ID := startApp(t, selfCtx, appID)
 	verifyHelperArgs(t, pingCh, testUserName) // Wait until the app pings us that it's ready.
-	stopApp(t, appID, instance1ID, selfRT)
+	stopApp(t, selfCtx, appID, instance1ID)
 
 	vlog.VI(2).Infof("other attempting to run an app without access. Should fail.")
-	startAppExpectError(t, appID, verror.NoAccess.ID, otherRT)
+	startAppExpectError(t, otherCtx, appID, verror.NoAccess.ID)
 
 	// Self will now let other also install apps.
-	if err := deviceStub.AssociateAccount(selfRT.NewContext(), []string{"root/other"}, testUserName); err != nil {
+	if err := deviceStub.AssociateAccount(selfCtx, []string{"root/other"}, testUserName); err != nil {
 		t.Fatalf("AssociateAccount failed %v", err)
 	}
 	// Add Start to the ACL list for root/other.
-	newACL, _, err := deviceStub.GetACL(selfRT.NewContext())
+	newACL, _, err := deviceStub.GetACL(selfCtx)
 	if err != nil {
 		t.Fatalf("GetACL failed %v", err)
 	}
 	newACL.Add("root/other", string(access.Write))
-	if err := deviceStub.SetACL(selfRT.NewContext(), newACL, ""); err != nil {
+	if err := deviceStub.SetACL(selfCtx, newACL, ""); err != nil {
 		t.Fatalf("SetACL failed %v", err)
 	}
 
@@ -1425,54 +1423,54 @@
 	// other doesn't have execution permissions for the app. So this will
 	// fail.
 	vlog.VI(2).Infof("other attempting to run an app still without access. Should fail.")
-	startAppExpectError(t, appID, verror.NoAccess.ID, otherRT)
+	startAppExpectError(t, otherCtx, appID, verror.NoAccess.ID)
 
 	// But self can give other permissions  to start applications.
 	vlog.VI(2).Infof("self attempting to give other permission to start %s", appID)
-	newACL, _, err = appStub(appID).GetACL(selfRT.NewContext())
+	newACL, _, err = appStub(appID).GetACL(selfCtx)
 	if err != nil {
 		t.Fatalf("GetACL on appID: %v failed %v", appID, err)
 	}
 	newACL.Add("root/other", string(access.Read))
-	if err = appStub(appID).SetACL(selfRT.NewContext(), newACL, ""); err != nil {
+	if err = appStub(appID).SetACL(selfCtx, newACL, ""); err != nil {
 		t.Fatalf("SetACL on appID: %v failed: %v", appID, err)
 	}
 
 	vlog.VI(2).Infof("other attempting to run an app with access. Should succeed.")
-	instance2ID := startApp(t, appID, otherRT)
+	instance2ID := startApp(t, otherCtx, appID)
 	verifyHelperArgs(t, pingCh, testUserName) // Wait until the app pings us that it's ready.
-	suspendApp(t, appID, instance2ID, otherRT)
+	suspendApp(t, otherCtx, appID, instance2ID)
 
 	vlog.VI(2).Infof("Verify that Resume with the same systemName works.")
-	resumeApp(t, appID, instance2ID, otherRT)
+	resumeApp(t, otherCtx, appID, instance2ID)
 	verifyHelperArgs(t, pingCh, testUserName) // Wait until the app pings us that it's ready.
-	suspendApp(t, appID, instance2ID, otherRT)
+	suspendApp(t, otherCtx, appID, instance2ID)
 
 	vlog.VI(2).Infof("Verify that other can install and run applications.")
-	otherAppID := installApp(t, otherRT)
+	otherAppID := installApp(t, otherCtx)
 
 	vlog.VI(2).Infof("other attempting to run an app that other installed. Should succeed.")
-	instance4ID := startApp(t, otherAppID, otherRT)
+	instance4ID := startApp(t, otherCtx, otherAppID)
 	verifyHelperArgs(t, pingCh, testUserName) // Wait until the app pings us that it's ready.
 
 	// Clean up.
-	stopApp(t, otherAppID, instance4ID, otherRT)
+	stopApp(t, otherCtx, otherAppID, instance4ID)
 
 	// Change the associated system name.
-	if err := deviceStub.AssociateAccount(selfRT.NewContext(), []string{"root/other"}, anotherTestUserName); err != nil {
+	if err := deviceStub.AssociateAccount(selfCtx, []string{"root/other"}, anotherTestUserName); err != nil {
 		t.Fatalf("AssociateAccount failed %v", err)
 	}
 
 	vlog.VI(2).Infof("Show that Resume with a different systemName fails.")
-	resumeAppExpectError(t, appID, instance2ID, verror.NoAccess.ID, otherRT)
+	resumeAppExpectError(t, otherCtx, appID, instance2ID, verror.NoAccess.ID)
 
 	// Clean up.
-	stopApp(t, appID, instance2ID, otherRT)
+	stopApp(t, otherCtx, appID, instance2ID)
 
 	vlog.VI(2).Infof("Show that Start with different systemName works.")
-	instance3ID := startApp(t, appID, otherRT)
+	instance3ID := startApp(t, otherCtx, appID)
 	verifyHelperArgs(t, pingCh, anotherTestUserName) // Wait until the app pings us that it's ready.
 
 	// Clean up.
-	stopApp(t, appID, instance3ID, otherRT)
+	stopApp(t, otherCtx, appID, instance3ID)
 }
diff --git a/services/mgmt/device/impl/util_test.go b/services/mgmt/device/impl/util_test.go
index b6817c7..ae3ddf7 100644
--- a/services/mgmt/device/impl/util_test.go
+++ b/services/mgmt/device/impl/util_test.go
@@ -10,6 +10,7 @@
 	"testing"
 
 	"v.io/core/veyron2"
+	"v.io/core/veyron2/context"
 	"v.io/core/veyron2/ipc"
 	"v.io/core/veyron2/naming"
 	"v.io/core/veyron2/security"
@@ -44,7 +45,7 @@
 
 // resolveExpectNotFound verifies that the given name is not in the mounttable.
 func resolveExpectNotFound(t *testing.T, name string) {
-	if results, err := veyron2.GetNamespace(globalCtx).Resolve(globalRT.NewContext(), name); err == nil {
+	if results, err := veyron2.GetNamespace(globalCtx).Resolve(globalCtx, name); err == nil {
 		t.Fatalf(testutil.FormatLogLine(2, "Resolve(%v) succeeded with results %v when it was expected to fail", name, results))
 	} else if expectErr := naming.ErrNoSuchName.ID; !verror2.Is(err, expectErr) {
 		t.Fatalf(testutil.FormatLogLine(2, "Resolve(%v) failed with error %v, expected error ID %v", name, err, expectErr))
@@ -80,37 +81,37 @@
 }
 
 func updateDeviceExpectError(t *testing.T, name string, errID verror.ID) {
-	if err := deviceStub(name).Update(globalRT.NewContext()); !verror2.Is(err, errID) {
+	if err := deviceStub(name).Update(globalCtx); !verror2.Is(err, errID) {
 		t.Fatalf(testutil.FormatLogLine(2, "Update(%v) expected to fail with %v, got %v instead", name, errID, err))
 	}
 }
 
 func updateDevice(t *testing.T, name string) {
-	if err := deviceStub(name).Update(globalRT.NewContext()); err != nil {
+	if err := deviceStub(name).Update(globalCtx); err != nil {
 		t.Fatalf(testutil.FormatLogLine(2, "Update(%v) failed: %v", name, err))
 	}
 }
 
 func revertDeviceExpectError(t *testing.T, name string, errID verror.ID) {
-	if err := deviceStub(name).Revert(globalRT.NewContext()); !verror2.Is(err, errID) {
+	if err := deviceStub(name).Revert(globalCtx); !verror2.Is(err, errID) {
 		t.Fatalf(testutil.FormatLogLine(2, "Revert(%v) expected to fail with %v, got %v instead", name, errID, err))
 	}
 }
 
 func revertDevice(t *testing.T, name string) {
-	if err := deviceStub(name).Revert(globalRT.NewContext()); err != nil {
+	if err := deviceStub(name).Revert(globalCtx); err != nil {
 		t.Fatalf(testutil.FormatLogLine(2, "Revert(%v) failed: %v", name, err))
 	}
 }
 
 func stopDevice(t *testing.T, name string) {
-	if err := deviceStub(name).Stop(globalRT.NewContext(), stopTimeout); err != nil {
+	if err := deviceStub(name).Stop(globalCtx, stopTimeout); err != nil {
 		t.Fatalf(testutil.FormatLogLine(1+1, "%s: Stop(%v) failed: %v", name, err))
 	}
 }
 
 func suspendDevice(t *testing.T, name string) {
-	if err := deviceStub(name).Suspend(globalRT.NewContext()); err != nil {
+	if err := deviceStub(name).Suspend(globalCtx); err != nil {
 		t.Fatalf(testutil.FormatLogLine(1+1, "%s: Suspend(%v) failed: %v", name, err))
 	}
 }
@@ -118,22 +119,14 @@
 // The following set of functions are convenience wrappers around various app
 // management methods.
 
-func ort(opt []veyron2.Runtime) veyron2.Runtime {
-	if len(opt) > 0 {
-		return opt[0]
-	} else {
-		return globalRT
-	}
-}
-
 func appStub(nameComponents ...string) device.ApplicationClientMethods {
 	appsName := "dm//apps"
 	appName := naming.Join(append([]string{appsName}, nameComponents...)...)
 	return device.ApplicationClient(appName)
 }
 
-func installApp(t *testing.T, opt ...veyron2.Runtime) string {
-	appID, err := appStub().Install(ort(opt).NewContext(), mockApplicationRepoName)
+func installApp(t *testing.T, ctx *context.T) string {
+	appID, err := appStub().Install(ctx, mockApplicationRepoName)
 	if err != nil {
 		t.Fatalf(testutil.FormatLogLine(2, "Install failed: %v", err))
 	}
@@ -150,12 +143,12 @@
 	return g.p.Bless(other.PublicKey(), g.p.BlessingStore().Default(), g.extension, security.UnconstrainedUse())
 }
 
-func startAppImpl(t *testing.T, appID, grant string, opt ...veyron2.Runtime) (string, error) {
+func startAppImpl(t *testing.T, ctx *context.T, appID, grant string) (string, error) {
 	var opts []ipc.CallOpt
 	if grant != "" {
-		opts = append(opts, &granter{p: ort(opt).Principal(), extension: grant})
+		opts = append(opts, &granter{p: veyron2.GetPrincipal(ctx), extension: grant})
 	}
-	if instanceIDs, err := appStub(appID).Start(ort(opt).NewContext(), opts...); err != nil {
+	if instanceIDs, err := appStub(appID).Start(ctx, opts...); err != nil {
 		return "", err
 	} else {
 		if want, got := 1, len(instanceIDs); want != got {
@@ -165,70 +158,70 @@
 	}
 }
 
-func startApp(t *testing.T, appID string, opt ...veyron2.Runtime) string {
-	instanceID, err := startAppImpl(t, appID, "forapp", opt...)
+func startApp(t *testing.T, ctx *context.T, appID string) string {
+	instanceID, err := startAppImpl(t, ctx, appID, "forapp")
 	if err != nil {
 		t.Fatalf(testutil.FormatLogLine(2, "Start(%v) failed: %v", appID, err))
 	}
 	return instanceID
 }
 
-func startAppExpectError(t *testing.T, appID string, expectedError verror.ID, opt ...veyron2.Runtime) {
-	if _, err := startAppImpl(t, appID, "forapp", opt...); err == nil || !verror2.Is(err, expectedError) {
+func startAppExpectError(t *testing.T, ctx *context.T, appID string, expectedError verror.ID) {
+	if _, err := startAppImpl(t, ctx, appID, "forapp"); err == nil || !verror2.Is(err, expectedError) {
 		t.Fatalf(testutil.FormatLogLine(2, "Start(%v) expected to fail with %v, got %v instead", appID, expectedError, err))
 	}
 }
 
-func stopApp(t *testing.T, appID, instanceID string, opt ...veyron2.Runtime) {
-	if err := appStub(appID, instanceID).Stop(ort(opt).NewContext(), stopTimeout); err != nil {
+func stopApp(t *testing.T, ctx *context.T, appID, instanceID string) {
+	if err := appStub(appID, instanceID).Stop(ctx, stopTimeout); err != nil {
 		t.Fatalf(testutil.FormatLogLine(2, "Stop(%v/%v) failed: %v", appID, instanceID, err))
 	}
 }
 
-func suspendApp(t *testing.T, appID, instanceID string, opt ...veyron2.Runtime) {
-	if err := appStub(appID, instanceID).Suspend(ort(opt).NewContext()); err != nil {
+func suspendApp(t *testing.T, ctx *context.T, appID, instanceID string) {
+	if err := appStub(appID, instanceID).Suspend(ctx); err != nil {
 		t.Fatalf(testutil.FormatLogLine(2, "Suspend(%v/%v) failed: %v", appID, instanceID, err))
 	}
 }
 
-func resumeApp(t *testing.T, appID, instanceID string, opt ...veyron2.Runtime) {
-	if err := appStub(appID, instanceID).Resume(ort(opt).NewContext()); err != nil {
+func resumeApp(t *testing.T, ctx *context.T, appID, instanceID string) {
+	if err := appStub(appID, instanceID).Resume(ctx); err != nil {
 		t.Fatalf(testutil.FormatLogLine(2, "Resume(%v/%v) failed: %v", appID, instanceID, err))
 	}
 }
 
-func resumeAppExpectError(t *testing.T, appID, instanceID string, expectedError verror.ID, opt ...veyron2.Runtime) {
-	if err := appStub(appID, instanceID).Resume(ort(opt).NewContext()); err == nil || !verror2.Is(err, expectedError) {
+func resumeAppExpectError(t *testing.T, ctx *context.T, appID, instanceID string, expectedError verror.ID) {
+	if err := appStub(appID, instanceID).Resume(ctx); err == nil || !verror2.Is(err, expectedError) {
 		t.Fatalf(testutil.FormatLogLine(2, "Resume(%v/%v) expected to fail with %v, got %v instead", appID, instanceID, expectedError, err))
 	}
 }
 
-func updateApp(t *testing.T, appID string, opt ...veyron2.Runtime) {
-	if err := appStub(appID).Update(ort(opt).NewContext()); err != nil {
+func updateApp(t *testing.T, ctx *context.T, appID string) {
+	if err := appStub(appID).Update(ctx); err != nil {
 		t.Fatalf(testutil.FormatLogLine(2, "Update(%v) failed: %v", appID, err))
 	}
 }
 
 func updateAppExpectError(t *testing.T, appID string, expectedError verror.ID) {
-	if err := appStub(appID).Update(globalRT.NewContext()); err == nil || !verror2.Is(err, expectedError) {
+	if err := appStub(appID).Update(globalCtx); err == nil || !verror2.Is(err, expectedError) {
 		t.Fatalf(testutil.FormatLogLine(2, "Update(%v) expected to fail with %v, got %v instead", appID, expectedError, err))
 	}
 }
 
 func revertApp(t *testing.T, appID string) {
-	if err := appStub(appID).Revert(globalRT.NewContext()); err != nil {
+	if err := appStub(appID).Revert(globalCtx); err != nil {
 		t.Fatalf(testutil.FormatLogLine(2, "Revert(%v) failed: %v", appID, err))
 	}
 }
 
 func revertAppExpectError(t *testing.T, appID string, expectedError verror.ID) {
-	if err := appStub(appID).Revert(globalRT.NewContext()); err == nil || !verror2.Is(err, expectedError) {
+	if err := appStub(appID).Revert(globalCtx); err == nil || !verror2.Is(err, expectedError) {
 		t.Fatalf(testutil.FormatLogLine(2, "Revert(%v) expected to fail with %v, got %v instead", appID, expectedError, err))
 	}
 }
 
 func uninstallApp(t *testing.T, appID string) {
-	if err := appStub(appID).Uninstall(globalRT.NewContext()); err != nil {
+	if err := appStub(appID).Uninstall(globalCtx); err != nil {
 		t.Fatalf(testutil.FormatLogLine(2, "Uninstall(%v) failed: %v", appID, err))
 	}
 }
diff --git a/services/mgmt/lib/testutil/modules.go b/services/mgmt/lib/testutil/modules.go
index 219c1ae..307993c 100644
--- a/services/mgmt/lib/testutil/modules.go
+++ b/services/mgmt/lib/testutil/modules.go
@@ -127,14 +127,14 @@
 }
 
 // NewRuntime makes an instance of the runtime.
-func NewRuntime(t *testing.T, octx *context.T, opts ...veyron2.ROpt) veyron2.Runtime {
+func NewRuntime(t *testing.T, octx *context.T, opts ...veyron2.ROpt) (*context.T, context.CancelFunc) {
 	runtime, err := rt.New(opts...)
 	if err != nil {
 		t.Fatalf("rt.New() failed: %v", err)
 	}
 	ctx := runtime.NewContext()
 	veyron2.GetNamespace(ctx).SetRoots(veyron2.GetNamespace(octx).Roots()[0])
-	return runtime
+	return ctx, runtime.Cleanup
 }
 
 // ReadPID waits for the "ready:<PID>" line from the child and parses out the