/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package e2e

import (
	. "github.com/onsi/ginkgo/v2"
	. "github.com/onsi/gomega"
	policyv1 "k8s.io/api/policy/v1"
	"regexp"
	"time"

	solrv1beta1 "github.com/apache/solr-operator/api/v1beta1"
	"github.com/apache/solr-operator/controllers/util"
	zk_api "github.com/apache/solr-operator/controllers/zk_api"
	"golang.org/x/net/context"
	appsv1 "k8s.io/api/apps/v1"
	corev1 "k8s.io/api/core/v1"
	netv1 "k8s.io/api/networking/v1"
	"k8s.io/apimachinery/pkg/api/resource"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/types"
	"k8s.io/apimachinery/pkg/util/intstr"
	"sigs.k8s.io/controller-runtime/pkg/client"
)

// Add one to an optional offset
func resolveOffset(additionalOffset []int) (offset int) {
	if len(additionalOffset) == 0 {
		offset = 0
	} else {
		offset = additionalOffset[0]
	}
	return offset + 1
}

func resourceKey(parentResource client.Object, name string) types.NamespacedName {
	return types.NamespacedName{Name: name, Namespace: parentResource.GetNamespace()}
}

func deleteAndWait(ctx context.Context, object client.Object, additionalOffset ...int) {
	key := resourceKey(object, object.GetName())
	kinds, _, err := k8sClient.Scheme().ObjectKinds(object)
	Expect(err).ToNot(HaveOccurred(), "Error fetching objectKind")
	Expect(kinds).ToNot(BeEmpty(), "No objectKinds found for object")
	objKind := kinds[0]
	Expect(k8sClient.Delete(ctx, object)).To(Or(Succeed(), MatchError(HaveSuffix("%q not found", testNamespace()))), "Failed to delete %s %s after test", objKind.Kind, key.Name)
	EventuallyWithOffset(resolveOffset(additionalOffset), func() error {
		return k8sClient.Get(ctx, key, object)
	}).Within(time.Minute).
		Should(MatchError(HaveSuffix("%q not found", key.Name)), objKind.Kind+" exists when it should not")
}

func expectSolrCloud(ctx context.Context, solrCloud *solrv1beta1.SolrCloud, additionalOffset ...int) *solrv1beta1.SolrCloud {
	return expectSolrCloudWithChecks(ctx, solrCloud, nil, resolveOffset(additionalOffset))
}

func expectSolrCloudWithChecks(ctx context.Context, solrCloud *solrv1beta1.SolrCloud, additionalChecks func(Gomega, *solrv1beta1.SolrCloud), additionalOffset ...int) *solrv1beta1.SolrCloud {
	foundSolrCloud := &solrv1beta1.SolrCloud{}
	EventuallyWithOffset(resolveOffset(additionalOffset), func(g Gomega) {
		g.Expect(k8sClient.Get(ctx, resourceKey(solrCloud, solrCloud.Name), foundSolrCloud)).To(Succeed(), "Expected SolrCloud does not exist")
		if additionalChecks != nil {
			additionalChecks(g, foundSolrCloud)
		}
	}).Should(Succeed())

	return foundSolrCloud
}

func expectSolrCloudWithConsistentChecks(ctx context.Context, solrCloud *solrv1beta1.SolrCloud, additionalChecks func(Gomega, *solrv1beta1.SolrCloud), additionalOffset ...int) *solrv1beta1.SolrCloud {
	foundSolrCloud := &solrv1beta1.SolrCloud{}
	ConsistentlyWithOffset(resolveOffset(additionalOffset), func(g Gomega) {
		g.Expect(k8sClient.Get(ctx, resourceKey(solrCloud, solrCloud.Name), foundSolrCloud)).To(Succeed(), "Expected SolrCloud does not exist")
		if additionalChecks != nil {
			additionalChecks(g, foundSolrCloud)
		}
	}).Should(Succeed())

	return foundSolrCloud
}

func expectSolrCloudStatus(ctx context.Context, solrCloud *solrv1beta1.SolrCloud, additionalOffset ...int) *solrv1beta1.SolrCloudStatus {
	return expectSolrCloudStatusWithChecks(ctx, solrCloud, nil, resolveOffset(additionalOffset))
}

func expectSolrCloudStatusWithChecks(ctx context.Context, solrCloud *solrv1beta1.SolrCloud, additionalChecks func(Gomega, *solrv1beta1.SolrCloudStatus), additionalOffset ...int) *solrv1beta1.SolrCloudStatus {
	foundSolrCloud := &solrv1beta1.SolrCloud{}
	EventuallyWithOffset(resolveOffset(additionalOffset), func(g Gomega) {
		g.Expect(k8sClient.Get(ctx, resourceKey(solrCloud, solrCloud.Name), foundSolrCloud)).To(Succeed(), "Expected SolrCloud does not exist")
		if additionalChecks != nil {
			additionalChecks(g, &foundSolrCloud.Status)
		}
	}).Should(Succeed())

	return &foundSolrCloud.Status
}

func expectSolrCloudStatusConsistentWithChecks(ctx context.Context, solrCloud *solrv1beta1.SolrCloud, additionalChecks func(Gomega, *solrv1beta1.SolrCloudStatus), additionalOffset ...int) *solrv1beta1.SolrCloudStatus {
	foundSolrCloud := &solrv1beta1.SolrCloud{}
	ConsistentlyWithOffset(resolveOffset(additionalOffset), func(g Gomega) {
		g.Expect(k8sClient.Get(ctx, resourceKey(solrCloud, solrCloud.Name), foundSolrCloud)).To(Succeed(), "Expected SolrCloud does not exist")
		if additionalChecks != nil {
			additionalChecks(g, &foundSolrCloud.Status)
		}
	}).Should(Succeed())

	return &foundSolrCloud.Status
}

func expectSolrPrometheusExporter(ctx context.Context, solrPrometheusExporter *solrv1beta1.SolrPrometheusExporter, additionalOffset ...int) *solrv1beta1.SolrPrometheusExporter {
	return expectSolrPrometheusExporterWithChecks(ctx, solrPrometheusExporter, nil, resolveOffset(additionalOffset))
}

