From 67c490ecd9691ab4499e13fc42edb3dd1122a13e Mon Sep 17 00:00:00 2001 From: liamfallon Date: Wed, 20 Nov 2024 13:21:54 +0000 Subject: [PATCH 1/2] Script to run a Porch load test --- scripts/run-load-test.sh | 420 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 420 insertions(+) create mode 100755 scripts/run-load-test.sh diff --git a/scripts/run-load-test.sh b/scripts/run-load-test.sh new file mode 100755 index 00000000..68ce8e8c --- /dev/null +++ b/scripts/run-load-test.sh @@ -0,0 +1,420 @@ +#! /opt/homebrew/bin/bash + +script_name=$(basename "$0") + +git_repo_server="" +git_repo_count=0 +package_count=0 +package_revision_count=0 +result_file=scalability_results.txt +repo_result_file=scalability_repo_results.csv +log_file=scalability.log +dirty_mode=false + +usage() +{ + echo "" + echo "$script_name - runs a load test on porch" + echo "" + echo " usage: $script_name [-options]" + echo "" + echo " options" + echo " -h - this help message" + echo " -s hostname - the host name of the git server for porch git repos" + echo " -r repo-count - the number of repos to create during the test, a positive integer" + echo " -p package-count - the number of packages to create in each repo during the test, a positive integer" + echo " -e package-revision-count - the number of packagerevisions to create on each package during the test, a positive integer" + echo " -f result-file - the file where the raw results will be stored, defaults to $result_file" + echo " -o repo-result-file - the file where the results by reop will be stored, defaults to $repo_result_file" + echo " -l log-file - the file where the test log will be stored, defaults to $log_file" + echo " -y - dirty mode, do not clean up after tests" + echo "" + exit 255; +} + +while getopts "hs:r:p:e:f:o:l:y" opt +do + case $opt in + h) + usage + ;; + s) + git_repo_server=$OPTARG + ;; + r) + git_repo_count=$OPTARG + ;; + p) + package_count=$OPTARG + ;; + e) + package_revision_count=$OPTARG + ;; + f) + result_file=$OPTARG + ;; + o) + repo_result_file=$OPTARG + ;; + l) + log_file=$OPTARG + ;; + y) + dirty_mode=true + ;; + \?) + usage + ;; + esac +done + +if [[ -z "$git_repo_server" ]] +then + echo "git server for porch git repos not specified with the -s flag" + exit 1 +fi + +if [[ "$git_repo_count" -lt 1 ]] +then + echo "git repo count must be specified as a positive integer on the -r flag" + exit 1 +fi + +if [[ "$package_count" -lt 1 ]] +then + echo "package count must be specified as a positive integer on the -p flag" + exit 1 +fi + +if [[ "$package_revision_count" -lt 1 ]] +then + echo "pacakge revision count must be specified as a positive integer on the -e flag" + exit 1 +fi + +if [ -z "$result_file" ] +then + echo "result file not specified on -f flag" + exit 1 +fi + +if [ -z "$repo_result_file" ] +then + echo "repo result file not specified on -o flag" + exit 1 +fi + +if [ -z "$log_file" ] +then + echo "log file not specified on -l flag" + exit 1 +fi + +echo "running scalability test towards git server http://nephio:secret@$git_repo_server:3000/nephio/" +echo " $git_repo_count repos will be created" +echo " $package_count packages in each repo" +echo " $package_revision_count pacakge revisions in each package" +echo " results will be stored in \"$result_file\"" +echo " repo results will be stored in \"$repo_result_file\"" +echo " the log will be stored in \"$log_file\"" + +update_package_resources() { + cat << EOF > "$1/Kptfile" +apiVersion: kpt.dev/v1 +kind: Kptfile + +metadata: + name: "$1" + annotations: + config.kubernetes.io/local-config: "true" + +info: + description: network function "$1" blueprint + +pipeline: + mutators: + - image: gcr.io/kpt-fn/apply-replacements:v0.1.1 + configPath: apply-replacements-annotation1.yaml + - image: gcr.io/kpt-fn/apply-replacements:v0.1.1 + configPath: apply-replacements-annotation2.yaml +EOF + + cat << EOF > "$1/deployment.yaml" +apiVersion: apps/v1 +kind: Deployment +metadata: + name: "$1" + annotations: + annotation1: no-value-1 + annotation2: no-value-2 +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/name: "$1" + template: + metadata: + labels: + app.kubernetes.io/name: "$1" + spec: + containers: + - name: nginx + image: nginx:latest +EOF + + cat << EOF > "$1/cm_deployment.yaml" +apiVersion: v1 +kind: ConfigMap +metadata: + name: cm-deployment + annotations: + config.kubernetes.io/local-config: "true" +data: + annotation1: local-annotation-1 + annotation2: local-annotation-2 +EOF + + cat << EOF > "$1/apply-replacements-annotation1.yaml" +apiVersion: fn.kpt.dev/v1alpha1 +kind: ApplyReplacements +metadata: + name: replace-annotation1 + annotations: + config.kubernetes.io/local-config: "true" +replacements: +- source: + kind: ConfigMap + name: cm-deployment + fieldPath: data.annotation1 + targets: + - select: + kind: Deployment + fieldPaths: + - metadata.annotations.annotation1 +EOF + + cat << EOF > "$1/apply-replacements-annotation2.yaml" +apiVersion: fn.kpt.dev/v1alpha1 +kind: ApplyReplacements +metadata: + name: replace-annotation1 + annotations: + config.kubernetes.io/local-config: "true" +replacements: +- source: + kind: ConfigMap + name: cm-deployment + fieldPath: data.annotation2 + targets: + - select: + kind: Deployment + fieldPaths: + - metadata.annotations.annotation2 +EOF +} + +create_package_revision() { + TMP_DIR=$(mktemp -d) + pushd "$TMP_DIR" || return + + porchctl -n porch-scale rpkg pull "$1" "$1" + update_package_resources "$1" + porchctl -n porch-scale rpkg push "$1" "$1" + porchctl -n porch-scale rpkg propose "$1" + porchctl -n porch-scale rpkg approve "$1" + + popd || return + + if ! $dirty_mode + then + rm -fr "$TMP_DIR" + fi +} + +create_package () { + start_prv1=$EPOCHREALTIME + pkg_v1=$(porchctl -n porch-scale rpkg init "network-function-$2" --repository="$1" --workspace=v1 | cut -f1 -d' ' ) + echo "$1:$2:1 $pkg_v1 initialized" >> "$result_file" + + create_package_revision "$pkg_v1" + echo "$1:$2:1 $pkg_v1 approved, took $(echo $EPOCHREALTIME-$start_prv1 | bc -l) seconds" >> "$result_file" + + for k in $(seq 2 "$package_revision_count") + do + start_prvx=$EPOCHREALTIME + + pkg_vx=$(porchctl rpkg copy -n porch-scale "$pkg_v1" "--workspace=v$k" | cut -f1 -d' ' ) + echo "$1:$2:$k $pkg_vx copied" >> "$result_file" + create_package_revision "$pkg_vx" + echo "$1:$2:$k $pkg_vx approved, took $(echo $EPOCHREALTIME-$start_prvx | bc -l) seconds" >> "$result_file" + done +} + +create_repo () { + git_repo_name="porch-scale-test-$1" + + echo "creating repo $git_repo_name . . ." + { + curl -k -H "content-type: application/json" "http://nephio:secret@$git_repo_server:3000/api/v1/user/repos" --data '{"name":"'"$git_repo_name"'"}' >> "$log_file" 2>&1 + + TMP_DIR=$(mktemp -d) + pushd "$TMP_DIR" || return + git clone "http://nephio:secret@$git_repo_server:3000/nephio/$git_repo_name.git" + + pushd "$git_repo_name" || return + git switch -c main + touch README.md + git add README.md + git config user.name nephio + git commit -m "first commit" + git push -u origin main + popd || return + + popd || return + + if ! $dirty_mode + then + rm -fr "$TMP_DIR" + fi + } >> "$log_file" 2>&1 + + kubectl apply -f - <> "$log_file" 2>&1 +apiVersion: config.porch.kpt.dev/v1alpha1 +kind: Repository + +metadata: + name: "$git_repo_name" + namespace: porch-scale + +spec: + description: "$git_repo_name" + content: Package + deployment: false + type: git + git: + repo: "http://$git_repo_server:3000/nephio/$git_repo_name.git" + directory: / + branch: main + createBranch: true + secretRef: + name: gitea +EOF + + echo "created repo $git_repo_name" + + for j in $(seq 1 "$package_count") + do + create_package "$git_repo_name" "$j" >> "$log_file" 2>&1 + done +} + +create_namespace_secret() { + kubectl apply -f - <> "$log_file" 2>&1 +apiVersion: v1 +kind: Namespace +metadata: + name: porch-scale + +--- +apiVersion: v1 +kind: Secret +metadata: + name: gitea + namespace: porch-scale +type: kubernetes.io/basic-auth +data: + username: bmVwaGlv + password: c2VjcmV0 +EOF +} + +delete_package_revisions () { + for pkg in $(porchctl rpkg get -n porch-scale | grep -v 'WORKSPACENAME' | cut -f1 -d' ') + do + start_prvd=$EPOCHREALTIME + porchctl -n porch-scale rpkg propose-delete "$pkg" >> "$log_file" 2>&1 + porchctl -n porch-scale rpkg delete "$pkg" >> "$log_file" 2>&1 + echo "$pkg deleted, took $(echo $EPOCHREALTIME-$start_prvd | bc -l) seconds" + done +} + +delete_repo () { + git_repo_name="porch-scale-test-$1" + + echo "deleting repo $git_repo_name . . ." + curl -k -H "content-type: application/json" --request DELETE "http://nephio:secret@$git_repo_server:3000/api/v1/repos/nephio/$git_repo_name" >> "$log_file" 2>&1 + kubectl delete -n porch-scale repositories.config.porch.kpt.dev "$git_repo_name" >> "$log_file" 2>&1 + echo "deleted repo $git_repo_name" +} + +delete_namespace_secret() { + kubectl delete -f - << EOF >> "$log_file" 2>&1 +apiVersion: v1 +kind: Secret +metadata: + name: gitea + namespace: porch-scale +type: kubernetes.io/basic-auth +data: + username: bmVwaGlv + password: c2VjcmV0 + +--- +apiVersion: v1 +kind: Namespace +metadata: + name: porch-scale + +EOF +} + +split_repo_results() { + TMP_DIR=$(mktemp -d) + CURRENT_DIR=$(pwd) + + grep "approved, took" "$result_file" | sed -e 's/\(:[0-9]* \).*, took /\1/' -e 's/ seconds$//' -e 's/ /,/' > "$TMP_DIR/approved.csv" + grep "deleted, took" "$result_file" | sed -e 's/deleted, took //' -e 's/ seconds$//' -e 's/ /,/' > "$TMP_DIR/deleted.csv" + + cd "$TMP_DIR" || exit + + for i in $(seq 1 "$git_repo_count") + do + repo_suffix=$(printf "%0${#git_repo_count}d" "$i") + echo "REPO-$repo_suffix-TEST,REPO-$repo_suffix-TIME" > "repo_$repo_suffix.csv" + grep "^porch-scale-test-$i\:" approved.csv | sed "s/^porch-scale-test-$i://" >> "repo_$repo_suffix.csv" + grep "^porch-scale-test-$i-" deleted.csv | sed "s/^porch-scale-test-$i-/del-/" >> "repo_$repo_suffix.csv" + done + + paste -d',' ./repo_*.csv + + cd "$CURRENT_DIR" || exit + if ! $dirty_mode + then + rm -fr "$TMP_DIR" + fi +} + +rm -fr "$result_file" "$repo_result_file" "$log_file" + +create_namespace_secret + +for i in $(seq 1 "$git_repo_count") +do + create_repo "$i" >> "$result_file" +done + +if ! $dirty_mode +then + delete_package_revisions >> "$result_file" + + for i in $(seq 1 "$git_repo_count") + do + delete_repo "$i" >> "$result_file" + done + + delete_namespace_secret +fi + +split_repo_results > "$repo_result_file" + +echo "scalability test towards git server http://nephio:secret@$git_repo_server:3000/nephio/ completed" From 098c1032fb444a22fc1894ccc6ca93329909b277 Mon Sep 17 00:00:00 2001 From: liamfallon Date: Mon, 25 Nov 2024 09:03:35 +0000 Subject: [PATCH 2/2] Address review comments --- scripts/run-load-test.sh | 35 +++++++---------------------------- 1 file changed, 7 insertions(+), 28 deletions(-) diff --git a/scripts/run-load-test.sh b/scripts/run-load-test.sh index 68ce8e8c..2cd8758c 100755 --- a/scripts/run-load-test.sh +++ b/scripts/run-load-test.sh @@ -1,4 +1,4 @@ -#! /opt/homebrew/bin/bash +#! /usr/bin/env bash script_name=$(basename "$0") @@ -6,9 +6,9 @@ git_repo_server="" git_repo_count=0 package_count=0 package_revision_count=0 -result_file=scalability_results.txt -repo_result_file=scalability_repo_results.csv -log_file=scalability.log +result_file=load_test_results.txt +repo_result_file=load_test_repo_results.csv +log_file=load_test.log dirty_mode=false usage() @@ -110,7 +110,7 @@ then exit 1 fi -echo "running scalability test towards git server http://nephio:secret@$git_repo_server:3000/nephio/" +echo "running load test towards git server http://nephio:secret@$git_repo_server:3000/nephio/" echo " $git_repo_count repos will be created" echo " $package_count packages in each repo" echo " $package_revision_count pacakge revisions in each package" @@ -347,27 +347,6 @@ delete_repo () { echo "deleted repo $git_repo_name" } -delete_namespace_secret() { - kubectl delete -f - << EOF >> "$log_file" 2>&1 -apiVersion: v1 -kind: Secret -metadata: - name: gitea - namespace: porch-scale -type: kubernetes.io/basic-auth -data: - username: bmVwaGlv - password: c2VjcmV0 - ---- -apiVersion: v1 -kind: Namespace -metadata: - name: porch-scale - -EOF -} - split_repo_results() { TMP_DIR=$(mktemp -d) CURRENT_DIR=$(pwd) @@ -412,9 +391,9 @@ then delete_repo "$i" >> "$result_file" done - delete_namespace_secret + kubectl delete ns porch-scale fi split_repo_results > "$repo_result_file" -echo "scalability test towards git server http://nephio:secret@$git_repo_server:3000/nephio/ completed" +echo "load test towards git server http://nephio:secret@$git_repo_server:3000/nephio/ completed"