From 32579ac346b561695c11d405034e23aa8447050b Mon Sep 17 00:00:00 2001 From: i343759 Date: Fri, 9 Oct 2026 12:27:40 +0300 Subject: [PATCH] Increase Eventually timeout for multibuildpack integration tests Fixes consistent failures observed in builds #19-22 of the create-cf-infrastructure-and-execute-integration-test-for-ruby job, where the nodejs multibuildpack test timed out after ~920 seconds across all 5 retry attempts. ## Problem The test `MultiBuildpack/when_supplied_with_nodejs` was using the default 20-second Eventually timeout, which is insufficient for: 1. **Heavy multi-buildpack staging**: The Rails 7.2 + Webpacker app with nodejs-buildpack + ruby-buildpack takes 4-5 minutes to stage - Node.js buildpack downloads Node 22.23.3, Yarn 1.22.22, Python - Yarn install takes ~53 seconds for node_modules - Ruby buildpack downloads Ruby 3.2.11, Bundler 2.7.2, RubyGems - Bundle install processes 78 gems including Rails 7.2.3 - Webpacker/asset compilation 2. **Slow app boot time**: Rails apps with Webpacker can take 60-120 seconds to start and bind their port 3. **Parallel execution resource contention**: Tests run with GINKGO_NODES=3, causing multiple heavy applications to compete for limited CF Diego cell resources ## Solution Extended Eventually timeout to 90 seconds with 2-second poll intervals for all multibuildpack tests: - `when_supplied_with_nodejs` (PRIMARY FIX) - `when_ruby_is_a_supply_for_the_binary_buildpack` - `when_supplied_with_go` - `when_supplied_with_.NET_Core` This matches the precedent established for other slow-booting fixtures: - PR #1140: JRuby test timeouts - Commit d5294b6d: Docker backend timeout fixes for 3 flaky tests ## Testing The fix follows the exact pattern proven successful in d5294b6d, which stated: "The default 20s Eventually timeout has been observed to intermittently race with the Docker platform backend under parallel CI load: the container reports as started before the app process inside has actually finished booting and bound its port." The same issue affects these multi-buildpack tests, particularly the nodejs test with its heavy Rails + Webpacker fixture. --- src/ruby/integration/multibuildpack_test.go | 22 +++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/ruby/integration/multibuildpack_test.go b/src/ruby/integration/multibuildpack_test.go index 6908fd9aa..b0fe52891 100644 --- a/src/ruby/integration/multibuildpack_test.go +++ b/src/ruby/integration/multibuildpack_test.go @@ -3,6 +3,7 @@ package integration_test import ( "path/filepath" "testing" + "time" "github.com/cloudfoundry/switchblade" "github.com/sclevine/spec" @@ -43,7 +44,9 @@ func testMultiBuildpack(platform switchblade.Platform, fixtures string) func(*te deployment, _, err := deploymentProcess.Execute(name, filepath.Join(fixtures, "multibuildpack", "no_gemfile")) Expect(err).NotTo(HaveOccurred()) - Eventually(deployment).Should(Serve(MatchRegexp(`Ruby Version: \d+\.\d+\.\d+`))) + // Extended timeout for multi-buildpack deployment consistency, + // matching the pattern established in d5294b6d. + Eventually(deployment, 90*time.Second, 2*time.Second).Should(Serve(MatchRegexp(`Ruby Version: \d+\.\d+\.\d+`))) }) }) @@ -57,8 +60,13 @@ func testMultiBuildpack(platform switchblade.Platform, fixtures string) func(*te Execute(name, filepath.Join(fixtures, "multibuildpack", "rails72")) Expect(err).NotTo(HaveOccurred()) - Eventually(deployment).Should(Serve(ContainSubstring("Ruby version: ruby 3."))) - Eventually(deployment).Should(Serve(MatchRegexp(`Node version: v\d+\.\d+\.\d+`))) + // The default 20s Eventually timeout has been observed to be insufficient for + // this heavy multi-buildpack Rails 7.2 + Webpacker app, especially under + // parallel test execution. Staging alone takes 4-5 minutes, and app boot can + // take 60-120s. Extended timeout matches the pattern established for JRuby + // (#1140) and other slow-booting fixtures (d5294b6d). + Eventually(deployment, 90*time.Second, 2*time.Second).Should(Serve(ContainSubstring("Ruby version: ruby 3."))) + Eventually(deployment, 90*time.Second, 2*time.Second).Should(Serve(MatchRegexp(`Node version: v\d+\.\d+\.\d+`))) }) }) @@ -72,8 +80,9 @@ func testMultiBuildpack(platform switchblade.Platform, fixtures string) func(*te Execute(name, filepath.Join(fixtures, "multibuildpack", "ruby_calls_go")) Expect(err).NotTo(HaveOccurred()) - Eventually(deployment).Should(Serve(MatchRegexp(`RUBY_VERSION IS \d+\.\d+\.\d+`))) - Eventually(deployment).Should(Serve(MatchRegexp(`go version go\d+\.\d+(\.\d+)?`))) + // Extended timeout for multi-buildpack deployment consistency. + Eventually(deployment, 90*time.Second, 2*time.Second).Should(Serve(MatchRegexp(`RUBY_VERSION IS \d+\.\d+\.\d+`))) + Eventually(deployment, 90*time.Second, 2*time.Second).Should(Serve(MatchRegexp(`go version go\d+\.\d+(\.\d+)?`))) }) }) @@ -87,7 +96,8 @@ func testMultiBuildpack(platform switchblade.Platform, fixtures string) func(*te Execute(name, filepath.Join(fixtures, "multibuildpack", "dotnet_core")) Expect(err).NotTo(HaveOccurred()) - Eventually(deployment).Should(Serve(MatchRegexp(`dotnet: \d+\.\d+\.\d+`))) + // Extended timeout for multi-buildpack deployment consistency. + Eventually(deployment, 90*time.Second, 2*time.Second).Should(Serve(MatchRegexp(`dotnet: \d+\.\d+\.\d+`))) }) }) }