This is an automated email from the ASF dual-hosted git repository.

houston pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/solr-operator.git


The following commit(s) were added to refs/heads/main by this push:
     new 89422c9  Improvments to e2e tests
89422c9 is described below

commit 89422c98d4400cdafa84b8ac8b32399fb3f72103
Author: Houston Putman <[email protected]>
AuthorDate: Thu May 11 15:50:06 2023 -0400

    Improvments to e2e tests
    
    - context.Context used for Eventually() pod execs
    - More pod execs use Eventually()'s to remove false negatives
    - Random pods are used for pod execs, instead of the first pod,
      therefore retries will succeed if one pod is having an issue
---
 api/v1beta1/solrcloud_types.go              |   9 ++
 tests/e2e/backups_test.go                   |  24 +--
 tests/e2e/prometheus_exporter_test.go       |   2 +-
 tests/e2e/resource_utils_test.go            |  22 +--
 tests/e2e/solrcloud_basic_test.go           |   9 +-
 tests/e2e/solrcloud_rolling_upgrade_test.go |   8 +-
 tests/e2e/suite_test.go                     |  21 ++-
 tests/e2e/test_utils_test.go                | 230 ++++++++++++++++------------
 8 files changed, 182 insertions(+), 143 deletions(-)

diff --git a/api/v1beta1/solrcloud_types.go b/api/v1beta1/solrcloud_types.go
index 8c9145c..b45a027 100644
--- a/api/v1beta1/solrcloud_types.go
+++ b/api/v1beta1/solrcloud_types.go
@@ -21,6 +21,7 @@ import (
        "fmt"
        "github.com/go-logr/logr"
        zkApi "github.com/pravega/zookeeper-operator/api/v1beta1"
+       "math/rand"
        "strconv"
        "strings"
 
@@ -1211,6 +1212,14 @@ func (sc *SolrCloud) GetAllSolrPodNames() []string {
        return podNames
 }
 
+func (sc *SolrCloud) GetRandomSolrPodName() string {
+       replicas := 1
+       if sc.Spec.Replicas != nil {
+               replicas = int(*sc.Spec.Replicas)
+       }
+       return sc.GetSolrPodName(rand.Intn(replicas))
+}
+
 func (sc *SolrCloud) GetSolrPodName(podNumber int) string {
        return fmt.Sprintf("%s-%d", sc.StatefulSetName(), podNumber)
 }
diff --git a/tests/e2e/backups_test.go b/tests/e2e/backups_test.go
index 3188bf7..1057522 100644
--- a/tests/e2e/backups_test.go
+++ b/tests/e2e/backups_test.go
@@ -72,7 +72,7 @@ var _ = FDescribe("E2E - Backups", Ordered, func() {
                })
 
                By("creating a Solr Collection to backup")
-               createAndQueryCollection(solrCloud, solrCollection, 1, 2)
+               createAndQueryCollection(ctx, solrCloud, solrCollection, 1, 2)
        })
 
        BeforeEach(func() {
@@ -122,10 +122,10 @@ var _ = FDescribe("E2E - Backups", Ordered, func() {
                        
Expect(foundSolrBackup.Status.History[len(foundSolrBackup.Status.History)-1].Successful).To(PointTo(BeTrue()),
 "The latest backup was not successful")
 
                        lastBackupId := 0
-                       checkBackup(solrCloud, solrBackup, func(collection 
string, backupListResponse *solr_api.SolrBackupListResponse) {
-                               
Expect(backupListResponse.Backups).To(HaveLen(3), "The wrong number of 
recurring backups have been saved")
+                       checkBackup(ctx, solrCloud, solrBackup, func(g Gomega, 
collection string, backupListResponse *solr_api.SolrBackupListResponse) {
+                               
g.Expect(backupListResponse.Backups).To(HaveLen(3), "The wrong number of 
recurring backups have been saved")
                                lastBackupId = 
backupListResponse.Backups[len(backupListResponse.Backups)-1].BackupId
-                               Expect(lastBackupId).To(BeNumerically(">", 3), 
"The last backup ID is too low")
+                               g.Expect(lastBackupId).To(BeNumerically(">", 
3), "The last backup ID is too low")
                        })
 
                        By("disabling further backup recurrence")
@@ -138,10 +138,10 @@ var _ = FDescribe("E2E - Backups", Ordered, func() {
                        // Use start time because we might have disabled the 
recurrence mid-backup, and the finish time might not have been set
                        
Expect(nextFoundSolrBackup.Status.StartTime).To(Equal(foundSolrBackup.Status.StartTime),
 "The last backup start time should be unchanged after recurrence is disabled")
 
-                       checkBackup(solrCloud, solrBackup, func(collection 
string, backupListResponse *solr_api.SolrBackupListResponse) {
-                               
Expect(backupListResponse.Backups).To(HaveLen(3), "The wrong number of 
recurring backups have been saved")
+                       checkBackup(ctx, solrCloud, solrBackup, func(g Gomega, 
collection string, backupListResponse *solr_api.SolrBackupListResponse) {
+                               
g.Expect(backupListResponse.Backups).To(HaveLen(3), "The wrong number of 
recurring backups have been saved")
                                newLastBackupId := 
backupListResponse.Backups[len(backupListResponse.Backups)-1].BackupId
-                               Expect(newLastBackupId).To(Equal(lastBackupId), 
"The last backup ID should not have been changed since the backup recurrence 
was disabled")
+                               
g.Expect(newLastBackupId).To(Equal(lastBackupId), "The last backup ID should 
not have been changed since the backup recurrence was disabled")
                        })
                })
        })
@@ -158,8 +158,8 @@ var _ = FDescribe("E2E - Backups", Ordered, func() {
                                
g.Expect(backup.Status.Successful).To(PointTo(BeTrue()), "Backup did not 
successfully complete")
                        })
 
-                       checkBackup(solrCloud, solrBackup, func(collection 
string, backupListResponse *solr_api.SolrBackupListResponse) {
-                               
Expect(backupListResponse.Backups).To(HaveLen(1), "A non-recurring backupList 
should have a length of 1")
+                       checkBackup(ctx, solrCloud, solrBackup, func(g Gomega, 
collection string, backupListResponse *solr_api.SolrBackupListResponse) {
+                               
g.Expect(backupListResponse.Backups).To(HaveLen(1), "A non-recurring backupList 
should have a length of 1")
                        })
 
                        // Make sure nothing else happens after the backup is 
complete
@@ -169,9 +169,9 @@ var _ = FDescribe("E2E - Backups", Ordered, func() {
                                
g.Expect(backup.Status.NextScheduledTime).To(BeNil(), "There should be no 
nextScheduledTime for a non-recurring backup")
                        })
 
-                       checkBackup(solrCloud, solrBackup, func(collection 
string, backupListResponse *solr_api.SolrBackupListResponse) {
-                               
Expect(backupListResponse.Backups).To(HaveLen(1), "A non-recurring backupList 
should have a length of 1")
-                               
Expect(backupListResponse.Backups[0].BackupId).To(Equal(0), "A non-recurring 
backup should have an ID of 1")
+                       checkBackup(ctx, solrCloud, solrBackup, func(g Gomega, 
collection string, backupListResponse *solr_api.SolrBackupListResponse) {
+                               
g.Expect(backupListResponse.Backups).To(HaveLen(1), "A non-recurring backupList 
should have a length of 1")
+                               
g.Expect(backupListResponse.Backups[0].BackupId).To(Equal(0), "A non-recurring 
backup should have an ID of 1")
                        })
                })
        })
diff --git a/tests/e2e/prometheus_exporter_test.go 
b/tests/e2e/prometheus_exporter_test.go
index e5d840c..23ac6a4 100644
--- a/tests/e2e/prometheus_exporter_test.go
+++ b/tests/e2e/prometheus_exporter_test.go
@@ -58,7 +58,7 @@ var _ = FDescribe("E2E - Prometheus Exporter", Ordered, 
func() {
                })
 
                By("creating a Solr Collection to query metrics for")
-               createAndQueryCollection(solrCloud, solrCollection, 1, 2)
+               createAndQueryCollection(ctx, solrCloud, solrCollection, 1, 2)
        })
 
        BeforeEach(func() {
diff --git a/tests/e2e/resource_utils_test.go b/tests/e2e/resource_utils_test.go
index 71aa698..3a9853f 100644
--- a/tests/e2e/resource_utils_test.go
+++ b/tests/e2e/resource_utils_test.go
@@ -76,7 +76,7 @@ func expectSolrCloudWithChecks(ctx context.Context, solrCloud 
*solrv1beta1.SolrC
                if additionalChecks != nil {
                        additionalChecks(g, foundSolrCloud)
                }
-       }).Should(Succeed())
+       }).WithContext(ctx).Should(Succeed())
 
        return foundSolrCloud
 }
@@ -238,20 +238,6 @@ func expectStatefulSetWithChecks(ctx context.Context, 
parentResource client.Obje
                        additionalChecks(g, statefulSet)
                }
        }).Should(Succeed())
-
-       By("recreating the StatefulSet after it is deleted")
-       ExpectWithOffset(resolveOffset(additionalOffset), k8sClient.Delete(ctx, 
statefulSet)).To(Succeed())
-       EventuallyWithOffset(
-               resolveOffset(additionalOffset),
-               func() (types.UID, error) {
-                       newResource := &appsv1.StatefulSet{}
-                       err := k8sClient.Get(ctx, resourceKey(parentResource, 
statefulSetName), newResource)
-                       if err != nil {
-                               return "", err
-                       }
-                       return newResource.UID, nil
-               }).Should(And(Not(BeEmpty()), Not(Equal(statefulSet.UID))), 
"New StatefulSet, with new UID, not created.")
-
        return statefulSet
 }
 
@@ -277,6 +263,12 @@ func expectNoStatefulSet(ctx context.Context, 
parentResource client.Object, stat
        }).Should(MatchError("statefulsets.apps \""+statefulSetName+"\" not 
found"), "StatefulSet exists when it should not")
 }
 
+func expectNoPod(ctx context.Context, parentResource client.Object, podName 
string, additionalOffset ...int) {
+       EventuallyWithOffset(resolveOffset(additionalOffset), func() error {
+               return k8sClient.Get(ctx, resourceKey(parentResource, podName), 
&corev1.Pod{})
+       }).Should(MatchError("pods \""+podName+"\" not found"), "Pod exists 
when it should not")
+}
+
 func expectService(ctx context.Context, parentResource client.Object, 
serviceName string, selectorLables map[string]string, isHeadless bool, 
additionalOffset ...int) *corev1.Service {
        return expectServiceWithChecks(ctx, parentResource, serviceName, 
selectorLables, isHeadless, nil, resolveOffset(additionalOffset))
 }
diff --git a/tests/e2e/solrcloud_basic_test.go 
b/tests/e2e/solrcloud_basic_test.go
index 673377d..c600d72 100644
--- a/tests/e2e/solrcloud_basic_test.go
+++ b/tests/e2e/solrcloud_basic_test.go
@@ -28,10 +28,6 @@ import (
 var _ = FDescribe("E2E - SolrCloud - Basic", func() {
        var (
                solrCloud *solrv1beta1.SolrCloud
-
-               solrCollection1 = "e2e-1"
-
-               solrCollection2 = "e2e-2"
        )
 
        BeforeEach(func() {
@@ -52,10 +48,7 @@ var _ = FDescribe("E2E - SolrCloud - Basic", func() {
                })
 
                By("creating a first Solr Collection")
-               createAndQueryCollection(solrCloud, solrCollection1, 1, 2)
-
-               By("creating a second Solr Collection")
-               createAndQueryCollection(solrCloud, solrCollection2, 2, 1)
+               createAndQueryCollection(ctx, solrCloud, "basic", 1, 1)
        })
 
        FContext("Provided Zookeeper", func() {
diff --git a/tests/e2e/solrcloud_rolling_upgrade_test.go 
b/tests/e2e/solrcloud_rolling_upgrade_test.go
index c9256ff..81b730c 100644
--- a/tests/e2e/solrcloud_rolling_upgrade_test.go
+++ b/tests/e2e/solrcloud_rolling_upgrade_test.go
@@ -53,10 +53,10 @@ var _ = FDescribe("E2E - SolrCloud - Rolling Upgrades", 
func() {
                })
 
                By("creating a first Solr Collection")
-               createAndQueryCollection(solrCloud, solrCollection1, 1, 2)
+               createAndQueryCollection(ctx, solrCloud, solrCollection1, 1, 2)
 
                By("creating a second Solr Collection")
-               createAndQueryCollection(solrCloud, solrCollection2, 2, 1)
+               createAndQueryCollection(ctx, solrCloud, solrCollection2, 2, 1)
        })
 
        FContext("Managed Update - Ephemeral Data - Slow", func() {
@@ -143,8 +143,8 @@ var _ = FDescribe("E2E - SolrCloud - Rolling Upgrades", 
func() {
                        }
 
                        By("checking that the collections can be queried after 
the restart")
-                       queryCollection(solrCloud, solrCollection1, 0)
-                       queryCollection(solrCloud, solrCollection2, 0)
+                       queryCollection(ctx, solrCloud, solrCollection1, 0)
+                       queryCollection(ctx, solrCloud, solrCollection2, 0)
                })
        })
 })
diff --git a/tests/e2e/suite_test.go b/tests/e2e/suite_test.go
index 14eeb3d..c53026c 100644
--- a/tests/e2e/suite_test.go
+++ b/tests/e2e/suite_test.go
@@ -81,11 +81,6 @@ var _ = SynchronizedBeforeSuite(func(ctx context.Context) {
        logger = zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))
        logf.SetLogger(logger)
 
-       // Run this once before all tests, not per-test-process
-       By("starting the test solr operator")
-       solrOperatorRelease := runSolrOperator(ctx)
-       Expect(solrOperatorRelease).ToNot(BeNil())
-
        var err error
        k8sConfig, err = config.GetConfig()
        Expect(err).NotTo(HaveOccurred(), "Could not load in default kubernetes 
config")
@@ -94,9 +89,19 @@ var _ = SynchronizedBeforeSuite(func(ctx context.Context) {
        Expect(err).NotTo(HaveOccurred(), "Could not create controllerRuntime 
Kubernetes client")
 
        // Set up a shared Zookeeper Cluster to be used for most SolrClouds
-       // This will significantly speed up tests
-       By("starting a shared zookeeper cluster")
-       runSharedZookeeperCluster(ctx)
+       // This will significantly speed up tests.
+       // The zookeeper will not be healthy until after the zookeeper operator 
is released with the solr operator
+       By("creating a shared zookeeper cluster")
+       zookeeper := runSharedZookeeperCluster(ctx)
+
+       // Run this once before all tests, not per-test-process
+       By("starting the test solr operator")
+       solrOperatorRelease := runSolrOperator(ctx)
+       Expect(solrOperatorRelease).ToNot(BeNil())
+
+       By("Waiting for the Zookeeper to come up healthy")
+       // This check must be done after the solr operator is installed
+       waitForSharedZookeeperCluster(ctx, zookeeper)
 }, func(ctx context.Context) {
        // Run these in each parallel test process before the tests
        rand.Seed(GinkgoRandomSeed() + int64(GinkgoParallelProcess()))
diff --git a/tests/e2e/test_utils_test.go b/tests/e2e/test_utils_test.go
index c3a262e..a1adff8 100644
--- a/tests/e2e/test_utils_test.go
+++ b/tests/e2e/test_utils_test.go
@@ -143,26 +143,35 @@ func runSharedZookeeperCluster(ctx context.Context) 
*zkApi.ZookeeperCluster {
                },
        }
 
-       By("creating the shared ZK cluster")
        Expect(k8sClient.Create(ctx, zookeeper)).To(Succeed(), "Failed to 
create shared Zookeeper Cluster")
 
-       By("Waiting for the Zookeeper to come up healthy")
-       zookeeper = expectZookeeperClusterWithChecks(ctx, zookeeper, 
zookeeper.Name, func(g Gomega, found *zkApi.ZookeeperCluster) {
-               
g.Expect(found.Status.ReadyReplicas).To(Equal(found.Spec.Replicas), "The 
ZookeeperCluster should have all nodes come up healthy")
-       })
-
        DeferCleanup(func(ctx context.Context) {
-               By("tearing down the shared Zookeeper Cluster")
                stopSharedZookeeperCluster(ctx, zookeeper)
        })
 
        return zookeeper
 }
 
-// Run Solr Operator for e2e testing of resources
+// Check if the sharedZookeeper Cluster is running
+func waitForSharedZookeeperCluster(ctx context.Context, sharedZk 
*zkApi.ZookeeperCluster) *zkApi.ZookeeperCluster {
+       sharedZk = expectZookeeperClusterWithChecks(ctx, sharedZk, 
sharedZk.Name, func(g Gomega, found *zkApi.ZookeeperCluster) {
+               
g.Expect(found.Status.ReadyReplicas).To(Equal(found.Spec.Replicas), "The 
ZookeeperCluster should have all nodes come up healthy")
+       }, 1)
+
+       // Cleanup here, because we want to delete the zk before deleting the 
Zookeeper Operator.
+       // DeferCleanup() is a stack, so this cleanup needs to be called after 
the solr operator DeferCleanup().
+       DeferCleanup(func(ctx context.Context) {
+               stopSharedZookeeperCluster(ctx, sharedZk)
+       })
+
+       return sharedZk
+}
+
+// Stop the sharedZookeeperCluster
 func stopSharedZookeeperCluster(ctx context.Context, sharedZk 
*zkApi.ZookeeperCluster) {
        err := k8sClient.Get(ctx, client.ObjectKey{Namespace: 
sharedZk.Namespace, Name: sharedZk.Name}, sharedZk)
        if err == nil {
+               By("tearing down the shared Zookeeper Cluster")
                Expect(k8sClient.Delete(ctx, sharedZk)).To(Succeed(), "Failed 
to delete shared Zookeeper Cluster")
        }
 }
@@ -194,12 +203,11 @@ func createOrRecreateNamespace(ctx context.Context, 
namespaceName string) {
        })
 }
 
-func createAndQueryCollection(solrCloud *solrv1beta1.SolrCloud, collection 
string, shards int, replicasPerShard int, nodes ...int) {
-       createAndQueryCollectionWithGomega(solrCloud, collection, shards, 
replicasPerShard, Default, nodes...)
+func createAndQueryCollection(ctx context.Context, solrCloud 
*solrv1beta1.SolrCloud, collection string, shards int, replicasPerShard int, 
nodes ...int) {
+       createAndQueryCollectionWithGomega(ctx, solrCloud, collection, shards, 
replicasPerShard, Default, 1, nodes...)
 }
 
-func createAndQueryCollectionWithGomega(solrCloud *solrv1beta1.SolrCloud, 
collection string, shards int, replicasPerShard int, g Gomega, nodes ...int) {
-       pod := solrCloud.GetAllSolrPodNames()[0]
+func createAndQueryCollectionWithGomega(ctx context.Context, solrCloud 
*solrv1beta1.SolrCloud, collection string, shards int, replicasPerShard int, g 
Gomega, additionalOffset int, nodes ...int) {
        asyncId := fmt.Sprintf("create-collection-%s-%d-%d", collection, 
shards, replicasPerShard)
 
        var nodeSet []string
@@ -211,29 +219,35 @@ func createAndQueryCollectionWithGomega(solrCloud 
*solrv1beta1.SolrCloud, collec
                createNodeSet = "&createNodeSet=" + strings.Join(nodeSet, ",")
        }
 
-       response, err := runExecForContainer(
-               util.SolrNodeContainer,
-               pod,
-               solrCloud.Namespace,
-               []string{
-                       "curl",
-                       fmt.Sprintf(
-                               
"http://localhost:%d/solr/admin/collections?action=CREATE&name=%s&replicationFactor=%d&numShards=%d%s&async=%s";,
-                               solrCloud.Spec.SolrAddressability.PodPort,
-                               collection,
-                               replicasPerShard,
-                               shards,
-                               createNodeSet,
-                               asyncId),
-               },
-       )
-       g.Expect(err).ToNot(HaveOccurred(), "Error occurred while creating Solr 
Collection")
-       g.Expect(response).To(ContainSubstring("\"status\":0"), "Error occurred 
while creating Solr Collection")
+       additionalOffset += 1
+       g.EventuallyWithOffset(additionalOffset, func(innerG Gomega) {
+               response, err := runExecForContainer(
+                       ctx,
+                       util.SolrNodeContainer,
+                       solrCloud.GetRandomSolrPodName(),
+                       solrCloud.Namespace,
+                       []string{
+                               "curl",
+                               fmt.Sprintf(
+                                       
"http://localhost:%d/solr/admin/collections?action=CREATE&name=%s&replicationFactor=%d&numShards=%d%s&async=%s";,
+                                       
solrCloud.Spec.SolrAddressability.PodPort,
+                                       collection,
+                                       replicasPerShard,
+                                       shards,
+                                       createNodeSet,
+                                       asyncId),
+                       },
+               )
+               innerG.Expect(err).ToNot(HaveOccurred(), "Error occurred while 
starting async command to create Solr Collection")
+               innerG.Expect(response).To(ContainSubstring("\"status\":0"), 
"Error occurred while starting async command to create Solr Collection")
+       }, time.Second*5).WithContext(ctx).Should(Succeed(), "Collection 
creation command start was not successful")
+       // Only wait 5 seconds when trying to create the asyncCommand
 
-       g.Eventually(func(innerG Gomega) {
-               response, err = runExecForContainer(
+       g.EventuallyWithOffset(additionalOffset, func(innerG Gomega) {
+               response, err := runExecForContainer(
+                       ctx,
                        util.SolrNodeContainer,
-                       pod,
+                       solrCloud.GetRandomSolrPodName(),
                        solrCloud.Namespace,
                        []string{
                                "curl",
@@ -243,10 +257,8 @@ func createAndQueryCollectionWithGomega(solrCloud 
*solrv1beta1.SolrCloud, collec
                                        asyncId),
                        },
                )
-               innerG.Expect(err).ToNot(HaveOccurred(), "Error occurred while 
checking if Solr Collection has been created")
-               innerG.Expect(response).To(ContainSubstring("\"status\":0"), 
"Error occurred while creating Solr Collection")
-               
innerG.Expect(response).To(ContainSubstring("\"state\":\"completed\""), "Did 
not finish creating Solr Collection in time")
-               if strings.Contains(response, "\"state\":\"failed\"") {
+               innerG.Expect(err).ToNot(HaveOccurred(), "Error occurred while 
checking if Solr Collection creation command was successful")
+               if strings.Contains(response, "\"state\":\"failed\"") || 
strings.Contains(response, "\"state\":\"notfound\"") {
                        StopTrying("A failure occurred while creating the Solr 
Collection").
                                Attach("Collection", collection).
                                Attach("Shards", shards).
@@ -254,43 +266,69 @@ func createAndQueryCollectionWithGomega(solrCloud 
*solrv1beta1.SolrCloud, collec
                                Attach("Response", response).
                                Now()
                }
-       }).Should(Succeed(), "Collection creation was not successful")
-
-       response, err = runExecForContainer(
-               util.SolrNodeContainer,
-               pod,
-               solrCloud.Namespace,
-               []string{
-                       "curl",
-                       fmt.Sprintf(
-                               
"http://localhost:%d/solr/admin/collections?action=DELETESTATUS&requestid=%s";,
-                               solrCloud.Spec.SolrAddressability.PodPort,
-                               asyncId),
-               },
-       )
-       g.Expect(err).ToNot(HaveOccurred(), "Error occurred while deleting Solr 
CollectionsAPI AsyncID")
-       g.Expect(response).To(ContainSubstring("\"status\":0"), "Error occurred 
while deleting Solr CollectionsAPI AsyncID")
+               innerG.Expect(response).To(ContainSubstring("\"status\":0"), "A 
failure occurred while creating the Solr Collection")
+               
innerG.Expect(response).To(ContainSubstring("\"state\":\"completed\""), "Did 
not finish creating Solr Collection in time")
+       }).WithContext(ctx).Should(Succeed(), "Collection creation was not 
successful")
 
-       queryCollectionWithGomega(solrCloud, collection, 0, g)
+       g.EventuallyWithOffset(additionalOffset, func(innerG Gomega) {
+               response, err := runExecForContainer(
+                       ctx,
+                       util.SolrNodeContainer,
+                       solrCloud.GetRandomSolrPodName(),
+                       solrCloud.Namespace,
+                       []string{
+                               "curl",
+                               fmt.Sprintf(
+                                       
"http://localhost:%d/solr/admin/collections?action=DELETESTATUS&requestid=%s";,
+                                       
solrCloud.Spec.SolrAddressability.PodPort,
+                                       asyncId),
+                       },
+               )
+               innerG.Expect(err).ToNot(HaveOccurred(), "Error occurred while 
deleting Solr CollectionsAPI AsyncID")
+               innerG.Expect(response).To(ContainSubstring("\"status\":0"), 
"Error occurred while deleting Solr CollectionsAPI AsyncID")
+       }, time.Second*5).WithContext(ctx).Should(Succeed(), "Could not delete 
aysncId after collection creation")
+       // Only wait 5 seconds when trying to delete the async requestId
+
+       queryCollectionWithGomega(ctx, solrCloud, collection, 0, g, 
additionalOffset)
 }
 
-func queryCollection(solrCloud *solrv1beta1.SolrCloud, collection string, 
docCount int) {
-       queryCollectionWithGomega(solrCloud, collection, docCount, Default)
+func queryCollection(ctx context.Context, solrCloud *solrv1beta1.SolrCloud, 
collection string, docCount int, additionalOffset ...int) {
+       queryCollectionWithGomega(ctx, solrCloud, collection, docCount, 
Default, resolveOffset(additionalOffset))
 }
 
-func queryCollectionWithGomega(solrCloud *solrv1beta1.SolrCloud, collection 
string, docCount int, g Gomega) {
-       pod := solrCloud.GetAllSolrPodNames()[0]
-       response, err := runExecForContainer(
-               util.SolrNodeContainer,
-               pod,
-               solrCloud.Namespace,
-               []string{
-                       "curl",
-                       fmt.Sprintf("http://localhost:%d/solr/%s/select";, 
solrCloud.Spec.SolrAddressability.PodPort, collection),
-               },
-       )
-       g.Expect(err).ToNot(HaveOccurred(), "Error occurred while querying 
empty Solr Collection")
-       g.Expect(response).To(ContainSubstring("\"numFound\":%d", docCount), 
"Error occurred while querying Solr Collection '%s'", collection)
+func queryCollectionWithGomega(ctx context.Context, solrCloud 
*solrv1beta1.SolrCloud, collection string, docCount int, g Gomega, 
additionalOffset ...int) {
+       g.EventuallyWithOffset(resolveOffset(additionalOffset), func(innerG 
Gomega) {
+               response, err := runExecForContainer(
+                       ctx,
+                       util.SolrNodeContainer,
+                       solrCloud.GetRandomSolrPodName(),
+                       solrCloud.Namespace,
+                       []string{
+                               "curl",
+                               
fmt.Sprintf("http://localhost:%d/solr/%s/select?rows=0";, 
solrCloud.Spec.SolrAddressability.PodPort, collection),
+                       },
+               )
+               g.ExpectWithOffset(resolveOffset(additionalOffset), 
err).ToNot(HaveOccurred(), "Error occurred while querying empty Solr 
Collection")
+               g.ExpectWithOffset(resolveOffset(additionalOffset), 
response).To(ContainSubstring("\"numFound\":%d", docCount), "Error occurred 
while querying Solr Collection '%s'", collection)
+       }, time.Second*5).WithContext(ctx).Should(Succeed(), "Could not 
successfully query collection")
+       // Only wait 5 seconds for the collection to be query-able
+}
+
+func queryCollectionWithNoReplicaAvailable(ctx context.Context, solrCloud 
*solrv1beta1.SolrCloud, collection string, additionalOffset ...int) {
+       EventuallyWithOffset(resolveOffset(additionalOffset), func(g Gomega) {
+               response, err := runExecForContainer(
+                       ctx,
+                       util.SolrNodeContainer,
+                       solrCloud.GetRandomSolrPodName(),
+                       solrCloud.Namespace,
+                       []string{
+                               "curl",
+                               
fmt.Sprintf("http://localhost:%d/solr/%s/select";, 
solrCloud.Spec.SolrAddressability.PodPort, collection),
+                       },
+               )
+               g.Expect(err).ToNot(HaveOccurred(), "Error occurred while 
querying empty Solr Collection")
+               g.Expect(response).To(ContainSubstring("Error trying to proxy 
request for url"), "Wrong occurred while querying Solr Collection '%s', 
expected a proxy forwarding error", collection)
+       }, time.Second*5).WithContext(ctx).Should(Succeed(), "Could not 
successfully query collection")
 }
 
 func getPrometheusExporterPod(ctx context.Context, solrPrometheusExporter 
*solrv1beta1.SolrPrometheusExporter) (podName string) {
@@ -316,14 +354,15 @@ func getPrometheusExporterPod(ctx context.Context, 
solrPrometheusExporter *solrv
        return podName
 }
 
-func checkMetrics(ctx context.Context, solrPrometheusExporter 
*solrv1beta1.SolrPrometheusExporter, solrCloud *solrv1beta1.SolrCloud, 
collection string) string {
-       return checkMetricsWithGomega(ctx, solrPrometheusExporter, solrCloud, 
collection, Default)
+func checkMetrics(ctx context.Context, solrPrometheusExporter 
*solrv1beta1.SolrPrometheusExporter, solrCloud *solrv1beta1.SolrCloud, 
collection string, additionalOffset ...int) string {
+       return checkMetricsWithGomega(ctx, solrPrometheusExporter, solrCloud, 
collection, Default, resolveOffset(additionalOffset))
 }
 
-func checkMetricsWithGomega(ctx context.Context, solrPrometheusExporter 
*solrv1beta1.SolrPrometheusExporter, solrCloud *solrv1beta1.SolrCloud, 
collection string, g Gomega) (response string) {
+func checkMetricsWithGomega(ctx context.Context, solrPrometheusExporter 
*solrv1beta1.SolrPrometheusExporter, solrCloud *solrv1beta1.SolrCloud, 
collection string, g Gomega, additionalOffset ...int) (response string) {
        g.Eventually(func(innerG Gomega) {
                var err error
                response, err = runExecForContainer(
+                       ctx,
                        util.SolrPrometheusExporterContainer,
                        getPrometheusExporterPod(ctx, solrPrometheusExporter),
                        solrCloud.Namespace,
@@ -342,18 +381,16 @@ func checkMetricsWithGomega(ctx context.Context, 
solrPrometheusExporter *solrv1b
                        
MatchRegexp("solr_metrics_core_query_[^{]+\\{category=\"QUERY\",searchHandler=\"/select\",[^}]*collection=\"%s\",[^}]*shard=\"shard1\",[^}]*\\}
 [0-9]+.0", collection),
                        "Could not find query metrics in the PrometheusExporter 
response",
                )
-       }).WithContext(ctx).Within(time.Second * 5).ProbeEvery(time.Millisecond 
* 200).Should(Succeed())
+       
}).WithContext(ctx).WithOffset(resolveOffset(additionalOffset)).Within(time.Second
 * 5).ProbeEvery(time.Millisecond * 200).Should(Succeed())
 
        return response
 }
 
-func checkBackup(solrCloud *solrv1beta1.SolrCloud, solrBackup 
*solrv1beta1.SolrBackup, checks func(collection string, backupListResponse 
*solr_api.SolrBackupListResponse)) {
-       checkBackupWithGomega(solrCloud, solrBackup, checks, Default)
+func checkBackup(ctx context.Context, solrCloud *solrv1beta1.SolrCloud, 
solrBackup *solrv1beta1.SolrBackup, checks func(g Gomega, collection string, 
backupListResponse *solr_api.SolrBackupListResponse)) {
+       checkBackupWithGomega(ctx, solrCloud, solrBackup, checks, Default)
 }
 
-func checkBackupWithGomega(solrCloud *solrv1beta1.SolrCloud, solrBackup 
*solrv1beta1.SolrBackup, checks func(collection string, backupListResponse 
*solr_api.SolrBackupListResponse), g Gomega) {
-       solrCloudPod := solrCloud.GetAllSolrPodNames()[0]
-
+func checkBackupWithGomega(ctx context.Context, solrCloud 
*solrv1beta1.SolrCloud, solrBackup *solrv1beta1.SolrBackup, checks func(g 
Gomega, collection string, backupListResponse 
*solr_api.SolrBackupListResponse), g Gomega) {
        repository := 
util.GetBackupRepositoryByName(solrCloud.Spec.BackupRepositories, 
solrBackup.Spec.RepositoryName)
        repositoryName := repository.Name
        if repositoryName == "" {
@@ -367,26 +404,29 @@ func checkBackupWithGomega(solrCloud 
*solrv1beta1.SolrCloud, solrBackup *solrv1b
                        repositoryName,
                        collection,
                        util.BackupLocationPath(repository, 
solrBackup.Spec.Location))
-               response, err := runExecForContainer(
-                       util.SolrNodeContainer,
-                       solrCloudPod,
-                       solrCloud.Namespace,
-                       []string{
-                               "curl",
-                               curlCommand,
-                       },
-               )
-               g.Expect(err).ToNot(HaveOccurred(), "Error occurred while 
fetching backup '%s' for collection '%s': %s", solrBackup.Name, collection, 
curlCommand)
-               backupListResponse := &solr_api.SolrBackupListResponse{}
+               g.Eventually(func(innerG Gomega) {
+                       response, err := runExecForContainer(
+                               ctx,
+                               util.SolrNodeContainer,
+                               solrCloud.GetRandomSolrPodName(),
+                               solrCloud.Namespace,
+                               []string{
+                                       "curl",
+                                       curlCommand,
+                               },
+                       )
+                       innerG.Expect(err).ToNot(HaveOccurred(), "Error 
occurred while fetching backup '%s' for collection '%s': %s", solrBackup.Name, 
collection, curlCommand)
+                       backupListResponse := &solr_api.SolrBackupListResponse{}
 
-               g.Expect(json.Unmarshal([]byte(response), 
&backupListResponse)).To(Succeed(), "Could not parse json from Solr BackupList 
API")
+                       innerG.Expect(json.Unmarshal([]byte(response), 
&backupListResponse)).To(Succeed(), "Could not parse json from Solr BackupList 
API")
 
-               g.Expect(backupListResponse.ResponseHeader.Status).To(BeZero(), 
"SolrBackupList API returned exception code: %d", 
backupListResponse.ResponseHeader.Status)
-               checks(collection, backupListResponse)
+                       
innerG.Expect(backupListResponse.ResponseHeader.Status).To(BeZero(), 
"SolrBackupList API returned exception code: %d", 
backupListResponse.ResponseHeader.Status)
+                       checks(innerG, collection, backupListResponse)
+               }).WithContext(ctx).Within(time.Second * 
5).ProbeEvery(time.Millisecond * 200).Should(Succeed())
        }
 }
 
-func runExecForContainer(container string, podName string, namespace string, 
command []string) (response string, err error) {
+func runExecForContainer(ctx context.Context, container string, podName 
string, namespace string, command []string) (response string, err error) {
        req := rawK8sClient.CoreV1().RESTClient().Post().
                Resource("pods").
                Name(podName).
@@ -414,7 +454,7 @@ func runExecForContainer(container string, podName string, 
namespace string, com
        }
 
        var stdout, stderr bytes.Buffer
-       err = exec.Stream(remotecommand.StreamOptions{
+       err = exec.StreamWithContext(ctx, remotecommand.StreamOptions{
                Stdout: &stdout,
                Stderr: &stderr,
                Tty:    false,
@@ -445,7 +485,7 @@ func generateBaseSolrCloud(replicas int) 
*solrv1beta1.SolrCloud {
                        ZookeeperRef: &solrv1beta1.ZookeeperRef{
                                ConnectionInfo: 
&solrv1beta1.ZookeeperConnectionInfo{
                                        InternalConnectionString: 
sharedZookeeperConnectionString,
-                                       ChRoot:                   "/" + 
rand.String(5),
+                                       ChRoot:                   "/" + 
testNamespace() + "/" + rand.String(5),
                                },
                        },
                        // This seems to be the lowest memory & CPU that allow 
the tests to pass

Reply via email to