func expectSolrPrometheusExporterWithChecks(ctx context.Context, solrPrometheusExporter *solrv1beta1.SolrPrometheusExporter, additionalChecks func(Gomega, *solrv1beta1.SolrPrometheusExporter), additionalOffset ...int) *solrv1beta1.SolrPrometheusExporter {
	foundSolrPrometheusExporter := &solrv1beta1.SolrPrometheusExporter{}
	EventuallyWithOffset(resolveOffset(additionalOffset), func(g Gomega) {
		g.Expect(k8sClient.Get(ctx, resourceKey(solrPrometheusExporter, solrPrometheusExporter.Name), foundSolrPrometheusExporter)).To(Succeed(), "Expected SolrPrometheusExporter does not exist")
		if additionalChecks != nil {
			additionalChecks(g, foundSolrPrometheusExporter)
		}
	}).Should(Succeed())

	return foundSolrPrometheusExporter
}

func expectSolrPrometheusExporterWithConsistentChecks(ctx context.Context, solrPrometheusExporter *solrv1beta1.SolrPrometheusExporter, additionalChecks func(Gomega, *solrv1beta1.SolrPrometheusExporter), additionalOffset ...int) *solrv1beta1.SolrPrometheusExporter {
	foundSolrPrometheusExporter := &solrv1beta1.SolrPrometheusExporter{}
	ConsistentlyWithOffset(resolveOffset(additionalOffset), func(g Gomega) {
		g.Expect(k8sClient.Get(ctx, resourceKey(solrPrometheusExporter, solrPrometheusExporter.Name), foundSolrPrometheusExporter)).To(Succeed(), "Expected SolrPrometheusExporter does not exist")
		if additionalChecks != nil {
			additionalChecks(g, foundSolrPrometheusExporter)
		}
	}).Should(Succeed())

	return foundSolrPrometheusExporter
}

func expectSolrBackup(ctx context.Context, solrBackup *solrv1beta1.SolrBackup, additionalOffset ...int) *solrv1beta1.SolrBackup {
	return expectSolrBackupWithChecks(ctx, solrBackup, nil, resolveOffset(additionalOffset))
}

func expectSolrBackupWithChecks(ctx context.Context, solrBackup *solrv1beta1.SolrBackup, additionalChecks func(Gomega, *solrv1beta1.SolrBackup), additionalOffset ...int) *solrv1beta1.SolrBackup {
	foundSolrBackup := &solrv1beta1.SolrBackup{}
	EventuallyWithOffset(resolveOffset(additionalOffset), func(g Gomega) {
		g.Expect(k8sClient.Get(ctx, resourceKey(solrBackup, solrBackup.Name), foundSolrBackup)).To(Succeed(), "Expected SolrBackup does not exist")
		if additionalChecks != nil {
			additionalChecks(g, foundSolrBackup)
		}
	}).Should(Succeed())

	return foundSolrBackup
}

func expectSolrBackupWithConsistentChecks(ctx context.Context, solrBackup *solrv1beta1.SolrBackup, additionalChecks func(Gomega, *solrv1beta1.SolrBackup), additionalOffset ...int) *solrv1beta1.SolrBackup {
	foundSolrBackup := &solrv1beta1.SolrBackup{}
	ConsistentlyWithOffset(resolveOffset(additionalOffset), func(g Gomega) {
		g.Expect(k8sClient.Get(ctx, resourceKey(solrBackup, solrBackup.Name), foundSolrBackup)).To(Succeed(), "Expected SolrBackup does not exist")
		if additionalChecks != nil {
			additionalChecks(g, foundSolrBackup)
		}
	}).Should(Succeed())

	return foundSolrBackup
}

func expectSecret(ctx context.Context, parentResource client.Object, secretName string, additionalOffset ...int) *corev1.Secret {
	return expectSecretWithChecks(ctx, parentResource, secretName, nil, resolveOffset(additionalOffset))
}

func expectSecretWithChecks(ctx context.Context, parentResource client.Object, secretName string, additionalChecks func(Gomega, *corev1.Secret), additionalOffset ...int) *corev1.Secret {
	found := &corev1.Secret{}
	EventuallyWithOffset(resolveOffset(additionalOffset), func(g Gomega) {
		g.Expect(k8sClient.Get(ctx, resourceKey(parentResource, secretName), found)).To(Succeed(), "Expected Secret does not exist")
		if additionalChecks != nil {
			additionalChecks(g, found)
		}
	}).Should(Succeed())

	return found
}

func expectStatefulSet(ctx context.Context, parentResource client.Object, statefulSetName string, additionalOffset ...int) *appsv1.StatefulSet {
	return expectStatefulSetWithChecks(ctx, parentResource, statefulSetName, nil, resolveOffset(additionalOffset))
}

func expectStatefulSetWithChecks(ctx context.Context, parentResource client.Object, statefulSetName string, 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)
		}
	}).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
}

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) {
		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)
		}
	}).Should(Succeed())

	return statefulSet
}

