From 28934897e3cf0cc0874b8ff5e69933cd8baaf35e Mon Sep 17 00:00:00 2001 From: Ed Santiago Date: Thu, 1 Jun 2023 15:42:21 -0600 Subject: [PATCH] e2e: GetPort(): safer allocation of random ports Intented to fix an obscure, unlikely race condition in which (I think) two parallel jobs called GetPort() and were assigned the same port. Also, add actual proper testing to two HTTP-registry tests, and Skip a third that's a waste of cycles (filed #18768) Signed-off-by: Ed Santiago --- test/e2e/common_test.go | 32 ++++++++++++++++++++++---------- test/e2e/search_test.go | 5 +++-- 2 files changed, 25 insertions(+), 12 deletions(-) diff --git a/test/e2e/common_test.go b/test/e2e/common_test.go index d48845fc99..78334d4814 100644 --- a/test/e2e/common_test.go +++ b/test/e2e/common_test.go @@ -1221,19 +1221,31 @@ func writeYaml(content string, fileName string) error { return nil } -// GetPort finds an unused port on the system +// GetPort finds an unused TCP/IP port on the system, in the range 5000-5999 func GetPort() int { - a, err := net.ResolveTCPAddr("tcp", "localhost:0") - if err != nil { - Fail(fmt.Sprintf("unable to get free port: %v", err)) + portMin := 5000 + portMax := 5999 + rng := rand.New(rand.NewSource(time.Now().UnixNano())) + + // Avoid dup-allocation races between parallel ginkgo processes + nProcs := GinkgoT().ParallelTotal() + myProc := GinkgoT().ParallelProcess() - 1 + + for i := 0; i < 50; i++ { + // Random port within that range + port := portMin + rng.Intn((portMax-portMin)/nProcs)*nProcs + myProc + + used, err := net.Listen("tcp", "localhost:"+strconv.Itoa(port)) + if err == nil { + // it's open. Return it. + err = used.Close() + Expect(err).ToNot(HaveOccurred(), "closing random port") + return port + } } - l, err := net.ListenTCP("tcp", a) - if err != nil { - Fail(fmt.Sprintf("unable to get free port: %v", err)) - } - defer l.Close() - return l.Addr().(*net.TCPAddr).Port + Fail(fmt.Sprintf("unable to get free port: %v", err)) + return 0 // notreached } func ncz(port int) bool { diff --git a/test/e2e/search_test.go b/test/e2e/search_test.go index 71ff2b586e..2d7ccf2ad3 100644 --- a/test/e2e/search_test.go +++ b/test/e2e/search_test.go @@ -318,7 +318,7 @@ registries = ['{{.Host}}:{{.Port}}']` Expect(search).Should(Exit(125)) Expect(search.OutputToString()).Should(BeEmpty()) - Expect(search.ErrorToString()).To(ContainSubstring("error")) + Expect(search.ErrorToString()).To(ContainSubstring("http: server gave HTTP response to HTTPS client")) // cleanup resetRegistriesConfigEnv() @@ -363,13 +363,14 @@ registries = ['{{.Host}}:{{.Port}}']` Expect(search).Should(Exit(125)) Expect(search.OutputToString()).Should(BeEmpty()) - Expect(search.ErrorToString()).To(ContainSubstring("error")) + Expect(search.ErrorToString()).To(ContainSubstring("http: server gave HTTP response to HTTPS client")) // cleanup resetRegistriesConfigEnv() }) It("podman search doesn't attempt HTTP if one registry is not listed as insecure", func() { + Skip("FIXME FIXME FIXME #18768: This test is a NOP") if podmanTest.Host.Arch == "ppc64le" { Skip("No registry image for ppc64le") }