// 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 applife_test

import (
	"crypto/md5"
	"encoding/base64"
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"regexp"
	"strings"
	"syscall"
	"testing"
	"time"

	"v.io/v23"
	"v.io/v23/context"
	"v.io/v23/naming"
	"v.io/v23/security"
	"v.io/v23/services/application"
	"v.io/v23/services/device"
	"v.io/x/ref"
	"v.io/x/ref/lib/mgmt"
	vsecurity "v.io/x/ref/lib/security"
	"v.io/x/ref/services/device/deviced/internal/impl/utiltest"
	"v.io/x/ref/services/device/deviced/internal/versioning"
	"v.io/x/ref/services/device/internal/errors"
	"v.io/x/ref/services/internal/servicetest"
	"v.io/x/ref/test"
	"v.io/x/ref/test/testutil"
)

func instanceDirForApp(root, appID, instanceID string) string {
	applicationDirName := func(title string) string {
		h := md5.New()
		h.Write([]byte(title))
		hash := strings.TrimRight(base64.URLEncoding.EncodeToString(h.Sum(nil)), "=")
		return "app-" + hash
	}
	components := strings.Split(appID, "/")
	appTitle, installationID := components[0], components[1]
	return filepath.Join(root, applicationDirName(appTitle), "installation-"+installationID, "instances", "instance-"+instanceID)
}

func verifyAppWorkspace(t *testing.T, root, appID, instanceID string) {
	// HACK ALERT: for now, we peek inside the device manager's directory
	// structure (which ought to be opaque) to check for what the app has
	// written to its local root.
	//
	// TODO(caprita): add support to device manager to browse logs/app local
	// root.
	rootDir := filepath.Join(instanceDirForApp(root, appID, instanceID), "root")
	testFile := filepath.Join(rootDir, "testfile")
	if read, err := ioutil.ReadFile(testFile); err != nil {
		t.Fatalf("Failed to read %v: %v", testFile, err)
	} else if want, got := "goodbye world", string(read); want != got {
		t.Fatalf("Expected to read %v, got %v instead", want, got)
	}
	// END HACK
}

// TestLifeOfAnApp installs an app, instantiates, runs, kills, and deletes
// several instances, and performs updates.
func TestLifeOfAnApp(t *testing.T) {
	ctx, shutdown := test.V23Init()
	defer shutdown()

	// Get app publisher context (used later to publish apps)
	var pubCtx *context.T
	var err error
	if pubCtx, err = setupPublishingCredentials(ctx); 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 := versioning.SaveCreatorInfo(ctx, 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.DeviceManager, "dm", root, helperPath, "unused_app_repo_name", "unused_curr_link")
	servicetest.ReadPID(t, dmh)
	utiltest.ClaimDevice(t, ctx, "claimable", "dm", "mydevice", utiltest.NoPairingToken)

	// Create the local server that the app uses to let us know it's ready.
	pingCh, cleanup := utiltest.SetupPingServer(t, ctx)
	defer cleanup()

	utiltest.Resolve(t, ctx, "pingserver", 1, true)

	// Create an envelope for a first version of the app.
	e, err := utiltest.SignedEnvelopeFromShell(pubCtx, sh, []string{utiltest.TestEnvVarName + "=env-val-envelope"}, utiltest.App, "google naps", 0, 0, fmt.Sprintf("--%s=flag-val-envelope", utiltest.TestFlagName), "appV1")
	if err != nil {
		t.Fatalf("Unable to get signed envelope: %v", err)
	}
	*envelope = e

	// Install the app.  The config-specified flag value for testFlagName
	// should override the value specified in the envelope above, and the
	// config-specified value for origin should override the value in the
	// Install rpc argument.
	mtName, ok := sh.GetVar(ref.EnvNamespacePrefix)
	if !ok {
		t.Fatalf("failed to get namespace root var from shell")
	}
	// This rooted name should be equivalent to the relative name "ar", but
	// we want to test that the config override for origin works.
	rootedAppRepoName := naming.Join(mtName, "ar")
	appID := utiltest.InstallApp(t, ctx, device.Config{utiltest.TestFlagName: "flag-val-install", mgmt.AppOriginConfigKey: rootedAppRepoName})
	v1 := utiltest.VerifyState(t, ctx, device.InstallationStateActive, appID)
	installationDebug := utiltest.Debug(t, ctx, appID)
	// We spot-check a couple pieces of information we expect in the debug
	// output.
	// TODO(caprita): Is there a way to verify more without adding brittle
	// logic that assumes too much about the format?  This may be one
	// argument in favor of making the output of Debug a struct instead of
	// free-form string.
	if !strings.Contains(installationDebug, fmt.Sprintf("Origin: %v", rootedAppRepoName)) {
		t.Fatalf("debug response doesn't contain expected info: %v", installationDebug)
	}
	if !strings.Contains(installationDebug, "Config: map[random_test_flag:flag-val-install]") {
		t.Fatalf("debug response doesn't contain expected info: %v", installationDebug)
	}

	// Start requires the caller to bless the app instance.
	expectedErr := "bless failed"
	if _, err := utiltest.LaunchAppImpl(t, ctx, appID, ""); err == nil || err.Error() != expectedErr {
		t.Fatalf("Start(%v) expected to fail with %v, got %v instead", appID, expectedErr, err)
	}

	// Start an instance of the app.
	instance1ID := utiltest.LaunchApp(t, ctx, appID)
	if v := utiltest.VerifyState(t, ctx, device.InstanceStateRunning, appID, instance1ID); v != v1 {
		t.Fatalf("Instance version expected to be %v, got %v instead", v1, v)
	}

	instanceDebug := utiltest.Debug(t, ctx, appID, instance1ID)

	// Verify the app's default blessings.
	if !strings.Contains(instanceDebug, fmt.Sprintf("Default Blessings                %s:forapp", v23.GetPrincipal(ctx).BlessingStore().Default().String())) {
		t.Fatalf("debug response doesn't contain expected info: %v", instanceDebug)
	}

	// Verify the "..." blessing, which will include the publisher blessings
	verifyAppPeerBlessings(t, ctx, pubCtx, instanceDebug, envelope)

	// Wait until the app pings us that it's ready.
	pingResult := pingCh.VerifyPingArgs(t, utiltest.UserName(t), "flag-val-install", "env-val-envelope")
	v1EP1 := utiltest.Resolve(t, ctx, "appV1", 1, true)[0]

	// Check that the instance name handed to the app looks plausible
	nameRE := regexp.MustCompile(".*/apps/google naps/[^/]+/[^/]+$")
	if nameRE.FindString(pingResult.InstanceName) == "" {
		t.Fatalf("Unexpected instance name: %v", pingResult.InstanceName)
	}

	// There should be at least one publisher blessing prefix, and all prefixes should
	// end in ":mydevice" because they are just the device manager's blessings
	prefixes := strings.Split(pingResult.PubBlessingPrefixes, ",")
	if len(prefixes) == 0 {
		t.Fatalf("No publisher blessing prefixes found: %v", pingResult)
	}
	for _, p := range prefixes {
		if !strings.HasSuffix(p, ":mydevice") {
			t.Fatalf("publisher Blessing prefixes don't look right: %v", pingResult.PubBlessingPrefixes)
		}
	}

	// We used a signed envelope, so there should have been some publisher blessings
	if !hasPrefixMatches(pingResult.PubBlessingPrefixes, pingResult.DefaultPeerBlessings) {
		t.Fatalf("Publisher Blessing Prefixes are not as expected: %v vs %v", pingResult.PubBlessingPrefixes, pingResult.DefaultPeerBlessings)
	}

	// Stop the app instance.
	utiltest.KillApp(t, ctx, appID, instance1ID)
	utiltest.VerifyState(t, ctx, device.InstanceStateNotRunning, appID, instance1ID)
	utiltest.ResolveExpectNotFound(t, ctx, "appV1", true)

	utiltest.RunApp(t, ctx, appID, instance1ID)
	utiltest.VerifyState(t, ctx, device.InstanceStateRunning, appID, instance1ID)
	pingCh.VerifyPingArgs(t, utiltest.UserName(t), "flag-val-install", "env-val-envelope") // Wait until the app pings us that it's ready.
	oldV1EP1 := v1EP1
	if v1EP1 = utiltest.Resolve(t, ctx, "appV1", 1, true)[0]; v1EP1 == oldV1EP1 {
		t.Fatalf("Expected a new endpoint for the app after kill/run")
	}

	// Start a second instance.
	instance2ID := utiltest.LaunchApp(t, ctx, appID)
	pingCh.VerifyPingArgs(t, utiltest.UserName(t), "flag-val-install", "env-val-envelope") // Wait until the app pings us that it's ready.

	// There should be two endpoints mounted as "appV1", one for each
	// instance of the app.
	endpoints := utiltest.Resolve(t, ctx, "appV1", 2, true)
	v1EP2 := endpoints[0]
	if endpoints[0] == v1EP1 {
		v1EP2 = endpoints[1]
		if v1EP2 == v1EP1 {
			t.Fatalf("Both endpoints are the same")
		}
	} else if endpoints[1] != v1EP1 {
		t.Fatalf("Second endpoint should have been v1EP1: %v, %v", endpoints, v1EP1)
	}

	// TODO(caprita): verify various non-standard combinations (kill when
	// canceled; run while still running).

	// Kill the first instance.
	utiltest.KillApp(t, ctx, appID, instance1ID)
	// Only the second instance should still be running and mounted.
	// In this case, we don't want to retry since we shouldn't need to.
	if want, got := v1EP2, utiltest.Resolve(t, ctx, "appV1", 1, false)[0]; want != got {
		t.Fatalf("Resolve(%v): want: %v, got %v", "appV1", want, got)
	}

	// Updating the installation to itself is a no-op.
	utiltest.UpdateAppExpectError(t, ctx, appID, errors.ErrUpdateNoOp.ID)

	// Updating the installation should not work with a mismatched title.
	*envelope = utiltest.EnvelopeFromShell(sh, nil, utiltest.App, "bogus", 0, 0)

	utiltest.UpdateAppExpectError(t, ctx, appID, errors.ErrAppTitleMismatch.ID)

	// Create a second version of the app and update the app to it.
	*envelope = utiltest.EnvelopeFromShell(sh, []string{utiltest.TestEnvVarName + "=env-val-envelope"}, utiltest.App, "google naps", 0, 0, "appV2")

	utiltest.UpdateApp(t, ctx, appID)

	v2 := utiltest.VerifyState(t, ctx, device.InstallationStateActive, appID)
	if v1 == v2 {
		t.Fatalf("Version did not change for %v: %v", appID, v1)
	}

	// Second instance should still be running, don't retry.
	if want, got := v1EP2, utiltest.Resolve(t, ctx, "appV1", 1, false)[0]; want != got {
		t.Fatalf("Resolve(%v): want: %v, got %v", "appV1", want, got)
	}
	if v := utiltest.VerifyState(t, ctx, device.InstanceStateRunning, appID, instance2ID); v != v1 {
		t.Fatalf("Instance version expected to be %v, got %v instead", v1, v)
	}

	// Resume first instance.
	utiltest.RunApp(t, ctx, appID, instance1ID)
	if v := utiltest.VerifyState(t, ctx, device.InstanceStateRunning, appID, instance1ID); v != v1 {
		t.Fatalf("Instance version expected to be %v, got %v instead", v1, v)
	}
	pingCh.VerifyPingArgs(t, utiltest.UserName(t), "flag-val-install", "env-val-envelope") // 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
	// v1EP2.
	endpoints = utiltest.Resolve(t, ctx, "appV1", 2, true)
	if endpoints[0] == v1EP2 {
		if endpoints[1] == v1EP2 {
			t.Fatalf("Both endpoints are the same")
		}
	} else if endpoints[1] != v1EP2 {
		t.Fatalf("Second endpoint should have been v1EP2: %v, %v", endpoints, v1EP2)
	}

	// Trying to update first instance while it's running should fail.
	utiltest.UpdateInstanceExpectError(t, ctx, appID, instance1ID, errors.ErrInvalidOperation.ID)
	// Stop first instance and try again.
	utiltest.KillApp(t, ctx, appID, instance1ID)
	// Only the second instance should still be running and mounted, don't retry.
	if want, got := v1EP2, utiltest.Resolve(t, ctx, "appV1", 1, false)[0]; want != got {
		t.Fatalf("Resolve(%v): want: %v, got %v", "appV1", want, got)
	}
	// Update succeeds now.
	utiltest.UpdateInstance(t, ctx, appID, instance1ID)
	if v := utiltest.VerifyState(t, ctx, device.InstanceStateNotRunning, appID, instance1ID); v != v2 {
		t.Fatalf("Instance version expected to be %v, got %v instead", v2, v)
	}
	// Resume the first instance and verify it's running v2 now.
	utiltest.RunApp(t, ctx, appID, instance1ID)
	pingResult = pingCh.VerifyPingArgs(t, utiltest.UserName(t), "flag-val-install", "env-val-envelope")
	utiltest.Resolve(t, ctx, "appV1", 1, false)
	utiltest.Resolve(t, ctx, "appV2", 1, false)

	// Although v2 does not have a signed envelope, this was an update of v1, which did.
	// This app's config still includes publisher blessing prefixes, and it should still
	// have the publisher blessing it acquired earlier.
	//
	// TODO: This behavior is non-ideal. A reasonable requirement in future would be that
	// the publisher blessing string remain unchanged on updates to an installation, just as the
	// title is not allowed to change.
	if !hasPrefixMatches(pingResult.PubBlessingPrefixes, pingResult.DefaultPeerBlessings) {
		t.Fatalf("Publisher Blessing Prefixes are not as expected: %v vs %v", pingResult.PubBlessingPrefixes, pingResult.DefaultPeerBlessings)
	}

	// Reverting first instance fails since it's still running.
	utiltest.RevertAppExpectError(t, ctx, appID+"/"+instance1ID, errors.ErrInvalidOperation.ID)
	// Stop first instance and try again.
	utiltest.KillApp(t, ctx, appID, instance1ID)
	verifyAppWorkspace(t, root, appID, instance1ID)
	utiltest.ResolveExpectNotFound(t, ctx, "appV2", true)
	utiltest.RevertApp(t, ctx, appID+"/"+instance1ID)
	// Resume the first instance and verify it's running v1 now.
	utiltest.RunApp(t, ctx, appID, instance1ID)
	pingCh.VerifyPingArgs(t, utiltest.UserName(t), "flag-val-install", "env-val-envelope")
	utiltest.Resolve(t, ctx, "appV1", 2, false)
	utiltest.TerminateApp(t, ctx, appID, instance1ID)
	utiltest.Resolve(t, ctx, "appV1", 1, false)

	// Start a third instance.
	instance3ID := utiltest.LaunchApp(t, ctx, appID)
	if v := utiltest.VerifyState(t, ctx, device.InstanceStateRunning, appID, instance3ID); v != v2 {
		t.Fatalf("Instance version expected to be %v, got %v instead", v2, v)
	}
	// Wait until the app pings us that it's ready.
	pingResult = pingCh.VerifyPingArgs(t, utiltest.UserName(t), "flag-val-install", "env-val-envelope")
	// This app should not have publisher blessings. It was started from an installation
	// that did not have a signed envelope.
	if hasPrefixMatches(pingResult.PubBlessingPrefixes, pingResult.DefaultPeerBlessings) {
		t.Fatalf("Publisher Blessing Prefixes are not as expected: %v vs %v", pingResult.PubBlessingPrefixes, pingResult.DefaultPeerBlessings)
	}

	utiltest.Resolve(t, ctx, "appV2", 1, true)

	// Suspend second instance.
	utiltest.KillApp(t, ctx, appID, instance2ID)
	utiltest.ResolveExpectNotFound(t, ctx, "appV1", true)

	// Reverting second instance is a no-op since it's already running v1.
	utiltest.RevertAppExpectError(t, ctx, appID+"/"+instance2ID, errors.ErrUpdateNoOp.ID)

	// Stop third instance.
	utiltest.TerminateApp(t, ctx, appID, instance3ID)
	utiltest.ResolveExpectNotFound(t, ctx, "appV2", true)

	// Revert the app.
	utiltest.RevertApp(t, ctx, appID)
	if v := utiltest.VerifyState(t, ctx, device.InstallationStateActive, appID); v != v1 {
		t.Fatalf("Installation version expected to be %v, got %v instead", v1, v)
	}

	// Start a fourth instance.  It should be running from version 1.
	instance4ID := utiltest.LaunchApp(t, ctx, appID)
	if v := utiltest.VerifyState(t, ctx, device.InstanceStateRunning, appID, instance4ID); v != v1 {
		t.Fatalf("Instance version expected to be %v, got %v instead", v1, v)
	}
	pingCh.VerifyPingArgs(t, utiltest.UserName(t), "flag-val-install", "env-val-envelope") // Wait until the app pings us that it's ready.
	utiltest.Resolve(t, ctx, "appV1", 1, true)
	utiltest.TerminateApp(t, ctx, appID, instance4ID)
	utiltest.ResolveExpectNotFound(t, ctx, "appV1", true)

	// We are already on the first version, no further revert possible.
	utiltest.RevertAppExpectError(t, ctx, appID, errors.ErrUpdateNoOp.ID)

	// Uninstall the app.
	utiltest.UninstallApp(t, ctx, appID)
	utiltest.VerifyState(t, ctx, device.InstallationStateUninstalled, appID)

	// Updating the installation should no longer be allowed.
	utiltest.UpdateAppExpectError(t, ctx, appID, errors.ErrInvalidOperation.ID)

	// Reverting the installation should no longer be allowed.
	utiltest.RevertAppExpectError(t, ctx, appID, errors.ErrInvalidOperation.ID)

	// Starting new instances should no longer be allowed.
	utiltest.LaunchAppExpectError(t, ctx, appID, errors.ErrInvalidOperation.ID)

	// Make sure that Kill will actually kill an app that doesn't exit
	// cleanly Do this by installing, instantiating, running, and killing
	// hangingApp, which sleeps (rather than exits) after being asked to
	// Stop()
	*envelope = utiltest.EnvelopeFromShell(sh, nil, utiltest.HangingApp, "hanging app", 0, 0, "hAppV1")
	hAppID := utiltest.InstallApp(t, ctx)
	hInstanceID := utiltest.LaunchApp(t, ctx, hAppID)
	hangingPid := pingCh.WaitForPingArgs(t).Pid
	if err := syscall.Kill(hangingPid, 0); err != nil && err != syscall.EPERM {
		t.Fatalf("Pid of hanging app (%v) is not live", hangingPid)
	}
	utiltest.KillApp(t, ctx, hAppID, hInstanceID)
	pidIsAlive := true
	for i := 0; i < 10 && pidIsAlive; i++ {
		if err := syscall.Kill(hangingPid, 0); err == nil || err == syscall.EPERM {
			time.Sleep(time.Second) // pid is still alive
		} else {
			pidIsAlive = false
		}
	}
	if pidIsAlive {
		t.Fatalf("Pid of hanging app (%d) has not exited after Stop() call", hangingPid)
	}

	// In the first pass, TidyNow (below), finds that everything should be too
	// young to be tidied becasue TidyNow's first call to MockableNow()
	// provides the current time.
	shouldKeepInstances := keepAll(t, root, filepath.Join(root, "app*", "installation*", "instances", "instance*"))
	shouldKeepInstallations := keepAll(t, root, filepath.Join(root, "app*", "installation*"))
	shouldKeepLogFiles := keepAll(t, root, filepath.Join(root, "app*", "installation*", "instances", "instance*", "logs", "*"))

	if err := utiltest.DeviceStub("dm").TidyNow(ctx); err != nil {
		t.Fatalf("TidyNow failed: %v", err)
	}

	verifyTidying(t, root, filepath.Join(root, "app*", "installation*", "instances", "instance*"), shouldKeepInstances)
	verifyTidying(t, root, filepath.Join(root, "app*", "installation*"), shouldKeepInstallations)
	verifyTidying(t, root, filepath.Join(root, "app*", "installation*", "instances", "instance*", "logs", "*"), shouldKeepLogFiles)

	// In the second pass, TidyNow() (below) calls MockableNow() again
	// which has advanced to tomorrow so it should find that all items have
	// become old enough to tidy.
	shouldKeepInstances = determineShouldKeep(t, root, filepath.Join(root, "app*", "installation*", "instances", "instance*"), "Deleted")
	shouldKeepInstallations = addBackLinks(t, root, determineShouldKeep(t, root, filepath.Join(root, "app*", "installation*"), "Uninstalled"))
	shouldKeepLogFiles = determineLogFilesToKeep(t, shouldKeepInstances)

	if err := utiltest.DeviceStub("dm").TidyNow(ctx); err != nil {
		t.Fatalf("TidyNow failed: %v", err)
	}

	verifyTidying(t, root, filepath.Join(root, "app*", "installation*", "instances", "instance*"), shouldKeepInstances)
	verifyTidying(t, root, filepath.Join(root, "app*", "installation*"), shouldKeepInstallations)
	verifyTidying(t, root, filepath.Join(root, "app*", "installation*", "instances", "instance*", "logs", "*"), shouldKeepLogFiles)

	// Cleanly shut down the device manager.
	defer utiltest.VerifyNoRunningProcesses(t)
	syscall.Kill(dmh.Pid(), syscall.SIGINT)
	dmh.Expect("dm terminated")
	dmh.ExpectEOF()
}

