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