func expectNoStatefulSet(ctx context.Context, parentResource client.Object, statefulSetName string, additionalOffset ...int) {
	ConsistentlyWithOffset(resolveOffset(additionalOffset), func() error {
		return k8sClient.Get(ctx, resourceKey(parentResource, statefulSetName), &appsv1.StatefulSet{})
	}).Should(MatchError("statefulsets.apps \""+statefulSetName+"\" not found"), "StatefulSet 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))
}

func expectServiceWithChecks(ctx context.Context, parentResource client.Object, serviceName string, selectorLables map[string]string, isHeadless bool, additionalChecks func(Gomega, *corev1.Service), additionalOffset ...int) *corev1.Service {
	service := &corev1.Service{}
	EventuallyWithOffset(resolveOffset(additionalOffset), func(g Gomega) {
		Expect(k8sClient.Get(ctx, resourceKey(parentResource, serviceName), service)).To(Succeed(), "Expected Service does not exist")

		g.Expect(service.Spec.Selector).To(Equal(selectorLables), "Service is not pointing to the correct Pods.")

		if isHeadless {
			g.Expect(service.Spec.ClusterIP).To(Equal("None"), "The clusterIP field of a headless service should be None")
		} else {
			g.Expect(service.Spec.ClusterIP).To(Not(Equal("None")), "The clusterIP field of a non-headless service should not be None")
		}

		if additionalChecks != nil {
			additionalChecks(g, service)
		}
	}).Should(Succeed())

	By("recreating the Service after it is deleted")
	ExpectWithOffset(resolveOffset(additionalOffset), k8sClient.Delete(ctx, service)).To(Succeed())
	EventuallyWithOffset(
		resolveOffset(additionalOffset),
		func() (types.UID, error) {
			newResource := &corev1.Service{}
			err := k8sClient.Get(ctx, resourceKey(parentResource, serviceName), newResource)
			if err != nil {
				return "", err
			}
			return newResource.UID, nil
		}).Should(And(Not(BeEmpty()), Not(Equal(service.UID))), "New Service, with new UID, not created.")

	return service
}

func expectServiceWithConsistentChecks(ctx context.Context, parentResource client.Object, serviceName string, selectorLables map[string]string, isHeadless bool, additionalChecks func(Gomega, *corev1.Service), additionalOffset ...int) *corev1.Service {
	service := &corev1.Service{}
	ConsistentlyWithOffset(resolveOffset(additionalOffset), func(g Gomega) {
		Expect(k8sClient.Get(ctx, resourceKey(parentResource, serviceName), service)).To(Succeed(), "Expected Service does not exist")

		g.Expect(service.Spec.Selector).To(Equal(selectorLables), "Service is not pointing to the correct Pods.")

		if isHeadless {
			g.Expect(service.Spec.ClusterIP).To(Equal("None"), "The clusterIP field of a headless service should be None")
		} else {
			g.Expect(service.Spec.ClusterIP).To(Not(Equal("None")), "The clusterIP field of a non-headless service should not be None")
		}

		if additionalChecks != nil {
			additionalChecks(g, service)
		}
	}).Should(Succeed())

	return service
}

func expectNoService(ctx context.Context, parentResource client.Object, serviceName string, message string, additionalOffset ...int) {
	ConsistentlyWithOffset(resolveOffset(additionalOffset), func() error {
		return k8sClient.Get(ctx, resourceKey(parentResource, serviceName), &corev1.Service{})
	}).Should(MatchError("services \""+serviceName+"\" not found"), message, "Service exists when it should not")
}

func expectNoServices(ctx context.Context, parentResource client.Object, message string, serviceNames []string, additionalOffset ...int) {
	ConsistentlyWithOffset(resolveOffset(additionalOffset), func(g Gomega) {
		for _, serviceName := range serviceNames {
			g.Expect(k8sClient.Get(ctx, resourceKey(parentResource, serviceName), &corev1.Service{})).To(MatchError("services \""+serviceName+"\" not found"), message)
		}
	}).Should(Succeed())
}

func expectIngress(ctx context.Context, parentResource client.Object, ingressName string, additionalOffset ...int) *netv1.Ingress {
	return expectIngressWithChecks(ctx, parentResource, ingressName, nil, resolveOffset(additionalOffset))
}

func expectIngressWithChecks(ctx context.Context, parentResource client.Object, ingressName string, additionalChecks func(Gomega, *netv1.Ingress), additionalOffset ...int) *netv1.Ingress {
	ingress := &netv1.Ingress{}
	EventuallyWithOffset(resolveOffset(additionalOffset), func(g Gomega) {
		g.Expect(k8sClient.Get(ctx, resourceKey(parentResource, ingressName), ingress)).To(Succeed(), "Expected Ingress does not exist")

		if additionalChecks != nil {
			additionalChecks(g, ingress)
		}
	}).Should(Succeed())

	By("recreating the Ingress after it is deleted")
	ExpectWithOffset(resolveOffset(additionalOffset), k8sClient.Delete(ctx, ingress)).To(Succeed())
	EventuallyWithOffset(
		resolveOffset(additionalOffset),
		func() (types.UID, error) {
			newResource := &netv1.Ingress{}
			err := k8sClient.Get(ctx, resourceKey(parentResource, ingressName), newResource)
			if err != nil {
				return "", err
			}
			return newResource.UID, nil
		}).Should(And(Not(BeEmpty()), Not(Equal(ingress.UID))), "New Ingress, with new UID, not created.")

	return ingress
}

func expectIngressWithConsistentChecks(ctx context.Context, parentResource client.Object, ingressName string, additionalChecks func(Gomega, *netv1.Ingress), additionalOffset ...int) *netv1.Ingress {
	ingress := &netv1.Ingress{}
	ConsistentlyWithOffset(resolveOffset(additionalOffset), func(g Gomega) {
		g.Expect(k8sClient.Get(ctx, resourceKey(parentResource, ingressName), ingress)).To(Succeed(), "Expected Ingress does not exist")

		if additionalChecks != nil {
			additionalChecks(g, ingress)
		}
	}).Should(Succeed())

	return ingress
}

func expectNoIngress(ctx context.Context, parentResource client.Object, ingressName string, additionalOffset ...int) {
	ConsistentlyWithOffset(resolveOffset(additionalOffset), func() error {
		return k8sClient.Get(ctx, resourceKey(parentResource, ingressName), &netv1.Ingress{})
	}).Should(MatchError("ingresses.networking.k8s.io \""+ingressName+"\" not found"), "Ingress exists when it should not")
}

func expectPodDisruptionBudget(ctx context.Context, parentResource client.Object, podDisruptionBudgetName string, selector *metav1.LabelSelector, maxUnavailable intstr.IntOrString, additionalOffset ...int) *policyv1.PodDisruptionBudget {
	return expectPodDisruptionBudgetWithChecks(ctx, parentResource, podDisruptionBudgetName, selector, maxUnavailable, nil, resolveOffset(additionalOffset))
}

func expectPodDisruptionBudgetWithChecks(ctx context.Context, parentResource client.Object, podDisruptionBudgetName string, selector *metav1.LabelSelector, maxUnavailable intstr.IntOrString, additionalChecks func(Gomega, *policyv1.PodDisruptionBudget), additionalOffset ...int) *policyv1.PodDisruptionBudget {
	podDisruptionBudget := &policyv1.PodDisruptionBudget{}
	EventuallyWithOffset(resolveOffset(additionalOffset), func(g Gomega) {
		g.Expect(k8sClient.Get(ctx, resourceKey(parentResource, podDisruptionBudgetName), podDisruptionBudget)).To(Succeed(), "Expected ConfigMap does not exist")

		// Verify the PodDisruptionBudget Spec
		g.Expect(podDisruptionBudget.Spec.Selector).To(Equal(selector), "PodDisruptionBudget does not have the correct selector.")
		g.Expect(podDisruptionBudget.Spec.MaxUnavailable).To(Equal(&maxUnavailable), "PodDisruptionBudget does not have the correct maxUnavailable setting.")

		if additionalChecks != nil {
			additionalChecks(g, podDisruptionBudget)
		}
	}).Should(Succeed())

	By("recreating the PodDisruptionBudget after it is deleted")
	ExpectWithOffset(resolveOffset(additionalOffset), k8sClient.Delete(ctx, podDisruptionBudget)).To(Succeed())
	EventuallyWithOffset(
		resolveOffset(additionalOffset),
		func() (types.UID, error) {
			newResource := &policyv1.PodDisruptionBudget{}
			err := k8sClient.Get(ctx, resourceKey(parentResource, podDisruptionBudgetName), newResource)
			if err != nil {
				return "", err
			}
			return newResource.UID, nil
		}).Should(And(Not(BeEmpty()), Not(Equal(podDisruptionBudget.UID))), "New PodDisruptionBudget, with new UID, not created.")

	return podDisruptionBudget
}

func expectConfigMap(ctx context.Context, parentResource client.Object, configMapName string, configMapData map[string]string, additionalOffset ...int) *corev1.ConfigMap {
	return expectConfigMapWithChecks(ctx, parentResource, configMapName, configMapData, nil, resolveOffset(additionalOffset))
}

func expectConfigMapWithChecks(ctx context.Context, parentResource client.Object, configMapName string, configMapData map[string]string, additionalChecks func(Gomega, *corev1.ConfigMap), additionalOffset ...int) *corev1.ConfigMap {
	configMap := &corev1.ConfigMap{}
	EventuallyWithOffset(resolveOffset(additionalOffset), func(g Gomega) {
		g.Expect(k8sClient.Get(ctx, resourceKey(parentResource, configMapName), configMap)).To(Succeed(), "Expected ConfigMap does not exist")

		// Verify the ConfigMap Data
		g.Expect(configMap.Data).To(Equal(configMapData), "ConfigMap does not have the correct data.")

		if additionalChecks != nil {
			additionalChecks(g, configMap)
		}
	}).Should(Succeed())

	By("recreating the ConfigMap after it is deleted")
	ExpectWithOffset(resolveOffset(additionalOffset), k8sClient.Delete(ctx, configMap)).To(Succeed())
	EventuallyWithOffset(
		resolveOffset(additionalOffset),
		func() (types.UID, error) {
			newResource := &corev1.ConfigMap{}
			err := k8sClient.Get(ctx, resourceKey(parentResource, configMapName), newResource)
			if err != nil {
				return "", err
			}
			return newResource.UID, nil
		}).Should(And(Not(BeEmpty()), Not(Equal(configMap.UID))), "New ConfigMap, with new UID, not created.")

	return configMap
}

func expectConfigMapWithConsistentChecks(ctx context.Context, parentResource client.Object, configMapName string, configMapData map[string]string, additionalChecks func(Gomega, *corev1.ConfigMap), additionalOffset ...int) *corev1.ConfigMap {
	configMap := &corev1.ConfigMap{}
	ConsistentlyWithOffset(resolveOffset(additionalOffset), func(g Gomega) {
		g.Expect(k8sClient.Get(ctx, resourceKey(parentResource, configMapName), configMap)).To(Succeed(), "Expected ConfigMap does not exist")

		// Verify the ConfigMap Data
		g.Expect(configMap.Data).To(Equal(configMapData), "ConfigMap does not have the correct data.")

		if additionalChecks != nil {
			additionalChecks(g, configMap)
		}
	}).Should(Succeed())

	return configMap
}

func expectNoConfigMap(ctx context.Context, parentResource client.Object, configMapName string, additionalOffset ...int) {
	ConsistentlyWithOffset(resolveOffset(additionalOffset), func() error {
		return k8sClient.Get(ctx, resourceKey(parentResource, configMapName), &corev1.ConfigMap{})
	}).Should(MatchError("configmaps \""+configMapName+"\" not found"), "ConfigMap exists when it should not")
}

func expectDeployment(ctx context.Context, parentResource client.Object, deploymentName string, additionalOffset ...int) *appsv1.Deployment {
	return expectDeploymentWithChecks(ctx, parentResource, deploymentName, nil, resolveOffset(additionalOffset))
}

func expectDeploymentWithChecks(ctx context.Context, parentResource client.Object, deploymentName string, additionalChecks func(Gomega, *appsv1.Deployment), additionalOffset ...int) *appsv1.Deployment {
	deployment := &appsv1.Deployment{}
	EventuallyWithOffset(resolveOffset(additionalOffset), func(g Gomega) {
		g.Expect(k8sClient.Get(ctx, resourceKey(parentResource, deploymentName), deployment)).To(Succeed(), "Expected Deployment does not exist")

		// Verify the Deployment Specs
		testMapContainsOtherWithGomega(g, "Deployment pod template selector", deployment.Spec.Template.Labels, deployment.Spec.Selector.MatchLabels)
		g.Expect(len(deployment.Spec.Selector.MatchLabels)).To(BeNumerically(">=", 1), "Deployment pod template selector must have at least 1 label")

		if additionalChecks != nil {
			additionalChecks(g, deployment)
		}
	}).Should(Succeed())

	By("recreating the Deployment after it is deleted")
	ExpectWithOffset(resolveOffset(additionalOffset), k8sClient.Delete(ctx, deployment)).To(Succeed())
	EventuallyWithOffset(
		resolveOffset(additionalOffset),
		func() (types.UID, error) {
			newResource := &appsv1.Deployment{}
			err := k8sClient.Get(ctx, resourceKey(parentResource, deploymentName), newResource)
			if err != nil {
				return "", err
			}
			return newResource.UID, nil
		}).Should(And(Not(BeEmpty()), Not(Equal(deployment.UID))), "New Deployment, with new UID, not created.")

	return deployment
}

func expectDeploymentWithConsistentChecks(ctx context.Context, parentResource client.Object, deploymentName string, additionalChecks func(Gomega, *appsv1.Deployment), additionalOffset ...int) *appsv1.Deployment {
	deployment := &appsv1.Deployment{}
	ConsistentlyWithOffset(resolveOffset(additionalOffset), func(g Gomega) {
		g.Expect(k8sClient.Get(ctx, resourceKey(parentResource, deploymentName), deployment)).To(Succeed(), "Expected Deployment does not exist")

		// Verify the Deployment Specs
		testMapContainsOtherWithGomega(g, "Deployment pod template selector", deployment.Spec.Template.Labels, deployment.Spec.Selector.MatchLabels)
		g.Expect(len(deployment.Spec.Selector.MatchLabels)).To(BeNumerically(">=", 1), "Deployment pod template selector must have at least 1 label")

		if additionalChecks != nil {
			additionalChecks(g, deployment)
		}
	}).Should(Succeed())

	return deployment
}

func expectNoDeployment(ctx context.Context, parentResource client.Object, deploymentName string, additionalOffset ...int) {
	ConsistentlyWithOffset(resolveOffset(additionalOffset), func() error {
		return k8sClient.Get(ctx, resourceKey(parentResource, deploymentName), &appsv1.Deployment{})
	}).Should(MatchError("deployments.apps \""+deploymentName+"\" not found"), "Deployment exists when it should not")
}

func expectNoNamespace(ctx context.Context, name string, additionalOffset ...int) {
	ConsistentlyWithOffset(resolveOffset(additionalOffset), func() error {
		return k8sClient.Get(ctx, client.ObjectKey{Name: name}, &corev1.Namespace{})
	}).Should(MatchError("namespaces \""+name+"\" not found"), "Namespace exists when it should not")
}

func createBasicAuthSecret(name string, key string, ns string) *corev1.Secret {
	secretData := map[string][]byte{corev1.BasicAuthUsernameKey: []byte(key), corev1.BasicAuthPasswordKey: []byte("secret password")}
	return &corev1.Secret{ObjectMeta: metav1.ObjectMeta{Name: name, Namespace: ns}, Data: secretData, Type: corev1.SecretTypeBasicAuth}
}

func expectInitdbVolumeMount(podTemplate *corev1.PodTemplateSpec, additionalOffset ...int) {
	offset := resolveOffset(additionalOffset)
	ExpectWithOffset(offset, podTemplate.Spec.Volumes).To(Not(BeNil()), "No volumes given for Pod")
	var initdbVol *corev1.Volume = nil
	for _, vol := range podTemplate.Spec.Volumes {
		if vol.Name == "initdb" {
			initdbVol = &vol
			break
		}
	}
	ExpectWithOffset(offset, initdbVol).To(Not(BeNil()), "initdb volume not found in pod template; volumes: %v", podTemplate.Spec.Volumes)
	ExpectWithOffset(offset, initdbVol.VolumeSource.EmptyDir).To(Not(BeNil()), "initdb volume should be an emptyDir")

	ExpectWithOffset(offset, podTemplate.Spec.Containers).To(Not(BeEmpty()), "No containers specified for Pod")
	mainContainer := podTemplate.Spec.Containers[0]
	var initdbMount *corev1.VolumeMount = nil
	for _, m := range mainContainer.VolumeMounts {
		if m.Name == "initdb" {
			initdbMount = &m
			break
		}
	}
	ExpectWithOffset(offset, initdbMount).To(Not(BeNil()), "No volume mount found for initdb")
	ExpectWithOffset(offset, initdbMount.MountPath).To(Equal(util.InitdbPath), "Incorrect Mount Path")
}

func expectInitContainer(podTemplate *corev1.PodTemplateSpec, expName string, expVolMountName string, expVolMountPath string, additionalOffset ...int) *corev1.Container {
	offset := resolveOffset(additionalOffset)
	var expInitContainer *corev1.Container = nil
	for _, cnt := range podTemplate.Spec.InitContainers {
		if cnt.Name == expName {
			expInitContainer = &cnt
			break
		}
	}
	ExpectWithOffset(offset, expInitContainer).To(Not(BeNil()), "Didn't find the %s InitContainer", expName)
	ExpectWithOffset(offset, expInitContainer.Command).To(HaveLen(3), "Wrong command length for %s init container", expName)

	var volMount *corev1.VolumeMount = nil
	for _, m := range expInitContainer.VolumeMounts {
		if m.Name == expVolMountName {
			volMount = &m
			break
		}
	}
	ExpectWithOffset(offset, volMount).To(Not(BeNil()), "No %s volumeMount for the %s InitContainer", expVolMountName, expName)
	ExpectWithOffset(offset, volMount.MountPath).To(Equal(expVolMountPath), "Wrong mount path for the %s InitContainer", expName)

	return expInitContainer
}

// filter env vars by name using a supplied match function
func filterVarsByName(envVars []corev1.EnvVar, f func(string) bool) []corev1.EnvVar {
	filtered := make([]corev1.EnvVar, 0)
	for _, v := range envVars {
		if f(v.Name) {
			filtered = append(filtered, v)
		}
	}
	return filtered
}

func testPodEnvVariables(expectedEnvVars map[string]string, foundEnvVars []corev1.EnvVar, additionalOffset ...int) {
	testPodEnvVariablesWithGomega(Default, expectedEnvVars, foundEnvVars, resolveOffset(additionalOffset))
}

func testPodEnvVariablesWithGomega(g Gomega, expectedEnvVars map[string]string, foundEnvVars []corev1.EnvVar, additionalOffset ...int) {
	envVarRegex := regexp.MustCompile(`\$\([a-zA-Z0-9_]+\)`)
	offset := resolveOffset(additionalOffset)
	matchCount := 0
	var processedEnvVarNames = make([]string, len(foundEnvVars))
	for i, envVar := range foundEnvVars {
		if expectedVal, match := expectedEnvVars[envVar.Name]; match {
			matchCount += 1
			g.ExpectWithOffset(offset, envVar.Value).To(Equal(expectedVal), "Wrong value for env variable '%s' in podSpec", envVar.Name)
		}

		// Check that the current envVar only references other env-vars that have already been defined
		envVarsReferencedByCurrent := envVarRegex.FindAllString(envVar.Value, -1)
		for _, referencedVar := range envVarsReferencedByCurrent {
			referencedVarTrimmed := referencedVar[2 : len(referencedVar)-1] // "$(ENV_VAR_NAME)" -> "ENV_VAR_NAME"
			g.Expect(processedEnvVarNames).To(ContainElement(referencedVarTrimmed),
				"Env-var %s with value [%s] must be defined after the env-var it depends on: %s",
				envVar.Name, envVar.Value, referencedVarTrimmed)
		}

		processedEnvVarNames[i] = envVar.Name
	}
	g.ExpectWithOffset(offset, matchCount).To(Equal(len(expectedEnvVars)), "Not all expected env variables found in podSpec")
}

func testMapContainsOther(mapName string, base map[string]string, other map[string]string, additionalOffset ...int) {
	testMapContainsOtherWithGomega(Default, mapName, base, other, resolveOffset(additionalOffset))
}

func testMapContainsOtherWithGomega(g Gomega, mapName string, base map[string]string, other map[string]string, additionalOffset ...int) {
	offset := resolveOffset(additionalOffset)
	for k, v := range other {
		g.ExpectWithOffset(offset, base).To(HaveKeyWithValue(k, v), "Expected key '%s' is not correct in found %s", k, mapName)
	}
}

func insertExpectedAclEnvVars(dest map[string]string, hasReadOnly bool) {
	expectedEnvVars := getExpectedAclEnvVars(hasReadOnly)
	for _, expectedEnvVar := range expectedEnvVars {
		dest[expectedEnvVar.Name] = expectedEnvVar.Value
	}
}

func getExpectedAclEnvVars(hasReadOnly bool) []corev1.EnvVar {
	/*
		Populates ACL related env vars are set correctly and in the correct order, assuming a very specific test SolrCloud config:
		set hasReadOnly = false if ReadOnlyACL is not provided
					AllACL: &solrv1beta1.ZookeeperACL{
						SecretRef:   "secret-name",
						UsernameKey: "user",
						PasswordKey: "pass",
					},
					ReadOnlyACL: &solrv1beta1.ZookeeperACL{
						SecretRef:   "read-secret-name",
						UsernameKey: "read-only-user",
						PasswordKey: "read-only-pass",
					},

	*/
	f := false
	zkAclEnvVars := []corev1.EnvVar{
		{
			Name: "ZK_ALL_ACL_USERNAME",
			ValueFrom: &corev1.EnvVarSource{
				SecretKeyRef: &corev1.SecretKeySelector{
					LocalObjectReference: corev1.LocalObjectReference{Name: "secret-name"},
					Key:                  "user",
					Optional:             &f,
				},
			},
		},
		{
			Name: "ZK_ALL_ACL_PASSWORD",
			ValueFrom: &corev1.EnvVarSource{
				SecretKeyRef: &corev1.SecretKeySelector{
					LocalObjectReference: corev1.LocalObjectReference{Name: "secret-name"},
					Key:                  "pass",
					Optional:             &f,
				},
			},
		},
	}
	if hasReadOnly {
		zkAclEnvVars = append(zkAclEnvVars,
			corev1.EnvVar{
				Name: "ZK_READ_ACL_USERNAME",
				ValueFrom: &corev1.EnvVarSource{
					SecretKeyRef: &corev1.SecretKeySelector{
						LocalObjectReference: corev1.LocalObjectReference{Name: "read-secret-name"},
						Key:                  "read-only-user",
						Optional:             &f,
					},
				},
			},
			corev1.EnvVar{
				Name: "ZK_READ_ACL_PASSWORD",
				ValueFrom: &corev1.EnvVarSource{
					SecretKeyRef: &corev1.SecretKeySelector{
						LocalObjectReference: corev1.LocalObjectReference{Name: "read-secret-name"},
						Key:                  "read-only-pass",
						Optional:             &f,
					},
				},
			},
			corev1.EnvVar{
				Name:      "SOLR_ZK_CREDS_AND_ACLS",
				Value:     "-DzkACLProvider=org.apache.solr.common.cloud.VMParamsAllAndReadonlyDigestZkACLProvider -DzkCredentialsProvider=org.apache.solr.common.cloud.VMParamsSingleSetCredentialsDigestZkCredentialsProvider -DzkDigestUsername=$(ZK_ALL_ACL_USERNAME) -DzkDigestPassword=$(ZK_ALL_ACL_PASSWORD) -DzkDigestReadonlyUsername=$(ZK_READ_ACL_USERNAME) -DzkDigestReadonlyPassword=$(ZK_READ_ACL_PASSWORD)",
				ValueFrom: nil,
			})
	} else {
		zkAclEnvVars = append(zkAclEnvVars,
			corev1.EnvVar{
				Name:      "SOLR_ZK_CREDS_AND_ACLS",
				Value:     "-DzkACLProvider=org.apache.solr.common.cloud.VMParamsAllAndReadonlyDigestZkACLProvider -DzkCredentialsProvider=org.apache.solr.common.cloud.VMParamsSingleSetCredentialsDigestZkCredentialsProvider -DzkDigestUsername=$(ZK_ALL_ACL_USERNAME) -DzkDigestPassword=$(ZK_ALL_ACL_PASSWORD)",
				ValueFrom: nil,
			})
	}
	return zkAclEnvVars
}

func testACLEnvVarsWithGomega(g Gomega, actualEnvVars []corev1.EnvVar, hasReadOnly bool, additionalOffset ...int) {
	zkAclEnvVars := getExpectedAclEnvVars(hasReadOnly)
	g.ExpectWithOffset(resolveOffset(additionalOffset), actualEnvVars).To(Equal(zkAclEnvVars), "ZK ACL Env Vars are not correct")
}

func cleanupTest(ctx context.Context, parentResource client.Object) {
	cleanupObjects := []client.Object{
		// Solr Operator CRDs, modify this list whenever CRDs are added/deleted
		&solrv1beta1.SolrCloud{}, &solrv1beta1.SolrBackup{}, &solrv1beta1.SolrPrometheusExporter{},
		&zk_api.ZookeeperCluster{},

		// All dependent Kubernetes types, in order of dependence (deployment then replicaSet then pod)
		&corev1.ConfigMap{}, &netv1.Ingress{},
		&corev1.PersistentVolumeClaim{}, &corev1.PersistentVolume{},
		&appsv1.StatefulSet{}, &appsv1.Deployment{}, &appsv1.ReplicaSet{}, &corev1.Pod{}, &corev1.PersistentVolumeClaim{},
		&corev1.Secret{},
	}
	By("deleting all managed resources")
	for _, obj := range cleanupObjects {
		Expect(k8sClient.DeleteAllOf(ctx, obj, client.InNamespace(parentResource.GetNamespace()))).To(Succeed())
	}

	By("deleting all services individually")
	// Clean up Services individually, since they do not support delete collection
	serviceList := &corev1.ServiceList{}
	Expect(k8sClient.List(ctx, serviceList, client.InNamespace(parentResource.GetNamespace()))).To(Succeed(), "List all of the services to delete in the namespace")
	for _, item := range serviceList.Items {
		Expect(k8sClient.Delete(ctx, &item)).To(Or(Succeed(), MatchError("services \""+item.Name+"\" not found")))
	}
}

var (
	testKubeDomain        = "kube.domain.com"
	testDomain            = "test.domain.com"
	testAdditionalDomains = []string{
		"test1.domain.com",
		"test2.domain.com",
	}
	testPodAnnotations = map[string]string{
		"testP1": "valueP1",
		"testP2": "valueP2",
	}
	testPodLabels = map[string]string{
		"testP3": "valueP3",
		"testP4": "valueP4",
	}
	testSSAnnotations = map[string]string{
		"testSS1": "valueSS1",
		"testSS2": "valueSS2",
	}
	testSSLabels = map[string]string{
		"testSS3": "valueSS3",
		"testSS4": "valueSS4",
	}
	testIngressLabels = map[string]string{
		"testI1": "valueI1",
		"testI2": "valueI2",
	}
	testIngressAnnotations = map[string]string{
		"testI3": "valueI3",
		"testI4": "valueI4",
	}
	testCommonServiceLabels = map[string]string{
		"testCS1": "valueCS1",
		"testCS2": "valueCS2",
	}
	testCommonServiceAnnotations = map[string]string{
		"testCS3": "valueCS3",
		"testCS4": "valueCS4",
	}
	testHeadlessServiceLabels = map[string]string{
		"testHS1": "valueHS1",
		"testHS2": "valueHS2",
	}
	testHeadlessServiceAnnotations = map[string]string{
		"testHS3": "valueHS3",
		"testHS4": "valueHS4",
	}
	testNodeServiceLabels = map[string]string{
		"testNS1": "valueNS1",
		"testNS2": "valueNS2",
	}
	testNodeServiceAnnotations = map[string]string{
		"testNS3": "valueNS3",
		"testNS4": "valueNS4",
	}
	testConfigMapLabels = map[string]string{
		"testCM1": "valueCM1",
		"testCM2": "valueCM2",
	}
	testConfigMapAnnotations = map[string]string{
		"testCM3": "valueCM3",
		"testCM4": "valueCM4",
	}
	testDeploymentAnnotations = map[string]string{
		"testD1": "valueD1",
		"testD2": "valueD2",
	}
	testDeploymentLabels = map[string]string{
		"testD3": "valueD3",
		"testD4": "valueD4",
	}
	testMetricsServiceLabels = map[string]string{
		"testS1": "valueS1",
		"testS2": "valueS2",
	}
	testMetricsServiceAnnotations = map[string]string{
		"testS3": "valueS3",
		"testS4": "valueS4",
	}
	testNodeSelectors = map[string]string{
		"kubernetes.io/arch": "amd64",
		"kubernetes.io/os":   "linux",
		"solrclouds":         "true",
	}
	testProbeLivenessNonDefaults = &corev1.Probe{
		InitialDelaySeconds: 20,
		TimeoutSeconds:      1,
		SuccessThreshold:    1,
		FailureThreshold:    3,
		PeriodSeconds:       10,
		ProbeHandler: corev1.ProbeHandler{
			HTTPGet: &corev1.HTTPGetAction{
				Scheme: corev1.URISchemeHTTP,
				Path:   "/solr/admin/info/system",
				Port:   intstr.FromInt(8983),
			},
		},
	}
	testProbeReadinessNonDefaults = &corev1.Probe{
		InitialDelaySeconds: 15,
		TimeoutSeconds:      1,
		SuccessThreshold:    1,
		FailureThreshold:    3,
		PeriodSeconds:       5,
		ProbeHandler: corev1.ProbeHandler{
			TCPSocket: &corev1.TCPSocketAction{
				Port: intstr.FromInt(8983),
			},
		},
	}
	testProbeStartup = &corev1.Probe{
		InitialDelaySeconds: 1,
		TimeoutSeconds:      1,
		SuccessThreshold:    1,
		FailureThreshold:    5,
		PeriodSeconds:       5,
		ProbeHandler: corev1.ProbeHandler{
			Exec: &corev1.ExecAction{
				Command: []string{
					"ls",
				},
			},
		},
	}
	testLifecycle = &corev1.Lifecycle{
		PostStart: &corev1.LifecycleHandler{
			Exec: &corev1.ExecAction{
				Command: []string{"/bin/sh", "-c", "echo Hello from the postStart handler"},
			},
		},
		PreStop: &corev1.LifecycleHandler{
			Exec: &corev1.ExecAction{
				Command: []string{"/bin/sh", "-c", "echo Hello from the preStop handler"},
			},
		},
	}
	testTolerations = []corev1.Toleration{
		{
			Effect:   "NoSchedule",
			Key:      "node-restriction.kubernetes.io/dedicated",
			Value:    "solrclouds",
			Operator: "Exists",
		},
	}
	testTolerationsPromExporter = []corev1.Toleration{
		{
			Effect:   "NoSchedule",
			Operator: "Exists",
		},
	}
	testPriorityClass              = "p4"
	testImagePullSecretName        = "MAIN_SECRET"
	testImagePullSecretName2       = "ANOTHER_SECRET"
	testAdditionalImagePullSecrets = []corev1.LocalObjectReference{
		{Name: "ADDITIONAL_SECRET_1"},
		{Name: "ADDITIONAL_SECRET_2"},
	}
	testTerminationGracePeriodSeconds = int64(50)
	extraVars                         = []corev1.EnvVar{
		{
			Name:  "VAR_1",
			Value: "VAL_1",
		},
		{
			Name: "VAR_2",
			ValueFrom: &corev1.EnvVarSource{
				FieldRef: &corev1.ObjectFieldSelector{
					APIVersion: "v1",
					FieldPath:  "metadata.name",
				},
			},
		},
	}
	one                    = int32(1)
	two                    = int32(2)
	three                  = int32(3)
	four                   = int32(4)
	five                   = int32(5)
	one64                  = int64(1)
	two64                  = int64(2)
	testPodSecurityContext = corev1.PodSecurityContext{
		RunAsUser:  &one64,
		RunAsGroup: &two64,
	}
	extraVolumes = []solrv1beta1.AdditionalVolume{
		{
			Name: "vol1",
			Source: corev1.VolumeSource{
				EmptyDir: &corev1.EmptyDirVolumeSource{},
			},
			DefaultContainerMount: &corev1.VolumeMount{
				Name:      "ignore",
				ReadOnly:  false,
				MountPath: "/test/mount/path",
				SubPath:   "sub/",
			},
		},
	}
	testAffinity = &corev1.Affinity{
		PodAffinity: &corev1.PodAffinity{
			RequiredDuringSchedulingIgnoredDuringExecution: []corev1.PodAffinityTerm{
				{
					TopologyKey: "testKey",
				},
			},
			PreferredDuringSchedulingIgnoredDuringExecution: nil,
		},
	}
	testResources = corev1.ResourceRequirements{
		Limits: map[corev1.ResourceName]resource.Quantity{
			corev1.ResourceCPU: resource.MustParse("5300m"),
		},
		Requests: map[corev1.ResourceName]resource.Quantity{
			corev1.ResourceEphemeralStorage: resource.MustParse("5Gi"),
		},
	}
	testResources2 = corev1.ResourceRequirements{
		Limits: map[corev1.ResourceName]resource.Quantity{
			corev1.ResourceCPU: resource.MustParse("400m"),
		},
		Requests: map[corev1.ResourceName]resource.Quantity{
			corev1.ResourceEphemeralStorage: resource.MustParse("3Gi"),
		},
	}
	extraContainers1 = []corev1.Container{
		{
			Name:                     "container1",
			Image:                    "image1",
			TerminationMessagePolicy: "File",
			TerminationMessagePath:   "/dev/termination-log",
			ImagePullPolicy:          "Always",
		},
		{
			Name:                     "container2",
			Image:                    "image2",
			TerminationMessagePolicy: "File",
			TerminationMessagePath:   "/dev/termination-log",
			ImagePullPolicy:          "Always",
		},
	}
	extraContainers2 = []corev1.Container{
		{
			Name:                     "container3",
			Image:                    "image3",
			TerminationMessagePolicy: "File",
			TerminationMessagePath:   "/dev/termination-log",
			ImagePullPolicy:          "Always",
		},
		{
			Name:                     "container4",
			Image:                    "image4",
			TerminationMessagePolicy: "File",
			TerminationMessagePath:   "/dev/termination-log",
			ImagePullPolicy:          "Always",
		},
	}
	testServiceAccountName = "test-service-account"
	zkConf                 = solrv1beta1.ZookeeperConfig{
		InitLimit:            1,
		SyncLimit:            5,
		PreAllocSize:         2,
		CommitLogCount:       10,
		MaxCnxns:             4,
		MinSessionTimeout:    6,
		QuorumListenOnAllIPs: true,
	}
	testTopologySpreadConstraints = []corev1.TopologySpreadConstraint{
		{
			MaxSkew:           3,
			TopologyKey:       "zone",
			WhenUnsatisfiable: corev1.DoNotSchedule,
			LabelSelector: &metav1.LabelSelector{
				MatchLabels: map[string]string{"test": "label"},
			},
		},
		{
			MaxSkew:           3,
			TopologyKey:       "region",
			WhenUnsatisfiable: corev1.ScheduleAnyway,
		},
	}
	testIngressClass = "test-ingress-class"
	testSolrZKOpts   = "-Dsolr.zk.opts=this"
	testSolrOpts     = "-Dsolr.opts=this"
)