func keepAll(t *testing.T, root, globpath string) map[string]bool {
	paths, err := filepath.Glob(globpath)
	if err != nil {
		t.Errorf("keepAll %v", err)
	}
	shouldKeep := make(map[string]bool)
	for _, idir := range paths {
		shouldKeep[idir] = true
	}
	return shouldKeep
}

func determineShouldKeep(t *testing.T, root, globpath, state string) map[string]bool {
	paths, err := filepath.Glob(globpath)
	if err != nil {
		t.Errorf("determineShouldKeep %v", err)
	}

	shouldKeep := make(map[string]bool)
	for _, idir := range paths {
		p := filepath.Join(idir, state)
		_, err := os.Stat(p)
		if os.IsNotExist(err) {
			shouldKeep[idir] = true
		} else if err == nil {
			shouldKeep[idir] = false
		} else {
			t.Errorf("determineShouldKeep Stat(%s) failed: %v", p, err)
		}
	}
	return shouldKeep

}

func addBackLinks(t *testing.T, root string, installationShouldKeep map[string]bool) map[string]bool {
	paths, err := filepath.Glob(filepath.Join(root, "app*", "installation*", "instances", "instance*", "installation"))
	if err != nil {
		t.Errorf("addBackLinks %v", err)
	}

	for _, idir := range paths {
		pth, err := os.Readlink(idir)
		if err != nil {
			t.Errorf("addBackLinks %v", err)
			continue
		}
		if _, ok := installationShouldKeep[pth]; ok {
			// An instance symlinks to this pth so must be kept.
			installationShouldKeep[pth] = true
		}
	}
	return installationShouldKeep
}

