X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=blobdiff_plain;f=test%2Fcommon%2Ftestcase_common.sh;h=b13b479f013303cf2b3182d7ce116a9eceb9875e;hb=refs%2Fchanges%2F33%2F9733%2F1;hp=66cbd96bbe079304a4ace330922b2a8b198dbf94;hpb=4c571ffb2d7e8b01d7bd2e66f15b7c610532e579;p=nonrtric.git diff --git a/test/common/testcase_common.sh b/test/common/testcase_common.sh index 66cbd96b..b13b479f 100755 --- a/test/common/testcase_common.sh +++ b/test/common/testcase_common.sh @@ -26,8 +26,11 @@ __print_args() { echo "Args: remote|remote-remove docker|kube --env-file [release] [auto-clean] [--stop-at-error] " echo " [--ricsim-prefix ] [--use-local-image +] [--use-snapshot-image +]" - echo " [--use-staging-image +] [--use-release-image +] [--image-repo ]" + echo " [--use-staging-image +] [--use-release-image +] [--use-external-image +] [--image-repo ]" + echo " [--repo-policy local|remote] [--cluster-timeout ] [--print-stats]" + echo " [--override ] [--pre-clean] [--gen-stats] [--delete-namespaces]" + echo " [--delete-containers] [--endpoint-stats] [--kubeconfig ] [--host-path-dir ]" + echo " [--kubecontext ] [--docker-host ] [--docker-proxy ]" } if [ $# -eq 1 ] && [ "$1" == "help" ]; then @@ -43,7 +46,7 @@ if [ $# -eq 1 ] && [ "$1" == "help" ]; then echo "remote-remove - Same as 'remote' but will also try to pull fresh images from remote repositories" echo "docker - Test executed in docker environment" echo "kube - Test executed in kubernetes environment - requires an already started kubernetes environment" - echo "--env-file - The script will use the supplied file to read environment variables from" + echo "--env-file - The script will use the supplied file to read environment variables from" echo "release - If this flag is given the script will use release version of the images" echo "auto-clean - If the function 'auto_clean_containers' is present in the end of the test script then all containers will be stopped and removed. If 'auto-clean' is not given then the function has no effect." echo "--stop-at-error - The script will stop when the first failed test or configuration" @@ -52,9 +55,22 @@ if [ $# -eq 1 ] && [ "$1" == "help" ]; then echo "--use-snapshot-image - The script will use images from the nexus snapshot repo for the supplied apps, space separated list of app short names" echo "--use-staging-image - The script will use images from the nexus staging repo for the supplied apps, space separated list of app short names" echo "--use-release-image - The script will use images from the nexus release repo for the supplied apps, space separated list of app short names" + echo "--use-external-image - The script will use images from the external (non oran/onap) repo for the supplied apps, space separated list of app short names" echo "--image-repo - Url to optional image repo. Only locally built images will be re-tagged and pushed to this repo" echo "--repo-policy - Policy controlling which images to re-tag and push if param --image-repo is set. Default is 'local'" echo "--cluster-timeout - Optional timeout for cluster where it takes time to obtain external ip/host-name. Timeout in seconds. " + echo "--print-stats - Print current test stats after each test." + echo "--override - Override setting from the file supplied by --env-file" + echo "--pre-clean - Will clean kube resouces when running docker and vice versa" + echo "--gen-stats - Collect container/pod runtime statistics" + echo "--delete-namespaces - Delete kubernetes namespaces before starting tests - but only those created by the test scripts. Kube mode only. Ignored if running with prestarted apps." + echo "--delete-containers - Delete docker containers before starting tests - but only those created by the test scripts. Docker mode only." + echo "--endpoint-stats - Collect endpoint statistics" + echo "--kubeconfig - Configure kubectl to use cluster specific cluster config file" + echo "--host-path-dir - (Base-)path on local-hostmounted to all VMs (nodes), for hostpath volumes in kube" + echo "--kubecontext - Configure kubectl to use a certain context, e.g 'minikube'" + echo "--docker-host - Configure docker to use docker in e.g. a VM" + echo "--docker-proxy - Configure ip/host to docker when docker is running in a VM" echo "" echo "List of app short names supported: "$APP_SHORT_NAMES exit 0 @@ -85,17 +101,17 @@ echo -ne $EBOLD # default test environment variables TEST_ENV_VAR_FILE="" +#Override env file, will be added on top of the above file +TEST_ENV_VAR_FILE_OVERRIDE="" echo "Test case started as: ${BASH_SOURCE[$i+1]} "$@ -#Localhost constants -LOCALHOST_NAME="localhost" -LOCALHOST_HTTP="http://localhost" -LOCALHOST_HTTPS="https://localhost" - # Var to hold 'auto' in case containers shall be stopped when test case ends AUTO_CLEAN="" +# Var to indicate pre clean, if flag --pre-clean is set the script will clean kube resouces when running docker and vice versa +PRE_CLEAN="0" + # Var to hold the app names to use local images for USE_LOCAL_IMAGES="" @@ -108,6 +124,8 @@ USE_STAGING_IMAGES="" # Var to hold the app names to use remote release images for USE_RELEASE_IMAGES="" +# Var to hold the app names to use external release images for +USE_EXTERNAL_IMAGES="" # Use this var (STOP_AT_ERROR=1 in the test script) for debugging/trouble shooting to take all logs and exit at first FAIL test case STOP_AT_ERROR=0 @@ -117,6 +135,11 @@ STOP_AT_ERROR=0 # Applies only to images defined in the test-env files with image names and tags defined as XXXX_RELEASE IMAGE_CATEGORY="DEV" +#Var to indicate docker-compose version, V1 or V2 +#V1 names replicated containers __ +#V2 names replicated containers -- +DOCKER_COMPOSE_VERSION="V1" + # Function to indent cmd output with one space indent1() { sed 's/^/ /'; } @@ -147,18 +170,52 @@ TESTLOGS=$PWD/logs # files in the ./tmp is moved to ./tmp/prev when a new test is started if [ ! -d "tmp" ]; then mkdir tmp + if [ $? -ne 0 ]; then + echo "Cannot create dir for temp files, $PWD/tmp" + echo "Exiting...." + exit 1 + fi fi curdir=$PWD cd tmp if [ $? -ne 0 ]; then echo "Cannot cd to $PWD/tmp" - echo "Dir cannot be created. Exiting...." + echo "Exiting...." + exit 1 fi + +TESTENV_TEMP_FILES=$PWD + if [ ! -d "prev" ]; then mkdir prev + if [ $? -ne 0 ]; then + echo "Cannot create dir for previous temp files, $PWD/prev" + echo "Exiting...." + exit 1 + fi +fi + +TMPFILES=$(ls -A | grep -vw prev) +if [ ! -z "$TMPFILES" ]; then + cp -r $TMPFILES prev #Move all temp files to prev dir + if [ $? -ne 0 ]; then + echo "Cannot move temp files in $PWD to previous temp files in, $PWD/prev" + echo "Exiting...." + exit 1 + fi + if [ $(pwd | xargs basename) == "tmp" ]; then #Check that current dir is tmp...for safety + + rm -rf $TMPFILES # Remove all temp files + fi fi + cd $curdir -mv ./tmp/* ./tmp/prev 2> /dev/null +if [ $? -ne 0 ]; then + echo "Cannot cd to $curdir" + echo "Exiting...." + exit 1 +fi + # Create a http message log for this testcase HTTPLOG=$PWD"/.httplog_"$ATC".txt" @@ -183,10 +240,16 @@ rm $TESTLOGS/$ATC/*.log &> /dev/null rm $TESTLOGS/$ATC/*.txt &> /dev/null rm $TESTLOGS/$ATC/*.json &> /dev/null +#Create result file in the log dir +echo "1" > "$TESTLOGS/$ATC/.result$ATC.txt" + # Log all output from the test case to a TC log TCLOG=$TESTLOGS/$ATC/TC.log exec &> >(tee ${TCLOG}) +echo $(date) > $TESTLOGS/$ATC/endpoint_tc_start.log +echo "Test failed" > $TESTLOGS/$ATC/endpoint_tc_end.log # Will be overritten if test is ok + #Variables for counting tests as well as passed and failed tests RES_TEST=0 RES_PASS=0 @@ -194,6 +257,41 @@ RES_FAIL=0 RES_CONF_FAIL=0 RES_DEVIATION=0 +#Var to control if current stats shall be printed +PRINT_CURRENT_STATS=0 + +#Var to control if container/pod runtim statistics shall be collected +COLLECT_RUNTIME_STATS=0 +COLLECT_RUNTIME_STATS_PID=0 + +#Var to control if endpoint statistics shall be collected +COLLECT_ENDPOINT_STATS=0 + +#Var to control if namespaces shall be delete before test setup +DELETE_KUBE_NAMESPACES=0 + +#Var to control if containers shall be delete before test setup +DELETE_CONTAINERS=0 + +#Var to configure kubectl from a config file or context +KUBECONF="" + +#Localhost, may be set to another host/ip by cmd parameter +LOCALHOST_NAME="localhost" + +#Reseting vars related to token/keys used by kubeproxy when istio is enabled +#The vars are populated if istio is used in the testcase +KUBE_PROXY_CURL_JWT="" +KUBE_PROXY_ISTIO_JWKS_KEYS="" + +#Var pointing to dir mounted to each kubernetes node (master and workers) +#Persistent volumes using "hostpath" are allocated beneath the point. +#Typically it is a dir on local host mounted to each VM running the master and worker. +#So the intention is make this dir available so the PODs can be restarted on any +#node and still access the persistent data +#If not set from cmd line, the path is defaults to "/tmp" +HOST_PATH_BASE_DIR="" + #File to keep deviation messages DEVIATION_FILE=".tmp_deviations" rm $DEVIATION_FILE &> /dev/null @@ -204,10 +302,19 @@ trap_fnc() { if [ $? -eq 127 ]; then echo -e $RED"Function not found, setting script to FAIL"$ERED ((RES_CONF_FAIL++)) + __print_current_stats fi } trap trap_fnc ERR +# Trap to kill subprocess for stats collection (if running) +trap_fnc2() { + if [ $COLLECT_RUNTIME_STATS_PID -ne 0 ]; then + kill $COLLECT_RUNTIME_STATS_PID + fi +} +trap trap_fnc2 EXIT + # Counter for tests TEST_SEQUENCE_NR=1 @@ -220,10 +327,18 @@ __log_test_start() { ((TEST_SEQUENCE_NR++)) } +# Function to print current statistics +__print_current_stats() { + if [ $PRINT_CURRENT_STATS -ne 0 ]; then + echo " Current stats - exe-time, tests, passes, fails, conf fails, deviations: $(($SECONDS-$TCTEST_START)), $RES_TEST, $RES_PASS, $RES_FAIL, $RES_CONF_FAIL, $RES_DEVIATION" + fi +} + # General function to log a failed test case __log_test_fail_general() { echo -e $RED" FAIL."$1 $ERED ((RES_FAIL++)) + __print_current_stats __check_stop_at_error } @@ -231,6 +346,7 @@ __log_test_fail_general() { __log_test_fail_status_code() { echo -e $RED" FAIL. Exepected status "$1", got "$2 $3 $ERED ((RES_FAIL++)) + __print_current_stats __check_stop_at_error } @@ -238,6 +354,7 @@ __log_test_fail_status_code() { __log_test_fail_body() { echo -e $RED" FAIL, returned body not correct"$ERED ((RES_FAIL++)) + __print_current_stats __check_stop_at_error } @@ -245,6 +362,7 @@ __log_test_fail_body() { __log_test_fail_not_supported() { echo -e $RED" FAIL, function not supported"$ERED ((RES_FAIL++)) + __print_current_stats __check_stop_at_error } @@ -255,6 +373,7 @@ __log_test_pass() { fi ((RES_PASS++)) echo -e $GREEN" PASS"$EGREEN + __print_current_stats } #Counter for configurations @@ -272,6 +391,7 @@ __log_conf_start() { __log_conf_fail_general() { echo -e $RED" FAIL."$1 $ERED ((RES_CONF_FAIL++)) + __print_current_stats __check_stop_at_error } @@ -279,6 +399,7 @@ __log_conf_fail_general() { __log_conf_fail_status_code() { echo -e $RED" FAIL. Exepected status "$1", got "$2 $3 $ERED ((RES_CONF_FAIL++)) + __print_current_stats __check_stop_at_error } @@ -286,6 +407,15 @@ __log_conf_fail_status_code() { __log_conf_fail_body() { echo -e $RED" FAIL, returned body not correct"$ERED ((RES_CONF_FAIL++)) + __print_current_stats + __check_stop_at_error +} + +# Function to log a configuration that is not supported +__log_conf_fail_not_supported() { + echo -e $RED" FAIL, function not supported"$ERED$@ + ((RES_CONF_FAIL++)) + __print_current_stats __check_stop_at_error } @@ -295,16 +425,62 @@ __log_conf_ok() { echo $@ fi echo -e $GREEN" OK"$EGREEN + __print_current_stats +} + +# Function to collect stats on endpoints +# args: [] +__collect_endpoint_stats() { + if [ $COLLECT_ENDPOINT_STATS -eq 0 ]; then + return + fi + ENDPOINT_COUNT=1 + if [ $# -gt 5 ]; then + ENDPOINT_COUNT=$6 + fi + ENDPOINT_STAT_FILE=$TESTLOGS/$ATC/endpoint_$ATC_$1_$2".log" + ENDPOINT_POS=0 + ENDPOINT_NEG=0 + if [ -f $ENDPOINT_STAT_FILE ]; then + ENDPOINT_VAL=$(< $ENDPOINT_STAT_FILE) + ENDPOINT_POS=$(echo $ENDPOINT_VAL | cut -f4 -d ' ' | cut -f1 -d '/') + ENDPOINT_NEG=$(echo $ENDPOINT_VAL | cut -f5 -d ' ' | cut -f1 -d '/') + fi + + if [ $5 -ge 200 ] && [ $5 -lt 300 ]; then + let ENDPOINT_POS=ENDPOINT_POS+$ENDPOINT_COUNT + else + let ENDPOINT_NEG=ENDPOINT_NEG+$ENDPOINT_COUNT + fi + + printf '%-2s %-10s %-45s %-16s %-16s' "#" "$3" "$4" "$ENDPOINT_POS/$ENDPOINT_POS" "$ENDPOINT_NEG/$ENDPOINT_NEG" > $ENDPOINT_STAT_FILE +} + +# Function to collect stats on endpoints +# args: +__collect_endpoint_stats_image_info() { + if [ $COLLECT_ENDPOINT_STATS -eq 0 ]; then + return + fi + ENDPOINT_STAT_FILE=$TESTLOGS/$ATC/imageinfo_$ATC_$1".log" + echo $A1PMS_IMAGE > $ENDPOINT_STAT_FILE } #Var for measuring execution time TCTEST_START=$SECONDS +#Vars to hold the start time and timer text for a custom timer +TC_TIMER_STARTTIME="" +TC_TIMER_TIMER_TEXT="" +TC_TIMER_CURRENT_FAILS="" # Then numer of failed test when timer starts. + # Compared with the current number of fails at timer stop + # to judge the measurement reliability + #File to save timer measurement results TIMER_MEASUREMENTS=".timer_measurement.txt" -echo -e "Activity \t Duration" > $TIMER_MEASUREMENTS +echo -e "Activity \t Duration \t Info" > $TIMER_MEASUREMENTS -# If this is set, some images (control by the parameter repo-polcy) will be re-tagged and pushed to this repo before any +# If this is set, some images (controlled by the parameter repo-policy) will be re-tagged and pushed to this repo before any IMAGE_REPO_ADR="" IMAGE_REPO_POLICY="local" CLUSTER_TIME_OUT=0 @@ -511,6 +687,31 @@ while [ $paramerror -eq 0 ] && [ $foundparm -eq 0 ]; do fi fi fi + if [ $paramerror -eq 0 ]; then + if [ "$1" == "--use-external-image" ]; then + USE_EXTERNAL_IMAGES="" + shift + while [ $# -gt 0 ] && [[ "$1" != "--"* ]]; do + USE_EXTERNAL_IMAGES=$USE_EXTERNAL_IMAGES" "$1 + if [[ "$AVAILABLE_IMAGES_OVERRIDE" != *"$1"* ]]; then + paramerror=1 + if [ -z "$paramerror_str" ]; then + paramerror_str="App name $1 is not available for release override for flag: '--use-external-image'" + fi + fi + shift; + done + foundparm=0 + if [ -z "$USE_EXTERNAL_IMAGES" ]; then + paramerror=1 + if [ -z "$paramerror_str" ]; then + paramerror_str="No app name found for flag: '--use-use-external-image'" + fi + else + echo "Option set - Overriding with external images for app(s):"$USE_EXTERNAL_IMAGES + fi + fi + fi if [ $paramerror -eq 0 ]; then if [ "$1" == "--image-repo" ]; then shift; @@ -576,6 +777,207 @@ while [ $paramerror -eq 0 ] && [ $foundparm -eq 0 ]; do fi fi fi + if [ $paramerror -eq 0 ]; then + if [ "$1" == "--override" ]; then + shift; + TEST_ENV_VAR_FILE_OVERRIDE=$1 + if [ -z "$1" ]; then + paramerror=1 + if [ -z "$paramerror_str" ]; then + paramerror_str="No env file found for flag: '--override'" + fi + else + if [ ! -f $TEST_ENV_VAR_FILE_OVERRIDE ]; then + paramerror=1 + if [ -z "$paramerror_str" ]; then + paramerror_str="File for '--override' does not exist : "$TEST_ENV_VAR_FILE_OVERRIDE + fi + fi + echo "Option set - Override env from: "$1 + shift; + foundparm=0 + fi + fi + fi + if [ $paramerror -eq 0 ]; then + if [ "$1" == "--pre-clean" ]; then + PRE_CLEAN=1 + echo "Option set - Pre-clean of kube/docker resouces" + shift; + foundparm=0 + fi + fi + if [ $paramerror -eq 0 ]; then + if [ "$1" == "--print-stats" ]; then + PRINT_CURRENT_STATS=1 + echo "Option set - Print stats after every test-case and config" + shift; + foundparm=0 + fi + fi + if [ $paramerror -eq 0 ]; then + if [ "$1" == "--gen-stats" ]; then + COLLECT_RUNTIME_STATS=1 + echo "Option set - Collect runtime statistics" + shift; + foundparm=0 + fi + fi + if [ $paramerror -eq 0 ]; then + if [ "$1" == "--delete-namespaces" ]; then + if [ $RUNMODE == "DOCKER" ]; then + DELETE_KUBE_NAMESPACES=0 + echo "Option ignored - Delete namespaces (ignored when running docker)" + else + if [ -z "KUBE_PRESTARTED_IMAGES" ]; then + DELETE_KUBE_NAMESPACES=0 + echo "Option ignored - Delete namespaces (ignored when using prestarted apps)" + else + DELETE_KUBE_NAMESPACES=1 + echo "Option set - Delete namespaces" + fi + fi + shift; + foundparm=0 + fi + fi + if [ $paramerror -eq 0 ]; then + if [ "$1" == "--delete-containers" ]; then + if [ $RUNMODE == "DOCKER" ]; then + DELETE_CONTAINERS=1 + echo "Option set - Delete containers started by previous test(s)" + else + echo "Option ignored - Delete containers (ignored when running kube)" + fi + shift; + foundparm=0 + fi + fi + if [ $paramerror -eq 0 ]; then + if [ "$1" == "--endpoint-stats" ]; then + COLLECT_ENDPOINT_STATS=1 + echo "Option set - Collect endpoint statistics" + shift; + foundparm=0 + fi + fi + if [ $paramerror -eq 0 ]; then + if [ "$1" == "--kubeconfig" ]; then + shift; + if [ -z "$1" ]; then + paramerror=1 + if [ -z "$paramerror_str" ]; then + paramerror_str="No path found for : '--kubeconfig'" + fi + else + if [ -f $1 ]; then + if [ ! -z "$KUBECONF" ]; then + paramerror=1 + if [ -z "$paramerror_str" ]; then + paramerror_str="Only one of --kubeconfig/--kubecontext can be set" + fi + else + KUBECONF="--kubeconfig $1" + echo "Option set - Kubeconfig path: "$1 + shift; + foundparm=0 + fi + else + paramerror=1 + if [ -z "$paramerror_str" ]; then + paramerror_str="File $1 for --kubeconfig not found" + fi + fi + fi + fi + fi + if [ $paramerror -eq 0 ]; then + if [ "$1" == "--kubecontext" ]; then + shift; + if [ -z "$1" ]; then + paramerror=1 + if [ -z "$paramerror_str" ]; then + paramerror_str="No context-name found for : '--kubecontext'" + fi + else + if [ ! -z "$KUBECONF" ]; then + paramerror=1 + if [ -z "$paramerror_str" ]; then + paramerror_str="Only one of --kubeconfig or --kubecontext can be set" + fi + else + KUBECONF="--context $1" + echo "Option set - Kubecontext name: "$1 + shift; + foundparm=0 + fi + fi + fi + fi + if [ $paramerror -eq 0 ]; then + if [ "$1" == "--host-path-dir" ]; then + shift; + if [ -z "$1" ]; then + paramerror=1 + if [ -z "$paramerror_str" ]; then + paramerror_str="No path found for : '--host-path-dir'" + fi + else + HOST_PATH_BASE_DIR=$1 + echo "Option set - Host path for kube set to: "$1 + shift + foundparm=0 + fi + fi + fi + if [ $paramerror -eq 0 ]; then + if [ "$1" == "--docker-host" ]; then + shift; + if [ -z "$1" ]; then + paramerror=1 + if [ -z "$paramerror_str" ]; then + paramerror_str="No url found for : '--docker-host'" + fi + else + export DOCKER_HOST="$1" + echo "Option set - DOCKER_HOST set to: "$1 + shift + foundparm=0 + fi + fi + fi + if [ $paramerror -eq 0 ]; then + if [ "$1" == "--docker-host" ]; then + shift; + if [ -z "$1" ]; then + paramerror=1 + if [ -z "$paramerror_str" ]; then + paramerror_str="No url found for : '--docker-host'" + fi + else + export DOCKER_HOST="$1" + echo "Option set - DOCKER_HOST set to: "$1 + shift + foundparm=0 + fi + fi + fi + if [ $paramerror -eq 0 ]; then + if [ "$1" == "--docker-proxy" ]; then + shift; + if [ -z "$1" ]; then + paramerror=1 + if [ -z "$paramerror_str" ]; then + paramerror_str="No ip/host found for : '--docker-proxy'" + fi + else + export LOCALHOST_NAME=$1 + echo "Option set - docker proxy set to: "$1 + shift + foundparm=0 + fi + fi + fi done echo "" @@ -593,10 +995,17 @@ if [ $paramerror -eq 1 ]; then exit 1 fi +LOCALHOST_HTTP="http://$LOCALHOST_NAME" +LOCALHOST_HTTPS="https://$LOCALHOST_NAME" + # sourcing the selected env variables for the test case if [ -f "$TEST_ENV_VAR_FILE" ]; then echo -e $BOLD"Sourcing env vars from: "$TEST_ENV_VAR_FILE$EBOLD . $TEST_ENV_VAR_FILE + if [ ! -z "$TEST_ENV_VAR_FILE_OVERRIDE" ]; then + echo -e $BOLD"Sourcing override env vars from: "$TEST_ENV_VAR_FILE_OVERRIDE$EBOLD + . $TEST_ENV_VAR_FILE_OVERRIDE + fi if [ -z "$TEST_ENV_PROFILE" ] || [ -z "$SUPPORTED_PROFILES" ]; then echo -e $YELLOW"This test case may not work with selected test env file. TEST_ENV_PROFILE is missing in test_env file or SUPPORTED_PROFILES is missing in test case file"$EYELLOW @@ -646,45 +1055,125 @@ else INCLUDED_IMAGES=$DOCKER_INCLUDED_IMAGES fi +echo "" +# auto adding system apps +__added_apps="" +echo -e $BOLD"Auto adding system apps"$EBOLD +if [ $RUNMODE == "KUBE" ]; then + INCLUDED_IMAGES=$INCLUDED_IMAGES" "$TESTENV_KUBE_SYSTEM_APPS + TMP_APPS=$TESTENV_KUBE_SYSTEM_APPS +else + INCLUDED_IMAGES=$INCLUDED_IMAGES" "$TESTENV_DOCKER_SYSTEM_APPS + TMP_APPS=$TESTENV_DOCKER_SYSTEM_APPS +fi +if [ ! -z "$TMP_APPS" ]; then + for iapp in "$TMP_APPS"; do + file_pointer=$(echo $iapp | tr '[:upper:]' '[:lower:]') + file_pointer="../common/"$file_pointer"_api_functions.sh" + padded_iapp=$iapp + while [ ${#padded_iapp} -lt 16 ]; do + padded_iapp=$padded_iapp" " + done + echo " Auto-adding system app $padded_iapp Sourcing $file_pointer" + . $file_pointer + if [ $? -ne 0 ]; then + echo " Include file $file_pointer contain errors. Exiting..." + exit 1 + fi + __added_apps=" $iapp "$__added_apps + done +else + echo " None" +fi + +if [ $RUNMODE == "KUBE" ]; then + TMP_APPS=$INCLUDED_IMAGES" "$KUBE_PRESTARTED_IMAGES +else + TMP_APPS=$INCLUDED_IMAGES +fi + +echo -e $BOLD"Auto adding included apps"$EBOLD + for iapp in $TMP_APPS; do + if [[ "$__added_apps" != *"$iapp"* ]]; then + file_pointer=$(echo $iapp | tr '[:upper:]' '[:lower:]') + file_pointer="../common/"$file_pointer"_api_functions.sh" + padded_iapp=$iapp + while [ ${#padded_iapp} -lt 16 ]; do + padded_iapp=$padded_iapp" " + done + echo " Auto-adding included app $padded_iapp Sourcing $file_pointer" + if [ ! -f "$file_pointer" ]; then + echo " Include file $file_pointer for app $iapp does not exist" + exit 1 + fi + . $file_pointer + if [ $? -ne 0 ]; then + echo " Include file $file_pointer contain errors. Exiting..." + exit 1 + fi + fi + done +echo "" + +echo -e $BOLD"Test environment info"$EBOLD + # Check needed installed sw + +tmp=$(which bash) +if [ $? -ne 0 ] || [ -z "$tmp" ]; then + echo -e $RED"bash is required to run the test environment, pls install"$ERED + exit 1 +fi +echo " bash is installed and using version:" +echo "$(bash --version)" | indent2 + tmp=$(which python3) -if [ $? -ne 0 ] || [ -z tmp ]; then +if [ $? -ne 0 ] || [ -z "$tmp" ]; then echo -e $RED"python3 is required to run the test environment, pls install"$ERED exit 1 fi +echo " python3 is installed and using version: $(python3 --version)" + tmp=$(which docker) -if [ $? -ne 0 ] || [ -z tmp ]; then +if [ $? -ne 0 ] || [ -z "$tmp" ]; then echo -e $RED"docker is required to run the test environment, pls install"$ERED exit 1 fi +echo " docker is installed and using versions:" +echo " $(docker version --format 'Client version {{.Client.Version}} Server version {{.Server.Version}}')" -tmp=$(which docker-compose) -if [ $? -ne 0 ] || [ -z tmp ]; then - if [ $RUNMODE == "DOCKER" ]; then +if [ $RUNMODE == "DOCKER" ]; then + tmp=$(which docker-compose) + if [ $? -ne 0 ] || [ -z "$tmp" ]; then echo -e $RED"docker-compose is required to run the test environment, pls install"$ERED exit 1 + else + tmp=$(docker-compose version) + echo " docker-compose installed and using version $tmp" + if [[ "$tmp" == *'v2'* ]]; then + DOCKER_COMPOSE_VERSION="V2" + fi fi fi - -tmp=$(which kubectl) -if [ $? -ne 0 ] || [ -z tmp ]; then - if [ $RUNMODE == "KUBE" ]; then +if [ $RUNMODE == "KUBE" ]; then + tmp=$(which kubectl) + if [ $? -ne 0 ] || [ -z tmp ]; then echo -e $RED"kubectl is required to run the test environment in kubernetes mode, pls install"$ERED exit 1 - fi -else - if [ $RUNMODE == "KUBE" ]; then - res=$(kubectl cluster-info 2>&1) + else + echo " kubectl is installed and using versions:" + echo $(kubectl $KUBECONF version --short=true) | indent2 + res=$(kubectl $KUBECONF cluster-info 2>&1) if [ $? -ne 0 ]; then echo -e "$BOLD$RED############################################# $ERED$EBOLD" - echo -e $BOLD$RED"Command 'kubectl cluster-info' returned error $ERED$EBOLD" + echo -e $BOLD$RED"Command 'kubectl '$KUBECONF' cluster-info' returned error $ERED$EBOLD" echo -e "$BOLD$RED############################################# $ERED$EBOLD" echo " " echo "kubectl response:" echo $res echo " " echo "This script may have been started with user with no permission to run kubectl" - echo "Try running with 'sudo' or set 'KUBECONFIG'" + echo "Try running with 'sudo', set env KUBECONFIG or set '--kubeconfig' parameter" echo "Do either 1, 2 or 3 " echo " " echo "1" @@ -697,14 +1186,29 @@ else echo -e $BOLD"sudo -E "$EBOLD echo " " echo "3" - echo "Set KUBECONFIG inline (replace user)" - echo -e $BOLD"sudo KUBECONFIG='/home//.kube/config' "$EBOLD + echo "Set KUBECONFIG via script parameter" + echo -e $BOLD"sudo ... --kubeconfig /home//.kube/ ...."$EBOLD + echo "The config file need to downloaded from the cluster" exit 1 fi + echo " Node(s) and container runtime config" + kubectl $KUBECONF get nodes -o wide | indent2 + echo "" + if [ -z "$HOST_PATH_BASE_DIR" ]; then + HOST_PATH_BASE_DIR="/tmp" + echo " Persistent volumes will be mounted to $HOST_PATH_BASE_DIR on applicable node" + echo " No guarantee that persistent volume data is available on all nodes in the cluster" + else + echo "Persistent volumes will be mounted to base dir: $HOST_PATH_BASE_DIR" + echo "Assuming this dir is mounted from each node to a dir on the localhost or other" + echo "file system available to all nodes" + fi fi fi +echo "" + echo -e $BOLD"Checking configured image setting for this test case"$EBOLD #Temp var to check for image variable name errors @@ -776,7 +1280,7 @@ __check_and_create_image_var() { if [ "$5" == "REMOTE_RELEASE_ORAN" ]; then image=$NEXUS_RELEASE_REPO_ORAN$image fi - #No nexus repo added for local images, tag: LOCAL + #No nexus repo added for local images, tag: LOCAL and other tags tmp=$tmp$image"\t" fi if [ -z $tag ]; then @@ -956,6 +1460,12 @@ __check_image_override() { ((CTR++)) fi done + for im in $USE_EXTERNAL_IMAGES; do + if [ "$1" == "$im" ]; then + suffix="EXTERNAL" + ((CTR++)) + fi + done echo $suffix if [ $CTR -gt 1 ]; then exit 1 @@ -1104,15 +1614,18 @@ setup_testenvironment() { IMAGE_SUFFIX="none" fi # A function name is created from the app short name - # for example app short name 'ECS' -> produce the function - # name __ECS_imagesetup + # for example app short name 'ICS' -> produce the function + # name __ICS_imagesetup # This function is called and is expected to exist in the imported - # file for the ecs test functions + # file for the ics test functions # The resulting function impl will call '__check_and_create_image_var' function # with appropriate parameters # If the image suffix is none, then the component decides the suffix function_pointer="__"$imagename"_imagesetup" $function_pointer $IMAGE_SUFFIX + + function_pointer="__"$imagename"_test_requirements" + $function_pointer fi done @@ -1150,9 +1663,38 @@ setup_testenvironment() { #Temp var to check for image pull errors IMAGE_ERR=0 - # The following sequence pull the configured images + # Delete namespaces + echo -e $BOLD"Deleting namespaces"$EBOLD + if [ "$DELETE_KUBE_NAMESPACES" -eq 1 ]; then + test_env_namespaces=$(kubectl $KUBECONF get ns --no-headers -o custom-columns=":metadata.name" -l autotest=engine) #Get list of ns created by the test env + if [ $? -ne 0 ]; then + echo " Cannot get list of namespaces...ignoring delete" + else + for test_env_ns in $test_env_namespaces; do + __kube_delete_namespace $test_env_ns + done + fi + else + echo " Namespace delete option not set or ignored" + fi + echo "" + + # Delete containers + echo -e $BOLD"Deleting containers"$EBOLD + + if [ "$DELETE_CONTAINERS" -eq 1 ]; then + echo " Stopping containers label 'nrttest_app'..." + docker stop $(docker ps -qa --filter "label=nrttest_app") 2> /dev/null + echo " Removing stopped containers..." + docker rm $(docker ps -qa --filter "label=nrttest_app") 2> /dev/null + else + echo " Contatiner delete option not set or ignored" + fi + echo "" + + # The following sequence pull the configured images echo -e $BOLD"Pulling configured images, if needed"$EBOLD if [ ! -z "$IMAGE_REPO_ADR" ] && [ $IMAGE_REPO_POLICY == "local" ]; then echo -e $YELLOW" Excluding all remote image check/pull when running with image repo: $IMAGE_REPO_ADR and image policy $IMAGE_REPO_POLICY"$EYELLOW @@ -1198,8 +1740,11 @@ setup_testenvironment() { echo -e $RED"One or more images could not be pulled or containers using the images could not be stopped/removed"$ERED echo -e $RED"Or local image, overriding remote image, does not exist"$ERED if [ $IMAGE_CATEGORY == "DEV" ]; then - echo -e $RED"Note that SNAPSHOT images may be purged from nexus after a certain period."$ERED - echo -e $RED"In that case, switch to use a released image instead."$ERED + echo "" + echo -e $RED"Note that SNAPSHOT and staging images may be purged from nexus after a certain period."$ERED + echo -e $RED"In addition, the image may not have been updated in the current release so no SNAPSHOT or staging image exists"$ERED + echo -e $RED"In these cases, switch to use a released image instead, use the flag '--use-release-image '"$ERED + echo -e $RED"Use the 'App-short-name' for the applicable image from the above table: 'Images configured for start arg'."$ERED fi echo "#################################################################################################" echo "" @@ -1322,8 +1867,8 @@ setup_testenvironment() { echo -e " Pulling remote snapshot or staging images my in some case result in pulling newer image versions outside the control of the test engine" export KUBE_IMAGE_PULL_POLICY="Always" fi - CLUSTER_IP=$(kubectl config view -o jsonpath={.clusters[0].cluster.server} | awk -F[/:] '{print $4}') - echo -e $YELLOW" The cluster hostname/ip is: $CLUSTER_IP"$EYELLOW + #CLUSTER_IP=$(kubectl $KUBECONF config view -o jsonpath={.clusters[0].cluster.server} | awk -F[/:] '{print $4}') + #echo -e $YELLOW" The cluster hostname/ip is: $CLUSTER_IP"$EYELLOW echo "=================================================================================" echo "=================================================================================" @@ -1335,6 +1880,34 @@ setup_testenvironment() { echo -e $BOLD"======================================================="$EBOLD echo "" + LOG_STAT_ARGS="" + + for imagename in $APP_SHORT_NAMES; do + __check_included_image $imagename + retcode_i=$? + __check_prestarted_image $imagename + retcode_p=$? + if [ $retcode_i -eq 0 ] || [ $retcode_p -eq 0 ]; then + # A function name is created from the app short name + # for example app short name 'RICMSIM' -> produce the function + # name __RICSIM__initial_setup + # This function is called and is expected to exist in the imported + # file for the ricsim test functions + # The resulting function impl shall perform initial setup of port, host etc + + function_pointer="__"$imagename"_initial_setup" + $function_pointer + + function_pointer="__"$imagename"_statisics_setup" + LOG_STAT_ARGS=$LOG_STAT_ARGS" "$($function_pointer) + fi + done + + if [ $COLLECT_RUNTIME_STATS -eq 1 ]; then + ../common/genstat.sh $RUNMODE $SECONDS $TESTLOGS/$ATC/stat_data.csv $LOG_STAT_ARGS & + COLLECT_RUNTIME_STATS_PID=$! + fi + } # Function to print the test result, shall be the last cmd in a test script @@ -1366,28 +1939,40 @@ print_result() { echo "Timer measurement in the test script" echo "====================================" column -t -s $'\t' $TIMER_MEASUREMENTS + if [ $RES_PASS != $RES_TEST ]; then + echo -e $RED"Measurement may not be reliable when there are failed test - failures may cause long measurement values due to timeouts etc."$ERED + fi echo "" + if [ $COLLECT_RUNTIME_STATS -eq 1 ]; then + echo "Runtime statistics collected in file: "$TESTLOGS/$ATC/stat_data.csv + echo "" + fi + TMP_FLAG_FAIL_PASS=0 total=$((RES_PASS+RES_FAIL)) if [ $RES_TEST -eq 0 ]; then + TMP_FLAG_FAIL_PASS=1 echo -e "\033[1mNo tests seem to have been executed. Check the script....\033[0m" echo -e "\033[31m\033[1m ___ ___ ___ ___ ___ _____ ___ _ ___ _ _ _ ___ ___ \033[0m" echo -e "\033[31m\033[1m/ __|/ __| _ \_ _| _ \_ _| | __/_\ |_ _| | | | | | _ \ __|\033[0m" echo -e "\033[31m\033[1m\__ \ (__| /| || _/ | | | _/ _ \ | || |_| |_| | / _| \033[0m" echo -e "\033[31m\033[1m|___/\___|_|_\___|_| |_| |_/_/ \_\___|____\___/|_|_\___|\033[0m" elif [ $total != $RES_TEST ]; then + TMP_FLAG_FAIL_PASS=1 echo -e "\033[1mTotal number of tests does not match the sum of passed and failed tests. Check the script....\033[0m" echo -e "\033[31m\033[1m ___ ___ ___ ___ ___ _____ ___ _ ___ _ _ _ ___ ___ \033[0m" echo -e "\033[31m\033[1m/ __|/ __| _ \_ _| _ \_ _| | __/_\ |_ _| | | | | | _ \ __|\033[0m" echo -e "\033[31m\033[1m\__ \ (__| /| || _/ | | | _/ _ \ | || |_| |_| | / _| \033[0m" echo -e "\033[31m\033[1m|___/\___|_|_\___|_| |_| |_/_/ \_\___|____\___/|_|_\___|\033[0m" elif [ $RES_CONF_FAIL -ne 0 ]; then + TMP_FLAG_FAIL_PASS=1 echo -e "\033[1mOne or more configurations has failed. Check the script log....\033[0m" echo -e "\033[31m\033[1m ___ ___ ___ ___ ___ _____ ___ _ ___ _ _ _ ___ ___ \033[0m" echo -e "\033[31m\033[1m/ __|/ __| _ \_ _| _ \_ _| | __/_\ |_ _| | | | | | _ \ __|\033[0m" echo -e "\033[31m\033[1m\__ \ (__| /| || _/ | | | _/ _ \ | || |_| |_| | / _| \033[0m" echo -e "\033[31m\033[1m|___/\___|_|_\___|_| |_| |_/_/ \_\___|____\___/|_|_\___|\033[0m" elif [ $RES_PASS = $RES_TEST ]; then + TMP_FLAG_FAIL_PASS=0 echo -e "All tests \033[32m\033[1mPASS\033[0m" echo -e "\033[32m\033[1m ___ _ ___ ___ \033[0m" echo -e "\033[32m\033[1m | _ \/_\ / __/ __| \033[0m" @@ -1406,13 +1991,19 @@ print_result() { fi #Create file with OK exit code echo "0" > "$AUTOTEST_HOME/.result$ATC.txt" + echo "0" > "$TESTLOGS/$ATC/.result$ATC.txt" + echo $(date) > $TESTLOGS/$ATC/endpoint_tc_end.log else + TMP_FLAG_FAIL_PASS=1 echo -e "One or more tests with status \033[31m\033[1mFAIL\033[0m " echo -e "\033[31m\033[1m ___ _ ___ _ \033[0m" echo -e "\033[31m\033[1m | __/_\ |_ _| | \033[0m" echo -e "\033[31m\033[1m | _/ _ \ | || |__ \033[0m" echo -e "\033[31m\033[1m |_/_/ \_\___|____|\033[0m" echo "" + fi + + if [ $TMP_FLAG_FAIL_PASS -ne 0 ]; then # Update test suite counter if [ -f .tmp_tcsuite_fail_ctr ]; then tmpval=$(< .tmp_tcsuite_fail_ctr) @@ -1442,57 +2033,44 @@ print_result() { ##################################################################### # Start timer for time measurement -# args - (any args will be printed though) +# args: - timer value and message will be printed both on screen +# and in the timer measurement report - if at least one "print_timer is called" start_timer() { echo -e $BOLD"INFO(${BASH_LINENO[0]}): "${FUNCNAME[0]}"," $@ $EBOLD - TC_TIMER=$SECONDS + TC_TIMER_STARTTIME=$SECONDS + TC_TIMER_TIMER_TEXT="${@:1}" + if [ $# -ne 1 ]; then + __print_err "need 1 arg, " $@ + TC_TIMER_TIMER_TEXT=${FUNCNAME[0]}":"${BASH_LINENO[0]} + echo " Assigning timer name: "$TC_TIMER_TIMER_TEXT + fi + TC_TIMER_CURRENT_FAILS=$(($RES_FAIL+$RES_CONF_FAIL)) echo " Timer started: $(date)" } -# Print the value of the time (in seconds) -# args - - timer value and message will be printed both on screen -# and in the timer measurement report +# Print the running timer the value of the time (in seconds) +# Timer value and message will be printed both on screen and in the timer measurement report print_timer() { - echo -e $BOLD"INFO(${BASH_LINENO[0]}): "${FUNCNAME[0]}"," $@ $EBOLD - if [ $# -lt 1 ]; then - ((RES_CONF_FAIL++)) - __print_err "need 1 or more args, " $@ - exit 1 + echo -e $BOLD"INFO(${BASH_LINENO[0]}): "${FUNCNAME[0]}"," $TC_TIMER_TIMER_TEXT $EBOLD + if [ -z "$TC_TIMER_STARTTIME" ]; then + __print_err "timer not started" $@ + return 1 fi - duration=$(($SECONDS-$TC_TIMER)) + duration=$(($SECONDS-$TC_TIMER_STARTTIME)) if [ $duration -eq 0 ]; then duration="<1 second" else duration=$duration" seconds" fi echo " Timer duration :" $duration - - echo -e "${@:1} \t $duration" >> $TIMER_MEASUREMENTS -} - -# Print the value of the time (in seconds) and reset the timer -# args - - timer value and message will be printed both on screen -# and in the timer measurement report -print_and_reset_timer() { - echo -e $BOLD"INFO(${BASH_LINENO[0]}): "${FUNCNAME[0]}"," $@ $EBOLD - if [ $# -lt 1 ]; then - ((RES_CONF_FAIL++)) - __print_err "need 1 or more args, " $@ - exit 1 - fi - duration=$(($SECONDS-$TC_TIMER))" seconds" - if [ $duration -eq 0 ]; then - duration="<1 second" - else - duration=$duration" seconds" + res="-" + if [ $(($RES_FAIL+$RES_CONF_FAIL)) -ne $TC_TIMER_CURRENT_FAILS ]; then + res="Failures occured during test - timer not reliabled" fi - echo " Timer duration :" $duration - TC_TIMER=$SECONDS - echo " Timer reset" - - echo -e "${@:1} \t $duration" >> $TIMER_MEASUREMENTS + echo -e "$TC_TIMER_TIMER_TEXT \t $duration \t $res" >> $TIMER_MEASUREMENTS } + # Print info about a deviations from intended tests # Each deviation counted is also printed in the testreport # args @@ -1506,6 +2084,7 @@ deviation() { ((RES_DEVIATION++)) echo -e $BOLD$YELLOW" Test case deviation: ${@:1}"$EYELLOW$EBOLD echo "Line: ${BASH_LINENO[0]} - ${@:1}" >> $DEVIATION_FILE + __print_current_stats echo "" } @@ -1514,6 +2093,16 @@ __check_stop_at_error() { if [ $STOP_AT_ERROR -eq 1 ]; then echo -e $RED"Test script configured to stop at first FAIL, taking all logs and stops"$ERED store_logs "STOP_AT_ERROR" + + # Update test suite counter + if [ -f .tmp_tcsuite_fail_ctr ]; then + tmpval=$(< .tmp_tcsuite_fail_ctr) + ((tmpval++)) + echo $tmpval > .tmp_tcsuite_fail_ctr + fi + if [ -f .tmp_tcsuite_fail ]; then + echo " - "$ATC " -- "$TC_ONELINE_DESCR" Execution stopped due to error" >> .tmp_tcsuite_fail + fi exit 1 fi return 0 @@ -1534,6 +2123,13 @@ __clean_containers() { for imagename in $APP_SHORT_NAMES; do docker ps -a --filter "label=nrttest_app=$imagename" --filter "network=$DOCKER_SIM_NWNAME" --format ' {{.Label "nrttest_dp"}}\n{{.Label "nrttest_app"}}\n{{.Names}}' >> $running_contr_file done + running_contr_file_empty="No docker containers running, started by previous test execution" + if [ -s $running_contr_file ]; then + running_contr_file_empty="" + fi + + # Kill all containers started by the test env - to speed up shut down + docker kill $(docker ps -a --filter "label=nrttest_app" --format '{{.Names}}') &> /dev/null tab_heading1="App display name" tab_heading2="App short name" @@ -1578,37 +2174,41 @@ __clean_containers() { tab_heading3="$tab_heading3"" " done - echo " $tab_heading1$tab_heading2$tab_heading3"" Actions" - cntr=0 - while read p; do - if (( $cntr % 3 == 0 ));then - row="" - heading=$p - heading_len=$tab_heading1_len - fi - if (( $cntr % 3 == 1));then - heading=$p - heading_len=$tab_heading2_len - fi - if (( $cntr % 3 == 2));then - contr=$p - heading=$p - heading_len=$tab_heading3_len - fi - while (( ${#heading} < $heading_len)); do - heading="$heading"" " - done - row=$row$heading - if (( $cntr % 3 == 2));then - echo -ne $row$SAMELINE - echo -ne " $row ${GREEN}stopping...${EGREEN}${SAMELINE}" - docker stop $(docker ps -qa --filter name=${contr} --filter network=$DOCKER_SIM_NWNAME) &> /dev/null - echo -ne " $row ${GREEN}stopped removing...${EGREEN}${SAMELINE}" - docker rm --force $(docker ps -qa --filter name=${contr} --filter network=$DOCKER_SIM_NWNAME) &> /dev/null - echo -e " $row ${GREEN}stopped removed ${EGREEN}" - fi - let cntr=cntr+1 - done <$running_contr_file + if [ ! -z "$running_contr_file_empty" ]; then + echo $running_contr_file_empty | indent1 + else + echo " $tab_heading1$tab_heading2$tab_heading3"" Actions" + cntr=0 + while read p; do + if (( $cntr % 3 == 0 ));then + row="" + heading=$p + heading_len=$tab_heading1_len + fi + if (( $cntr % 3 == 1));then + heading=$p + heading_len=$tab_heading2_len + fi + if (( $cntr % 3 == 2));then + contr=$p + heading=$p + heading_len=$tab_heading3_len + fi + while (( ${#heading} < $heading_len)); do + heading="$heading"" " + done + row=$row$heading + if (( $cntr % 3 == 2));then + echo -ne $row$SAMELINE + echo -ne " $row ${GREEN}stopping...${EGREEN}${SAMELINE}" + docker stop $(docker ps -qa --filter name=${contr} --filter network=$DOCKER_SIM_NWNAME) &> /dev/null + echo -ne " $row ${GREEN}stopped removing...${EGREEN}${SAMELINE}" + docker rm --force $(docker ps -qa --filter name=${contr} --filter network=$DOCKER_SIM_NWNAME) &> /dev/null + echo -e " $row ${GREEN}stopped removed ${EGREEN}" + fi + let cntr=cntr+1 + done <$running_contr_file + fi echo "" @@ -1653,12 +2253,12 @@ __clean_containers() { # Get resource type for scaling # args: __kube_get_resource_type() { - kubectl get deployment $1 -n $2 1> /dev/null 2> ./tmp/kubeerr + kubectl $KUBECONF get deployment $1 -n $2 1> /dev/null 2> ./tmp/kubeerr if [ $? -eq 0 ]; then echo "deployment" return 0 fi - kubectl get sts $1 -n $2 1> /dev/null 2> ./tmp/kubeerr + kubectl $KUBECONF get sts $1 -n $2 1> /dev/null 2> ./tmp/kubeerr if [ $? -eq 0 ]; then echo "sts" return 0 @@ -1672,7 +2272,7 @@ __kube_get_resource_type() { # (Not for test scripts) __kube_scale() { echo -ne " Setting $1 $2 replicas=$4 in namespace $3"$SAMELINE - kubectl scale $1 $2 -n $3 --replicas=$4 1> /dev/null 2> ./tmp/kubeerr + kubectl $KUBECONF scale $1 $2 -n $3 --replicas=$4 1> /dev/null 2> ./tmp/kubeerr if [ $? -ne 0 ]; then echo -e " Setting $1 $2 replicas=$4 in namespace $3 $RED Failed $ERED" ((RES_CONF_FAIL++)) @@ -1685,7 +2285,7 @@ __kube_scale() { TSTART=$SECONDS for i in {1..500}; do - count=$(kubectl get $1/$2 -n $3 -o jsonpath='{.status.replicas}' 2> /dev/null) + count=$(kubectl $KUBECONF get $1/$2 -n $3 -o jsonpath='{.status.replicas}' 2> /dev/null) retcode=$? if [ -z "$count" ]; then #No value is sometimes returned for some reason, in case the resource has replica 0 @@ -1723,41 +2323,49 @@ __kube_scale_all_resources() { labelid=$3 resources="deployment replicaset statefulset" for restype in $resources; do - result=$(kubectl get $restype -n $namespace -o jsonpath='{.items[?(@.metadata.labels.'$labelname'=="'$labelid'")].metadata.name}') + result=$(kubectl $KUBECONF get $restype -n $namespace -o jsonpath='{.items[?(@.metadata.labels.'$labelname'=="'$labelid'")].metadata.name}') if [ $? -eq 0 ] && [ ! -z "$result" ]; then - deleted_resourcetypes=$deleted_resourcetypes" "$restype for resid in $result; do - echo -ne " Ordered caling $restype $resid from namespace $namespace with label $labelname=$labelid to 0"$SAMELINE - kubectl scale $restype $resid -n $namespace --replicas=0 1> /dev/null 2> ./tmp/kubeerr - echo -e " Ordered scaling $restype $resid from namespace $namespace with label $labelname=$labelid to 0 $GREEN OK $EGREEN" + echo -ne " Ordered caling $restype $resid in namespace $namespace with label $labelname=$labelid to 0"$SAMELINE + kubectl $KUBECONF scale $restype $resid -n $namespace --replicas=0 1> /dev/null 2> ./tmp/kubeerr + echo -e " Ordered scaling $restype $resid in namespace $namespace with label $labelname=$labelid to 0 $GREEN OK $EGREEN" done fi done } -# Scale all kube resource sets to 0 in a namespace for resources having a certain lable and label-id +# Scale all kube resource sets to 0 in a namespace for resources having a certain lable and an optional label-id # This function do wait for the resource to reach 0 -# args: +# args: [ ] # (Not for test scripts) __kube_scale_and_wait_all_resources() { namespace=$1 labelname=$2 labelid=$3 + if [ -z "$3" ]; then + echo " Attempt to scale - deployment replicaset statefulset - in namespace $namespace with label $labelname" + else + echo " Attempt to scale - deployment replicaset statefulset - in namespace $namespace with label $labelname=$labelid" + fi resources="deployment replicaset statefulset" scaled_all=1 while [ $scaled_all -ne 0 ]; do scaled_all=0 for restype in $resources; do - result=$(kubectl get $restype -n $namespace -o jsonpath='{.items[?(@.metadata.labels.'$labelname'=="'$labelid'")].metadata.name}') + if [ -z "$3" ]; then + result=$(kubectl $KUBECONF get $restype -n $namespace -o jsonpath='{.items[?(@.metadata.labels.'$labelname')].metadata.name}') + else + result=$(kubectl $KUBECONF get $restype -n $namespace -o jsonpath='{.items[?(@.metadata.labels.'$labelname'=="'$labelid'")].metadata.name}') + fi if [ $? -eq 0 ] && [ ! -z "$result" ]; then for resid in $result; do - echo -e " Ordered scaling $restype $resid from namespace $namespace with label $labelname=$labelid to 0" - kubectl scale $restype $resid -n $namespace --replicas=0 1> /dev/null 2> ./tmp/kubeerr + echo -e " Ordered scaling $restype $resid in namespace $namespace with label $labelname=$labelid to 0" + kubectl $KUBECONF scale $restype $resid -n $namespace --replicas=0 1> /dev/null 2> ./tmp/kubeerr count=1 T_START=$SECONDS while [ $count -ne 0 ]; do - count=$(kubectl get $restype $resid -n $namespace -o jsonpath='{.status.replicas}' 2> /dev/null) - echo -ne " Scaling $restype $resid from namespace $namespace with label $labelname=$labelid to 0,count=$count"$SAMELINE + count=$(kubectl $KUBECONF get $restype $resid -n $namespace -o jsonpath='{.status.replicas}' 2> /dev/null) + echo -ne " Scaling $restype $resid in namespace $namespace with label $labelname=$labelid to 0, current count=$count"$SAMELINE if [ $? -eq 0 ] && [ ! -z "$count" ]; then sleep 0.5 else @@ -1770,7 +2378,7 @@ __kube_scale_and_wait_all_resources() { count=0 fi done - echo -e " Scaled $restype $resid from namespace $namespace with label $labelname=$labelid to 0,count=$count $GREEN OK $EGREEN" + echo -e " Scaled $restype $resid in namespace $namespace with label $labelname=$labelid to 0, current count=$count $GREEN OK $EGREEN" done fi done @@ -1785,32 +2393,42 @@ __kube_delete_all_resources() { namespace=$1 labelname=$2 labelid=$3 - resources="deployments replicaset statefulset services pods configmaps persistentvolumeclaims persistentvolumes" + resources="deployments replicaset statefulset services pods configmaps persistentvolumeclaims persistentvolumes serviceaccounts clusterrolebindings secrets authorizationpolicies requestauthentications" deleted_resourcetypes="" for restype in $resources; do - result=$(kubectl get $restype -n $namespace -o jsonpath='{.items[?(@.metadata.labels.'$labelname'=="'$labelid'")].metadata.name}') + ns_flag="-n $namespace" + ns_text="in namespace $namespace" + if [ $restype == "persistentvolumes" ]; then + ns_flag="" + ns_text="" + fi + if [ $restype == "clusterrolebindings" ]; then + ns_flag="" + ns_text="" + fi + result=$(kubectl $KUBECONF get $restype $ns_flag -o jsonpath='{.items[?(@.metadata.labels.'$labelname'=="'$labelid'")].metadata.name}' 2> /dev/null) if [ $? -eq 0 ] && [ ! -z "$result" ]; then deleted_resourcetypes=$deleted_resourcetypes" "$restype for resid in $result; do if [ $restype == "replicaset" ] || [ $restype == "statefulset" ]; then count=1 while [ $count -ne 0 ]; do - count=$(kubectl get $restype $resid -n $namespace -o jsonpath='{.status.replicas}' 2> /dev/null) - echo -ne " Scaling $restype $resid from namespace $namespace with label $labelname=$labelid to 0,count=$count"$SAMELINE + count=$(kubectl $KUBECONF get $restype $resid $ns_flag -o jsonpath='{.status.replicas}' 2> /dev/null) + echo -ne " Scaling $restype $resid $ns_text with label $labelname=$labelid to 0, current count=$count"$SAMELINE if [ $? -eq 0 ] && [ ! -z "$count" ]; then sleep 0.5 else count=0 fi done - echo -e " Scaled $restype $resid from namespace $namespace with label $labelname=$labelid to 0,count=$count $GREEN OK $EGREEN" + echo -e " Scaled $restype $resid $ns_text with label $labelname=$labelid to 0, current count=$count $GREEN OK $EGREEN" fi - echo -ne " Deleting $restype $resid from namespace $namespace with label $labelname=$labelid "$SAMELINE - kubectl delete $restype $resid -n $namespace 1> /dev/null 2> ./tmp/kubeerr + echo -ne " Deleting $restype $resid $ns_text with label $labelname=$labelid "$SAMELINE + kubectl $KUBECONF delete --grace-period=1 $restype $resid $ns_flag 1> /dev/null 2> ./tmp/kubeerr if [ $? -eq 0 ]; then - echo -e " Deleted $restype $resid from namespace $namespace with label $labelname=$labelid $GREEN OK $EGREEN" + echo -e " Deleted $restype $resid $ns_text with label $labelname=$labelid $GREEN OK $EGREEN" else - echo -e " Deleted $restype $resid from namespace $namespace with label $labelname=$labelid $GREEN Does not exist - OK $EGREEN" + echo -e " Deleted $restype $resid $ns_text with label $labelname=$labelid $GREEN Does not exist - OK $EGREEN" fi #fi done @@ -1818,17 +2436,23 @@ __kube_delete_all_resources() { done if [ ! -z "$deleted_resourcetypes" ]; then for restype in $deleted_resources; do - echo -ne " Waiting for $restype in namespace $namespace with label $labelname=$labelid to be deleted..."$SAMELINE + ns_flag="-n $namespace" + ns_text="in namespace $namespace" + if [ $restype == "persistentvolumes" ]; then + ns_flag="" + ns_text="" + fi + echo -ne " Waiting for $restype $ns_text with label $labelname=$labelid to be deleted..."$SAMELINE T_START=$SECONDS result="dummy" while [ ! -z "$result" ]; do sleep 0.5 - result=$(kubectl get $restype -n $namespace -o jsonpath='{.items[?(@.metadata.labels.'$labelname'=="'$labelid'")].metadata.name}') - echo -ne " Waiting for $restype in namespace $namespace with label $labelname=$labelid to be deleted...$(($SECONDS-$T_START)) seconds "$SAMELINE + result=$(kubectl $KUBECONF get $restype $ns_flag -o jsonpath='{.items[?(@.metadata.labels.'$labelname'=="'$labelid'")].metadata.name}') + echo -ne " Waiting for $restype $ns_text with label $labelname=$labelid to be deleted...$(($SECONDS-$T_START)) seconds "$SAMELINE if [ -z "$result" ]; then - echo -e " Waiting for $restype in namespace $namespace with label $labelname=$labelid to be deleted...$(($SECONDS-$T_START)) seconds $GREEN OK $EGREEN" + echo -e " Waiting for $restype $ns_text with label $labelname=$labelid to be deleted...$(($SECONDS-$T_START)) seconds $GREEN OK $EGREEN" elif [ $(($SECONDS-$T_START)) -gt 300 ]; then - echo -e " Waiting for $restype in namespace $namespace with label $labelname=$labelid to be deleted...$(($SECONDS-$T_START)) seconds $RED Failed $ERED" + echo -e " Waiting for $restype $ns_text with label $labelname=$labelid to be deleted...$(($SECONDS-$T_START)) seconds $RED Failed $ERED" result="" fi done @@ -1842,16 +2466,17 @@ __kube_delete_all_resources() { __kube_create_namespace() { #Check if test namespace exists, if not create it - kubectl get namespace $1 1> /dev/null 2> ./tmp/kubeerr + kubectl $KUBECONF get namespace $1 1> /dev/null 2> ./tmp/kubeerr if [ $? -ne 0 ]; then echo -ne " Creating namespace "$1 $SAMELINE - kubectl create namespace $1 1> /dev/null 2> ./tmp/kubeerr + kubectl $KUBECONF create namespace $1 1> /dev/null 2> ./tmp/kubeerr if [ $? -ne 0 ]; then echo -e " Creating namespace $1 $RED$BOLD FAILED $EBOLD$ERED" ((RES_CONF_FAIL++)) echo " Message: $(<./tmp/kubeerr)" return 1 else + kubectl $KUBECONF label ns $1 autotest=engine > /dev/null echo -e " Creating namespace $1 $GREEN$BOLD OK $EBOLD$EGREEN" fi else @@ -1860,6 +2485,66 @@ __kube_create_namespace() { return 0 } +# Removes a namespace if it exists +# args: +# (Not for test scripts) +__kube_delete_namespace() { + + #Check if test namespace exists, if so remove it + kubectl $KUBECONF get namespace $1 1> /dev/null 2> ./tmp/kubeerr + if [ $? -eq 0 ]; then + echo -ne " Removing namespace "$1 $SAMELINE + kubectl $KUBECONF delete namespace $1 1> /dev/null 2> ./tmp/kubeerr + if [ $? -ne 0 ]; then + echo -e " Removing namespace $1 $RED$BOLD FAILED $EBOLD$ERED" + ((RES_CONF_FAIL++)) + echo " Message: $(<./tmp/kubeerr)" + return 1 + else + echo -e " Removing namespace $1 $GREEN$BOLD OK $EBOLD$EGREEN" + fi + else + echo -e " Namespace $1 $GREEN$BOLD does not exist, OK $EBOLD$EGREEN" + fi + return 0 +} + +# Removes and re-create a namespace +# args: +# (Not for test scripts) +clean_and_create_namespace() { + __log_conf_start $@ + + if [ $# -ne 1 ]; then + __print_err "" $@ + return 1 + fi + __kube_delete_namespace $1 + if [ $? -ne 0 ]; then + return 1 + fi + __kube_create_namespace $1 + if [ $? -ne 0 ]; then + return 1 + fi +} + +# Add/remove label on non-namespaced kube object +# args: