Merge "profiles/internal/rpc/stream/manager: Continue after "temporary" error"
diff --git a/services/device/internal/impl/impl_test.go b/services/device/internal/impl/impl_test.go
index f89e266..326ab3e 100644
--- a/services/device/internal/impl/impl_test.go
+++ b/services/device/internal/impl/impl_test.go
@@ -400,6 +400,7 @@
dmh := servicetest.RunCommand(t, sh, dmPauseBeforeStopEnv, deviceManagerCmd, dmArgs...)
defer func() {
syscall.Kill(dmh.Pid(), syscall.SIGINT)
+ verifyNoRunningProcesses(t)
}()
servicetest.ReadPID(t, dmh)
@@ -854,6 +855,7 @@
startAppExpectError(t, ctx, appID, impl.ErrInvalidOperation.ID)
// Cleanly shut down the device manager.
+ defer verifyNoRunningProcesses(t)
syscall.Kill(dmh.Pid(), syscall.SIGINT)
dmh.Expect("dm terminated")
dmh.ExpectEOF()
@@ -1006,6 +1008,7 @@
dmh := servicetest.RunCommand(t, sh, nil, deviceManagerCmd, "dm", root, "unused_helper", "unused_app_repo_name", "unused_curr_link")
pid := servicetest.ReadPID(t, dmh)
defer syscall.Kill(pid, syscall.SIGINT)
+ defer verifyNoRunningProcesses(t)
// Create an envelope for an app.
*envelope = envelopeFromShell(sh, nil, appCmd, "google naps")
@@ -1172,6 +1175,7 @@
// Start an instance of the app.
instance1ID := startApp(t, ctx, appID)
+ defer stopApp(t, ctx, appID, instance1ID)
// Wait until the app pings us that it's ready.
select {
@@ -1287,6 +1291,7 @@
dmh := servicetest.RunCommand(t, sh, nil, deviceManagerCmd, "dm", root, helperPath, "unused_app_repo_name", "unused_curr_link")
pid := servicetest.ReadPID(t, dmh)
defer syscall.Kill(pid, syscall.SIGINT)
+ defer verifyNoRunningProcesses(t)
// Create the local server that the app uses to let us know it's ready.
pingCh, cleanup := setupPingServer(t, ctx)
@@ -1323,7 +1328,8 @@
appID := installApp(t, ctx, packages)
// Start an instance of the app.
- startApp(t, ctx, appID)
+ instance1ID := startApp(t, ctx, appID)
+ defer stopApp(t, ctx, appID, instance1ID)
// Wait until the app pings us that it's ready.
select {
@@ -1404,6 +1410,7 @@
dmh := servicetest.RunCommand(t, sh, nil, deviceManagerCmd, "dm", root, "unused_helper", "unused_app_repo_name", "unused_curr_link")
pid := servicetest.ReadPID(t, dmh)
defer syscall.Kill(pid, syscall.SIGINT)
+ defer verifyNoRunningProcesses(t)
deviceStub := device.DeviceClient("dm/device")
// Attempt to list associations on the device manager without having
@@ -1503,6 +1510,7 @@
dmh := servicetest.RunCommand(t, sh, nil, deviceManagerCmd, "-mocksetuid", "dm", root, helperPath, "unused_app_repo_name", "unused_curr_link")
pid := servicetest.ReadPID(t, dmh)
defer syscall.Kill(pid, syscall.SIGINT)
+ defer verifyNoRunningProcesses(t)
// Claim the devicemanager with selfCtx as root/self/alice
claimDevice(t, selfCtx, "dm", "alice", noPairingToken)
diff --git a/services/device/internal/impl/instance_reaping.go b/services/device/internal/impl/instance_reaping.go
index 2c7da8c..f7e9672 100644
--- a/services/device/internal/impl/instance_reaping.go
+++ b/services/device/internal/impl/instance_reaping.go
@@ -30,8 +30,14 @@
type reaper chan pidInstanceDirPair
+var stashedPidMap map[string]int
+
func newReaper(ctx *context.T, root string) (reaper, error) {
pidMap, err := findAllTheInstances(ctx, root)
+
+ // Used only by the testing code that verifies that all processes
+ // have been shutdown.
+ stashedPidMap = pidMap
if err != nil {
return nil, err
}
diff --git a/services/device/internal/impl/instance_reaping_test.go b/services/device/internal/impl/instance_reaping_test.go
index bac5e15..d50d3cc 100644
--- a/services/device/internal/impl/instance_reaping_test.go
+++ b/services/device/internal/impl/instance_reaping_test.go
@@ -78,6 +78,7 @@
// TODO(rjkroege): Exercise the polling loop code.
// Cleanly shut down the device manager.
+ verifyNoRunningProcesses(t)
syscall.Kill(dmh.Pid(), syscall.SIGINT)
dmh.Expect("dm terminated")
dmh.ExpectEOF()
@@ -198,6 +199,7 @@
// TODO(rjkroege): Should be in a defer to ensure that the device
// manager is cleaned up even if the test fails in an exceptional way.
+ verifyNoRunningProcesses(t)
syscall.Kill(dmh.Pid(), syscall.SIGINT)
dmh.Expect("dm terminated")
dmh.ExpectEOF()
diff --git a/services/device/internal/impl/only_for_test.go b/services/device/internal/impl/only_for_test.go
index 23bcc37..583d545 100644
--- a/services/device/internal/impl/only_for_test.go
+++ b/services/device/internal/impl/only_for_test.go
@@ -68,3 +68,9 @@
func WrapBaseCleanupDir(path, helper string) {
baseCleanupDir(path, helper)
}
+
+// RunningChildrenProcesses uses the reaper to verify that a test has
+// successfully shut down all processes.
+func RunningChildrenProcesses() bool {
+ return len(stashedPidMap) > 0
+}
diff --git a/services/device/internal/impl/util_test.go b/services/device/internal/impl/util_test.go
index 3cc4314..3a99927 100644
--- a/services/device/internal/impl/util_test.go
+++ b/services/device/internal/impl/util_test.go
@@ -613,3 +613,9 @@
}
}
+
+func verifyNoRunningProcesses(t *testing.T) {
+ if impl.RunningChildrenProcesses() {
+ t.Errorf("device manager incorrectly terminating with child processes still running")
+ }
+}