You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flink.apache.org by mb...@apache.org on 2022/11/30 11:59:06 UTC
[flink-kubernetes-operator] branch main updated: [FLINK-30199] Script for running Kubernetes Operator e2e tests manually
This is an automated email from the ASF dual-hosted git repository.
mbalassi pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/flink-kubernetes-operator.git
The following commit(s) were added to refs/heads/main by this push:
new f033976f [FLINK-30199] Script for running Kubernetes Operator e2e tests manually
f033976f is described below
commit f033976f2f225e8b5b869b0e523624230a2540eb
Author: pvary <pe...@gmail.com>
AuthorDate: Wed Nov 30 12:59:01 2022 +0100
[FLINK-30199] Script for running Kubernetes Operator e2e tests manually
Co-authored-by: Peter Vary <pe...@apple.com>
---
.github/workflows/ci.yml | 63 +-------
docs/content/docs/development/guide.md | 33 +++++
e2e-tests/run_tests.sh | 253 +++++++++++++++++++++++++++++++++
e2e-tests/utils.sh | 81 ++++++++++-
4 files changed, 371 insertions(+), 59 deletions(-)
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index c48b631c..7d5fd0b6 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -59,9 +59,8 @@ jobs:
start_minikube
- name: Install cert-manager
run: |
- kubectl get pods -A
- kubectl apply -f https://github.com/jetstack/cert-manager/releases/download/v1.8.2/cert-manager.yaml
- kubectl -n cert-manager wait --all=true --for=condition=Available --timeout=300s deploy
+ source e2e-tests/utils.sh
+ install_cert_manager
- name: Build image
run: |
export SHELL=/bin/bash
@@ -95,29 +94,8 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
- version: ["v1_16","v1_15","v1_14","v1_13"]
- namespace: ["default","flink"]
- mode: ["native", "standalone"]
- test:
- - test_application_kubernetes_ha.sh
- - test_application_operations.sh
- - test_sessionjob_kubernetes_ha.sh
- - test_sessionjob_operations.sh
- - test_multi_sessionjob.sh
- include:
- - namespace: flink
- extraArgs: '--create-namespace --set "watchNamespaces={default,flink}"'
- - version: v1_16
- image: flink:1.16
- - version: v1_15
- image: flink:1.15
- - version: v1_14
- image: flink:1.14
- - version: v1_13
- image: flink:1.13
- exclude:
- - namespace: default
- test: test_multi_sessionjob.sh
+ version: [ "v1_16","v1_15","v1_14","v1_13" ]
+ namespace: [ "default","flink" ]
name: e2e_ci
steps:
- uses: actions/checkout@v2
@@ -133,39 +111,10 @@ jobs:
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
restore-keys: |
${{ runner.os }}-maven-
- - name: Start minikube
+ - name: Run the tests
run: |
source e2e-tests/utils.sh
- start_minikube
- - name: Install cert-manager
- run: |
- kubectl get pods -A
- kubectl apply -f https://github.com/jetstack/cert-manager/releases/download/v1.8.2/cert-manager.yaml
- kubectl -n cert-manager wait --all=true --for=condition=Available --timeout=300s deploy
- - name: Build image
- run: |
- export SHELL=/bin/bash
- export DOCKER_BUILDKIT=1
- eval $(minikube -p minikube docker-env)
- docker build --progress=plain --no-cache -f ./Dockerfile -t flink-kubernetes-operator:ci-latest --progress plain .
- docker images
- - name: Start the operator
- run: |
- helm --debug install flink-kubernetes-operator -n ${{ matrix.namespace }} helm/flink-kubernetes-operator --set image.repository=flink-kubernetes-operator --set image.tag=ci-latest ${{ matrix.extraArgs }}
- kubectl wait --for=condition=Available --timeout=120s -n ${{ matrix.namespace }} deploy/flink-kubernetes-operator
- kubectl get pods
- - name: Run Flink e2e tests
- run: |
- sed -i "s/image: flink:.*/image: ${{ matrix.image }}/" e2e-tests/data/*.yaml
- sed -i "s/flinkVersion: .*/flinkVersion: ${{ matrix.version }}/" e2e-tests/data/*.yaml
- sed -i "s/mode: .*/mode: ${{ matrix.mode }}/" e2e-tests/data/*.yaml
- git diff HEAD
- echo "Running e2e-tests/$test"
- bash e2e-tests/${{ matrix.test }} || exit 1
- git reset --hard
- - name: Stop the operator
- run: |
- helm uninstall -n ${{ matrix.namespace }} flink-kubernetes-operator
+ bash e2e-tests/run_tests.sh -f ${{ matrix.version }} -n ${{ matrix.namespace }} -m native,standalone -d test_multi_sessionjob.sh test_application_operations.sh test_application_kubernetes_ha.sh test_sessionjob_kubernetes_ha.sh test_sessionjob_operations.sh || exit 1
- name: Stop minikube
run: |
source e2e-tests/utils.sh
diff --git a/docs/content/docs/development/guide.md b/docs/content/docs/development/guide.md
index 402a5f71..d786aeb6 100644
--- a/docs/content/docs/development/guide.md
+++ b/docs/content/docs/development/guide.md
@@ -82,6 +82,28 @@ To uninstall you can simply call:
helm uninstall flink-kubernetes-operator
```
+### Installing the operator locally using the e2e test scripts
+
+Alternatively you can skip [Building docker images](#building-docker-images) and
+[Installing the operator locally](#installing-the-operator-locally) altogether and with the
+use of the e2e test scripts you can install the Flink Kubernetes Operator from the local codebase.
+
+You still need to install [Docker Desktop](https://www.docker.com/products/docker-desktop),
+[minikube](https://minikube.sigs.k8s.io/docs/start/) and [helm](https://helm.sh/docs/intro/quickstart/) locally.
+
+The e2e test scripts automate the following steps:
+- Starting minikube (if needed)
+- Installing the Certification Manager (overwriting the existing one if already installed)
+- Compiling the Flink Kubernetes Operator binary from the local codebase
+- Building the Flink Kubernetes Operator Docker image using the previously compiled binary
+- Installing the freshly created Kubernetes Operator to the specified namespace
+- Run a single test to check if the operator is working as expected
+
+It could be done simplz by calling the following script:
+```bash
+./e2e-tests/run_tests.sh -k
+```
+
### Running the operator from the IDE
You can run or debug the `FlinkOperator` from your preferred IDE. The operator itself is accessing the deployed Flink clusters through the REST interface. When running locally the `rest.port`, `rest.address` and `kubernetes.rest-service.exposed.type` Flink configuration parameters must be modified.
@@ -152,3 +174,14 @@ Considering the cost of running the builds, the stability, and the maintainabili
All the unit tests, integration tests, and the end-to-end tests will be triggered for each PR.
Note: Please make sure the CI passed before merging.
+
+## Running the e2e tests locally
+
+After installing [Docker Desktop](https://www.docker.com/products/docker-desktop),
+[minikube](https://minikube.sigs.k8s.io/docs/start/) and [helm](https://helm.sh/docs/intro/quickstart/) locally
+you will be able to run the end-to-end tests locally using the `e2e-tests/run_tests.sh` script.
+
+For usage examples, please execute it with the following command:
+```bash
+./e2e-tests/run_tests.sh -h
+```
diff --git a/e2e-tests/run_tests.sh b/e2e-tests/run_tests.sh
new file mode 100755
index 00000000..a888168e
--- /dev/null
+++ b/e2e-tests/run_tests.sh
@@ -0,0 +1,253 @@
+#!/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.
+################################################################################
+
+
+readlink -f "$0" 2>/dev/null
+if [[ $? -ne 0 ]]; then
+ echo
+ echo "-----------------------------------"
+ echo "Please make sure that 'readlink -f \"$0\"' works."
+ echo "Maybe:"
+ echo " brew install coreutils"
+ echo " alias readlink=greadlink"
+ echo "-----------------------------------"
+ echo
+ exit 1
+fi
+
+ROOT_DIR=$(dirname $(dirname "$(readlink -f "$0")"))
+source "${ROOT_DIR}/e2e-tests/utils.sh"
+
+function help() {
+ # Display Help
+ echo "Script to run the flink kubernetes operator e2e tests."
+ echo
+ echo "Syntax: run_tests.sh [-i|-f|-m|-n|-s|-c|-h] scripts"
+ echo
+ echo "Options:"
+ echo " -i The Flink image to use (eg. flink:1.16 / flink:1.15 / flink:1.14). Only needed if the default docker image for the Flink version need to be changed."
+ echo " -f The Flink version(s) to use (eg. v1_16 / v1_15 / v1_14). Could contain multiple values separated by ','"
+ echo " -m The run mode(s) to use (eg. native / standalone). Could contain multiple values separated by ','"
+ echo " -n The namespace(s) to install the operator to. Could contain multiple values separated by ','"
+ echo " -s If set then skips the operator build (Make sure that minikube already has a version of the operator with the name of 'flink-kubernetes-operator:ci-latest')."
+ echo " -k After the test run the operator is not uninstalled. Will exit after the first test run."
+ echo " -d If set then the script will print debug logs."
+ echo " -h Print this help."
+ echo
+ echo "On MAC do not forget to start the 'minikube tunnel' in a different terminal."
+ echo "Visit this terminal from time to time, as it will ask you for root password."
+ echo "This is needed to forward the rest endpoint requests to port 80."
+ echo
+ echo "Examples:"
+ echo " Start the test_application_operations.sh (default) test on a newly built and deployed operator."
+ echo " The test will use the default settings for every config value:"
+ echo " ./run_tests.sh"
+ echo
+ echo " Start a single test using the currently compiled docker image of the operator which should be available on the minikube."
+ echo " The operator will be deployed in the 'flink' namespace:"
+ echo " ./run_tests.sh -s -namespace flink"
+ echo
+ echo " Run multiple tests:"
+ echo " ./run_tests.sh test_application_operations.sh test_sessionjob_operations.sh"
+ echo
+ echo " Run a single test and show debug logs:"
+ echo " ./run_tests.sh -d"
+ echo
+ echo " Use every possible configuration:"
+ echo " ./run_tests.sh -i 'flink:1.15' -f 'v1_15' -m standalone -n flink -s -k test_sessionjob_operations.sh"
+ echo
+ echo " Run every possible test configuration:"
+ echo " ./run_tests.sh -f v1_16,v1_15,v1_14,v1_13 -m native,standalone -n flink,default -d test_multi_sessionjob.sh test_application_operations.sh test_application_kubernetes_ha.sh test_sessionjob_kubernetes_ha.sh test_sessionjob_operations.sh"
+ echo
+ echo
+ echo " Use the script to compile and deploy the current version of the operator, and check the deployment:"
+ echo " ./run_tests.sh -k"
+ echo
+}
+
+# Default values
+image=""
+flink_versions="v1_16"
+modes="native"
+namespaces="default"
+skip_operator="false"
+keep_operator="false"
+
+# Flink version to Flink docker image mapping. Add new version and image here if it is supported.
+versions=("v1_16" "v1_15" "v1_14" "v1_13")
+images=("flink:1.16" "flink:1.15" "flink:1.14" "flink:1.13")
+
+while getopts "i:f:m:n:hsdk" option; do
+ case $option in
+ i) image=$OPTARG;;
+ f) flink_versions=$OPTARG;;
+ m) modes=$OPTARG;;
+ n) namespaces=$OPTARG;;
+ s) skip_operator="true";;
+ k) keep_operator="true";;
+ d) DEBUG="true";;
+ h) # display Help
+ help
+ exit;;
+ \?) # Invalid option
+ echo "Error: Invalid option"
+ exit;;
+ esac
+done
+
+scripts=${@:$OPTIND}
+if [[ -z "${scripts}" ]]; then
+ scripts="test_application_operations.sh"
+fi
+
+echo
+echo "-----------------------------------"
+echo "Start testing with the following parameters:"
+echo " Image: ${image}"
+echo " Flink version(s): ${flink_versions}"
+echo " Mode(s): ${modes}"
+echo " Operator namespace(s): ${namespaces}"
+echo " Skip operator build: ${skip_operator}"
+echo " Script() to run: ${scripts}"
+echo "-----------------------------------"
+
+pushd $ROOT_DIR
+echo
+echo "-----------------------------------"
+echo "Starting minikube"
+echo "-----------------------------------"
+echo
+time start_minikube
+
+echo
+echo "-----------------------------------"
+echo "Installing certificate manager"
+echo "-----------------------------------"
+echo
+time install_cert_manager
+
+if [[ "$skip_operator" = true ]]; then
+ echo
+ echo "-----------------------------------"
+ echo "Skipping operator build"
+ echo "-----------------------------------"
+else
+ echo
+ echo "-----------------------------------"
+ echo "Building operator"
+ echo "-----------------------------------"
+ echo
+ time build_image
+fi
+
+if [[ ! -z $(get_operator_pod_name 2>/dev/null) ]]; then
+ operator_pod_namespace=$(get_operator_pod_namespace)
+ echo
+ echo "-----------------------------------"
+ echo "Found existing operator. Please remove and restart the script. The following commands could be used:"
+ echo " helm delete flink-kubernetes-operator -n ${operator_pod_namespace}"
+ echo " kubectl delete namespace flink"
+ echo " kubectl delete serviceaccount flink"
+ echo " kubectl delete role flink"
+ echo " kubectl delete rolebinding flink-role-binding"
+ echo "-----------------------------------"
+ echo
+ exit 1;
+fi
+
+IFS=',' read -ra flink_version_list <<< "${flink_versions}"
+IFS=',' read -ra mode_list <<< "${modes}"
+IFS=',' read -ra namespace_list <<< "${namespaces}"
+
+for flink_version in ${flink_version_list[@]}; do
+ test_image=${image}
+ if [[ -z ${test_image} ]]; then
+ position=$(get_position ${flink_version} ${versions[@]})
+ if [[ -z ${position} ]]; then
+ echo
+ echo "-----------------------------------"
+ echo "Unknown Flink version ${flink_version}, please provide an image or a known Flink version"
+ echo "-----------------------------------"
+ echo
+ exit 1;
+ fi
+ test_image=${images[${position}]};
+ fi
+
+ for mode in ${mode_list[@]}; do
+ prepare_tests ${test_image} ${flink_version} ${mode}
+ for namespace in ${namespace_list[@]}; do
+ for script in ${scripts}; do
+ if [[ ${script} = "test_multi_sessionjob.sh" && ${namespace} = "default" ]]; then
+ echo
+ echo "-----------------------------------"
+ echo "Skipping ${script} on 'default' namespace, since an equivalent test will/should run on the 'flink' namespace and we want to save CPU time"
+ echo "-----------------------------------"
+ echo
+ continue
+ fi
+ echo
+ echo "-----------------------------------"
+ echo "Installing operator to '${namespace}' namespace"
+ echo "-----------------------------------"
+ echo
+ install_operator $namespace
+ echo
+ echo "-----------------------------------"
+ echo "Running test:"
+ echo " Namespace: ${namespace}"
+ echo " Flink version: ${flink_version}"
+ echo " Flink image: ${test_image}"
+ echo " Mode: ${mode}"
+ echo " Script: ${script}"
+ echo "-----------------------------------"
+ echo
+ time bash $ROOT_DIR/e2e-tests/${script}
+ if [[ $? -ne 0 ]]; then
+ echo
+ echo "-----------------------------------"
+ echo "Test failed: $ROOT_DIR/e2e-tests/${script}"
+ echo "-----------------------------------"
+ echo
+ exit 1
+ fi
+ echo
+ echo "-----------------------------------"
+ echo "Test succeeded: $ROOT_DIR/e2e-tests/${script}"
+ echo "-----------------------------------"
+ if [[ "$keep_operator" = true ]]; then
+ echo
+ echo "-----------------------------------"
+ echo "Keeping operator and exiting"
+ echo "-----------------------------------"
+ echo
+ exit 0
+ fi
+ echo
+ echo "-----------------------------------"
+ echo "Removing operator from '${namespace}' namespace"
+ echo "-----------------------------------"
+ echo
+ uninstall_operator $namespace
+ done
+ done
+ revert_tests
+ done
+done
+popd
diff --git a/e2e-tests/utils.sh b/e2e-tests/utils.sh
index e38f9631..a7726234 100755
--- a/e2e-tests/utils.sh
+++ b/e2e-tests/utils.sh
@@ -60,7 +60,12 @@ function wait_for_status {
function assert_available_slots() {
expected=$1
CLUSTER_ID=$2
- ip=$(minikube ip)
+ if [[ $OSTYPE == 'darwin'* ]]; then
+ # docker ingress forwards the ports to the localhost instead of the minikube ip on MacOS
+ ip="localhost"
+ else
+ ip=$(minikube ip)
+ fi
actual=$(curl "http://$ip/default/${CLUSTER_ID}/overview" 2>/dev/null | grep -E -o '"slots-available":[0-9]+' | awk -F':' '{print $2}')
if [[ "${expected}" != "${actual}" ]]; then
echo "Expected available slots: ${expected}, actual: ${actual}"
@@ -212,7 +217,7 @@ function stop_minikube {
}
function cleanup_and_exit() {
- if [ $TRAPPED_EXIT_CODE != 0 ];then
+ if [[ $TRAPPED_EXIT_CODE != 0 && -n $DEBUG ]]; then
debug_and_show_logs
fi
@@ -265,3 +270,75 @@ function create_namespace() {
fi;
}
+
+function install_cert_manager() {
+ if [[ -n ${DEBUG} ]]; then
+ kubectl get pods -A
+ fi
+ kubectl apply -f https://github.com/jetstack/cert-manager/releases/download/v1.8.2/cert-manager.yaml
+ kubectl -n cert-manager wait --all=true --for=condition=Available --timeout=300s deploy
+}
+
+function build_image() {
+ export SHELL=/bin/bash
+ export DOCKER_BUILDKIT=1
+ eval $(minikube docker-env)
+ docker build --progress=plain --no-cache -f ./Dockerfile -t flink-kubernetes-operator:ci-latest --progress plain .
+ if [[ -n ${DEBUG} ]]; then
+ docker images
+ fi
+}
+
+function install_operator() {
+ local namespace=$1
+
+ create_namespace flink
+ if [[ -n ${DEBUG} ]]; then
+ debug="--debug"
+ fi
+ helm ${debug} install flink-kubernetes-operator -n ${namespace} helm/flink-kubernetes-operator --set image.repository=flink-kubernetes-operator --set image.tag=ci-latest --create-namespace --set 'watchNamespaces={default,flink}'
+ kubectl wait --for=condition=Available --timeout=120s -n ${namespace} deploy/flink-kubernetes-operator
+ if [[ -n ${DEBUG} ]]; then
+ kubectl get pods
+ fi
+}
+
+function uninstall_operator() {
+ local namespace=$1
+
+ helm uninstall -n ${namespace} flink-kubernetes-operator
+ kubectl delete namespace flink
+ kubectl delete serviceaccount flink
+ kubectl delete role flink
+ kubectl delete rolebinding flink-role-binding
+}
+
+function prepare_tests() {
+ local image=$1
+ local flink_version=$2
+ local mode="$3"
+
+ sed -i -e "s/image: flink:.*/image: ${image}/" e2e-tests/data/*.yaml
+ sed -i -e "s/flinkVersion: .*/flinkVersion: ${flink_version}/" e2e-tests/data/*.yaml
+ sed -i -e "s/mode: .*/mode: ${mode}/" e2e-tests/data/*.yaml
+ if [[ -n ${DEBUG} ]]; then
+ git --no-pager diff HEAD
+ fi
+}
+
+function revert_tests() {
+ git checkout e2e-tests/data
+ rm e2e-tests/data/*.yaml-e
+}
+
+function get_position() {
+ local input_value=$1
+ shift
+ local input_array=("$@")
+
+ for i in "${!input_array[@]}"; do
+ if [[ "${input_array[$i]}" = "${input_value}" ]]; then
+ echo "${i}";
+ fi
+ done
+}