services/device/internal/impl: shard device unit tests (5)
This is CL 5 of n to shard device manager unit tests into multiple
files and packages to permit concurrent test execution. This CL moves
suidhelper glob and package tests into a separate package so that it
can execute in parallel.
Change-Id: I1fd0e75e0954ed985879551c755a18c3abda482b
diff --git a/services/device/internal/impl/args_darwin_test.go b/services/device/internal/impl/globsuid/args_darwin_test.go
similarity index 91%
rename from services/device/internal/impl/args_darwin_test.go
rename to services/device/internal/impl/globsuid/args_darwin_test.go
index c1d0b11..8925295 100644
--- a/services/device/internal/impl/args_darwin_test.go
+++ b/services/device/internal/impl/globsuid/args_darwin_test.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-package impl_test
+package globsuid_test
const (
testUserName = "_uucp"
diff --git a/services/device/internal/impl/args_linux_test.go b/services/device/internal/impl/globsuid/args_linux_test.go
similarity index 91%
rename from services/device/internal/impl/args_linux_test.go
rename to services/device/internal/impl/globsuid/args_linux_test.go
index dc9a365..e7e4aa6 100644
--- a/services/device/internal/impl/args_linux_test.go
+++ b/services/device/internal/impl/globsuid/args_linux_test.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-package impl_test
+package globsuid_test
const (
testUserName = "uucp"
diff --git a/services/device/internal/impl/globsuid/doc.go b/services/device/internal/impl/globsuid/doc.go
new file mode 100644
index 0000000..4e210e6
--- /dev/null
+++ b/services/device/internal/impl/globsuid/doc.go
@@ -0,0 +1,8 @@
+// Copyright 2015 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package globsuid
+
+// Test code for the device manager's globbing, suidhelper and
+// signature matching functionality.
diff --git a/services/device/internal/impl/globsuid/glob_test.go b/services/device/internal/impl/globsuid/glob_test.go
new file mode 100644
index 0000000..f9becde
--- /dev/null
+++ b/services/device/internal/impl/globsuid/glob_test.go
@@ -0,0 +1,112 @@
+// Copyright 2015 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package globsuid_test
+
+import (
+ "path"
+ "syscall"
+ "testing"
+
+ "v.io/x/ref/services/device/internal/impl"
+ "v.io/x/ref/services/device/internal/impl/utiltest"
+ "v.io/x/ref/services/internal/servicetest"
+)
+
+func TestDeviceManagerGlobAndDebug(t *testing.T) {
+ ctx, shutdown := utiltest.InitForTest()
+ defer shutdown()
+
+ sh, deferFn := servicetest.CreateShellAndMountTable(t, ctx, nil)
+ defer deferFn()
+
+ // Set up mock application and binary repositories.
+ envelope, cleanup := utiltest.StartMockRepos(t, ctx)
+ defer cleanup()
+
+ root, cleanup := servicetest.SetupRootDir(t, "devicemanager")
+ defer cleanup()
+ if err := impl.SaveCreatorInfo(root); err != nil {
+ t.Fatal(err)
+ }
+
+ // Create a script wrapping the test target that implements suidhelper.
+ helperPath := utiltest.GenerateSuidHelperScript(t, root)
+
+ // Set up the device manager. Since we won't do device manager updates,
+ // don't worry about its application envelope and current link.
+ dmh := servicetest.RunCommand(t, sh, nil, utiltest.DeviceManagerCmd, "dm", root, helperPath, "unused_app_repo_name", "unused_curr_link")
+ pid := servicetest.ReadPID(t, dmh)
+ defer syscall.Kill(pid, syscall.SIGINT)
+
+ // Create the local server that the app uses to let us know it's ready.
+ pingCh, cleanup := utiltest.SetupPingServer(t, ctx)
+ defer cleanup()
+
+ // Create the envelope for the first version of the app.
+ *envelope = utiltest.EnvelopeFromShell(sh, nil, utiltest.AppCmd, "google naps", "appV1")
+
+ // Device must be claimed before applications can be installed.
+ utiltest.ClaimDevice(t, ctx, "claimable", "dm", "mydevice", utiltest.NoPairingToken)
+ // Install the app.
+ appID := utiltest.InstallApp(t, ctx)
+ install1ID := path.Base(appID)
+
+ // Start an instance of the app.
+ instance1ID := utiltest.LaunchApp(t, ctx, appID)
+ defer utiltest.TerminateApp(t, ctx, appID, instance1ID)
+
+ // Wait until the app pings us that it's ready.
+ pingCh.WaitForPingArgs(t)
+
+ app2ID := utiltest.InstallApp(t, ctx)
+ install2ID := path.Base(app2ID)
+
+ // Base name of argv[0] that the app should have when it executes
+ // It will be path.Base(envelope.Title + "@" + envelope.Binary.File + "/app").
+ // Note the suffix, which ensures that the result is always "app" at the moment.
+ // Someday in future we may remove that and have binary names that reflect the app name.
+ const appName = "app"
+
+ testcases := []utiltest.GlobTestVector{
+ {"dm", "...", []string{
+ "",
+ "apps",
+ "apps/google naps",
+ "apps/google naps/" + install1ID,
+ "apps/google naps/" + install1ID + "/" + instance1ID,
+ "apps/google naps/" + install1ID + "/" + instance1ID + "/logs",
+ "apps/google naps/" + install1ID + "/" + instance1ID + "/logs/STDERR-<timestamp>",
+ "apps/google naps/" + install1ID + "/" + instance1ID + "/logs/STDOUT-<timestamp>",
+ "apps/google naps/" + install1ID + "/" + instance1ID + "/logs/" + appName + ".INFO",
+ "apps/google naps/" + install1ID + "/" + instance1ID + "/logs/" + appName + ".<*>.INFO.<timestamp>",
+ "apps/google naps/" + install1ID + "/" + instance1ID + "/pprof",
+ "apps/google naps/" + install1ID + "/" + instance1ID + "/stats",
+ "apps/google naps/" + install1ID + "/" + instance1ID + "/stats/rpc",
+ "apps/google naps/" + install1ID + "/" + instance1ID + "/stats/system",
+ "apps/google naps/" + install1ID + "/" + instance1ID + "/stats/system/start-time-rfc1123",
+ "apps/google naps/" + install1ID + "/" + instance1ID + "/stats/system/start-time-unix",
+ "apps/google naps/" + install2ID,
+ "device",
+ }},
+ {"dm/apps", "*", []string{"google naps"}},
+ {"dm/apps/google naps", "*", []string{install1ID, install2ID}},
+ {"dm/apps/google naps/" + install1ID, "*", []string{instance1ID}},
+ {"dm/apps/google naps/" + install1ID + "/" + instance1ID, "*", []string{"logs", "pprof", "stats"}},
+ {"dm/apps/google naps/" + install1ID + "/" + instance1ID + "/logs", "*", []string{
+ "STDERR-<timestamp>",
+ "STDOUT-<timestamp>",
+ appName + ".INFO",
+ appName + ".<*>.INFO.<timestamp>",
+ }},
+ {"dm/apps/google naps/" + install1ID + "/" + instance1ID + "/stats/system", "start-time*", []string{"start-time-rfc1123", "start-time-unix"}},
+ }
+
+ res := utiltest.NewGlobTestRegexHelper(appName)
+
+ utiltest.VerifyGlob(t, ctx, appName, testcases, res)
+ utiltest.VerifyLog(t, ctx, "dm", "apps/google naps", install1ID, instance1ID, "logs", "*")
+ utiltest.VerifyStatsValues(t, ctx, "dm", "apps/google naps", install1ID, instance1ID, "stats/system/start-time*")
+ utiltest.VerifyPProfCmdLine(t, ctx, appName, "dm", "apps/google naps", install1ID, instance1ID, "pprof")
+}
diff --git a/services/device/internal/impl/globsuid/impl_test.go b/services/device/internal/impl/globsuid/impl_test.go
new file mode 100644
index 0000000..a6be62e
--- /dev/null
+++ b/services/device/internal/impl/globsuid/impl_test.go
@@ -0,0 +1,21 @@
+// Copyright 2015 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package globsuid_test
+
+import (
+ "testing"
+
+ "v.io/x/ref/services/device/internal/impl/utiltest"
+)
+
+func TestMain(m *testing.M) {
+ utiltest.TestMainImpl(m)
+}
+
+// TestSuidHelper is testing boilerplate for suidhelper that does not
+// create a runtime because the suidhelper is not a Vanadium application.
+func TestSuidHelper(t *testing.T) {
+ utiltest.TestSuidHelperImpl(t)
+}
diff --git a/services/device/internal/impl/globsuid/signature_match_test.go b/services/device/internal/impl/globsuid/signature_match_test.go
new file mode 100644
index 0000000..ded825f
--- /dev/null
+++ b/services/device/internal/impl/globsuid/signature_match_test.go
@@ -0,0 +1,143 @@
+// Copyright 2015 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package globsuid_test
+
+import (
+ "io/ioutil"
+ "os"
+ "path/filepath"
+ "syscall"
+ "testing"
+
+ "v.io/v23"
+ "v.io/v23/naming"
+ "v.io/v23/services/application"
+ "v.io/v23/services/device"
+ "v.io/v23/services/repository"
+ "v.io/v23/verror"
+
+ "v.io/x/ref/services/device/internal/impl"
+ "v.io/x/ref/services/device/internal/impl/utiltest"
+ "v.io/x/ref/services/internal/binarylib"
+ "v.io/x/ref/services/internal/servicetest"
+ "v.io/x/ref/test/testutil"
+)
+
+func TestDownloadSignatureMatch(t *testing.T) {
+ ctx, shutdown := utiltest.InitForTest()
+ defer shutdown()
+
+ sh, deferFn := servicetest.CreateShellAndMountTable(t, ctx, nil)
+ defer deferFn()
+
+ binaryVON := "binary"
+ pkgVON := naming.Join(binaryVON, "testpkg")
+ defer utiltest.StartRealBinaryRepository(t, ctx, binaryVON)()
+
+ up := testutil.RandomBytes(testutil.Intn(5 << 20))
+ mediaInfo := repository.MediaInfo{Type: "application/octet-stream"}
+ sig, err := binarylib.Upload(ctx, naming.Join(binaryVON, "testbinary"), up, mediaInfo)
+ if err != nil {
+ t.Fatalf("Upload(%v) failed:%v", binaryVON, err)
+ }
+
+ // Upload packages for this application
+ tmpdir, err := ioutil.TempDir("", "test-package-")
+ if err != nil {
+ t.Fatalf("ioutil.TempDir failed: %v", err)
+ }
+ defer os.RemoveAll(tmpdir)
+ pkgContents := testutil.RandomBytes(testutil.Intn(5 << 20))
+ if err := ioutil.WriteFile(filepath.Join(tmpdir, "pkg.txt"), pkgContents, 0600); err != nil {
+ t.Fatalf("ioutil.WriteFile failed: %v", err)
+ }
+ pkgSig, err := binarylib.UploadFromDir(ctx, pkgVON, tmpdir)
+ if err != nil {
+ t.Fatalf("binarylib.UploadFromDir failed: %v", err)
+ }
+
+ // Start the application repository
+ envelope, serverStop := utiltest.StartApplicationRepository(ctx)
+ defer serverStop()
+
+ root, cleanup := servicetest.SetupRootDir(t, "devicemanager")
+ defer cleanup()
+ if err := impl.SaveCreatorInfo(root); err != nil {
+ t.Fatal(err)
+ }
+
+ // Create a script wrapping the test target that implements suidhelper.
+ helperPath := utiltest.GenerateSuidHelperScript(t, root)
+
+ // Set up the device manager. Since we won't do device manager updates,
+ // don't worry about its application envelope and current link.
+ dmh := servicetest.RunCommand(t, sh, nil, utiltest.DeviceManagerCmd, "dm", root, helperPath, "unused_app_repo_name", "unused_curr_link")
+ pid := servicetest.ReadPID(t, dmh)
+ defer syscall.Kill(pid, syscall.SIGINT)
+ utiltest.ClaimDevice(t, ctx, "claimable", "dm", "mydevice", utiltest.NoPairingToken)
+
+ publisher, err := v23.GetPrincipal(ctx).BlessSelf("publisher")
+ if err != nil {
+ t.Fatalf("Failed to generate publisher blessings:%v", err)
+ }
+ *envelope = application.Envelope{
+ Binary: application.SignedFile{
+ File: naming.Join(binaryVON, "testbinary"),
+ Signature: *sig,
+ },
+ Publisher: publisher,
+ Packages: map[string]application.SignedFile{
+ "pkg": application.SignedFile{
+ File: pkgVON,
+ Signature: *pkgSig,
+ },
+ },
+ }
+ if _, err := utiltest.AppStub().Install(ctx, utiltest.MockApplicationRepoName, device.Config{}, nil); err != nil {
+ t.Fatalf("Failed to Install app:%v", err)
+ }
+
+ // Verify that when the binary is corrupted, signature verification fails.
+ up[0] = up[0] ^ 0xFF
+ if err := binarylib.Delete(ctx, naming.Join(binaryVON, "testbinary")); err != nil {
+ t.Fatalf("Delete(%v) failed:%v", binaryVON, err)
+ }
+ if _, err := binarylib.Upload(ctx, naming.Join(binaryVON, "testbinary"), up, mediaInfo); err != nil {
+ t.Fatalf("Upload(%v) failed:%v", binaryVON, err)
+ }
+ if _, err := utiltest.AppStub().Install(ctx, utiltest.MockApplicationRepoName, device.Config{}, nil); verror.ErrorID(err) != impl.ErrOperationFailed.ID {
+ t.Fatalf("Failed to verify signature mismatch for binary:%v. Got errorid=%v[%v], want errorid=%v", binaryVON, verror.ErrorID(err), err, impl.ErrOperationFailed.ID)
+ }
+
+ // Restore the binary and verify that installation succeeds.
+ up[0] = up[0] ^ 0xFF
+ if err := binarylib.Delete(ctx, naming.Join(binaryVON, "testbinary")); err != nil {
+ t.Fatalf("Delete(%v) failed:%v", binaryVON, err)
+ }
+ if _, err := binarylib.Upload(ctx, naming.Join(binaryVON, "testbinary"), up, mediaInfo); err != nil {
+ t.Fatalf("Upload(%v) failed:%v", binaryVON, err)
+ }
+ if _, err := utiltest.AppStub().Install(ctx, utiltest.MockApplicationRepoName, device.Config{}, nil); err != nil {
+ t.Fatalf("Failed to Install app:%v", err)
+ }
+
+ // Verify that when the package contents are corrupted, signature verification fails.
+ pkgContents[0] = pkgContents[0] ^ 0xFF
+ if err := binarylib.Delete(ctx, pkgVON); err != nil {
+ t.Fatalf("Delete(%v) failed:%v", pkgVON, err)
+ }
+ if err := os.Remove(filepath.Join(tmpdir, "pkg.txt")); err != nil {
+ t.Fatalf("Remove(%v) failed:%v", filepath.Join(tmpdir, "pkg.txt"), err)
+ }
+ if err := ioutil.WriteFile(filepath.Join(tmpdir, "pkg.txt"), pkgContents, 0600); err != nil {
+ t.Fatalf("ioutil.WriteFile failed: %v", err)
+ }
+ if _, err = binarylib.UploadFromDir(ctx, pkgVON, tmpdir); err != nil {
+ t.Fatalf("binarylib.UploadFromDir failed: %v", err)
+ }
+ if _, err := utiltest.AppStub().Install(ctx, utiltest.MockApplicationRepoName, device.Config{}, nil); verror.ErrorID(err) != impl.ErrOperationFailed.ID {
+ t.Fatalf("Failed to verify signature mismatch for package:%v", pkgVON)
+ }
+}
diff --git a/services/device/internal/impl/globsuid/suid_test.go b/services/device/internal/impl/globsuid/suid_test.go
new file mode 100644
index 0000000..83ae185
--- /dev/null
+++ b/services/device/internal/impl/globsuid/suid_test.go
@@ -0,0 +1,203 @@
+// Copyright 2015 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package globsuid_test
+
+import (
+ "flag"
+ "fmt"
+ "os"
+ "reflect"
+ "syscall"
+ "testing"
+
+ "v.io/x/lib/vlog"
+
+ "v.io/v23"
+ "v.io/v23/security"
+ "v.io/v23/security/access"
+ "v.io/v23/services/device"
+ "v.io/v23/verror"
+
+ "v.io/x/ref/services/device/internal/impl"
+ "v.io/x/ref/services/device/internal/impl/utiltest"
+ "v.io/x/ref/services/internal/servicetest"
+ "v.io/x/ref/test/testutil"
+)
+
+var mockIsSetuid = flag.Bool("mocksetuid", false, "set flag to pretend to have a helper with setuid permissions")
+
+func possiblyMockIsSetuid(fileStat os.FileInfo) bool {
+ vlog.VI(2).Infof("Mock isSetuid is reporting: %v", *mockIsSetuid)
+ return *mockIsSetuid
+}
+
+func init() {
+ impl.IsSetuid = possiblyMockIsSetuid
+}
+
+func TestAppWithSuidHelper(t *testing.T) {
+ ctx, shutdown := utiltest.InitForTest()
+ defer shutdown()
+
+ // Identity provider used to ensure that all processes recognize each
+ // others' blessings.
+ idp := testutil.NewIDProvider("root")
+ if err := idp.Bless(v23.GetPrincipal(ctx), "self"); err != nil {
+ t.Fatal(err)
+ }
+
+ sh, deferFn := servicetest.CreateShellAndMountTable(t, ctx, nil)
+ defer deferFn()
+
+ // Set up mock application and binary repositories.
+ envelope, cleanup := utiltest.StartMockRepos(t, ctx)
+ defer cleanup()
+
+ root, cleanup := servicetest.SetupRootDir(t, "devicemanager")
+ defer cleanup()
+ if err := impl.SaveCreatorInfo(root); err != nil {
+ t.Fatal(err)
+ }
+
+ selfCtx := ctx
+ otherCtx := utiltest.CtxWithNewPrincipal(t, selfCtx, idp, "other")
+
+ // Create a script wrapping the test target that implements suidhelper.
+ helperPath := utiltest.GenerateSuidHelperScript(t, root)
+
+ dmh := servicetest.RunCommand(t, sh, nil, utiltest.DeviceManagerCmd, "-mocksetuid", "dm", root, helperPath, "unused_app_repo_name", "unused_curr_link")
+ pid := servicetest.ReadPID(t, dmh)
+ defer syscall.Kill(pid, syscall.SIGINT)
+ defer utiltest.VerifyNoRunningProcesses(t)
+ // Claim the devicemanager with selfCtx as root/self/alice
+ utiltest.ClaimDevice(t, selfCtx, "claimable", "dm", "alice", utiltest.NoPairingToken)
+
+ deviceStub := device.DeviceClient("dm/device")
+
+ // Create the local server that the app uses to tell us which system
+ // name the device manager wished to run it as.
+ pingCh, cleanup := utiltest.SetupPingServer(t, ctx)
+ defer cleanup()
+
+ // Create an envelope for a first version of the app.
+ *envelope = utiltest.EnvelopeFromShell(sh, []string{utiltest.TestEnvVarName + "=env-var"}, utiltest.AppCmd, "google naps", fmt.Sprintf("--%s=flag-val-envelope", utiltest.TestFlagName), "appV1")
+
+ // Install and start the app as root/self.
+ appID := utiltest.InstallApp(t, selfCtx)
+
+ vlog.VI(2).Infof("Validate that the created app has the right permission lists.")
+ perms, _, err := utiltest.AppStub(appID).GetPermissions(selfCtx)
+ if err != nil {
+ t.Fatalf("GetPermissions on appID: %v failed %v", appID, err)
+ }
+ expected := make(access.Permissions)
+ for _, tag := range access.AllTypicalTags() {
+ expected[string(tag)] = access.AccessList{In: []security.BlessingPattern{"root/self/$"}}
+ }
+ if got, want := perms.Normalize(), expected.Normalize(); !reflect.DeepEqual(got, want) {
+ t.Errorf("got %#v, expected %#v", got, want)
+ }
+
+ // Start an instance of the app but this time it should fail: we do not
+ // have an associated uname for the invoking identity.
+ utiltest.LaunchAppExpectError(t, selfCtx, appID, verror.ErrNoAccess.ID)
+
+ // Create an association for selfCtx
+ if err := deviceStub.AssociateAccount(selfCtx, []string{"root/self"}, testUserName); err != nil {
+ t.Fatalf("AssociateAccount failed %v", err)
+ }
+
+ instance1ID := utiltest.LaunchApp(t, selfCtx, appID)
+ pingCh.VerifyPingArgs(t, testUserName, "flag-val-envelope", "env-var") // Wait until the app pings us that it's ready.
+ utiltest.TerminateApp(t, selfCtx, appID, instance1ID)
+
+ vlog.VI(2).Infof("other attempting to run an app without access. Should fail.")
+ utiltest.LaunchAppExpectError(t, otherCtx, appID, verror.ErrNoAccess.ID)
+
+ // Self will now let other also install apps.
+ if err := deviceStub.AssociateAccount(selfCtx, []string{"root/other"}, testUserName); err != nil {
+ t.Fatalf("AssociateAccount failed %v", err)
+ }
+ // Add Start to the AccessList list for root/other.
+ newAccessList, _, err := deviceStub.GetPermissions(selfCtx)
+ if err != nil {
+ t.Fatalf("GetPermissions failed %v", err)
+ }
+ newAccessList.Add("root/other", string(access.Write))
+ if err := deviceStub.SetPermissions(selfCtx, newAccessList, ""); err != nil {
+ t.Fatalf("SetPermissions failed %v", err)
+ }
+
+ // With the introduction of per installation and per instance AccessLists,
+ // while other now has administrator permissions on the device manager,
+ // 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.")
+ utiltest.LaunchAppExpectError(t, otherCtx, appID, verror.ErrNoAccess.ID)
+
+ // But self can give other permissions to start applications.
+ vlog.VI(2).Infof("self attempting to give other permission to start %s", appID)
+ newAccessList, _, err = utiltest.AppStub(appID).GetPermissions(selfCtx)
+ if err != nil {
+ t.Fatalf("GetPermissions on appID: %v failed %v", appID, err)
+ }
+ newAccessList.Add("root/other", string(access.Read))
+ if err = utiltest.AppStub(appID).SetPermissions(selfCtx, newAccessList, ""); err != nil {
+ t.Fatalf("SetPermissions on appID: %v failed: %v", appID, err)
+ }
+
+ vlog.VI(2).Infof("other attempting to run an app with access. Should succeed.")
+ instance2ID := utiltest.LaunchApp(t, otherCtx, appID)
+ pingCh.VerifyPingArgs(t, testUserName, "flag-val-envelope", "env-var") // Wait until the app pings us that it's ready.
+
+ vlog.VI(2).Infof("Validate that created instance has the right permissions.")
+ expected = make(access.Permissions)
+ for _, tag := range access.AllTypicalTags() {
+ expected[string(tag)] = access.AccessList{In: []security.BlessingPattern{"root/other/$"}}
+ }
+ perms, _, err = utiltest.AppStub(appID, instance2ID).GetPermissions(selfCtx)
+ if err != nil {
+ t.Fatalf("GetPermissions on instance %v/%v failed: %v", appID, instance2ID, err)
+ }
+ if got, want := perms.Normalize(), expected.Normalize(); !reflect.DeepEqual(got, want) {
+ t.Errorf("got %#v, expected %#v ", got, want)
+ }
+
+ // Shutdown the app.
+ utiltest.KillApp(t, otherCtx, appID, instance2ID)
+
+ vlog.VI(2).Infof("Verify that Run with the same systemName works.")
+ utiltest.RunApp(t, otherCtx, appID, instance2ID)
+ pingCh.VerifyPingArgs(t, testUserName, "flag-val-envelope", "env-var") // Wait until the app pings us that it's ready.
+ utiltest.KillApp(t, otherCtx, appID, instance2ID)
+
+ vlog.VI(2).Infof("Verify that other can install and run applications.")
+ otherAppID := utiltest.InstallApp(t, otherCtx)
+
+ vlog.VI(2).Infof("other attempting to run an app that other installed. Should succeed.")
+ instance4ID := utiltest.LaunchApp(t, otherCtx, otherAppID)
+ pingCh.VerifyPingArgs(t, testUserName, "flag-val-envelope", "env-var") // Wait until the app pings us that it's ready.
+
+ // Clean up.
+ utiltest.TerminateApp(t, otherCtx, otherAppID, instance4ID)
+
+ // Change the associated system name.
+ if err := deviceStub.AssociateAccount(selfCtx, []string{"root/other"}, anotherTestUserName); err != nil {
+ t.Fatalf("AssociateAccount failed %v", err)
+ }
+
+ vlog.VI(2).Infof("Show that Run with a different systemName fails.")
+ utiltest.RunAppExpectError(t, otherCtx, appID, instance2ID, verror.ErrNoAccess.ID)
+
+ // Clean up.
+ utiltest.DeleteApp(t, otherCtx, appID, instance2ID)
+
+ vlog.VI(2).Infof("Show that Start with different systemName works.")
+ instance3ID := utiltest.LaunchApp(t, otherCtx, appID)
+ pingCh.VerifyPingArgs(t, anotherTestUserName, "flag-val-envelope", "env-var") // Wait until the app pings us that it's ready.
+
+ // Clean up.
+ utiltest.TerminateApp(t, otherCtx, appID, instance3ID)
+}
diff --git a/services/device/internal/impl/helper_manager.go b/services/device/internal/impl/helper_manager.go
index 280db2b..09b75c8 100644
--- a/services/device/internal/impl/helper_manager.go
+++ b/services/device/internal/impl/helper_manager.go
@@ -135,9 +135,9 @@
return nil
}
-// isSetuid is defined like this so we can override its
+// IsSetuid is defined like this so we can override its
// implementation for tests.
-var isSetuid = func(fileStat os.FileInfo) bool {
+var IsSetuid = func(fileStat os.FileInfo) bool {
vlog.VI(2).Infof("running the original isSetuid")
return fileStat.Mode()&os.ModeSetuid == os.ModeSetuid
}
@@ -152,7 +152,7 @@
if err != nil {
return false, verror.New(ErrOperationFailed, nil, fmt.Sprintf("Stat(%v) failed: %v. helper is required.", s.helperPath, err))
}
- haveHelper := isSetuid(helperStat)
+ haveHelper := IsSetuid(helperStat)
switch {
case haveHelper && s.dmUser != targetUser:
diff --git a/services/device/internal/impl/impl_test.go b/services/device/internal/impl/impl_test.go
index 0a3bccd..c51f1ac 100644
--- a/services/device/internal/impl/impl_test.go
+++ b/services/device/internal/impl/impl_test.go
@@ -14,9 +14,7 @@
"fmt"
"io/ioutil"
"os"
- "path"
"path/filepath"
- "reflect"
"strings"
"syscall"
"testing"
@@ -27,12 +25,8 @@
"v.io/v23"
"v.io/v23/context"
"v.io/v23/naming"
- "v.io/v23/security"
- "v.io/v23/security/access"
"v.io/v23/services/application"
"v.io/v23/services/device"
- "v.io/v23/services/repository"
- "v.io/v23/verror"
"v.io/x/ref/envvar"
"v.io/x/ref/lib/mgmt"
@@ -585,33 +579,6 @@
dmh.ExpectEOF()
}
-func startRealBinaryRepository(t *testing.T, ctx *context.T, von string) func() {
- rootDir, err := binarylib.SetupRootDir("")
- if err != nil {
- t.Fatalf("binarylib.SetupRootDir failed: %v", err)
- }
- state, err := binarylib.NewState(rootDir, "", 3)
- if err != nil {
- t.Fatalf("binarylib.NewState failed: %v", err)
- }
- server, _ := servicetest.NewServer(ctx)
- d, err := binarylib.NewDispatcher(v23.GetPrincipal(ctx), state)
- if err != nil {
- t.Fatalf("server.NewDispatcher failed: %v", err)
- }
- if err := server.ServeDispatcher(von, d); err != nil {
- t.Fatalf("server.ServeDispatcher failed: %v", err)
- }
- return func() {
- if err := server.Stop(); err != nil {
- t.Fatalf("server.Stop failed: %v", err)
- }
- if err := os.RemoveAll(rootDir); err != nil {
- t.Fatalf("os.RemoveAll(%q) failed: %v", rootDir, err)
- }
- }
-}
-
type simpleRW chan []byte
func (s simpleRW) Write(p []byte) (n int, err error) {
@@ -687,103 +654,6 @@
}
}
-func TestDeviceManagerGlobAndDebug(t *testing.T) {
- ctx, shutdown := utiltest.InitForTest()
- defer shutdown()
-
- sh, deferFn := servicetest.CreateShellAndMountTable(t, ctx, nil)
- defer deferFn()
-
- // Set up mock application and binary repositories.
- envelope, cleanup := utiltest.StartMockRepos(t, ctx)
- defer cleanup()
-
- root, cleanup := servicetest.SetupRootDir(t, "devicemanager")
- defer cleanup()
- if err := impl.SaveCreatorInfo(root); err != nil {
- t.Fatal(err)
- }
-
- // Create a script wrapping the test target that implements suidhelper.
- helperPath := utiltest.GenerateSuidHelperScript(t, root)
-
- // Set up the device manager. Since we won't do device manager updates,
- // don't worry about its application envelope and current link.
- dmh := servicetest.RunCommand(t, sh, nil, utiltest.DeviceManagerCmd, "dm", root, helperPath, "unused_app_repo_name", "unused_curr_link")
- pid := servicetest.ReadPID(t, dmh)
- defer syscall.Kill(pid, syscall.SIGINT)
-
- // Create the local server that the app uses to let us know it's ready.
- pingCh, cleanup := utiltest.SetupPingServer(t, ctx)
- defer cleanup()
-
- // Create the envelope for the first version of the app.
- *envelope = utiltest.EnvelopeFromShell(sh, nil, utiltest.AppCmd, "google naps", "appV1")
-
- // Device must be claimed before applications can be installed.
- utiltest.ClaimDevice(t, ctx, "claimable", "dm", "mydevice", utiltest.NoPairingToken)
- // Install the app.
- appID := utiltest.InstallApp(t, ctx)
- install1ID := path.Base(appID)
-
- // Start an instance of the app.
- instance1ID := utiltest.LaunchApp(t, ctx, appID)
- defer utiltest.TerminateApp(t, ctx, appID, instance1ID)
-
- // Wait until the app pings us that it's ready.
- pingCh.WaitForPingArgs(t)
-
- app2ID := utiltest.InstallApp(t, ctx)
- install2ID := path.Base(app2ID)
-
- // Base name of argv[0] that the app should have when it executes
- // It will be path.Base(envelope.Title + "@" + envelope.Binary.File + "/app").
- // Note the suffix, which ensures that the result is always "app" at the moment.
- // Someday in future we may remove that and have binary names that reflect the app name.
- const appName = "app"
-
- testcases := []utiltest.GlobTestVector{
- {"dm", "...", []string{
- "",
- "apps",
- "apps/google naps",
- "apps/google naps/" + install1ID,
- "apps/google naps/" + install1ID + "/" + instance1ID,
- "apps/google naps/" + install1ID + "/" + instance1ID + "/logs",
- "apps/google naps/" + install1ID + "/" + instance1ID + "/logs/STDERR-<timestamp>",
- "apps/google naps/" + install1ID + "/" + instance1ID + "/logs/STDOUT-<timestamp>",
- "apps/google naps/" + install1ID + "/" + instance1ID + "/logs/" + appName + ".INFO",
- "apps/google naps/" + install1ID + "/" + instance1ID + "/logs/" + appName + ".<*>.INFO.<timestamp>",
- "apps/google naps/" + install1ID + "/" + instance1ID + "/pprof",
- "apps/google naps/" + install1ID + "/" + instance1ID + "/stats",
- "apps/google naps/" + install1ID + "/" + instance1ID + "/stats/rpc",
- "apps/google naps/" + install1ID + "/" + instance1ID + "/stats/system",
- "apps/google naps/" + install1ID + "/" + instance1ID + "/stats/system/start-time-rfc1123",
- "apps/google naps/" + install1ID + "/" + instance1ID + "/stats/system/start-time-unix",
- "apps/google naps/" + install2ID,
- "device",
- }},
- {"dm/apps", "*", []string{"google naps"}},
- {"dm/apps/google naps", "*", []string{install1ID, install2ID}},
- {"dm/apps/google naps/" + install1ID, "*", []string{instance1ID}},
- {"dm/apps/google naps/" + install1ID + "/" + instance1ID, "*", []string{"logs", "pprof", "stats"}},
- {"dm/apps/google naps/" + install1ID + "/" + instance1ID + "/logs", "*", []string{
- "STDERR-<timestamp>",
- "STDOUT-<timestamp>",
- appName + ".INFO",
- appName + ".<*>.INFO.<timestamp>",
- }},
- {"dm/apps/google naps/" + install1ID + "/" + instance1ID + "/stats/system", "start-time*", []string{"start-time-rfc1123", "start-time-unix"}},
- }
-
- res := utiltest.NewGlobTestRegexHelper(appName)
-
- utiltest.VerifyGlob(t, ctx, appName, testcases, res)
- utiltest.VerifyLog(t, ctx, "dm", "apps/google naps", install1ID, instance1ID, "logs", "*")
- utiltest.VerifyStatsValues(t, ctx, "dm", "apps/google naps", install1ID, instance1ID, "stats/system/start-time*")
- utiltest.VerifyPProfCmdLine(t, ctx, appName, "dm", "apps/google naps", install1ID, instance1ID, "pprof")
-}
-
// TODO(caprita): We need better test coverage for how updating/reverting apps
// affects the package configured for the app.
func TestDeviceManagerPackages(t *testing.T) {
@@ -798,7 +668,7 @@
defer cleanup()
binaryVON := "realbin"
- defer startRealBinaryRepository(t, ctx, binaryVON)()
+ defer utiltest.StartRealBinaryRepository(t, ctx, binaryVON)()
// upload package to binary repository
tmpdir, err := ioutil.TempDir("", "test-package-")
@@ -1011,285 +881,3 @@
},
})
}
-
-func TestAppWithSuidHelper(t *testing.T) {
- ctx, shutdown := utiltest.InitForTest()
- defer shutdown()
-
- // Identity provider used to ensure that all processes recognize each
- // others' blessings.
- idp := testutil.NewIDProvider("root")
- if err := idp.Bless(v23.GetPrincipal(ctx), "self"); err != nil {
- t.Fatal(err)
- }
-
- sh, deferFn := servicetest.CreateShellAndMountTable(t, ctx, nil)
- defer deferFn()
-
- // Set up mock application and binary repositories.
- envelope, cleanup := utiltest.StartMockRepos(t, ctx)
- defer cleanup()
-
- root, cleanup := servicetest.SetupRootDir(t, "devicemanager")
- defer cleanup()
- if err := impl.SaveCreatorInfo(root); err != nil {
- t.Fatal(err)
- }
-
- selfCtx := ctx
- otherCtx := utiltest.CtxWithNewPrincipal(t, selfCtx, idp, "other")
-
- // Create a script wrapping the test target that implements suidhelper.
- helperPath := utiltest.GenerateSuidHelperScript(t, root)
-
- dmh := servicetest.RunCommand(t, sh, nil, utiltest.DeviceManagerCmd, "-mocksetuid", "dm", root, helperPath, "unused_app_repo_name", "unused_curr_link")
- pid := servicetest.ReadPID(t, dmh)
- defer syscall.Kill(pid, syscall.SIGINT)
- defer utiltest.VerifyNoRunningProcesses(t)
- // Claim the devicemanager with selfCtx as root/self/alice
- utiltest.ClaimDevice(t, selfCtx, "claimable", "dm", "alice", utiltest.NoPairingToken)
-
- deviceStub := device.DeviceClient("dm/device")
-
- // Create the local server that the app uses to tell us which system
- // name the device manager wished to run it as.
- pingCh, cleanup := utiltest.SetupPingServer(t, ctx)
- defer cleanup()
-
- // Create an envelope for a first version of the app.
- *envelope = utiltest.EnvelopeFromShell(sh, []string{utiltest.TestEnvVarName + "=env-var"}, utiltest.AppCmd, "google naps", fmt.Sprintf("--%s=flag-val-envelope", utiltest.TestFlagName), "appV1")
-
- // Install and start the app as root/self.
- appID := utiltest.InstallApp(t, selfCtx)
-
- vlog.VI(2).Infof("Validate that the created app has the right permission lists.")
- perms, _, err := utiltest.AppStub(appID).GetPermissions(selfCtx)
- if err != nil {
- t.Fatalf("GetPermissions on appID: %v failed %v", appID, err)
- }
- expected := make(access.Permissions)
- for _, tag := range access.AllTypicalTags() {
- expected[string(tag)] = access.AccessList{In: []security.BlessingPattern{"root/self/$"}}
- }
- if got, want := perms.Normalize(), expected.Normalize(); !reflect.DeepEqual(got, want) {
- t.Errorf("got %#v, expected %#v", got, want)
- }
-
- // Start an instance of the app but this time it should fail: we do not
- // have an associated uname for the invoking identity.
- utiltest.LaunchAppExpectError(t, selfCtx, appID, verror.ErrNoAccess.ID)
-
- // Create an association for selfCtx
- if err := deviceStub.AssociateAccount(selfCtx, []string{"root/self"}, testUserName); err != nil {
- t.Fatalf("AssociateAccount failed %v", err)
- }
-
- instance1ID := utiltest.LaunchApp(t, selfCtx, appID)
- pingCh.VerifyPingArgs(t, testUserName, "flag-val-envelope", "env-var") // Wait until the app pings us that it's ready.
- utiltest.TerminateApp(t, selfCtx, appID, instance1ID)
-
- vlog.VI(2).Infof("other attempting to run an app without access. Should fail.")
- utiltest.LaunchAppExpectError(t, otherCtx, appID, verror.ErrNoAccess.ID)
-
- // Self will now let other also install apps.
- if err := deviceStub.AssociateAccount(selfCtx, []string{"root/other"}, testUserName); err != nil {
- t.Fatalf("AssociateAccount failed %v", err)
- }
- // Add Start to the AccessList list for root/other.
- newAccessList, _, err := deviceStub.GetPermissions(selfCtx)
- if err != nil {
- t.Fatalf("GetPermissions failed %v", err)
- }
- newAccessList.Add("root/other", string(access.Write))
- if err := deviceStub.SetPermissions(selfCtx, newAccessList, ""); err != nil {
- t.Fatalf("SetPermissions failed %v", err)
- }
-
- // With the introduction of per installation and per instance AccessLists,
- // while other now has administrator permissions on the device manager,
- // 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.")
- utiltest.LaunchAppExpectError(t, otherCtx, appID, verror.ErrNoAccess.ID)
-
- // But self can give other permissions to start applications.
- vlog.VI(2).Infof("self attempting to give other permission to start %s", appID)
- newAccessList, _, err = utiltest.AppStub(appID).GetPermissions(selfCtx)
- if err != nil {
- t.Fatalf("GetPermissions on appID: %v failed %v", appID, err)
- }
- newAccessList.Add("root/other", string(access.Read))
- if err = utiltest.AppStub(appID).SetPermissions(selfCtx, newAccessList, ""); err != nil {
- t.Fatalf("SetPermissions on appID: %v failed: %v", appID, err)
- }
-
- vlog.VI(2).Infof("other attempting to run an app with access. Should succeed.")
- instance2ID := utiltest.LaunchApp(t, otherCtx, appID)
- pingCh.VerifyPingArgs(t, testUserName, "flag-val-envelope", "env-var") // Wait until the app pings us that it's ready.
-
- vlog.VI(2).Infof("Validate that created instance has the right permissions.")
- expected = make(access.Permissions)
- for _, tag := range access.AllTypicalTags() {
- expected[string(tag)] = access.AccessList{In: []security.BlessingPattern{"root/other/$"}}
- }
- perms, _, err = utiltest.AppStub(appID, instance2ID).GetPermissions(selfCtx)
- if err != nil {
- t.Fatalf("GetPermissions on instance %v/%v failed: %v", appID, instance2ID, err)
- }
- if got, want := perms.Normalize(), expected.Normalize(); !reflect.DeepEqual(got, want) {
- t.Errorf("got %#v, expected %#v ", got, want)
- }
-
- // Shutdown the app.
- utiltest.KillApp(t, otherCtx, appID, instance2ID)
-
- vlog.VI(2).Infof("Verify that Run with the same systemName works.")
- utiltest.RunApp(t, otherCtx, appID, instance2ID)
- pingCh.VerifyPingArgs(t, testUserName, "flag-val-envelope", "env-var") // Wait until the app pings us that it's ready.
- utiltest.KillApp(t, otherCtx, appID, instance2ID)
-
- vlog.VI(2).Infof("Verify that other can install and run applications.")
- otherAppID := utiltest.InstallApp(t, otherCtx)
-
- vlog.VI(2).Infof("other attempting to run an app that other installed. Should succeed.")
- instance4ID := utiltest.LaunchApp(t, otherCtx, otherAppID)
- pingCh.VerifyPingArgs(t, testUserName, "flag-val-envelope", "env-var") // Wait until the app pings us that it's ready.
-
- // Clean up.
- utiltest.TerminateApp(t, otherCtx, otherAppID, instance4ID)
-
- // Change the associated system name.
- if err := deviceStub.AssociateAccount(selfCtx, []string{"root/other"}, anotherTestUserName); err != nil {
- t.Fatalf("AssociateAccount failed %v", err)
- }
-
- vlog.VI(2).Infof("Show that Run with a different systemName fails.")
- utiltest.RunAppExpectError(t, otherCtx, appID, instance2ID, verror.ErrNoAccess.ID)
-
- // Clean up.
- utiltest.DeleteApp(t, otherCtx, appID, instance2ID)
-
- vlog.VI(2).Infof("Show that Start with different systemName works.")
- instance3ID := utiltest.LaunchApp(t, otherCtx, appID)
- pingCh.VerifyPingArgs(t, anotherTestUserName, "flag-val-envelope", "env-var") // Wait until the app pings us that it's ready.
-
- // Clean up.
- utiltest.TerminateApp(t, otherCtx, appID, instance3ID)
-}
-
-func TestDownloadSignatureMatch(t *testing.T) {
- ctx, shutdown := utiltest.InitForTest()
- defer shutdown()
-
- sh, deferFn := servicetest.CreateShellAndMountTable(t, ctx, nil)
- defer deferFn()
-
- binaryVON := "binary"
- pkgVON := naming.Join(binaryVON, "testpkg")
- defer startRealBinaryRepository(t, ctx, binaryVON)()
-
- up := testutil.RandomBytes(testutil.Intn(5 << 20))
- mediaInfo := repository.MediaInfo{Type: "application/octet-stream"}
- sig, err := binarylib.Upload(ctx, naming.Join(binaryVON, "testbinary"), up, mediaInfo)
- if err != nil {
- t.Fatalf("Upload(%v) failed:%v", binaryVON, err)
- }
-
- // Upload packages for this application
- tmpdir, err := ioutil.TempDir("", "test-package-")
- if err != nil {
- t.Fatalf("ioutil.TempDir failed: %v", err)
- }
- defer os.RemoveAll(tmpdir)
- pkgContents := testutil.RandomBytes(testutil.Intn(5 << 20))
- if err := ioutil.WriteFile(filepath.Join(tmpdir, "pkg.txt"), pkgContents, 0600); err != nil {
- t.Fatalf("ioutil.WriteFile failed: %v", err)
- }
- pkgSig, err := binarylib.UploadFromDir(ctx, pkgVON, tmpdir)
- if err != nil {
- t.Fatalf("binarylib.UploadFromDir failed: %v", err)
- }
-
- // Start the application repository
- envelope, serverStop := utiltest.StartApplicationRepository(ctx)
- defer serverStop()
-
- root, cleanup := servicetest.SetupRootDir(t, "devicemanager")
- defer cleanup()
- if err := impl.SaveCreatorInfo(root); err != nil {
- t.Fatal(err)
- }
-
- // Create a script wrapping the test target that implements suidhelper.
- helperPath := utiltest.GenerateSuidHelperScript(t, root)
-
- // Set up the device manager. Since we won't do device manager updates,
- // don't worry about its application envelope and current link.
- dmh := servicetest.RunCommand(t, sh, nil, utiltest.DeviceManagerCmd, "dm", root, helperPath, "unused_app_repo_name", "unused_curr_link")
- pid := servicetest.ReadPID(t, dmh)
- defer syscall.Kill(pid, syscall.SIGINT)
- utiltest.ClaimDevice(t, ctx, "claimable", "dm", "mydevice", utiltest.NoPairingToken)
-
- publisher, err := v23.GetPrincipal(ctx).BlessSelf("publisher")
- if err != nil {
- t.Fatalf("Failed to generate publisher blessings:%v", err)
- }
- *envelope = application.Envelope{
- Binary: application.SignedFile{
- File: naming.Join(binaryVON, "testbinary"),
- Signature: *sig,
- },
- Publisher: publisher,
- Packages: map[string]application.SignedFile{
- "pkg": application.SignedFile{
- File: pkgVON,
- Signature: *pkgSig,
- },
- },
- }
- if _, err := utiltest.AppStub().Install(ctx, utiltest.MockApplicationRepoName, device.Config{}, nil); err != nil {
- t.Fatalf("Failed to Install app:%v", err)
- }
-
- // Verify that when the binary is corrupted, signature verification fails.
- up[0] = up[0] ^ 0xFF
- if err := binarylib.Delete(ctx, naming.Join(binaryVON, "testbinary")); err != nil {
- t.Fatalf("Delete(%v) failed:%v", binaryVON, err)
- }
- if _, err := binarylib.Upload(ctx, naming.Join(binaryVON, "testbinary"), up, mediaInfo); err != nil {
- t.Fatalf("Upload(%v) failed:%v", binaryVON, err)
- }
- if _, err := utiltest.AppStub().Install(ctx, utiltest.MockApplicationRepoName, device.Config{}, nil); verror.ErrorID(err) != impl.ErrOperationFailed.ID {
- t.Fatalf("Failed to verify signature mismatch for binary:%v. Got errorid=%v[%v], want errorid=%v", binaryVON, verror.ErrorID(err), err, impl.ErrOperationFailed.ID)
- }
-
- // Restore the binary and verify that installation succeeds.
- up[0] = up[0] ^ 0xFF
- if err := binarylib.Delete(ctx, naming.Join(binaryVON, "testbinary")); err != nil {
- t.Fatalf("Delete(%v) failed:%v", binaryVON, err)
- }
- if _, err := binarylib.Upload(ctx, naming.Join(binaryVON, "testbinary"), up, mediaInfo); err != nil {
- t.Fatalf("Upload(%v) failed:%v", binaryVON, err)
- }
- if _, err := utiltest.AppStub().Install(ctx, utiltest.MockApplicationRepoName, device.Config{}, nil); err != nil {
- t.Fatalf("Failed to Install app:%v", err)
- }
-
- // Verify that when the package contents are corrupted, signature verification fails.
- pkgContents[0] = pkgContents[0] ^ 0xFF
- if err := binarylib.Delete(ctx, pkgVON); err != nil {
- t.Fatalf("Delete(%v) failed:%v", pkgVON, err)
- }
- if err := os.Remove(filepath.Join(tmpdir, "pkg.txt")); err != nil {
- t.Fatalf("Remove(%v) failed:%v", filepath.Join(tmpdir, "pkg.txt"), err)
- }
- if err := ioutil.WriteFile(filepath.Join(tmpdir, "pkg.txt"), pkgContents, 0600); err != nil {
- t.Fatalf("ioutil.WriteFile failed: %v", err)
- }
- if _, err = binarylib.UploadFromDir(ctx, pkgVON, tmpdir); err != nil {
- t.Fatalf("binarylib.UploadFromDir failed: %v", err)
- }
- if _, err := utiltest.AppStub().Install(ctx, utiltest.MockApplicationRepoName, device.Config{}, nil); verror.ErrorID(err) != impl.ErrOperationFailed.ID {
- t.Fatalf("Failed to verify signature mismatch for package:%v", pkgVON)
- }
-}
diff --git a/services/device/internal/impl/only_for_test.go b/services/device/internal/impl/only_for_test.go
index 0cec861..d257860 100644
--- a/services/device/internal/impl/only_for_test.go
+++ b/services/device/internal/impl/only_for_test.go
@@ -5,7 +5,6 @@
package impl
import (
- "flag"
"fmt"
"os"
"path/filepath"
@@ -17,8 +16,6 @@
// This file contains code in the impl package that we only want built for tests
// (it exposes public API methods that we don't want to normally expose).
-var mockIsSetuid = flag.Bool("mocksetuid", false, "set flag to pretend to have a helper with setuid permissions")
-
func (c *callbackState) leaking() bool {
c.Lock()
defer c.Unlock()
@@ -52,12 +49,6 @@
vlog.Errorf("Rename(%v, %v) failed: %v", dir, renamed, err)
}
}
- isSetuid = possiblyMockIsSetuid
-}
-
-func possiblyMockIsSetuid(fileStat os.FileInfo) bool {
- vlog.VI(2).Infof("Mock isSetuid is reporting: %v", *mockIsSetuid)
- return *mockIsSetuid
}
func WrapBaseCleanupDir(path, helper string) {
diff --git a/services/device/internal/impl/utiltest/helpers.go b/services/device/internal/impl/utiltest/helpers.go
index 4e82508..35d1e06 100644
--- a/services/device/internal/impl/utiltest/helpers.go
+++ b/services/device/internal/impl/utiltest/helpers.go
@@ -36,6 +36,7 @@
"v.io/x/ref/envvar"
_ "v.io/x/ref/profiles/roaming"
"v.io/x/ref/services/device/internal/impl"
+ "v.io/x/ref/services/internal/binarylib"
"v.io/x/ref/services/internal/servicetest"
"v.io/x/ref/test"
"v.io/x/ref/test/modules"
@@ -676,3 +677,30 @@
v23.GetNamespace(ctx).CacheCtl(naming.DisableCache(true))
return ctx, shutdown
}
+
+func StartRealBinaryRepository(t *testing.T, ctx *context.T, von string) func() {
+ rootDir, err := binarylib.SetupRootDir("")
+ if err != nil {
+ t.Fatalf("binarylib.SetupRootDir failed: %v", err)
+ }
+ state, err := binarylib.NewState(rootDir, "", 3)
+ if err != nil {
+ t.Fatalf("binarylib.NewState failed: %v", err)
+ }
+ server, _ := servicetest.NewServer(ctx)
+ d, err := binarylib.NewDispatcher(v23.GetPrincipal(ctx), state)
+ if err != nil {
+ t.Fatalf("server.NewDispatcher failed: %v", err)
+ }
+ if err := server.ServeDispatcher(von, d); err != nil {
+ t.Fatalf("server.ServeDispatcher failed: %v", err)
+ }
+ return func() {
+ if err := server.Stop(); err != nil {
+ t.Fatalf("server.Stop failed: %v", err)
+ }
+ if err := os.RemoveAll(rootDir); err != nil {
+ t.Fatalf("os.RemoveAll(%q) failed: %v", rootDir, err)
+ }
+ }
+}