From fca8070882a672f270bc28d61d9a8dec1f1d791f Mon Sep 17 00:00:00 2001 From: Lukas Krejci Date: Wed, 18 Sep 2024 18:43:15 +0200 Subject: [PATCH 1/2] Update the Perl image to the oldest one available in the image stream. Because perl:5.32 image no longer supports the PERL_APACHE2_RELOAD env var, the portion of the test that tests the ability to switch off hot-deploy has been removed. --- test/extended/image_ecosystem/s2i_perl.go | 51 ++++--------------- test/extended/testdata/bindata.go | 2 +- .../image_ecosystem/perl-hotdeploy/perl.json | 2 +- 3 files changed, 11 insertions(+), 44 deletions(-) diff --git a/test/extended/image_ecosystem/s2i_perl.go b/test/extended/image_ecosystem/s2i_perl.go index 5146b260f5a4..d15959a81a13 100644 --- a/test/extended/image_ecosystem/s2i_perl.go +++ b/test/extended/image_ecosystem/s2i_perl.go @@ -3,7 +3,7 @@ package image_ecosystem import ( "context" "fmt" - "strings" + "os" "time" g "github.com/onsi/ginkgo/v2" @@ -11,7 +11,6 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" - "k8s.io/apimachinery/pkg/util/wait" e2e "k8s.io/kubernetes/test/e2e/framework" exutil "github.com/openshift/origin/test/extended/util" @@ -45,9 +44,7 @@ var _ = g.Describe("[sig-devex][Feature:ImageEcosystem][perl][Slow] hot deploy f modifyCommand = []string{"sed", "-ie", `s/initial value/modified value/`, "lib/My/Test.pm"} dcName = "perl" rcNameOne = fmt.Sprintf("%s-1", dcName) - rcNameTwo = fmt.Sprintf("%s-2", dcName) dcLabelOne = exutil.ParseLabelsOrDie(fmt.Sprintf("deployment=%s", rcNameOne)) - dcLabelTwo = exutil.ParseLabelsOrDie(fmt.Sprintf("deployment=%s", rcNameTwo)) ) g.Context("", func() { @@ -69,9 +66,14 @@ var _ = g.Describe("[sig-devex][Feature:ImageEcosystem][perl][Slow] hot deploy f if !archHasModPerl(oc) { g.Skip("mod_perl based builder image is not available on arm64") } + // Make sure the index.pl is executable in the fixture assets as it is in the sources. + // (FixturePath resets the perms on the files) + err := os.Chmod(exutil.FixturePath("testdata", "image_ecosystem", "perl-hotdeploy", "index.pl"), os.FileMode(0o755)) + o.Expect(err).NotTo(o.HaveOccurred()) + exutil.WaitForOpenShiftNamespaceImageStreams(oc) g.By(fmt.Sprintf("calling oc new-app -f %q", perlTemplate)) - err := oc.Run("new-app").Args("-f", perlTemplate, "-e", "HTTPD_START_SERVERS=1", "-e", "HTTPD_MAX_SPARE_SERVERS=1", "-e", "HTTPD_MAX_REQUEST_WORKERS=1").Execute() + err = oc.Run("new-app").Args("-f", perlTemplate, "-e", "HTTPD_START_SERVERS=1", "-e", "HTTPD_MAX_SPARE_SERVERS=1", "-e", "HTTPD_MAX_REQUEST_WORKERS=1").Execute() o.Expect(err).NotTo(o.HaveOccurred()) br, err := exutil.StartBuildAndWait(oc, "perl", fmt.Sprintf("--from-dir=%s", appSource)) @@ -91,8 +93,6 @@ var _ = g.Describe("[sig-devex][Feature:ImageEcosystem][perl][Slow] hot deploy f g.By("waiting for endpoint") err = exutil.WaitForEndpoint(oc.KubeFramework().ClientSet, oc.Namespace(), dcName) o.Expect(err).NotTo(o.HaveOccurred()) - oldEndpoint, err := oc.KubeFramework().ClientSet.CoreV1().Endpoints(oc.Namespace()).Get(context.Background(), dcName, metav1.GetOptions{}) - o.Expect(err).NotTo(o.HaveOccurred()) checkPage := func(expected string, dcLabel labels.Selector) { _, err := exutil.WaitForPods(oc.KubeClient().CoreV1().Pods(oc.Namespace()), dcLabel, exutil.CheckPodIsRunning, 1, 4*time.Minute) @@ -104,45 +104,12 @@ var _ = g.Describe("[sig-devex][Feature:ImageEcosystem][perl][Slow] hot deploy f checkPage("initial value", dcLabelOne) - g.By("modifying the source code with disabled hot deploy") + g.By("modifying the source code") err = RunInPodContainer(oc, dcLabelOne, modifyCommand) o.Expect(err).NotTo(o.HaveOccurred()) - checkPage("initial value", dcLabelOne) - - g.By("turning on hot-deploy") - err = oc.Run("set", "env").Args("dc", dcName, "PERL_APACHE2_RELOAD=true").Execute() - o.Expect(err).NotTo(o.HaveOccurred()) - err = exutil.WaitForDeploymentConfig(oc.KubeClient(), oc.AppsClient().AppsV1(), oc.Namespace(), dcName, 2, true, oc) - o.Expect(err).NotTo(o.HaveOccurred()) - g.By("waiting for a new endpoint") - err = exutil.WaitForEndpoint(oc.KubeFramework().ClientSet, oc.Namespace(), dcName) - o.Expect(err).NotTo(o.HaveOccurred()) - - // Ran into an issue where we'd try to hit the endpoint before it was updated, resulting in - // request timeouts against the previous pod's ip. So make sure the endpoint is pointing to the - // new pod before hitting it. - err = wait.Poll(1*time.Second, 1*time.Minute, func() (bool, error) { - newEndpoint, err := oc.KubeFramework().ClientSet.CoreV1().Endpoints(oc.Namespace()).Get(context.Background(), dcName, metav1.GetOptions{}) - if err != nil { - return false, err - } - if !strings.Contains(newEndpoint.Subsets[0].Addresses[0].TargetRef.Name, rcNameTwo) { - e2e.Logf("waiting on endpoint address ref %s to contain %s", newEndpoint.Subsets[0].Addresses[0].TargetRef.Name, rcNameTwo) - return false, nil - } - e2e.Logf("old endpoint was %#v, new endpoint is %#v", oldEndpoint, newEndpoint) - return true, nil - }) - o.Expect(err).NotTo(o.HaveOccurred()) - - g.By("modifying the source code with enabled hot deploy") - checkPage("initial value", dcLabelTwo) - err = RunInPodContainer(oc, dcLabelTwo, modifyCommand) - o.Expect(err).NotTo(o.HaveOccurred()) - checkPage("modified value", dcLabelTwo) + checkPage("modified value", dcLabelOne) }) }) - }) }) diff --git a/test/extended/testdata/bindata.go b/test/extended/testdata/bindata.go index 6c538463e697..29cc42fa7f3c 100644 --- a/test/extended/testdata/bindata.go +++ b/test/extended/testdata/bindata.go @@ -45639,7 +45639,7 @@ var _testExtendedTestdataImage_ecosystemPerlHotdeployPerlJson = []byte(`{ "from": { "kind": "ImageStreamTag", "namespace": "openshift", - "name": "perl:5.30-el7" + "name": "perl:5.32-ubi8" } } }, diff --git a/test/extended/testdata/image_ecosystem/perl-hotdeploy/perl.json b/test/extended/testdata/image_ecosystem/perl-hotdeploy/perl.json index bfa366f66417..0c4bd702e33c 100644 --- a/test/extended/testdata/image_ecosystem/perl-hotdeploy/perl.json +++ b/test/extended/testdata/image_ecosystem/perl-hotdeploy/perl.json @@ -47,7 +47,7 @@ "from": { "kind": "ImageStreamTag", "namespace": "openshift", - "name": "perl:5.30-el7" + "name": "perl:5.32-ubi8" } } }, From 01239a2d9b2b96f6ecda6667ff5fe39f9a96ccae Mon Sep 17 00:00:00 2001 From: Lukas Krejci Date: Thu, 12 Sep 2024 11:06:27 +0200 Subject: [PATCH 2/2] Re-enable the s2i rails test and update it to also support samples with Deployments instead of DeploymentConfigs. This should enable us using either the old templates in 4.16 stream that use DeploymentConfigs and the new templates in 4.17+ that use Deployments. --- test/extended/image_ecosystem/s2i_ruby.go | 104 ++++++++---------- test/extended/image_ecosystem/sample_repos.go | 46 +++++--- test/extended/util/deployment.go | 24 +++- test/extended/util/framework.go | 21 ++-- 4 files changed, 106 insertions(+), 89 deletions(-) diff --git a/test/extended/image_ecosystem/s2i_ruby.go b/test/extended/image_ecosystem/s2i_ruby.go index 288e6fed31fe..85435de2f965 100644 --- a/test/extended/image_ecosystem/s2i_ruby.go +++ b/test/extended/image_ecosystem/s2i_ruby.go @@ -1,34 +1,24 @@ package image_ecosystem import ( - "context" "fmt" - "strings" "time" g "github.com/onsi/ginkgo/v2" o "github.com/onsi/gomega" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/apimachinery/pkg/util/wait" - e2e "k8s.io/kubernetes/test/e2e/framework" - exutil "github.com/openshift/origin/test/extended/util" ) var _ = g.Describe("[sig-devex][Feature:ImageEcosystem][ruby][Slow] hot deploy for openshift ruby image", func() { defer g.GinkgoRecover() var ( - railsTemplate = "rails-postgresql-example" - oc = exutil.NewCLI("s2i-ruby") - modifyCommand = []string{"sed", "-ie", `s%render :file => 'public/index.html'%%`, "app/controllers/welcome_controller.rb"} - removeCommand = []string{"rm", "-f", "public/index.html"} - dcName = "rails-postgresql-example" - rcNameOne = fmt.Sprintf("%s-1", dcName) - rcNameTwo = fmt.Sprintf("%s-2", dcName) - dcLabelOne = exutil.ParseLabelsOrDie(fmt.Sprintf("deployment=%s", rcNameOne)) - dcLabelTwo = exutil.ParseLabelsOrDie(fmt.Sprintf("deployment=%s", rcNameTwo)) + railsTemplate = "rails-postgresql-example" + oc = exutil.NewCLI("s2i-ruby") + modifyCommand = []string{"sed", "-ie", `s%render :file => 'public/index.html'%%`, "app/controllers/welcome_controller.rb"} + removeCommand = []string{"rm", "-f", "public/index.html"} + deploymentName = "rails-postgresql-example" + podLabel = exutil.ParseLabelsOrDie(fmt.Sprintf("name=%s", deploymentName)) ) g.Context("", func() { @@ -45,36 +35,32 @@ var _ = g.Describe("[sig-devex][Feature:ImageEcosystem][ruby][Slow] hot deploy f g.Describe("Rails example", func() { g.It(fmt.Sprintf("should work with hot deploy [apigroup:image.openshift.io][apigroup:operator.openshift.io][apigroup:config.openshift.io][apigroup:build.openshift.io]"), func() { - // The rails sample is not supported in the Samples operator and has bitrotten. Let's skip the test but keep the test code around - // just in case the sample gets resurrected in the future. - g.Skip("The rails-postgresql-example is not working anymore and is not supported by the samples operator (since OCP 4.16) so let's not use it for tests.") - exutil.WaitForOpenShiftNamespaceImageStreams(oc) g.By(fmt.Sprintf("calling oc new-app %q", railsTemplate)) err := oc.Run("new-app").Args(railsTemplate).Execute() o.Expect(err).NotTo(o.HaveOccurred()) g.By("waiting for build to finish") - err = exutil.WaitForABuild(oc.BuildClient().BuildV1().Builds(oc.Namespace()), rcNameOne, nil, nil, nil) + // This example seems to be taking quite some time, so let's use custom timeouts + err = exutil.WaitForABuildWithTimeout(oc.BuildClient().BuildV1().Builds(oc.Namespace()), deploymentName+"-1", 5*time.Minute, 15*time.Minute, nil, nil, nil) if err != nil { - exutil.DumpBuildLogs(dcName, oc) + exutil.DumpBuildLogs(deploymentName, oc) } + o.Expect(err).NotTo(o.HaveOccurred()) - err = exutil.WaitForDeploymentConfig(oc.KubeClient(), oc.AppsClient().AppsV1(), oc.Namespace(), dcName, 1, true, oc) + err = exutil.WaitForDeploymentReadyWithTimeout(oc, deploymentName, oc.Namespace(), 15*time.Minute) o.Expect(err).NotTo(o.HaveOccurred()) g.By("waiting for endpoint") - err = exutil.WaitForEndpoint(oc.KubeFramework().ClientSet, oc.Namespace(), dcName) - o.Expect(err).NotTo(o.HaveOccurred()) - oldEndpoint, err := oc.KubeFramework().ClientSet.CoreV1().Endpoints(oc.Namespace()).Get(context.Background(), dcName, metav1.GetOptions{}) + err = exutil.WaitForEndpoint(oc.KubeFramework().ClientSet, oc.Namespace(), deploymentName) o.Expect(err).NotTo(o.HaveOccurred()) - assertPageContent := func(content string, dcLabel labels.Selector) { - _, err := exutil.WaitForPods(oc.KubeClient().CoreV1().Pods(oc.Namespace()), dcLabel, exutil.CheckPodIsRunning, 1, 4*time.Minute) + assertPageContent := func(content string) { + _, err := exutil.WaitForPods(oc.KubeClient().CoreV1().Pods(oc.Namespace()), podLabel, exutil.CheckPodIsRunning, 1, 4*time.Minute) o.ExpectWithOffset(1, err).NotTo(o.HaveOccurred()) - result, err := CheckPageContains(oc, dcName, "", content) + result, err := CheckPageContains(oc, deploymentName, "", content) o.ExpectWithOffset(1, err).NotTo(o.HaveOccurred()) o.ExpectWithOffset(1, result).To(o.BeTrue()) } @@ -82,53 +68,53 @@ var _ = g.Describe("[sig-devex][Feature:ImageEcosystem][ruby][Slow] hot deploy f // with hot deploy disabled, making a change to // welcome_controller.rb should not affect the app g.By("testing application content") - assertPageContent("Welcome to your Rails application on OpenShift", dcLabelOne) + assertPageContent("Welcome to your Rails application on OpenShift") g.By("modifying the source code with disabled hot deploy") - err = RunInPodContainer(oc, dcLabelOne, modifyCommand) + err = RunInPodContainer(oc, podLabel, modifyCommand) o.Expect(err).NotTo(o.HaveOccurred()) g.By("testing application content source modification") - assertPageContent("Welcome to your Rails application on OpenShift", dcLabelOne) - - pods, err := oc.KubeClient().CoreV1().Pods(oc.Namespace()).List(context.Background(), metav1.ListOptions{LabelSelector: dcLabelOne.String()}) - o.Expect(err).NotTo(o.HaveOccurred()) - o.Expect(len(pods.Items)).To(o.Equal(1)) + assertPageContent("Welcome to your Rails application on OpenShift") g.By("turning on hot-deploy") - err = oc.Run("set", "env").Args("dc", dcName, "RAILS_ENV=development").Execute() + err = oc.Run("set", "env").Args("deployment", deploymentName, "RAILS_ENV=development").Execute() o.Expect(err).NotTo(o.HaveOccurred()) - err = exutil.WaitForDeploymentConfig(oc.KubeClient(), oc.AppsClient().AppsV1(), oc.Namespace(), dcName, 2, true, oc) + err = exutil.WaitForDeploymentReady(oc, deploymentName, oc.Namespace()) o.Expect(err).NotTo(o.HaveOccurred()) g.By("waiting for a new endpoint") - err = exutil.WaitForEndpoint(oc.KubeFramework().ClientSet, oc.Namespace(), dcName) + err = exutil.WaitForEndpoint(oc.KubeFramework().ClientSet, oc.Namespace(), deploymentName) o.Expect(err).NotTo(o.HaveOccurred()) - // Ran into an issue where we'd try to hit the endpoint before it was updated, resulting in - // request timeouts against the previous pod's ip. So make sure the endpoint is pointing to the - // new pod before hitting it. - err = wait.Poll(1*time.Second, 1*time.Minute, func() (bool, error) { - newEndpoint, err := oc.KubeFramework().ClientSet.CoreV1().Endpoints(oc.Namespace()).Get(context.Background(), dcName, metav1.GetOptions{}) - if err != nil { - return false, err - } - if !strings.Contains(newEndpoint.Subsets[0].Addresses[0].TargetRef.Name, rcNameTwo) { - e2e.Logf("waiting on endpoint address ref %s to contain %s", newEndpoint.Subsets[0].Addresses[0].TargetRef.Name, rcNameTwo) - return false, nil - } - e2e.Logf("old endpoint was %#v, new endpoint is %#v", oldEndpoint, newEndpoint) - return true, nil - }) - o.Expect(err).NotTo(o.HaveOccurred()) + // NOTE: The code below was here when the test was based on DeploymentConfig. The deployments seem to exhibit a different behavior + // where the deployment is not ready until the pods and endpoints have transitioned to the new replica set. Therefore, I'm commenting this + // out. If we ever encounter spurious errors here, we can learn from how the situation was handled with the DeploymentConfigs. + // + // // Ran into an issue where we'd try to hit the endpoint before it was updated, resulting in + // // request timeouts against the previous pod's ip. So make sure the endpoint is pointing to the + // // new pod before hitting it. + // err = wait.Poll(1*time.Second, 1*time.Minute, func() (bool, error) { + // newEndpoint, err := oc.KubeFramework().ClientSet.CoreV1().Endpoints(oc.Namespace()).Get(context.Background(), dcName, metav1.GetOptions{}) + // if err != nil { + // return false, err + // } + // if !strings.Contains(newEndpoint.Subsets[0].Addresses[0].TargetRef.Name, rcNameTwo) { + // e2e.Logf("waiting on endpoint address ref %s to contain %s", newEndpoint.Subsets[0].Addresses[0].TargetRef.Name, rcNameTwo) + // return false, nil + // } + // e2e.Logf("old endpoint was %#v, new endpoint is %#v", oldEndpoint, newEndpoint) + // return true, nil + // }) + // o.Expect(err).NotTo(o.HaveOccurred()) // now hot deploy is enabled, a change to welcome_controller.rb // should affect the app g.By("modifying the source code with enabled hot deploy") - assertPageContent("Welcome to your Rails application on OpenShift", dcLabelTwo) - err = RunInPodContainer(oc, dcLabelTwo, modifyCommand) + assertPageContent("Welcome to your Rails application on OpenShift") + err = RunInPodContainer(oc, podLabel, modifyCommand) o.Expect(err).NotTo(o.HaveOccurred()) - err = RunInPodContainer(oc, dcLabelTwo, removeCommand) + err = RunInPodContainer(oc, podLabel, removeCommand) o.Expect(err).NotTo(o.HaveOccurred()) - assertPageContent("Hello, Rails!", dcLabelTwo) + assertPageContent("Hello, Rails!") }) }) }) diff --git a/test/extended/image_ecosystem/sample_repos.go b/test/extended/image_ecosystem/sample_repos.go index d5d50e513566..210f2292bb74 100644 --- a/test/extended/image_ecosystem/sample_repos.go +++ b/test/extended/image_ecosystem/sample_repos.go @@ -23,9 +23,11 @@ type sampleRepoConfig struct { buildConfigName string serviceName string deploymentConfigName string + deploymentName string expectedString string appPath string dbDeploymentConfigName string + dbDeploymentName string dbServiceName string newAppParams string } @@ -36,7 +38,7 @@ type sampleRepoConfig struct { func NewSampleRepoTest(c sampleRepoConfig) func() { return func() { defer g.GinkgoRecover() - var oc = exutil.NewCLI(c.repoName + "-repo-test") + oc := exutil.NewCLI(c.repoName + "-repo-test") g.Context("", func() { g.BeforeEach(func() { @@ -52,7 +54,6 @@ func NewSampleRepoTest(c sampleRepoConfig) func() { g.Describe("Building "+c.repoName+" app from new-app", func() { g.It(fmt.Sprintf("should build a "+c.repoName+" image and run it in a pod [apigroup:build.openshift.io]"), func() { - err := exutil.WaitForOpenShiftNamespaceImageStreams(oc) o.Expect(err).NotTo(o.HaveOccurred()) g.By(fmt.Sprintf("calling oc new-app with the " + c.repoName + " example template")) @@ -76,12 +77,25 @@ func NewSampleRepoTest(c sampleRepoConfig) func() { o.Expect(err).NotTo(o.HaveOccurred()) g.By("expecting the app deployment to be complete") - err = exutil.WaitForDeploymentConfig(oc.KubeClient(), oc.AppsClient().AppsV1(), oc.Namespace(), c.deploymentConfigName, 1, true, oc) + + if c.deploymentConfigName != "" { + err = exutil.WaitForDeploymentConfig(oc.KubeClient(), oc.AppsClient().AppsV1(), oc.Namespace(), c.deploymentConfigName, 1, true, oc) + } else if c.deploymentName != "" { + err = exutil.WaitForDeploymentReadyWithTimeout(oc, c.deploymentName, oc.Namespace(), 15*time.Minute) + } else { + g.Fail("invalid test configuration: neither deploymentConfigName nor deploymentName is set") + } o.Expect(err).NotTo(o.HaveOccurred()) if len(c.dbDeploymentConfigName) > 0 { g.By("expecting the db deployment to be complete") - err = exutil.WaitForDeploymentConfig(oc.KubeClient(), oc.AppsClient().AppsV1(), oc.Namespace(), c.dbDeploymentConfigName, 1, true, oc) + if c.dbDeploymentConfigName != "" { + err = exutil.WaitForDeploymentConfig(oc.KubeClient(), oc.AppsClient().AppsV1(), oc.Namespace(), c.dbDeploymentConfigName, 1, true, oc) + } else if c.dbDeploymentName != "" { + err = exutil.WaitForDeploymentReadyWithTimeout(oc, c.dbDeploymentName, oc.Namespace(), 15*time.Minute) + } else { + g.Fail("invalid test configuration: neither dbDeploymentConfigName nor dbDeploymentName is set") + } o.Expect(err).NotTo(o.HaveOccurred()) g.By("expecting the db service is available") @@ -124,19 +138,18 @@ func NewSampleRepoTest(c sampleRepoConfig) func() { } var _ = g.Describe("[sig-devex][Feature:ImageEcosystem][Slow] openshift sample application repositories", func() { - g.Describe("[sig-devex][Feature:ImageEcosystem][ruby] test ruby images with rails-ex db repo", NewSampleRepoTest( sampleRepoConfig{ - repoName: "rails-postgresql", - templateURL: "rails-postgresql-example", - buildConfigName: "rails-postgresql-example", - serviceName: "rails-postgresql-example", - deploymentConfigName: "rails-postgresql-example", - expectedString: "Listing articles", - appPath: "/articles", - dbDeploymentConfigName: "postgresql", - dbServiceName: "postgresql", - newAppParams: "APPLICATION_DOMAIN=rails-%s.ocp.io", + repoName: "rails-postgresql", + templateURL: "rails-postgresql-example", + buildConfigName: "rails-postgresql-example", + serviceName: "rails-postgresql-example", + deploymentName: "rails-postgresql-example", + expectedString: "Listing articles", + appPath: "/articles", + dbDeploymentName: "postgresql", + dbServiceName: "postgresql", + newAppParams: "APPLICATION_DOMAIN=rails-%s.ocp.io", }, )) @@ -170,7 +183,7 @@ var _ = g.Describe("[sig-devex][Feature:ImageEcosystem][Slow] openshift sample a }, )) - var _ = g.Describe("[sig-devex][Feature:ImageEcosystem][php] test php images with cakephp-ex db repo", NewSampleRepoTest( + _ = g.Describe("[sig-devex][Feature:ImageEcosystem][php] test php images with cakephp-ex db repo", NewSampleRepoTest( sampleRepoConfig{ repoName: "cakephp-mysql", templateURL: "cakephp-mysql-example", @@ -214,5 +227,4 @@ var _ = g.Describe("[sig-devex][Feature:ImageEcosystem][Slow] openshift sample a dbServiceName: "", }, ))*/ - }) diff --git a/test/extended/util/deployment.go b/test/extended/util/deployment.go index 6fb19c6b64d5..0d74d635e5dd 100644 --- a/test/extended/util/deployment.go +++ b/test/extended/util/deployment.go @@ -32,18 +32,30 @@ func GetDeploymentTemplateAnnotations(oc *CLI, deployName, namespace string) map // WaitForDeploymentReady waits for the deployment become ready func WaitForDeploymentReady(oc *CLI, deployName, namespace string) error { + return WaitForDeploymentReadyWithTimeout(oc, deployName, namespace, defaultMaxWaitingTime) +} + +// WaitForDeploymentReadyWithTimeout waits for the deployment become ready with defined timeout +func WaitForDeploymentReadyWithTimeout(oc *CLI, deployName, namespace string, timeout time.Duration) error { var ( deployment *v1.Deployment labelSelector string getErr error ) - pollErr := wait.PollUntilContextTimeout(context.Background(), defaultPollingTime, defaultMaxWaitingTime, true, func(context.Context) (isReady bool, err error) { + pollErr := wait.PollUntilContextTimeout(context.Background(), defaultPollingTime, timeout, true, func(context.Context) (isReady bool, err error) { deployment, getErr = oc.AdminKubeClient().AppsV1().Deployments(namespace).Get(context.Background(), deployName, metav1.GetOptions{}) if getErr != nil { e2e.Logf("Unable to retrieve deployment %q:\n%v", deployName, getErr) + return false, nil } if deployment.Status.AvailableReplicas == *deployment.Spec.Replicas { + descOutput, err := oc.AsAdmin().Run("describe").WithoutNamespace().Args("deployment/"+deployment.Name, "-n", deployment.Namespace).Output() e2e.Logf("Deployment %q is ready", deployName) + if err != nil { + e2e.Logf("Failed to describe the deployment %q", deployName) + } else { + e2e.Logf("Describing deployment %s/%s\n%s\n\n:", deployment.Name, deployment.Namespace, descOutput) + } return true, nil } e2e.Logf("Deployment %q is still unready, available replicas %d/%d", deployName, deployment.Status.AvailableReplicas, *deployment.Spec.Replicas) @@ -52,11 +64,13 @@ func WaitForDeploymentReady(oc *CLI, deployName, namespace string) error { if pollErr != nil { e2e.Logf("Waiting for deployment %s ready timeout", deployName) - for key, value := range deployment.Spec.Selector.MatchLabels { - labelSelector = fmt.Sprintf("%s=%s", key, value) - break + if deployment != nil && deployment.Spec.Selector != nil { + for key, value := range deployment.Spec.Selector.MatchLabels { + labelSelector = fmt.Sprintf("%s=%s", key, value) + break + } + DumpDeploymentPodsLogs(oc, deployName, namespace, labelSelector) } - DumpDeploymentPodsLogs(oc, deployName, namespace, labelSelector) } return pollErr } diff --git a/test/extended/util/framework.go b/test/extended/util/framework.go index 6426cad3ec0a..be0fe355ea84 100644 --- a/test/extended/util/framework.go +++ b/test/extended/util/framework.go @@ -527,7 +527,6 @@ func DumpSampleOperator(oc *CLI) { e2e.Logf("\n error on getting samples operator CR: %+v\n%#v\n", err, out) } DumpPodLogsStartingWithInNamespace("cluster-samples-operator", "openshift-cluster-samples-operator", oc) - } // DumpBuildLogs will dump the latest build logs for a BuildConfig for debug purposes @@ -1058,6 +1057,11 @@ func WaitForBuildResult(c buildv1clienttyped.BuildInterface, result *BuildResult // WaitForABuild waits for a Build object to match either isOK or isFailed conditions. func WaitForABuild(c buildv1clienttyped.BuildInterface, name string, isOK, isFailed, isCanceled func(*buildv1.Build) bool) error { + return WaitForABuildWithTimeout(c, name, 2*time.Minute, 10*time.Minute, isOK, isFailed, isCanceled) +} + +// WaitForABuild waits for a Build object to match either isOK or isFailed conditions. +func WaitForABuildWithTimeout(c buildv1clienttyped.BuildInterface, name string, createTimeout, completeTimeout time.Duration, isOK, isFailed, isCanceled func(*buildv1.Build) bool) error { if isOK == nil { isOK = CheckBuildSuccess } @@ -1069,8 +1073,9 @@ func WaitForABuild(c buildv1clienttyped.BuildInterface, name string, isOK, isFai } // wait 2 minutes for build to exist - err := wait.Poll(1*time.Second, 2*time.Minute, func() (bool, error) { + err := wait.Poll(1*time.Second, createTimeout, func() (bool, error) { if _, err := c.Get(context.Background(), name, metav1.GetOptions{}); err != nil { + e2e.Logf("attempt to get buildconfig %s failed with error: %s", name, err.Error()) return false, nil } return true, nil @@ -1082,7 +1087,7 @@ func WaitForABuild(c buildv1clienttyped.BuildInterface, name string, isOK, isFai return err } // wait longer for the build to run to completion - err = wait.Poll(5*time.Second, 10*time.Minute, func() (bool, error) { + err = wait.Poll(5*time.Second, completeTimeout, func() (bool, error) { list, err := c.List(context.Background(), metav1.ListOptions{FieldSelector: fields.Set{"metadata.name": name}.AsSelector().String()}) if err != nil { e2e.Logf("error listing builds: %v", err) @@ -1220,7 +1225,8 @@ func WaitForNamespaceSCCAnnotations(c corev1client.CoreV1Interface, name string) // WaitForAnImageStream waits for an ImageStream to fulfill the isOK function func WaitForAnImageStream(client imagev1typedclient.ImageStreamInterface, name string, - isOK, isFailed func(*imagev1.ImageStream) bool) error { + isOK, isFailed func(*imagev1.ImageStream) bool, +) error { for { list, err := client.List(context.Background(), metav1.ListOptions{FieldSelector: fields.Set{"metadata.name": name}.AsSelector().String()}) if err != nil { @@ -1336,7 +1342,6 @@ func WaitForResourceQuotaSync( expectedIsUpperLimit bool, timeout time.Duration, ) (corev1.ResourceList, error) { - startTime := time.Now() endTime := startTime.Add(timeout) @@ -1610,7 +1615,6 @@ func FixturePath(elem ...string) string { if err := restoreFixtureAssets(fixtureDir, relativePath); err != nil { panic(err) } - } else { // defer extraction of content to a BeforeEach when called before tests start g.BeforeEach(func() { @@ -1689,7 +1693,7 @@ func FetchURL(oc *CLI, url string, retryTimeout time.Duration) (string, error) { var response string waitFn := func() (bool, error) { e2e.Logf("Waiting up to %v to wget %s", retryTimeout, url) - //cmd := fmt.Sprintf("wget -T 30 -O- %s", url) + // cmd := fmt.Sprintf("wget -T 30 -O- %s", url) cmd := fmt.Sprintf("curl -vvv %s", url) response, err = e2eoutput.RunHostCmd(execPod.Namespace, execPod.Name, cmd) if err != nil { @@ -1937,7 +1941,8 @@ func getPodLogs(oc *CLI, pod *corev1.Pod) (string, error) { } func newCommandPod(name, image, command string, args []string, volumeMounts []corev1.VolumeMount, - volumes []corev1.Volume, env []corev1.EnvVar) *corev1.Pod { + volumes []corev1.Volume, env []corev1.EnvVar, +) *corev1.Pod { return &corev1.Pod{ ObjectMeta: metav1.ObjectMeta{ Name: name,