blob: f85a3e13b0adde986babf2895523153199905178 [file] [log] [blame]
#!/usr/bin/env bash
# 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.
# exit immediately when a command fails
set -e
# only exit with zero if all commands of the pipeline exit successfully
set -o pipefail
# error on unset variables
set -u
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
REPO_DIR=$( cd -- "${SCRIPT_DIR}" &> /dev/null && cd -- ../.. &> /dev/null && pwd )
show_help() {
cat << EOF
Usage: ./tests/scripts/manage_e2e_tests.sh (run-tests|create-cluster|destroy-cluster|kubeconfig) [-h] [-k KUBERNETES_VERSION] [-s SOLR_IMAGE] [-a ADDITIONAL_IMAGES (bash array)] -i OPERATOR_IMAGE
Manage the Solr Operator E2E tests via a KinD cluster.
Available actions are: run-tests, create-cluster, destroy-cluster, kubeconfig
-h Display this help and exit
-i Solr Operator docker image to use (Optional, defaults to apache/solr-operator:<version>)
-k Kubernetes Version to test with (full tag, e.g. v1.21.2) (Optional, defaults to a compatible version)
-s Full solr image, or image tag (for the official Solr image), to test with (e.g. apache/solr-nightly:9.0.0, 8.11). (Optional, defaults to a compatible version)
-a Load additional local images into the test Kubernetes cluster. Provide option multiple times for multiple images. (Optional)
EOF
}
ADDITIONAL_IMAGES=("pravega/zookeeper:0.2.15")
OPTIND=1
while getopts hv:i:k:s:a: opt; do
case $opt in
h)
show_help
exit 0
;;
i) OPERATOR_IMAGE=$OPTARG
;;
k) KUBERNETES_VERSION=$OPTARG
;;
s) SOLR_IMAGE=$OPTARG
;;
a) ADDITIONAL_IMAGES+=("$OPTARG")
;;
*)
show_help >&2
exit 1
;;
esac
done
shift "$((OPTIND-1))" # Discard the options and sentinel --
ACTION="${1:-}"
if [[ -z "${ACTION:-}" ]]; then
echo "You must specify a cluster action. Either 'run-tests', 'create-cluster', 'destroy-cluster' or 'kubeconfig'." >&2 && exit 1
fi
ACTION_ARGS=("${@:2}")
if [[ -z "${OPERATOR_IMAGE:-}" ]]; then
echo "Specify a Docker image for the Solr Operator through -i, or through the OPERATOR_IMAGE env var" >&2 && exit 1
fi
if [[ -z "${KUBERNETES_VERSION:-}" ]]; then
KUBERNETES_VERSION="v1.21.14"
fi
if [[ -z "${SOLR_IMAGE:-}" ]]; then
SOLR_IMAGE="${SOLR_VERSION:-8.11}"
fi
if [[ "${SOLR_IMAGE}" != *":"* ]]; then
SOLR_IMAGE="solr:${SOLR_IMAGE}"
fi
IFS=$'\036'; RAW_GINKGO=(${RAW_GINKGO:-}); unset IFS
CLUSTER_NAME="$(echo "solr-op-e2e-${OPERATOR_IMAGE##*:}-k-${KUBERNETES_VERSION}-s-${SOLR_IMAGE##*:}" | tr '[:upper:]' '[:lower:]' | sed "s/snapshot/snap/" | sed "s/prerelease/pre/")"
export CLUSTER_NAME
export KUBE_CONTEXT="kind-${CLUSTER_NAME}"
export KUBERNETES_VERSION
export OPERATOR_IMAGE
export SOLR_IMAGE
export ADDITIONAL_IMAGES
export RAW_GINKGO
# Cluster Operation Options
export REUSE_KIND_CLUSTER_IF_EXISTS="${REUSE_KIND_CLUSTER_IF_EXISTS:-true}" # This is used for all start_cluster calls
export LEAVE_KIND_CLUSTER_ON_SUCCESS="${LEAVE_KIND_CLUSTER_ON_SUCCESS:-false}" # This is only used when using run_tests or run_with_cluster
function add_image_to_kind_repo_if_local() {
IMAGE="$1"
PULL_IF_NOT_LOCAL="$2"
if (docker image inspect "${IMAGE}" &>/dev/null); then
printf "\nUsing local version of image \"%s\".\nIf you want to use an updated version of this image, run \"docker pull %s\" before running the integration tests again.\n\n" "${IMAGE}" "${IMAGE}"
kind load docker-image --name "${CLUSTER_NAME}" "${IMAGE}"
else
if [ "${PULL_IF_NOT_LOCAL}" = true ]; then
printf "\nPulling image \"%s\" since it was not found locally.\n\n" "${IMAGE}" "${IMAGE}"
docker pull "${IMAGE}"
kind load docker-image --name "${CLUSTER_NAME}" "${IMAGE}"
else
printf "\nUsing the remote image \"%s\", since it was not found in the local Docker image list.\n\n" "${IMAGE}"
fi
fi
}
# These gingko params are customized via the following envVars
GINKGO_PARAM_NAMES=(--seed --procs --focus-file --label-filter --focus --skip)
GINKGO_PARAM_ENVS=( TEST_SEED TEST_PARALLELISM TEST_FILES TEST_LABELS TEST_FILTER TEST_SKIP)
function run_tests() {
start_cluster
GINKGO_PARAMS=()
for idx in "${!GINKGO_PARAM_NAMES[@]}"; do
param=${GINKGO_PARAM_NAMES[$idx]}
envName=${GINKGO_PARAM_ENVS[$idx]}
if [[ -n "${!envName:-}" ]]; then
GINKGO_PARAMS+=("${param}" "${!envName}")
fi
done
GINKGO_PARAMS+=("${RAW_GINKGO[@]}")
GINKGO_EDITOR_INTEGRATION=true ginkgo --randomize-all "${GINKGO_PARAMS[@]}" "${REPO_DIR}"/tests/e2e/...
printf "\n********************\n"
printf "Local end-to-end cluster test successfully run!\n\n"
if [[ "${LEAVE_KIND_CLUSTER_ON_SUCCESS}" != true ]]; then
printf "Deleting test KinD Kubernetes cluster after a successful test run.\n\n"
delete_cluster
fi
}
function export_kubeconfig() {
kind export kubeconfig --name "${CLUSTER_NAME}"
}
function delete_cluster() {
kind delete clusters "${CLUSTER_NAME}"
}
function start_cluster() {
if (kind get clusters | grep "^${CLUSTER_NAME}$"); then
if [[ "${REUSE_KIND_CLUSTER_IF_EXISTS}" = true ]]; then
printf "KinD cluster exists and REUSE_KIND_CLUSTER_IF_EXISTS = true, so using existing KinD cluster.\n\n"
kind export kubeconfig --name "${CLUSTER_NAME}"
setup_cluster
return
else
printf "Delete KinD cluster, so the test starts with a clean slate.\n\n"
delete_cluster
fi
fi
echo "Create test Kubernetes ${KUBERNETES_VERSION} cluster in KinD. This will allow us to test the CRDs, Helm chart and the Docker image."
kind create cluster --name "${CLUSTER_NAME}" --image "kindest/node:${KUBERNETES_VERSION}" --config "${SCRIPT_DIR}/e2e-kind-config.yaml"
setup_cluster
}
function setup_cluster() {
# Load the docker images into the cluster
add_image_to_kind_repo_if_local "${OPERATOR_IMAGE}" false
add_image_to_kind_repo_if_local "${SOLR_IMAGE}" true
for IMAGE in "${ADDITIONAL_IMAGES[@]}"; do
add_image_to_kind_repo_if_local "${IMAGE}" true
done
printf "Installing Solr & Zookeeper CRDs\n"
kubectl create -f "${REPO_DIR}/config/crd/bases/" 2>/dev/null || kubectl replace -f "${REPO_DIR}/config/crd/bases/"
kubectl create -f "${REPO_DIR}/config/dependencies/" 2>/dev/null || kubectl replace -f "${REPO_DIR}/config/dependencies/"
echo ""
}
case "$ACTION" in
run-tests)
run_tests
;;
create-cluster)
echo "Creating test Kubernetes ${KUBERNETES_VERSION} cluster in KinD. This will allow us to run end-to-end tests."
start_cluster
;;
destroy-cluster)
echo "Deleting test KinD Kubernetes cluster."
delete_cluster
;;
kubeconfig)
export_kubeconfig
;;
*)
show_help >&2
echo "" >&2
echo "Invalid action '${ACTION}' provided" >&2
exit 1
;;
esac