// determineLogFilesToKeep produces a map of the log files that
// should remain after tidying. It returns a map to be compatible
// with the verifyTidying.
func determineLogFilesToKeep(t *testing.T, instances map[string]bool) map[string]bool {
	shouldKeep := make(map[string]bool)
	for idir, keep := range instances {
		if !keep {
			continue
		}

		paths, err := filepath.Glob(filepath.Join(idir, "logs", "*"))
		if err != nil {
			t.Errorf("determineLogFilesToKeep filepath.Glob(%s) failed: %v", idir, err)
			return shouldKeep
		}

		for _, p := range paths {
			fi, err := os.Stat(p)
			if err != nil {
				t.Errorf("determineLogFilesToKeep os.Stat(%s): %v", p, err)
				return shouldKeep
			}

			if fi.Mode()&os.ModeSymlink == 0 {
				continue
			}

			shouldKeep[p] = true
			target, err := os.Readlink(p)
			if err != nil {
				t.Errorf("determineLogFilesToKeep os.Readlink(%s): %v", p, err)
				return shouldKeep
			}
			shouldKeep[target] = true
		}
	}
	return shouldKeep
}

func verifyTidying(t *testing.T, root, globpath string, shouldKeep map[string]bool) {
	paths, err := filepath.Glob(globpath)
	if err != nil {
		t.Errorf("verifyTidying %v", err)
	}

	// TidyUp adds nothing: pth should be a subset of shouldKeep.
	for _, pth := range paths {
		if !shouldKeep[pth] {
			t.Errorf("TidyUp (%s) wrongly added path: %s", globpath, pth)
			return
		}
	}

	// Tidy should not leave unkept instances: shouldKeep ^ pth should be entirely true.
	for _, pth := range paths {
		if !shouldKeep[pth] {
			t.Errorf("TidyUp (%s) failed to delete: %s", globpath, pth)
			return
		}
	}

	// Tidy must not delete any kept instances.
	for k, v := range shouldKeep {
		if v {
			if _, err := os.Stat(k); os.IsNotExist(err) {
				t.Errorf("TidyUp (%s) deleted an instance it shouldn't have: %s", globpath, k)
			}
		}
	}
}

