From e4c9da01b6a92b9ce26ce4adbb4112e56e480a54 Mon Sep 17 00:00:00 2001 From: Saif Chaudhry Date: Mon, 28 Sep 2026 10:10:45 -0700 Subject: [PATCH] ROX-37266: wait for plop server instead of fixed sleep (#4045) * fix(tests): wait for plop server instead of fixed sleep TestProcessListeningOnPort slept a fixed 5s after starting the flask "plop" container and then made a single request with no retry. Since the GCP ubuntu-2404-lts-amd64 image moved to a newer kernel (around 2026-09-05), flask's first start on that VM often takes longer than 5s, so the suite fails with "connection refused" on ubuntu-os in most runs. ubuntu-2204 binds in 3-5s and has lost the same race too. Flask isn't hung. In the failing runs the container had only been up for 5-6s when the request was made, and in one it had already printed "Serving Flask app". The next suite (TestSymbolicLinkProcess) starts the same image on the same VM and it binds port 5000 within 0-7s. Poll the port for up to 30s instead, so the test waits as long as it needs to and fails with a clear message if the server never comes up. Signed-off-by: Saif Chaudhry * fix: shorten plop readiness timeout to 15s Review feedback: 30s delays the error when the plop container fails to start. CI showed flask binding in up to ~8s on ubuntu-2404, so 15s keeps headroom for slower kernels without a long wait on real failures. Signed-off-by: Saif Chaudhry --------- Signed-off-by: Saif Chaudhry (cherry picked from commit 1b6093dbe4307cd30ada172b8bfdee85822e12dc) Signed-off-by: Saif Chaudhry --- integration-tests/suites/listening_ports.go | 23 ++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/integration-tests/suites/listening_ports.go b/integration-tests/suites/listening_ports.go index 22f45eccbe..77931e9602 100644 --- a/integration-tests/suites/listening_ports.go +++ b/integration-tests/suites/listening_ports.go @@ -3,6 +3,7 @@ package suites import ( "fmt" "io" + "net" "net/http" "sort" "time" @@ -57,10 +58,12 @@ func (s *ProcessListeningOnPortTestSuite) SetupSuite() { ports, err := s.getPorts(serverName) s.Require().NoError(err) - s.serverURL = fmt.Sprintf("http://%s:%d", ip, ports[0]) + serverAddr := net.JoinHostPort(ip, fmt.Sprint(ports[0])) + s.serverURL = "http://" + serverAddr - // Wait 5 seconds for the plop service to start - common.Sleep(5 * time.Second) + // Flask usually binds within a few seconds, but a cold start on some + // VMs (e.g. ubuntu-2404) has been seen to take longer than that. + s.waitForServer(serverAddr, 15*time.Second) log.Info("Opening ports...") s.openPort(8081) @@ -146,6 +149,20 @@ func getProcessListeningOnPortsImage() string { return config.Images().QaImageByKey("qa-plop") } +// waitForServer polls until the plop server accepts TCP connections on addr, +// failing the suite if it doesn't within timeout. +func (s *ProcessListeningOnPortTestSuite) waitForServer(addr string, timeout time.Duration) { + log.Info("Waiting for plop server on %s...", addr) + s.Require().Eventually(func() bool { + conn, err := net.DialTimeout("tcp", addr, time.Second) + if err != nil { + return false + } + conn.Close() + return true + }, timeout, 500*time.Millisecond, "plop server did not start listening on %s within %s", addr, timeout) +} + func (s *ProcessListeningOnPortTestSuite) openPort(port uint16) { res, err := http.Get(fmt.Sprintf("%s/open/%d", s.serverURL, port)) s.Require().NoError(err)