From 0a6f10a7cc40fd5833d8199473d0bee70bb75fa9 Mon Sep 17 00:00:00 2001 From: "Xinwei Xiong(cubxxw-openim)" <3293172751nss@gmail.com> Date: Wed, 9 Aug 2023 14:53:36 +0800 Subject: [PATCH] feat: add lib and start scripts Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> --- scripts/enterprise/check_all.sh | 3 +- scripts/genconfig.sh | 4 +- scripts/init_pwd.sh | 3 +- scripts/lib/chat.sh | 1 - scripts/lib/color.sh | 3 + scripts/lib/init.sh | 177 ++++++++++- scripts/lib/logging.sh | 2 - scripts/lib/release.sh | 1 + scripts/lib/test.sh | 548 ++++++++++++++++++++++++++++++++ scripts/lib/util.sh | 47 +++ scripts/msg_gateway_start.sh | 3 +- scripts/msg_transfer_start.sh | 3 +- scripts/push_start.sh | 3 +- scripts/start_all.sh | 3 +- scripts/start_rpc_service.sh | 3 +- test/wrktest.sh | 10 +- 16 files changed, 781 insertions(+), 33 deletions(-) create mode 100644 scripts/lib/test.sh diff --git a/scripts/enterprise/check_all.sh b/scripts/enterprise/check_all.sh index 6ac8d185e..415571b00 100755 --- a/scripts/enterprise/check_all.sh +++ b/scripts/enterprise/check_all.sh @@ -18,9 +18,8 @@ SCRIPTS_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) OPENIM_ROOT=$(dirname "${BASH_SOURCE[0]}")/.. #Include shell font styles and some basic information -source $SCRIPTS_ROOT/style_info.sh +source $SCRIPTS_ROOT/lib/init.sh source $SCRIPTS_ROOT/path_info.sh -source $SCRIPTS_ROOT/function.sh cd $SCRIPTS_ROOT diff --git a/scripts/genconfig.sh b/scripts/genconfig.sh index 457d48a73..b8f6ac0ad 100755 --- a/scripts/genconfig.sh +++ b/scripts/genconfig.sh @@ -5,7 +5,7 @@ # license that can be found in the LICENSE file. # 本脚本功能:根据 scripts/environment.sh 配置,生成 OPENIM 组件 YAML 配置文件。 -# 示例:genconfig.sh scripts/environment.sh configs/openim-apiserver.yaml +# 示例:genconfig.sh scripts/environment.sh configs/openim-api.yaml # Path to the original script file env_file="$1" @@ -15,7 +15,7 @@ template_file="$2" . $(dirname ${BASH_SOURCE})/lib/init.sh if [ $# -ne 2 ];then - openim::log::error "Usage: genconfig.sh scripts/environment.sh configs/openim-apiserver.yaml" + openim::log::error "Usage: genconfig.sh scripts/environment.sh configs/openim-api.yaml" exit 1 fi diff --git a/scripts/init_pwd.sh b/scripts/init_pwd.sh index 1e5fa3b34..f2696ea9b 100755 --- a/scripts/init_pwd.sh +++ b/scripts/init_pwd.sh @@ -19,9 +19,8 @@ SCRIPTS_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) OPENIM_ROOT=$(dirname "${SCRIPTS_ROOT}")/.. #Include shell font styles and some basic information -source $SCRIPTS_ROOT/style_info.sh +source $SCRIPTS_ROOT/lib/init.sh source $SCRIPTS_ROOT/path_info.sh -source $SCRIPTS_ROOT/function.sh cd $SCRIPTS_ROOT diff --git a/scripts/lib/chat.sh b/scripts/lib/chat.sh index 33268cee6..4798940be 100644 --- a/scripts/lib/chat.sh +++ b/scripts/lib/chat.sh @@ -97,7 +97,6 @@ openim::chat::scrape() { curl -s -S "${OPENIM_INTEGRATION_CHAT_URL}/metrics" > "${CHAT_SCRAPE_DIR}/next" && mv "${CHAT_SCRAPE_DIR}/next" "${CHAT_SCRAPE_DIR}/$(date +%s).scrape" } - openim::chat::stop() { if [[ -n "${CHAT_SCRAPE_PID:-}" ]] && [[ -n "${CHAT_SCRAPE_DIR:-}" ]] ; then kill "${CHAT_SCRAPE_PID}" &>/dev/null || : diff --git a/scripts/lib/color.sh b/scripts/lib/color.sh index 0259b2643..3f1a9fafb 100755 --- a/scripts/lib/color.sh +++ b/scripts/lib/color.sh @@ -53,6 +53,9 @@ CYAN_PREFIX="\033[0;36m" # Cyan prefix # --- make demo (run demo) --- reset=$(tput sgr0) +bold=$(tput bold) +black=$(tput setaf 0) +red=$(tput setaf 1) green=$(tput bold; tput setaf 2) yellow=$(tput bold; tput setaf 3) blue=$(tput bold; tput setaf 6) diff --git a/scripts/lib/init.sh b/scripts/lib/init.sh index 294696087..2b7e2abc5 100755 --- a/scripts/lib/init.sh +++ b/scripts/lib/init.sh @@ -13,25 +13,188 @@ # See the License for the specific language governing permissions and # limitations under the License. - set -o errexit set +o nounset set -o pipefail +# Short-circuit if init.sh has already been sourced +[[ $(type -t openim::init::loaded) == function ]] && return 0 + # Unset CDPATH so that path interpolation can work correctly unset CDPATH -# Default use go modules +# Until all GOPATH references are removed from all build scripts as well, +# explicitly disable module mode to avoid picking up user-set GO111MODULE preferences. +# As individual scripts (like hack/update-vendor.sh) make use of go modules, +# they can explicitly set GO111MODULE=on export GO111MODULE=on # The root of the build/dist directory OPENIM_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd -P)" -source "${OPENIM_ROOT}/scripts/lib/util.sh" -source "${OPENIM_ROOT}/scripts/lib/logging.sh" -source "${OPENIM_ROOT}/scripts/lib/color.sh" +OPENIM_OUTPUT_SUBPATH="${OPENIM_OUTPUT_SUBPATH:-_output}" +OPENIM_OUTPUT="${OPENIM_ROOT}/${OPENIM_OUTPUT_SUBPATH}" +OPENIM_OUTPUT_BINPATH="${OPENIM_OUTPUT}/bin/platforms" +OPENIM_OUTPUT_BINTOOLPATH="${OPENIM_OUTPUT}/bin-tools" +OPENIM_OUTPUT_TOOLS="${OPENIM_OUTPUT}/tools" + +# This controls rsync compression. Set to a value > 0 to enable rsync +# compression for build container +OPENIM_RSYNC_COMPRESS="${KUBE_RSYNC_COMPRESS:-0}" + +# Set no_proxy for localhost if behind a proxy, otherwise, +# the connections to localhost in scripts will time out +export no_proxy="127.0.0.1,localhost${no_proxy:+,${no_proxy}}" + +# This is a symlink to binaries for "this platform", e.g. build tools. +export THIS_PLATFORM_BIN="${OPENIM_ROOT}/_output/bin/platforms" + +. $(dirname ${BASH_SOURCE})/color.sh +. $(dirname ${BASH_SOURCE})/util.sh +. $(dirname ${BASH_SOURCE})/logging.sh openim::log::install_errexit +openim::util::ensure-bash-version -source "${OPENIM_ROOT}/scripts/lib/version.sh" -source "${OPENIM_ROOT}/scripts/lib/golang.sh" +. $(dirname ${BASH_SOURCE})/version.sh +. $(dirname ${BASH_SOURCE})/golang.sh +. $(dirname ${BASH_SOURCE})/test.sh +. $(dirname ${BASH_SOURCE})/release.sh +. $(dirname ${BASH_SOURCE})/chat.sh + +OPENIM_OUTPUT_HOSTBIN="${OPENIM_OUTPUT_BINPATH}/$(openim::util::host_platform)" +export OPENIM_OUTPUT_HOSTBIN + +export OPENIM_NONSERVER_GROUP_VERSIONS + +# This emulates "readlink -f" which is not available on MacOS X. +# Test: +# T=/tmp/$$.$RANDOM +# mkdir $T +# touch $T/file +# mkdir $T/dir +# ln -s $T/file $T/linkfile +# ln -s $T/dir $T/linkdir +# function testone() { +# X=$(readlink -f $1 2>&1) +# Y=$(kube::readlinkdashf $1 2>&1) +# if [ "$X" != "$Y" ]; then +# echo readlinkdashf $1: expected "$X", got "$Y" +# fi +# } +# testone / +# testone /tmp +# testone $T +# testone $T/file +# testone $T/dir +# testone $T/linkfile +# testone $T/linkdir +# testone $T/nonexistant +# testone $T/linkdir/file +# testone $T/linkdir/dir +# testone $T/linkdir/linkfile +# testone $T/linkdir/linkdir +function openim::readlinkdashf { + # run in a subshell for simpler 'cd' + ( + if [[ -d "${1}" ]]; then # This also catch symlinks to dirs. + cd "${1}" + pwd -P + else + cd "$(dirname "${1}")" + local f + f=$(basename "${1}") + if [[ -L "${f}" ]]; then + readlink "${f}" + else + echo "$(pwd -P)/${f}" + fi + fi + ) +} + +# This emulates "readlink -f" which is not available on MacOS X. +# Test: +# T=/tmp/$$.$RANDOM +# mkdir $T +# touch $T/file +# mkdir $T/dir +# ln -s $T/file $T/linkfile +# ln -s $T/dir $T/linkdir +# function testone() { +# X=$(readlink -f $1 2>&1) +# Y=$(kube::readlinkdashf $1 2>&1) +# if [ "$X" != "$Y" ]; then +# echo readlinkdashf $1: expected "$X", got "$Y" +# fi +# } +# testone / +# testone /tmp +# testone $T +# testone $T/file +# testone $T/dir +# testone $T/linkfile +# testone $T/linkdir +# testone $T/nonexistant +# testone $T/linkdir/file +# testone $T/linkdir/dir +# testone $T/linkdir/linkfile +# testone $T/linkdir/linkdir +function openim::readlinkdashf { + # run in a subshell for simpler 'cd' + ( + if [[ -d "${1}" ]]; then # This also catch symlinks to dirs. + cd "${1}" + pwd -P + else + cd "$(dirname "${1}")" + local f + f=$(basename "${1}") + if [[ -L "${f}" ]]; then + readlink "${f}" + else + echo "$(pwd -P)/${f}" + fi + fi + ) +} + +# This emulates "realpath" which is not available on MacOS X +# Test: +# T=/tmp/$$.$RANDOM +# mkdir $T +# touch $T/file +# mkdir $T/dir +# ln -s $T/file $T/linkfile +# ln -s $T/dir $T/linkdir +# function testone() { +# X=$(realpath $1 2>&1) +# Y=$(kube::realpath $1 2>&1) +# if [ "$X" != "$Y" ]; then +# echo realpath $1: expected "$X", got "$Y" +# fi +# } +# testone / +# testone /tmp +# testone $T +# testone $T/file +# testone $T/dir +# testone $T/linkfile +# testone $T/linkdir +# testone $T/nonexistant +# testone $T/linkdir/file +# testone $T/linkdir/dir +# testone $T/linkdir/linkfile +# testone $T/linkdir/linkdir +openim::realpath() { + if [[ ! -e "${1}" ]]; then + echo "${1}: No such file or directory" >&2 + return 1 + fi + openim::readlinkdashf "${1}" +} + +# Marker function to indicate init.sh has been fully sourced +openim::init::loaded() { + return 0 +} \ No newline at end of file diff --git a/scripts/lib/logging.sh b/scripts/lib/logging.sh index a82b9e3fc..092db5513 100755 --- a/scripts/lib/logging.sh +++ b/scripts/lib/logging.sh @@ -17,8 +17,6 @@ # Controls verbosity of the script output and logging. OPENIM_VERBOSE="${OPENIM_VERBOSE:-5}" -souorce $(dirname ${BASH_SOURCE})/color.sh - # Handler for when we exit automatically on an error. # Borrowed from https://gist.github.com/ahendrix/7030300 openim::log::errexit() { diff --git a/scripts/lib/release.sh b/scripts/lib/release.sh index a198e1ae6..7d5ff16d0 100755 --- a/scripts/lib/release.sh +++ b/scripts/lib/release.sh @@ -38,6 +38,7 @@ readonly RELEASE_IMAGES="${LOCAL_OUTPUT_ROOT}/release-images" # OpenIM github account info readonly OPENIM_GITHUB_ORG=OpenIMSDK readonly OPENIM_GITHUB_REPO=Open-IM-Server +readonly CHAT_GITHUB_REPO=chat readonly ARTIFACT=openim.tar.gz readonly CHECKSUM=${ARTIFACT}.sha1sum diff --git a/scripts/lib/test.sh b/scripts/lib/test.sh new file mode 100644 index 000000000..782af21ef --- /dev/null +++ b/scripts/lib/test.sh @@ -0,0 +1,548 @@ +#!/usr/bin/env bash + +# A set of helpers for tests + +openim::test::clear_all() { + if openim::test::if_supports_resource "rc" ; then + # shellcheck disable=SC2154 + # Disabling because "kube_flags" is set in a parent script + kubectl delete "${kube_flags[@]}" rc --all --grace-period=0 --force + fi + if openim::test::if_supports_resource "pods" ; then + kubectl delete "${kube_flags[@]}" pods --all --grace-period=0 --force + fi +} + +# Prints the calling file and line number $1 levels deep +# Defaults to 2 levels so you can call this to find your own caller +openim::test::get_caller() { + local levels=${1:-2} + local caller_file="${BASH_SOURCE[${levels}]}" + local caller_line="${BASH_LINENO[${levels}-1]}" + echo "$(basename "${caller_file}"):${caller_line}" +} + +# Force exact match of a returned result for a object query. Wrap this with || to support multiple +# valid return types. +# This runs `kubectl get` once and asserts that the result is as expected. +# $1: Object on which get should be run +# $2: The go-template to run on the result +# $3: The expected output +# $4: Additional args to be passed to kubectl +openim::test::get_object_assert() { + openim::test::object_assert 1 "$@" +} + +# Asserts that the output of a given get query is as expected. +# Runs the query multiple times before failing it. +# $1: Object on which get should be run +# $2: The go-template to run on the result +# $3: The expected output +# $4: Additional args to be passed to kubectl +openim::test::wait_object_assert() { + openim::test::object_assert 10 "$@" +} + +# Asserts that the output of a given get query is as expected. +# Can run the query multiple times before failing it. +# $1: Number of times the query should be run before failing it. +# $2: Object on which get should be run +# $3: The go-template to run on the result +# $4: The expected output +# $5: Additional args to be passed to kubectl +openim::test::object_assert() { + local tries=$1 + local object=$2 + local request=$3 + local expected=$4 + local args=${5:-} + + for j in $(seq 1 "${tries}"); do + # shellcheck disable=SC2086 + # Disabling because to allow for expansion here + res=$(kubectl get "${kube_flags[@]}" ${args} ${object} -o go-template="${request}") + if [[ "${res}" =~ ^$expected$ ]]; then + echo -n "${green}" + echo "$(openim::test::get_caller 3): Successful get ${object} ${request}: ${res}" + echo -n "${reset}" + return 0 + fi + echo "Waiting for Get ${object} ${request} ${args}: expected: ${expected}, got: ${res}" + sleep $((j-1)) + done + + echo "${bold}${red}" + echo "$(openim::test::get_caller 3): FAIL!" + echo "Get ${object} ${request}" + echo " Expected: ${expected}" + echo " Got: ${res}" + echo "${reset}${red}" + caller + echo "${reset}" + return 1 +} + +openim::test::get_object_jsonpath_assert() { + local object=$1 + local request=$2 + local expected=$3 + + # shellcheck disable=SC2086 + # Disabling to allow for expansion here + res=$(kubectl get "${kube_flags[@]}" ${object} -o jsonpath=${request}) + + if [[ "${res}" =~ ^$expected$ ]]; then + echo -n "${green}" + echo "$(openim::test::get_caller): Successful get ${object} ${request}: ${res}" + echo -n "${reset}" + return 0 + else + echo "${bold}${red}" + echo "$(openim::test::get_caller): FAIL!" + echo "Get ${object} ${request}" + echo " Expected: ${expected}" + echo " Got: ${res}" + echo "${reset}${red}" + caller + echo "${reset}" + return 1 + fi +} + +openim::test::describe_object_assert() { + local resource=$1 + local object=$2 + local matches=( "${@:3}" ) + + # shellcheck disable=SC2086 + # Disabling to allow for expansion here + result=$(kubectl describe "${kube_flags[@]}" ${resource} ${object}) + + for match in "${matches[@]}"; do + if grep -q "${match}" <<< "${result}"; then + echo "matched ${match}" + else + echo "${bold}${red}" + echo "$(openim::test::get_caller): FAIL!" + echo "Describe ${resource} ${object}" + echo " Expected Match: ${match}" + echo " Not found in:" + echo "${result}" + echo "${reset}${red}" + caller + echo "${reset}" + return 1 + fi + done + + echo -n "${green}" + echo "$(openim::test::get_caller): Successful describe ${resource} ${object}:" + echo "${result}" + echo -n "${reset}" + return 0 +} + +openim::test::describe_object_events_assert() { + local resource=$1 + local object=$2 + local showevents=${3:-"true"} + + # shellcheck disable=SC2086 + # Disabling to allow for expansion here + if [[ -z "${3:-}" ]]; then + result=$(kubectl describe "${kube_flags[@]}" ${resource} ${object}) + else + result=$(kubectl describe "${kube_flags[@]}" "--show-events=${showevents}" ${resource} ${object}) + fi + + if grep -q "No events.\|Events:" <<< "${result}"; then + local has_events="true" + else + local has_events="false" + fi + if [[ "${showevents}" == "${has_events}" ]]; then + echo -n "${green}" + echo "$(openim::test::get_caller): Successful describe" + echo "${result}" + echo "${reset}" + return 0 + else + echo "${bold}${red}" + echo "$(openim::test::get_caller): FAIL" + if [[ "${showevents}" == "false" ]]; then + echo " Events information should not be described in:" + else + echo " Events information not found in:" + fi + echo "${result}" + echo "${reset}${red}" + caller + echo "${reset}" + return 1 + fi +} + +openim::test::describe_resource_assert() { + local resource=$1 + local matches=( "${@:2}" ) + + # shellcheck disable=SC2086 + # Disabling to allow for expansion here + result=$(kubectl describe "${kube_flags[@]}" ${resource}) + + for match in "${matches[@]}"; do + if grep -q "${match}" <<< "${result}"; then + echo "matched ${match}" + else + echo "${bold}${red}" + echo "FAIL!" + echo "Describe ${resource}" + echo " Expected Match: ${match}" + echo " Not found in:" + echo "${result}" + echo "${reset}${red}" + caller + echo "${reset}" + return 1 + fi + done + + echo -n "${green}" + echo "Successful describe ${resource}:" + echo "${result}" + echo -n "${reset}" + return 0 +} + +openim::test::describe_resource_events_assert() { + local resource=$1 + local showevents=${2:-"true"} + + # shellcheck disable=SC2086 + # Disabling to allow for expansion here + result=$(kubectl describe "${kube_flags[@]}" "--show-events=${showevents}" ${resource}) + + if grep -q "No events.\|Events:" <<< "${result}"; then + local has_events="true" + else + local has_events="false" + fi + if [[ "${showevents}" == "${has_events}" ]]; then + echo -n "${green}" + echo "Successful describe" + echo "${result}" + echo -n "${reset}" + return 0 + else + echo "${bold}${red}" + echo "FAIL" + if [[ "${showevents}" == "false" ]]; then + echo " Events information should not be described in:" + else + echo " Events information not found in:" + fi + echo "${result}" + caller + echo "${reset}" + return 1 + fi +} + +openim::test::describe_resource_chunk_size_assert() { + # $1: the target resource + local resource=$1 + # $2: comma-separated list of additional resources that will be listed + local additionalResources=${2:-} + # Remaining args are flags to pass to kubectl + local args=${3:-} + + # Expect list requests for the target resource and the additional resources + local expectLists + IFS="," read -r -a expectLists <<< "${resource},${additionalResources}" + + # shellcheck disable=SC2086 + # Disabling to allow for expansion here + defaultResult=$(kubectl describe ${resource} --show-events=true -v=6 ${args} "${kube_flags[@]}" 2>&1 >/dev/null) + for r in "${expectLists[@]}"; do + if grep -q "${r}?.*limit=500" <<< "${defaultResult}"; then + echo "query for ${r} had limit param" + else + echo "${bold}${red}" + echo "FAIL!" + echo "Describe ${resource}" + echo " Expected limit param on request for: ${r}" + echo " Not found in:" + echo "${defaultResult}" + echo "${reset}${red}" + caller + echo "${reset}" + return 1 + fi + done + + # shellcheck disable=SC2086 + # Disabling to allow for expansion here + # Try a non-default chunk size + customResult=$(kubectl describe ${resource} --show-events=false --chunk-size=10 -v=6 ${args} "${kube_flags[@]}" 2>&1 >/dev/null) + if grep -q "${resource}?limit=10" <<< "${customResult}"; then + echo "query for ${resource} had user-specified limit param" + else + echo "${bold}${red}" + echo "FAIL!" + echo "Describe ${resource}" + echo " Expected limit param on request for: ${r}" + echo " Not found in:" + echo "${customResult}" + echo "${reset}${red}" + caller + echo "${reset}" + return 1 + fi + + echo -n "${green}" + echo "Successful describe ${resource} verbose logs:" + echo "${defaultResult}" + echo -n "${reset}" + + return 0 +} + +# Compare sort-by resource name output (first column, skipping first line) with expected order specify in the last parameter +openim::test::if_sort_by_has_correct_order() { + local var + var="$(echo "$1" | awk '{if(NR!=1) print $1}' | tr '\n' ':')" + openim::test::if_has_string "${var}" "${@:$#}" +} + +openim::test::if_has_string() { + local message=$1 + local match=$2 + + if grep -q "${match}" <<< "${message}"; then + echo -n "${green}" + echo "Successful" + echo -n "${reset}" + echo "message:${message}" + echo "has:${match}" + return 0 + else + echo -n "${bold}${red}" + echo "FAIL!" + echo -n "${reset}" + echo "message:${message}" + echo "has not:${match}" + caller + return 1 + fi +} + +openim::test::if_has_not_string() { + local message=$1 + local match=$2 + + if grep -q "${match}" <<< "${message}"; then + echo -n "${bold}${red}" + echo "FAIL!" + echo -n "${reset}" + echo "message:${message}" + echo "has:${match}" + caller + return 1 + else + echo -n "${green}" + echo "Successful" + echo -n "${reset}" + echo "message:${message}" + echo "has not:${match}" + return 0 + fi +} + +openim::test::if_empty_string() { + local match=$1 + if [ -n "${match}" ]; then + echo -n "${bold}${red}" + echo "FAIL!" + echo "${match} is not empty" + echo -n "${reset}" + caller + return 1 + else + echo -n "${green}" + echo "Successful" + echo -n "${reset}" + return 0 + fi +} + +# Returns true if the required resource is part of supported resources. +# Expects env vars: +# SUPPORTED_RESOURCES: Array of all resources supported by the apiserver. "*" +# means it supports all resources. For ex: ("*") or ("rc" "*") both mean that +# all resources are supported. +# $1: Name of the resource to be tested. +openim::test::if_supports_resource() { + SUPPORTED_RESOURCES=${SUPPORTED_RESOURCES:-""} + REQUIRED_RESOURCE=${1:-""} + + for r in "${SUPPORTED_RESOURCES[@]}"; do + if [[ "${r}" == "*" || "${r}" == "${REQUIRED_RESOURCE}" ]]; then + return 0 + fi + done + return 1 +} + +openim::test::version::object_to_file() { + name=$1 + flags=${2:-""} + file=$3 + # shellcheck disable=SC2086 + # Disabling because "flags" needs to allow for expansion here + kubectl version ${flags} | grep "${name} Version:" | sed -e s/"${name} Version: "/""/g > "${file}" +} + +openim::test::version::json_object_to_file() { + flags=$1 + file=$2 + # shellcheck disable=SC2086 + # Disabling because "flags" needs to allow for expansion here + kubectl version ${flags} --output json | sed -e s/' '/''/g -e s/'\"'/''/g -e s/'}'/''/g -e s/'{'/''/g -e s/'clientVersion:'/'clientVersion:,'/ -e s/'serverVersion:'/'serverVersion:,'/ | tr , '\n' > "${file}" +} + +openim::test::version::json_client_server_object_to_file() { + flags=$1 + name=$2 + file=$3 + # shellcheck disable=SC2086 + # Disabling because "flags" needs to allow for expansion here + kubectl version ${flags} --output json | jq -r ".${name}" | sed -e s/'\"'/''/g -e s/'}'/''/g -e s/'{'/''/g -e /^$/d -e s/','/''/g -e s/':'/'='/g > "${file}" +} + +openim::test::version::yaml_object_to_file() { + flags=$1 + file=$2 + # shellcheck disable=SC2086 + # Disabling because "flags" needs to allow for expansion here + kubectl version ${flags} --output yaml | sed -e s/' '/''/g -e s/'\"'/''/g -e /^$/d > "${file}" +} + +openim::test::version::diff_assert() { + local original=$1 + local comparator=${2:-"eq"} + local latest=$3 + local diff_msg=${4:-""} + local res="" + + if [ ! -f "${original}" ]; then + echo "${bold}${red}" + echo "FAIL! ${diff_msg}" + echo "the file '${original}' does not exit" + echo "${reset}${red}" + caller + echo "${reset}" + return 1 + fi + + if [ ! -f "${latest}" ]; then + echo "${bold}${red}" + echo "FAIL! ${diff_msg}" + echo "the file '${latest}' does not exit" + echo "${reset}${red}" + caller + echo "${reset}" + return 1 + fi + + if [ "${comparator}" == "exact" ]; then + # Skip sorting of file content for exact comparison. + cp "${original}" "${original}.sorted" + cp "${latest}" "${latest}.sorted" + else + sort "${original}" > "${original}.sorted" + sort "${latest}" > "${latest}.sorted" + fi + + if [ "${comparator}" == "eq" ] || [ "${comparator}" == "exact" ]; then + if [ "$(diff -iwB "${original}".sorted "${latest}".sorted)" == "" ] ; then + echo -n "${green}" + echo "Successful: ${diff_msg}" + echo -n "${reset}" + return 0 + else + echo "${bold}${red}" + echo "FAIL! ${diff_msg}" + echo " Expected: " + cat "${original}" + echo " Got: " + cat "${latest}" + echo "${reset}${red}" + caller + echo "${reset}" + return 1 + fi + else + if [ -n "$(diff -iwB "${original}".sorted "${latest}".sorted)" ] ; then + echo -n "${green}" + echo "Successful: ${diff_msg}" + echo -n "${reset}" + return 0 + else + echo "${bold}${red}" + echo "FAIL! ${diff_msg}" + echo " Expected: " + cat "${original}" + echo " Got: " + cat "${latest}" + echo "${reset}${red}" + caller + echo "${reset}" + return 1 + fi + fi +} + +# Force exact match of kubectl stdout, stderr, and return code. +# $1: file with actual stdout +# $2: file with actual stderr +# $3: the actual return code +# $4: file with expected stdout +# $5: file with expected stderr +# $6: expected return code +# $7: additional message describing the invocation +openim::test::results::diff() { + local actualstdout=$1 + local actualstderr=$2 + local actualcode=$3 + local expectedstdout=$4 + local expectedstderr=$5 + local expectedcode=$6 + local message=$7 + local result=0 + + if ! openim::test::version::diff_assert "${expectedstdout}" "exact" "${actualstdout}" "stdout for ${message}"; then + result=1 + fi + if ! openim::test::version::diff_assert "${expectedstderr}" "exact" "${actualstderr}" "stderr for ${message}"; then + result=1 + fi + if [ "${actualcode}" -ne "${expectedcode}" ]; then + echo "${bold}${red}" + echo "$(openim::test::get_caller): FAIL!" + echo "Return code for ${message}" + echo " Expected: ${expectedcode}" + echo " Got: ${actualcode}" + echo "${reset}${red}" + caller + echo "${reset}" + result=1 + fi + + if [ "${result}" -eq 0 ]; then + echo -n "${green}" + echo "$(openim::test::get_caller): Successful: ${message}" + echo -n "${reset}" + fi + + return "$result" +} \ No newline at end of file diff --git a/scripts/lib/util.sh b/scripts/lib/util.sh index 6f314ee67..89fbaae85 100755 --- a/scripts/lib/util.sh +++ b/scripts/lib/util.sh @@ -680,6 +680,33 @@ function openim::util::ensure-cfssl { popd > /dev/null || return 1 } +# openim::util::ensure-docker-buildx +# Check if we have "docker buildx" commands available +# +function openim::util::ensure-docker-buildx { + # podman returns 0 on `docker buildx version`, docker on `docker buildx`. One of them must succeed. + if docker buildx version >/dev/null 2>&1 || docker buildx >/dev/null 2>&1; then + return 0 + else + echo "ERROR: docker buildx not available. Docker 19.03 or higher is required with experimental features enabled" + exit 1 + fi +} + +# openim::util::ensure-bash-version +# Check if we are using a supported bash version +# +function openim::util::ensure-bash-version { + # shellcheck disable=SC2004 + if ((${BASH_VERSINFO[0]}<4)) || ( ((${BASH_VERSINFO[0]}==4)) && ((${BASH_VERSINFO[1]}<2)) ); then + echo "ERROR: This script requires a minimum bash version of 4.2, but got version of ${BASH_VERSINFO[0]}.${BASH_VERSINFO[1]}" + if [ "$(uname)" = 'Darwin' ]; then + echo "On macOS with homebrew 'brew install bash' is sufficient." + fi + exit 1 + fi +} + # openim::util::ensure-gnu-sed # Determines which sed binary is gnu-sed on linux/darwin # @@ -701,6 +728,26 @@ function openim::util::ensure-gnu-sed { openim::util::sourced_variable "${SED}" } +# openim::util::ensure-gnu-date +# Determines which date binary is gnu-date on linux/darwin +# +# Sets: +# DATE: The name of the gnu-date binary +# +function openim::util::ensure-gnu-date { + # NOTE: the echo below is a workaround to ensure date is executed before the grep. + date_help="$(LANG=C date --help 2>&1 || true)" + if echo "${date_help}" | grep -q "GNU\|BusyBox"; then + DATE="date" + elif command -v gdate &>/dev/null; then + DATE="gdate" + else + openim::log::error "Failed to find GNU date as date or gdate. If you are on Mac: brew install coreutils." >&2 + return 1 + fi + openim::util::sourced_variable "${DATE}" +} + # openim::util::check-file-in-alphabetical-order # Check that the file is in alphabetical order # diff --git a/scripts/msg_gateway_start.sh b/scripts/msg_gateway_start.sh index 073afce11..4479dd539 100755 --- a/scripts/msg_gateway_start.sh +++ b/scripts/msg_gateway_start.sh @@ -18,9 +18,8 @@ SCRIPTS_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) OPENIM_ROOT=$(dirname "${BASH_SOURCE[0]}")/.. #Include shell font styles and some basic information -source $SCRIPTS_ROOT/style_info.sh +source $SCRIPTS_ROOT/lib/init.sh source $SCRIPTS_ROOT/path_info.sh -source $SCRIPTS_ROOT/function.sh cd $SCRIPTS_ROOT diff --git a/scripts/msg_transfer_start.sh b/scripts/msg_transfer_start.sh index e1d91577d..b54770466 100755 --- a/scripts/msg_transfer_start.sh +++ b/scripts/msg_transfer_start.sh @@ -18,9 +18,8 @@ SCRIPTS_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) OPENIM_ROOT=$(dirname "${BASH_SOURCE[0]}")/.. #Include shell font styles and some basic information -source $SCRIPTS_ROOT/style_info.sh +source $SCRIPTS_ROOT/lib/init.sh source $SCRIPTS_ROOT/path_info.sh -source $SCRIPTS_ROOT/function.sh echo -e "${YELLOW_PREFIX}=======>SCRIPTS_ROOT=$SCRIPTS_ROOT${COLOR_SUFFIX}" echo -e "${YELLOW_PREFIX}=======>OPENIM_ROOT=$OPENIM_ROOT${COLOR_SUFFIX}" diff --git a/scripts/push_start.sh b/scripts/push_start.sh index b5e197983..88eb8c198 100755 --- a/scripts/push_start.sh +++ b/scripts/push_start.sh @@ -20,9 +20,8 @@ SCRIPTS_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) OPENIM_ROOT=$(dirname "${BASH_SOURCE[0]}")/.. #Include shell font styles and some basic information -source $SCRIPTS_ROOT/style_info.sh +source $SCRIPTS_ROOT/lib/init.sh source $SCRIPTS_ROOT/path_info.sh -source $SCRIPTS_ROOT/function.sh cd $SCRIPTS_ROOT diff --git a/scripts/start_all.sh b/scripts/start_all.sh index b6b4e3428..7c9d807cc 100755 --- a/scripts/start_all.sh +++ b/scripts/start_all.sh @@ -21,9 +21,8 @@ SCRIPTS_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) OPENIM_ROOT=$(dirname "${SCRIPTS_ROOT}")/.. #Include shell font styles and some basic information -source $SCRIPTS_ROOT/style_info.sh +source $SCRIPTS_ROOT/lib/init.sh source $SCRIPTS_ROOT/path_info.sh -source $SCRIPTS_ROOT/function.sh cd $SCRIPTS_ROOT diff --git a/scripts/start_rpc_service.sh b/scripts/start_rpc_service.sh index d778914a0..f34587ec7 100755 --- a/scripts/start_rpc_service.sh +++ b/scripts/start_rpc_service.sh @@ -19,9 +19,8 @@ SCRIPTS_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) OPENIM_ROOT=$(dirname "${BASH_SOURCE[0]}")/.. #Include shell font styles and some basic information -source $SCRIPTS_ROOT/style_info.sh +source $SCRIPTS_ROOT/lib/init.sh source $SCRIPTS_ROOT/path_info.sh -source $SCRIPTS_ROOT/function.sh cd $SCRIPTS_ROOT diff --git a/test/wrktest.sh b/test/wrktest.sh index f57d16402..a0a5574d6 100755 --- a/test/wrktest.sh +++ b/test/wrktest.sh @@ -8,18 +8,14 @@ The API performance test script automatically executes wrk commands, collects data, analyzes it, and calls gnuplot to plot it Usage (to test API performance) : - -Start the openim-api(port 10002) - -Execute the test script: ./wrktest.sh +1. Start the openim-api(port 10002) +2. Execute the test script: ./wrktest.sh The script will generate the data file.dat, each column meaning: concurrency QPS average response time success rate Usage (Compare the results of 2 tests) - 1. The performance test:. / wrktest. Sh openim apiserver - http://127.0.0.1:10002/healthz - -Execute the command:./wrktest.sh diff apiserver.dat http.dat +2. Execute the command:./wrktest.sh diff apiserver.dat http.dat > Note: Make sure you have wrk and gnuplot installed on your system