// setupPublishingCredentials creates two principals, which, in addition to the one passed in
// (which is "the user") allow us to have an "identity provider", and a "publisher". The
// user and the publisher are both blessed by the identity provider. The return value is
// a context that can be used to publish an envelope with a signed binary.
func setupPublishingCredentials(ctx *context.T) (*context.T, error) {
	IDPPrincipal := testutil.NewPrincipal("identitypro")
	IDPBlessing := IDPPrincipal.BlessingStore().Default()

	PubPrincipal := testutil.NewPrincipal()
	UserPrincipal := v23.GetPrincipal(ctx)

	var b security.Blessings
	var c security.Caveat
	var err error
	if c, err = security.NewExpiryCaveat(time.Now().Add(time.Hour * 24 * 30)); err != nil {
		return nil, err
	}
	if b, err = IDPPrincipal.Bless(UserPrincipal.PublicKey(), IDPBlessing, "u:alice", c); err != nil {
		return nil, err
	}
	if err := vsecurity.SetDefaultBlessings(UserPrincipal, b); err != nil {
		return nil, err
	}

	if b, err = IDPPrincipal.Bless(PubPrincipal.PublicKey(), IDPBlessing, "m:publisher", security.UnconstrainedUse()); err != nil {
		return nil, err
	}
	if err := vsecurity.SetDefaultBlessings(PubPrincipal, b); err != nil {
		return nil, err
	}

	var pubCtx *context.T
	if pubCtx, err = v23.WithPrincipal(ctx, PubPrincipal); err != nil {
		return nil, err
	}

	return pubCtx, nil
}

