From 6d5a432c2e6e538308961b9c130c3aeb32138c7b Mon Sep 17 00:00:00 2001
From: Ed Santiago <santiago@redhat.com>
Date: Wed, 17 Jun 2020 05:51:04 -0600
Subject: "streaming output" logs test: fix flake

Test has been flaking excessively. A quick look shows that
the test itself is broken, making a bad assumption.

'podman logs -f' is guaranteed to exit when a container
terminates. This does not (and should not) mean that the
container has been cleaned up. It is undefined and unsafe
to run 'podman run -n same-name-as-terminated-container'
immediately after 'podman logs' exits.

Solution: instead of 'podman run', do 'podman inspect'.
This, too, is unsafe, but we can expect to see one of
two possible conditions:

  1) command succeeds, in which case we require that
     container State.Status be "exited"; or
  2) command fails, in which case we expect "no such
     container" in error output

For full coverage we should add a small delay-check test
to (1) to ensure that the container is cleaned up after
a short amount of time. Leaving that as a TODO because
it's more than my Go skills can handle, and I want to
get this checked in ASAP to get rid of the flake hassle.

Signed-off-by: Ed Santiago <santiago@redhat.com>
---
 test/e2e/logs_test.go | 20 ++++++++++++++++----
 1 file changed, 16 insertions(+), 4 deletions(-)

(limited to 'test')

diff --git a/test/e2e/logs_test.go b/test/e2e/logs_test.go
index f9446e0c6..5d8ce24e9 100644
--- a/test/e2e/logs_test.go
+++ b/test/e2e/logs_test.go
@@ -283,10 +283,22 @@ var _ = Describe("Podman logs", func() {
 		results.WaitWithDefaultTimeout()
 		Expect(results).To(Exit(0))
 
-		// Verify that the cleanup process worked correctly and we can recreate a container with the same name
-		logc = podmanTest.Podman([]string{"run", "--rm", "--name", containerName, "-dt", ALPINE, "true"})
-		logc.WaitWithDefaultTimeout()
-		Expect(logc).To(Exit(0))
+		// TODO: we should actually check for two podman lines,
+		// but as of 2020-06-17 there's a race condition in which
+		// 'logs -f' may not catch all output from a container
+		Expect(results.OutputToString()).To(ContainSubstring("podman"))
+
+		// Container should now be terminatING or terminatED, but we
+		// have no guarantee of which: 'logs -f' does not necessarily
+		// wait for cleanup. Run 'inspect' and accept either state.
+		inspect := podmanTest.Podman([]string{"container", "inspect", "--format", "{{.State.Status}}", containerName})
+		inspect.WaitWithDefaultTimeout()
+		if inspect.ExitCode() == 0 {
+			Expect(inspect.OutputToString()).To(Equal("exited"))
+			// TODO: add 2-second wait loop to confirm cleanup
+		} else {
+			Expect(inspect.ErrorToString()).To(ContainSubstring("no such container"))
+		}
 	})
 
 	It("follow output stopped container", func() {
-- 
cgit v1.2.3-54-g00ecf