diff --git a/tests/compose_down.go b/tests/compose_down.go index 649f646..1d7d9df 100644 --- a/tests/compose_down.go +++ b/tests/compose_down.go @@ -77,19 +77,30 @@ func createComposeYmlForDownCmd(serviceNames []string, containerNames []string) gomega.Expect(serviceNames).Should(gomega.HaveLen(2)) gomega.Expect(containerNames).Should(gomega.HaveLen(2)) + // Service commands should have SIGTERM handlers so graceful shutdown is quick. composeYmlContent := fmt.Sprintf( ` services: %[1]s: image: "%[3]s" container_name: "%[4]s" - command: sleep infinity + command: | + sh -c " + trap 'echo shutting down; exit 0' SIGTERM + sleep infinity & + wait + " volumes: - compose_data_volume:/usr/local/data %[2]s: image: "%[3]s" container_name: "%[5]s" - command: sleep infinity + command: | + sh -c " + trap 'echo shutting down; exit 0' SIGTERM + sleep infinity & + wait + " volumes: - compose_data_volume:/usr/local/data volumes: diff --git a/tests/compose_kill.go b/tests/compose_kill.go index a471ab9..57a3530 100644 --- a/tests/compose_kill.go +++ b/tests/compose_kill.go @@ -41,13 +41,11 @@ func ComposeKill(o *option.Option) { containerShouldNotBeRunning(o, containerNames...) }) - // With PID=1, `sleep infinity` will only exit when receiving SIGKILL. Default signal for kill is SIGKILL. - // https://stackoverflow.com/questions/45148381/why-cant-i-ctrl-c-a-sleep-infinity-in-docker-when-it-runs-as-pid-1 for _, signal := range []string{"-s", "--signal"} { for _, term := range []string{"SIGTERM", "TERM"} { - ginkgo.It(fmt.Sprintf("should not kill running containers with %s %s", signal, term), func() { + ginkgo.It(fmt.Sprintf("should send %s to containers when using %s", term, signal), func() { command.Run(o, "compose", "kill", signal, term, "--file", composeFilePath) - containerShouldBeRunning(o, containerNames...) + containerShouldNotBeRunning(o, containerNames...) }) } } @@ -58,17 +56,32 @@ func createComposeYmlForKillCmd(serviceNames []string, containerNames []string) gomega.Expect(serviceNames).Should(gomega.HaveLen(2)) gomega.Expect(containerNames).Should(gomega.HaveLen(2)) + // Service commands implement SIGTERM handler to test compose kill + // can send non-default signals. + // + // With PID=1, `sleep infinity` would only exit when receiving SIGKILL. + // https://stackoverflow.com/questions/45148381/why-cant-i-ctrl-c-a-sleep-infinity-in-docker-when-it-runs-as-pid-1 composeYmlContent := fmt.Sprintf( ` services: %[1]s: image: "%[3]s" container_name: "%[4]s" - command: sleep infinity + command: | + sh -c " + trap 'echo shutting down; exit 0' SIGTERM + sleep infinity & + wait + " %[2]s: image: "%[3]s" container_name: "%[5]s" - command: sleep infinity + command: | + sh -c " + trap 'echo shutting down; exit 0' SIGTERM + sleep infinity & + wait + " `, serviceNames[0], serviceNames[1], localImages[defaultImage], containerNames[0], containerNames[1]) return ffs.CreateComposeYmlContext(composeYmlContent) } diff --git a/tests/compose_logs.go b/tests/compose_logs.go index bbfa5d4..29de401 100644 --- a/tests/compose_logs.go +++ b/tests/compose_logs.go @@ -80,17 +80,32 @@ func createComposeYmlForLogsCmd(serviceNames []string, imageNames []string, cont gomega.Expect(imageNames).Should(gomega.HaveLen(2)) gomega.Expect(containerNames).Should(gomega.HaveLen(2)) + // Service commands should have SIGTERM handlers so graceful shutdown is quick. composeYmlContent := fmt.Sprintf( ` services: %[1]s: image: "%[3]s" container_name: "%[5]s" - command: sh -c 'echo "hello from service 1"; echo "again hello"; sleep infinity' + command: | + sh -c " + trap 'echo shutting down; exit 0' SIGTERM + echo 'hello from service 2' + echo 'again hello' + sleep infinity & + wait + " %[2]s: image: "%[4]s" container_name: "%[6]s" - command: sh -c 'echo "hello from service 2"; echo "again hello"; sleep infinity' + command: | + sh -c " + trap 'echo shutting down; exit 0' SIGTERM + echo 'hello from service 2' + echo 'again hello' + sleep infinity & + wait + " `, serviceNames[0], serviceNames[1], imageNames[0], imageNames[1], containerNames[0], containerNames[1]) return ffs.CreateComposeYmlContext(composeYmlContent) }