// findPrefixMatches takes a set of comma-separated prefixes, and a set of comma-separated
// strings, and checks if any of the strings match any of the prefixes
func hasPrefixMatches(prefixList, stringList string) bool {
	prefixes := strings.Split(prefixList, ",")
	inStrings := strings.Split(stringList, ",")

	for _, s := range inStrings {
		for _, p := range prefixes {
			if strings.HasPrefix(s, p) {
				return true
			}
		}
	}
	return false
}

// verifyAppPeerBlessings checks the instanceDebug string to ensure that the app is running with
// the expected blessings for peer "..." (i.e. security.AllPrincipals) .
//
// The app should have one blessing that came from the user, of the form
// <base_blessing>:forapp. It should also have one or more publisher blessings, that are the
// cross product of the device manager blessings and the publisher blessings in the app
// envelope.
func verifyAppPeerBlessings(t *testing.T, ctx, pubCtx *context.T, instanceDebug string, e *application.Envelope) {
	// Extract the blessings from the debug output
	//
	// TODO(caprita): This is flaky, since the '...' peer pattern may not be
	// the first one in the sorted pattern list.  See v.io/i/680
	blessingRE := regexp.MustCompile(`Blessings\s?\n\s?\.\.\.\s*([^\n]+)`)
	blessingMatches := blessingRE.FindStringSubmatch(instanceDebug)
	if len(blessingMatches) < 2 {
		t.Fatalf("Failed to match blessing regex: [%v] [%v]", blessingMatches, instanceDebug)
	}
	blessingList := strings.Split(blessingMatches[1], ",")

	// Compute a map of the blessings we expect to find
	expBlessings := make(map[string]bool)
	baseBlessing := v23.GetPrincipal(ctx).BlessingStore().Default().String()
	expBlessings[baseBlessing+":forapp"] = false

	// App blessings should be the cross product of device manager and publisher blessings

	// dmBlessings below is a slice even though we have just one entry because we'll likely
	// want it to have more than one in future. (Today, a device manager typically has a
	// blessing from its claimer, but in many cases there might be other blessings too, such
	// as one from the manufacturer, or one from the organization that owns the device.)
	dmBlessings := []string{baseBlessing + ":mydevice"}
	pubBlessings := strings.Split(e.Publisher.String(), ",")
	for _, dmb := range dmBlessings {
		for _, pb := range pubBlessings {
			expBlessings[dmb+":a:"+pb] = false
		}
	}

	// Check the list of blessings against the map of expected blessings
	matched := 0
	for _, b := range blessingList {
		if seen, ok := expBlessings[b]; ok && !seen {
			expBlessings[b] = true
			matched++
		}
	}
	if matched != len(expBlessings) {
		t.Fatalf("Missing some blessings in set %v. App blessings were: %v", expBlessings, blessingList)
	}
}
