-
Notifications
You must be signed in to change notification settings - Fork 64
/
performance-tests.sh
executable file
·160 lines (143 loc) · 6.29 KB
/
performance-tests.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
#!/bin/bash
# Copyright 2019 The Knative Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# This is a helper script for Knative performance test scripts.
# See README.md for instructions on how to use it.
source "$(dirname "${BASH_SOURCE[0]}")"/library.sh
# Configurable parameters.
# If not provided, they will fall back to the default values.
readonly BENCHMARK_ROOT_PATH=${BENCHMARK_ROOT_PATH:-test/performance/benchmarks}
readonly PROJECT_NAME=${PROJECT_NAME:-knative-performance}
readonly SERVICE_ACCOUNT_NAME=${SERVICE_ACCOUNT_NAME:[email protected]}
# Setup env vars.
export KO_DOCKER_REPO="gcr.io/${PROJECT_NAME}"
# Constants
readonly GOOGLE_APPLICATION_CREDENTIALS="/etc/performance-test/service-account.json"
readonly GITHUB_TOKEN="/etc/performance-test/github-token"
readonly SLACK_READ_TOKEN="/etc/performance-test/slack-read-token"
readonly SLACK_WRITE_TOKEN="/etc/performance-test/slack-write-token"
# Set up the user for cluster operations.
function setup_user() {
echo ">> Setting up user"
echo "Using gcloud user ${SERVICE_ACCOUNT_NAME}"
gcloud config set core/account "${SERVICE_ACCOUNT_NAME}"
echo "Using gcloud project ${PROJECT_NAME}"
gcloud config set core/project "${PROJECT_NAME}"
}
# Update resources installed on the cluster.
# Parameters: $1 - cluster name
# $2 - cluster region/zone
function update_cluster() {
# --zone option can work with both region and zone, (e.g. us-central1 and
# us-central1-a), so we don't need to add extra check here.
gcloud container clusters get-credentials "$1" --zone="$2" --project="${PROJECT_NAME}" || abort "failed to get cluster creds"
# Set up the configmap to run benchmarks in production
echo ">> Setting up 'prod' config-mako on cluster $1 in zone $2"
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ConfigMap
metadata:
name: config-mako
data:
# This should only be used by our performance automation.
environment: prod
EOF
# Create secrets required for running benchmarks on the cluster
echo ">> Creating secrets on cluster $1 in zone $2"
kubectl create secret generic mako-secrets \
--from-file=robot.json=${GOOGLE_APPLICATION_CREDENTIALS} \
--from-file=github-token=${GITHUB_TOKEN} \
--from-file=slack-read-token=${SLACK_READ_TOKEN} \
--from-file=slack-write-token=${SLACK_WRITE_TOKEN}
# Delete all benchmark jobs to avoid noise in the update process
echo ">> Deleting all cronjobs and jobs on cluster $1 in zone $2"
kubectl delete cronjob --all
kubectl delete job --all
if function_exists update_knative; then
update_knative || abort "failed to update knative"
fi
# get benchmark name from the cluster name
local benchmark_name
benchmark_name=$(get_benchmark_name "$1")
if function_exists update_benchmark; then
update_benchmark "${benchmark_name}" || abort "failed to update benchmark"
fi
}
# Get benchmark name from the cluster name.
# Parameters: $1 - cluster name
function get_benchmark_name() {
# get benchmark_name by removing the prefix from cluster name, e.g. get "load-test" from "serving--load-test"
echo "${1#$REPO_NAME"--"}"
}
# Update the clusters related to the current repo.
function update_clusters() {
header "Updating all clusters for ${REPO_NAME}"
local all_clusters
all_clusters=$(gcloud container clusters list --project="${PROJECT_NAME}" --format="csv[no-heading](name,zone)")
echo ">> Project contains clusters:" "${all_clusters}"
for cluster in ${all_clusters}; do
local name
name=$(echo "${cluster}" | cut -f1 -d",")
# the cluster name is prefixed with "${REPO_NAME}--", here we should only handle clusters belonged to the current repo
[[ ! ${name} =~ ^${REPO_NAME}-- ]] && continue
local zone
zone=$(echo "${cluster}" | cut -f2 -d",")
# Update all resources installed on the cluster
update_cluster "${name}" "${zone}"
done
header "Done updating all clusters"
}
# Run the perf-tests tool
# Parameters: $1..$n - parameters passed to the tool
function run_perf_cluster_tool() {
perf-tests "$@"
}
# Delete the old clusters belonged to the current repo, and recreate them with the same configuration.
function recreate_clusters() {
header "Recreating clusters for ${REPO_NAME}"
run_perf_cluster_tool --recreate \
--gcp-project="${PROJECT_NAME}" --repository="${REPO_NAME}" --benchmark-root="${BENCHMARK_ROOT_PATH}" \
|| abort "failed recreating clusters for ${REPO_NAME}"
header "Done recreating clusters"
# Update all clusters after they are recreated
update_clusters
}
# Try to reconcile clusters for benchmarks in the current repo.
# This function will be run as postsubmit jobs.
function reconcile_benchmark_clusters() {
header "Reconciling clusters for ${REPO_NAME}"
run_perf_cluster_tool --reconcile \
--gcp-project="${PROJECT_NAME}" --repository="${REPO_NAME}" --benchmark-root="${BENCHMARK_ROOT_PATH}" \
|| abort "failed reconciling clusters for ${REPO_NAME}"
header "Done reconciling clusters"
# For now, do nothing after reconciling the clusters, and the next update_clusters job will automatically
# update them. So there will be a period that the newly created clusters are being idle, and the duration
# can be as long as <update_clusters interval>.
}
# Parse flags and excute the command.
function main() {
if (( ! IS_PROW )); then
abort "this script should only be run by Prow since it needs secrets created on Prow cluster"
fi
# Set up the user credential for cluster operations
setup_user || abort "failed to set up user"
# Try parsing the first flag as a command.
case $1 in
--recreate-clusters) recreate_clusters ;;
--update-clusters) update_clusters ;;
--reconcile-benchmark-clusters) reconcile_benchmark_clusters ;;
*) abort "unknown command $1, must be --recreate-clusters, --update-clusters or --reconcile_benchmark_clusters"
esac
shift
}