You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@solr.apache.org by ho...@apache.org on 2023/09/27 19:58:43 UTC
[solr-operator] branch main updated: Small fixes for integration tests
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 2694e6a Small fixes for integration tests
2694e6a is described below
commit 2694e6a1a6db5b305e77a2581514d3c19f844bfa
Author: Houston Putman <ho...@apache.org>
AuthorDate: Mon Sep 25 12:04:06 2023 -0400
Small fixes for integration tests
---
controllers/solrcloud_controller.go | 3 ++-
tests/e2e/resource_utils_test.go | 19 +++++++++++++++++--
tests/e2e/solrcloud_scaling_test.go | 13 ++++++++-----
tests/e2e/test_utils_test.go | 25 ++++++++++++-------------
4 files changed, 39 insertions(+), 21 deletions(-)
diff --git a/controllers/solrcloud_controller.go b/controllers/solrcloud_controller.go
index e586e77..6bd81e8 100644
--- a/controllers/solrcloud_controller.go
+++ b/controllers/solrcloud_controller.go
@@ -385,7 +385,8 @@ func (r *SolrCloudReconciler) Reconcile(ctx context.Context, req ctrl.Request) (
if err = controllerutil.SetControllerReference(instance, expectedStatefulSet, r.Scheme); err == nil {
err = r.Create(ctx, expectedStatefulSet)
}
- statefulSet = expectedStatefulSet
+ // Wait for the next reconcile loop
+ statefulSet = nil
} else if err == nil {
util.MaintainPreservedStatefulSetFields(expectedStatefulSet, foundStatefulSet)
diff --git a/tests/e2e/resource_utils_test.go b/tests/e2e/resource_utils_test.go
index a41770b..fc7a998 100644
--- a/tests/e2e/resource_utils_test.go
+++ b/tests/e2e/resource_utils_test.go
@@ -68,14 +68,14 @@ func deleteAndWait(ctx context.Context, object client.Object, additionalOffset .
func expectSolrCloudToBeReady(ctx context.Context, solrCloud *solrv1beta1.SolrCloud, additionalOffset ...int) *solrv1beta1.SolrCloud {
return expectSolrCloudWithChecks(ctx, solrCloud, func(g Gomega, found *solrv1beta1.SolrCloud) {
- g.Expect(found.Status.ReadyReplicas).To(Equal(*found.Spec.Replicas), "The SolrCloud should have all nodes come up healthy")
+ g.Expect(found.Status.ReadyReplicas).To(Equal(*solrCloud.Spec.Replicas), "The SolrCloud should have all nodes come up healthy")
// We have to check the status.replicas, because when a cloud is deleted/recreated, the statefulset can be recreated
// before the pods of the previous statefulset are deleted. So those pods will still be matched to the label selector,
// but the new statefulset doesn't know about them.
// The "Status.ReadyReplicas" value is populated from querying with the label selector
// The "Status.Replicas" value is populated from the statefulSet status
// So we need both to be equal to the requested number of replicas in order to know the statefulset is ready to go.
- g.Expect(found.Status.Replicas).To(Equal(*found.Spec.Replicas), "The SolrCloud should have all nodes come up healthy")
+ g.Expect(found.Status.Replicas).To(Equal(*solrCloud.Spec.Replicas), "The SolrCloud should have all nodes come up healthy")
}, resolveOffset(additionalOffset))
}
@@ -255,6 +255,21 @@ func expectStatefulSetWithChecks(ctx context.Context, parentResource client.Obje
return statefulSet
}
+func expectStatefulSetWithChecksAndTimeout(ctx context.Context, parentResource client.Object, statefulSetName string, within time.Duration, checkEvery time.Duration, additionalChecks func(Gomega, *appsv1.StatefulSet), additionalOffset ...int) *appsv1.StatefulSet {
+ statefulSet := &appsv1.StatefulSet{}
+ EventuallyWithOffset(resolveOffset(additionalOffset), func(g Gomega) {
+ g.Expect(k8sClient.Get(ctx, resourceKey(parentResource, statefulSetName), statefulSet)).To(Succeed(), "Expected StatefulSet does not exist")
+
+ testMapContainsOtherWithGomega(g, "StatefulSet pod template selector", statefulSet.Spec.Template.Labels, statefulSet.Spec.Selector.MatchLabels)
+ g.Expect(len(statefulSet.Spec.Selector.MatchLabels)).To(BeNumerically(">=", 1), "StatefulSet pod template selector must have at least 1 label")
+
+ if additionalChecks != nil {
+ additionalChecks(g, statefulSet)
+ }
+ }).Within(within).WithPolling(checkEvery).Should(Succeed())
+ return statefulSet
+}
+
func expectStatefulSetWithConsistentChecks(ctx context.Context, parentResource client.Object, statefulSetName string, additionalChecks func(Gomega, *appsv1.StatefulSet), additionalOffset ...int) *appsv1.StatefulSet {
statefulSet := &appsv1.StatefulSet{}
ConsistentlyWithOffset(resolveOffset(additionalOffset), func(g Gomega) {
diff --git a/tests/e2e/solrcloud_scaling_test.go b/tests/e2e/solrcloud_scaling_test.go
index d3a0868..1fa3890 100644
--- a/tests/e2e/solrcloud_scaling_test.go
+++ b/tests/e2e/solrcloud_scaling_test.go
@@ -26,6 +26,7 @@ import (
appsv1 "k8s.io/api/apps/v1"
"k8s.io/utils/pointer"
"sigs.k8s.io/controller-runtime/pkg/client"
+ "time"
)
var _ = FDescribe("E2E - SolrCloud - Scale Down", func() {
@@ -120,13 +121,15 @@ var _ = FDescribe("E2E - SolrCloud - Scale Down", func() {
Expect(clusterOp.Metadata).To(Equal("1"), "StatefulSet scaling lock operation has the wrong metadata.")
// Wait for the last pod to be deleted
- statefulSet = expectStatefulSetWithChecks(ctx, solrCloud, solrCloud.StatefulSetName(), func(g Gomega, found *appsv1.StatefulSet) {
+ expectStatefulSetWithChecks(ctx, solrCloud, solrCloud.StatefulSetName(), func(g Gomega, found *appsv1.StatefulSet) {
g.Expect(found.Status.Replicas).To(HaveValue(BeEquivalentTo(1)), "StatefulSet should now have 1 pods, after the replicas have been moved.")
})
- // Once the scale down actually occurs, the statefulSet annotations should already be removed
- clusterOp, err = controllers.GetCurrentClusterOp(statefulSet)
- Expect(err).ToNot(HaveOccurred(), "Error occurred while finding clusterLock for SolrCloud")
- Expect(clusterOp).To(BeNil(), "StatefulSet should not have a ScaleDown lock after scaling is complete.")
+ // Once the scale down actually occurs, the statefulSet annotations should be removed very soon
+ expectStatefulSetWithChecksAndTimeout(ctx, solrCloud, solrCloud.StatefulSetName(), time.Second*2, time.Millisecond*500, func(g Gomega, found *appsv1.StatefulSet) {
+ clusterOp, err = controllers.GetCurrentClusterOp(found)
+ g.Expect(err).ToNot(HaveOccurred(), "Error occurred while finding clusterLock for SolrCloud")
+ g.Expect(clusterOp).To(BeNil(), "StatefulSet should not have a ScaleDown lock after scaling is complete.")
+ })
expectNoPod(ctx, solrCloud, solrCloud.GetSolrPodName(1))
queryCollection(ctx, solrCloud, solrCollection1, 0)
diff --git a/tests/e2e/test_utils_test.go b/tests/e2e/test_utils_test.go
index 4e1db8f..b28df88 100644
--- a/tests/e2e/test_utils_test.go
+++ b/tests/e2e/test_utils_test.go
@@ -34,6 +34,7 @@ import (
"helm.sh/helm/v3/pkg/cli"
"helm.sh/helm/v3/pkg/release"
"helm.sh/helm/v3/pkg/storage/driver"
+ "io"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -432,7 +433,7 @@ func checkBackupWithGomega(ctx context.Context, solrCloud *solrv1beta1.SolrCloud
innerG.Expect(err).ToNot(HaveOccurred(), "Error occurred while fetching backup '%s' for collection '%s': %s", solrBackup.Name, collection, backupParams)
backupListResponse := &solr_api.SolrBackupListResponse{}
- innerG.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: %s", response)
innerG.Expect(backupListResponse.ResponseHeader.Status).To(BeZero(), "SolrBackupList API returned exception code: %d", backupListResponse.ResponseHeader.Status)
checks(innerG, collection, backupListResponse)
@@ -455,7 +456,7 @@ func (r *ExecError) Error() string {
}
func callSolrApiInPod(ctx context.Context, solrCloud *solrv1beta1.SolrCloud, httpMethod string, apiPath string, queryParams map[string]string, hostnameOptional ...string) (response string, err error) {
- hostname := "${POD_NAME}"
+ hostname := "${SOLR_HOST}"
if len(hostnameOptional) > 0 {
hostname = hostnameOptional[0]
}
@@ -511,28 +512,26 @@ func runExecForContainer(ctx context.Context, container string, podName string,
return "", fmt.Errorf("error while creating Executor: %v", err)
}
- var stdout, stderr bytes.Buffer
+ var combined, stdout, stderr bytes.Buffer
err = exec.StreamWithContext(ctx, remotecommand.StreamOptions{
- Stdout: &stdout,
- Stderr: &stderr,
+ Stdout: io.MultiWriter(&stdout, &combined),
+ Stderr: io.MultiWriter(&stderr, &combined),
Tty: false,
})
- responseOutput := stdout.String()
- errOutput := stderr.String()
+ response = combined.String()
if err != nil {
err = &ExecError{
Command: strings.Join(command, " "),
Err: err,
- ResponseOutput: responseOutput,
- ErrorOutput: errOutput,
+ ResponseOutput: stdout.String(),
+ ErrorOutput: stderr.String(),
}
- }
- if len(responseOutput) == 0 {
- response = errOutput
+
+ response = combined.String()
} else {
- response = responseOutput
+ response = stdout.String()
}
return response, err