-
Notifications
You must be signed in to change notification settings - Fork 23
/
Copy pathdriver.sh
executable file
·262 lines (234 loc) · 6 KB
/
driver.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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
#!/bin/sh --
#
# Driver for distributed JMeter testing.
#
# This script will
# i. Create a Docker container each for the specified number
# of JMeter servers.
# ii. Create a Docker container for the JMeter client (master).
# The client will connect to the servers created in step
# (i) and trigger the test script that is provided.
# Tips -- Look for the following in the client logs
#
# TODO: Cleanup - Not a biggie. Just watiting on shutdown to be done.
#
# The environment
SERVER_IMAGE=ssankara/jmeter-server
CLIENT_IMAGE=ssankara/jmeter
DATADIR=
JMX_SCRIPT=
WORK_DIR=$(readlink -f /tmp)
NUM_SERVERS=1
HOST_WRITE_PORT=49500
HOST_READ_PORT=49501
# Name of the JMeter client container
CLIENT_NAME=jmeter-client
# Prefix of all JMeter server containers. Actual name will be PREFIX-#
SERVER_NAME_PREFIX=jmeter-server
JTL_FILE=jtl.jtl
function validate_env() {
if [[ ! -d ${WORK_DIR} ]] ; then
echo "The working directory '${WORK_DIR}' does not exist"
usage
exit 1
fi
if [[ ! -d ${DATADIR} ]] ; then
echo "The data directory '${DATADIR}' does not exist"
usage
exit 2
fi
if [[ ! -f ${JMX_SCRIPT} ]] ; then
echo "The script file '${JMX_SCRIPT}' does not exist"
usage
exit 3
fi
if [[ ${NUM_SERVERS} -lt 1 ]]; then
echo "Must start at least 1 JMX server."
usage
exit 4
fi
}
function display_env() {
echo " DATADIR=${DATADIR}"
echo " JMX_SCRIPT=${JMX_SCRIPT}"
echo " WORK_DIR=${WORK_DIR}"
echo "NUM_SERVERS=${NUM_SERVERS}"
}
function start_servers() {
n=1
while [[ ${n} -le ${NUM_SERVERS} ]]
do
# Create a log directory for the server
LOGDIR=${WORK_DIR}/${SERVER_NAME_PREFIX}-${n}
mkdir -p ${LOGDIR}
# Start the server container
docker run --cidfile ${LOGDIR}/cid \
-d \
-p 0.0.0.0:${HOST_READ_PORT}:1099 \
-p 0.0.0.0:${HOST_WRITE_PORT}:60000 \
-v ${LOGDIR}:/logs \
-v ${DATADIR}:/input_data \
--name jmeter-server-${n} \
${SERVER_IMAGE} 2>/dev/null 1>&2
err=$?
if [[ ${err} -ne 0 ]] ; then
echo "Error '${err}' while starting a jmeter server. Quitting"
exit ${err}
fi
# Prepare for next server
n=$((${n} + 1))
HOST_READ_PORT=$((${HOST_READ_PORT} + 2))
HOST_WRITE_PORT=$((${HOST_WRITE_PORT} + 2))
done
}
function server_ips() {
#
# CAUTION: The logic here assumes that we want to use all
# active jmeter servers.
for pid in $(docker ps | grep ${SERVER_IMAGE} | awk '{print $1}')
do
# Get the IP for the current pid
x=$(docker inspect --format '{{ .NetworkSettings.IPAddress }}' ${pid})
# Append to SERVER_IPS
if [[ ! -z "${SERVER_IPS}" ]]; then
SERVER_IPS=${SERVER_IPS},
fi
SERVER_IPS=${SERVER_IPS}$x
done
}
#
# Get confirmation
function confirm() {
echo "Here's what we've got..."
echo "---------------------------------"
display_env
echo "---------------------------------"
read -n 1 -e -p "Does this look OK?y/[n]: " yesno
case ${yesno} in
y) return ;;
n) exit 6;;
esac
}
#
# Wait for client to terminate
function wait_for_client() {
echo "Checking on JMeter client status every 30 secs..."
echo "Logs etc. can be found in sub-directories of ${WORK_DIR}"
CLIENT_CID=$(cat ${LOGDIR}/cid)
# Wait for client CID to clear
while :
do
docker ps --no-trunc | grep ${CLIENT_CID} 2>/dev/null 1>&2
if [[ $? -ne 0 ]]; then
echo
echo "JMeter client done"
break
fi
echo -n "."
sleep 30
done
}
#
# Stop servers
function stop_servers() {
echo "Stopping all (${NUM_SERVERS}) JMeter servers..."
n=1
while [[ ${n} -le ${NUM_SERVERS} ]]
do
docker stop ${SERVER_NAME_PREFIX}-${n}
n=$((${n}+1))
done
}
#
# Remove all stopped containers
function remove_containers() {
echo "Removing containers..."
docker rm ${CLIENT_NAME}
n=1
while [[ ${n} -le ${NUM_SERVERS} ]]
do
docker rm ${SERVER_NAME_PREFIX}-${n}
n=$((${n}+1))
done
}
#
# Le usage
function usage() {
echo "Usage: $0 [-d data-dir] [-n num-jmeter-servers] [-s jmx] [-w work-dir]"
echo "-d The data directory for data files used by the JMX script."
echo "-h This help message"
echo "-n The required number of servers"
echo "-s The JMX script file"
echo "-w The working directory. Logs are relative to it."
}
# ------------- Show starts here -------------
#
# Getopts to read - datadir, WORK_DIR, count of servers, script dir
# script -d data-dir -s script-dir -w work-dir -n num-servers
while getopts :d:hn:s:w: opt
do
case ${opt} in
d) DATADIR=$(readlink -f ${OPTARG}) ;;
h) usage && exit 0 ;;
n) NUM_SERVERS=${OPTARG} ;;
s) JMX_SCRIPT=$(readlink -f ${OPTARG}) ;;
w) WORK_DIR=$(readlink -f ${OPTARG}) ;;
:) echo "The -${OPTARG} option requires a parameter"
exit 1 ;;
?) echo "Invalid option: -${OPTARG}"
exit 1 ;;
esac
done
shift $((OPTIND -1))
#
# Validate environment
validate_env
#
# Make sure the user is satisfied with the settings
confirm
#
# Set a working directory
# - It will be the specified-work-dir/current-process-id
cd ${WORK_DIR}
if [[ -d $$ ]]
then
echo "Work directory (${WORK_DIR}/$$) already exists. Quitting."
exit 7
fi
mkdir $$
WORK_DIR=${WORK_DIR}/$$
# Start the specified number of jmeter-server containers
echo "Starting servers..."
start_servers
#
# Get the IP addresses for the servers
SERVER_IPS=
server_ips
echo "Server IPs are: ${SERVER_IPS}"
# SERVER_IPS will now be string of the form 1.2.3.4,9.8.7.6
#
# Start the jmeter (client) container and connect to the servers
echo "Starting client..."
LOGDIR=${WORK_DIR}/client
mkdir -p ${LOGDIR}
docker run --cidfile ${LOGDIR}/cid \
-d \
-v ${LOGDIR}:/logs \
-v ${DATADIR}:/input_data \
-v $(dirname ${JMX_SCRIPT}):/scripts \
--name jmeter-client \
${CLIENT_IMAGE} -n -t /scripts/$(basename ${JMX_SCRIPT}) -l /logs/${JTL_FILE} -LDEBUG -R${SERVER_IPS} 2>/dev/null 1>&2
err=$?
if [[ ${err} -ne 0 ]] ; then
echo "Error '${err}' while starting the Jmeter client. Shutting down servers & quitting."
exit ${err}
else
wait_for_client
fi
# Shutdown the servers
stop_servers
# Clean up
remove_containers
if [[ ${err} -ne 0 ]] ; then
echo "Please see ${LOGDIR}/${JTL_FILE} for the results of the run"
fi