2
0
mirror of https://github.com/xcat2/xcat-core.git synced 2025-05-30 09:36:41 +00:00
xcat-core/xCAT-test/bin/xcatperftest
2017-05-26 17:51:28 +08:00

382 lines
11 KiB
Bash
Executable File

#!/bin/bash
# IBM(c) 2017 EPL license http://www.eclipse.org/legal/epl-v10.html
#(C)IBM Corp
#
###################################################################
#
# Description:
# This script is used for performance testing purpose. It could
# generate n*250 fake nodes based on a predefined template (/opt/xcat/share/xcat/templates/objects/node/),
# and then run the performance testing on a batch of xCAT commands.
#
# Note: It is availabe for the commands which require management node only.
#
# Syntax:
# $prog <total> [command-list-file]
#
###################################################################
if [ -z $LC_ALL ]; then
export LC_ALL=C
fi
# Used for number parameter validation
isNumber()
{
expr $1 + 0 &>/dev/null
}
# Used for prerequiste checking
preChecking()
{
local val=""
for cmd in brctl ifconfig; do
which $cmd > /dev/null 2>&1
[ $? -ne 0 ] && val="$cmd,$val"
done
echo $val | sed s/,$//
}
# Give a simple usage
if [ -z "$1" ] || [ "$1" = "-h" ] || [ "$1" = "--help" ]; then
echo "[PERF_DRYRUN=y] [PERF_NOCREATE=y] $0 <total> [command-list-file]"
exit
else
isNumber $1
if [ ! $? -eq 0 ]; then
echo "You must input an numeric string for total nodes number."
exit -1
fi
fi
# Source xCAT profile to make sure the xCAT commands could be executed without absolute path.
if [ -z $XCATROOT ]; then
if [ -r /etc/profile.d/xcat.sh ]; then
. /etc/profile.d/xcat.sh
fi
fi
pass=$(preChecking)
if [ ! -z "$pass" ]; then
echo "Error: Missing required tools: $pass"
[ -z $PERF_DRYRUN ] && exit -1
fi
# Mandatory, to specify the number of total fake nodes which will be created for testing
FAKE_NODE_TOTAL=$1
# Optional, the prefix of the fake compute node name.
# By default, it is 'fake' but it could be changed when you set environment variable `FAKE_NODE_PREFIX`
if [ -z $FAKE_NODE_PREFIX ]; then
FAKE_NODE_PREFIX='fake'
fi
# Optional, the group name of all the fake compute nodes.
# By default, it is 'perftest' but it could be changed when you set environment variable `FAKE_NODE_GROUP`
if [ -z $FAKE_NODE_GROUP ]; then
FAKE_NODE_GROUP='perftest'
fi
# Mandatory, the Provision network for all the fake compute nodes. It must be a string like 'A.B', and be matched with `tabdump networks`
# By default, it is '192.168' but it could be changed when you set environment variable `FAKE_NETWORK_PRO`
if [ -z $FAKE_NETWORK_PRO ]; then
FAKE_NETWORK_PRO='192.168'
fi
# Mandatory, the BMC network for all the fake compute nodes. It must be a string like 'A.B' and no need to be defined in 'networks' table.
# By default, it is '192.169' but it could be changed when you set environment variable `FAKE_NETWORK_BMC`
# Note: it could not be the same subnet as 'FAKE_NETWORK_PRO'
if [ -z $FAKE_NETWORK_BMC ]; then
FAKE_NETWORK_BMC='192.169'
fi
# Optional, The network mask for the fake network object.
# By default, it is '255.255.0.0' but it could be changed when you set environment variable `FAKE_NETWORK_MASK`
if [ -z $FAKE_NETWORK_MASK ]; then
FAKE_NETWORK_MASK='255.255.0.0'
fi
# Optional, The bridge device name for the temporary interface which is required on MN as nodeset/makedhcp will check if the MN and CN in same subnet.
# By default, it is 'perfvirbr0' but it could be changed when you set environment variable `FAKE_NETWORK_INTF`
if [ -z $FAKE_NETWORK_INTF ]; then
FAKE_NETWORK_INTF='perfvirbr0'
fi
# Optional, The node template name used for generating fake nodes.
# By default, it is '<arch>-template' but it could be changed when you set environment variable `FAKE_NODE_GROUP`
if [ -z $PERF_NODETEMPL ]; then
PERF_NODETEMPL="`arch`-template"
fi
# IP address assinged to node will be in [1-250]
NODE_PER_ROW=250
MYSUFFIX=`date +"%Y%m%d%H%M%S"`
if [ -z $PERFORMANCE_DIR ]; then
PERFORMANCE_DIR=$XCATROOT/share/xcat/tools/autotest/result
fi
PERFORMANCE_NODE_TMPL=$PERFORMANCE_DIR/perf-node.tmpl
PERFORMANCE_REPORT=$PERFORMANCE_DIR/perfreport-$FAKE_NODE_TOTAL.log.$MYSUFFIX
PERFORMANCE_STANZ=$PERFORMANCE_DIR/perfstanz-$FAKE_NODE_TOTAL.$MYSUFFIX
# If the command list file is not specified, the tool will only create the stanz file for fake nodes.
# If it is specified but not exists, the tool will exit with error.
if [ ! -z $2 ]; then
if [ -f $2 ]; then
RUN_CMD_LIST=$2
else
echo "ERROR: The command list file you specified does not exist."
exit -1
fi
fi
# Get a random MAC address
genMAC()
{
printf '00:60:2F:%02X:%02X:%02X' $[RANDOM%256] $[RANDOM%256] $[RANDOM%256]
}
# Generate stanz file for all fake nodes
genStanz()
{
if [ ! -z $PERF_DRYRUN ]; then
echo $1, $2, $3, $4
else
echo -n .
fi
sed -e '/Object name:/c \'"$1"':\n objtype=node' \
-e '/ip=/c \ ip='"$3"'' \
-e '/mac=/c \ mac='"$2"'' \
-e '/bmc=/c \ bmc='"$4"'' \
-e '/bmcusername=/c \ bmcusername=fake' \
-e '/bmcpassword=/c \ bmcpassword=fake' \
-e '/groups=/c \ groups=all,'"$FAKE_NODE_GROUP"'' \
-e '/postscripts=/c \ postscripts=mypostboot' \
-e '/postbootscripts=/c \ postbootscripts=mypostboot' \
$PERFORMANCE_NODE_TMPL >> $PERFORMANCE_STANZ
}
# Create a fake xCAT node definition
fakeNode()
{
# TODO: support regular expression for IP
genStanz $FAKE_NODE_PREFIX$1 $(genMAC) $FAKE_NETWORK_PRO.$2.$3 $FAKE_NETWORK_BMC.$2.$3
#mkdef -f -t node $FAKE_NODE_PREFIX$1 --template $PERF_NODETEMPL ip=$FAKE_NETWORK_PRO.$2.$3 mac=$(genMAC) \
# bmc=$FAKE_NETWORK_BMC.$2.$3 bmcpassword=fake bmcusername=fake groups=all,performance > /dev/null 2>&1
}
# Create a fake xCAT network definition
fakeNetwork()
{
lsdef -t network -o net-$FAKE_NODE_PREFIX > /dev/null 2>&1
if [ 0 != $? ]; then
mkdef -t network net-$FAKE_NODE_PREFIX net=$FAKE_NETWORK_PRO.0.0 mask=$FAKE_NETWORK_MASK > /dev/null
else
chdef -t network -o net-$FAKE_NODE_PREFIX net=$FAKE_NETWORK_PRO.0.0 mask=$FAKE_NETWORK_MASK > /dev/null
fi
}
# Create a fake xCAT network definition
fakeInterface()
{
result=`ifconfig $1 2>/dev/null`
if [ -z "$2" ]; then
[ -z "$result" ] && brctl addbr $1
ifconfig $1 $FAKE_NETWORK_PRO.251.254 netmask $FAKE_NETWORK_MASK || echo "$1 is not configured successfully"
elif [ ! -z "$result" ]; then
ifconfig $1 down
brctl delbr $1 || echo "$1 is not removed successfully, you may need to clean up manually."
fi
}
getOSimage()
{
# The OS image name used in nodeset to replace the MACRO Variable `#OSIMAGE#`.
# By default, it could be detectd automatically according to the arch
if [ -z $PERF_OSIMAGE ]; then
# covert it to an array
osimage_array=($(lsdef -t osimage 2>/dev/null| grep `arch`|grep 'install'|awk '/compute/ {print $1}'))
index=`expr $RANDOM % ${#osimage_array[@]} 2>/dev/null`
echo ${osimage_array[$index]}
else
echo $PERF_OSIMAGE
fi
}
# Create batch fake nodes stanz file for testing
bootstrap()
{
declare -i count=0
[ $rack = 0 ] && rack=1
for i in $(seq 0 $(expr $rack - 1))
do
for j in $(seq 1 $NODE_PER_ROW)
do
count+=1
fakeNode $count $i $j
[ $(($count % $1)) = 0 ] && echo
[ "x$count" == "x$FAKE_NODE_TOTAL" ] && break
done
done
}
# Get current time
getTime()
{
date +%s -d "$1"
}
# Executing the testing on specific commands defined in command list file
# All MACROs defined in command list file will be replaced with the real value
runTest()
{
cmd=$1
[ -z $osimage ] || cmd="${cmd/\#OSIMAGE\#/$osimage}"
if [[ $cmd =~ '#STANZ#' ]]; then
#mkdef -z
execCmd "${cmd/\#STANZ\#/$PERFORMANCE_STANZ}" "$FAKE_NODE_TOTAL"
elif [[ $cmd =~ '#NODES#' ]]; then
#noderange operation
if [ -z "$2" ]; then
# No SERIES defined, run command on the whole group
execCmd "${cmd/\#NODES\#/$FAKE_NODE_GROUP}" "$FAKE_NODE_TOTAL"
else
# run the command for each number in SERIES
for num in $2
do
isNumber $num || continue
if [[ $num -le $FAKE_NODE_TOTAL ]]; then
#cmd=$1
execCmd "${cmd/\#NODES\#/$FAKE_NODE_PREFIX[1-$num]}" "$num"
fi
done
fi
elif [[ $cmd =~ '#PERFGRP#' ]]; then
execCmd "${cmd/\#PERFGRP\#/$FAKE_NODE_GROUP}" "$FAKE_NODE_TOTAL"
else
execCmd "$cmd" "N/A"
fi
}
# Output performance result for each command.
printResult()
{
#TODO, more clear short desc for this command
desc=`echo "$1" | awk '{print $1}'`
result=$([[ $4 = 0 ]] && echo "SUCESS" || echo "FAIL")
# TOTAL, CMD, NODERANGE, TIME, SUCESS, FULL COMMAND
echo "$FAKE_NODE_TOTAL; $desc; $2; $3; $result; \"$1\"" | tee -a $PERFORMANCE_REPORT
}
# Executing each command and print the result to report file
execCmd()
{
echo "Testing for [ $1 ] ..."
if [ ! -z $PERF_DRYRUN ]; then
return
fi
starttime=`date +'%Y-%m-%d %H:%M:%S'`
start=$(getTime "$starttime")
eval "$1" > /dev/null 2>&1
retval=$?
endtime=`date +'%Y-%m-%d %H:%M:%S'`
end=$(getTime "$endtime")
printResult "$1" "$2" "$(($end-$start))" "$retval"
}
#################################################
# Main Loop of the performance baseline testing #
#################################################
version=`lsxcatd -a 2>/dev/null | grep Version`
if [ 0 != $? ]; then
echo "ERROR: xCAT daemon is not running. Start 'xcatd' and rerun this tool."
exit 99
fi
mkdir -p $PERFORMANCE_DIR
lsdef -t node --template $PERF_NODETEMPL > $PERFORMANCE_NODE_TMPL 2>/dev/null
if [ 0 != $? ]; then
echo "ERROR: Cannot find the default template for `arch`, make sure it exists and rerun this tool."
exit 99
fi
#Get available OS image, it will be used for nodeset if possible
osimage=$(getOSimage)
rack=$(expr $FAKE_NODE_TOTAL / $NODE_PER_ROW)
echo "=================================================="
# Starting to add fake nodes
starttime=`date +'%Y-%m-%d %H:%M:%S'`
start=$(getTime "$starttime")
bootstrap 50
endtime=`date +'%Y-%m-%d %H:%M:%S'`
end=$(getTime "$endtime")
echo
echo "=================================================="
#echo "It takes $(($end-$start)) seconds to create $FAKE_NODE_TOTAL nodes"
#echo "$FAKE_NODE_TOTAL", "$(($end-$start))", "mkdef" >> $PERFORMANCE_REPORT
if [ -z $RUN_CMD_LIST ]; then
echo "Done. Check the stanz file in $PERFORMANCE_STANZ"
exit 0
fi
echo "Continue the performance testing for commands in $RUN_CMD_LIST "
if [ -z "$osimage" ]; then
echo "WARN: Cannot determine the OS image, the commands which defined with #OSIMAGE# will be failed."
fi
echo $version | tee $PERFORMANCE_REPORT
echo "=================================================="
# Initial Populate the fake nodes into DB
if [ -z $PERF_NOCREATE ]; then
#create fake network for makedns, makedhcp etc...
fakeNetwork
execCmd "mkdef -z -f < $PERFORMANCE_STANZ" "$FAKE_NODE_TOTAL"
fi
# fake interface is required for topology with service nodes as it will determine if then Mn/Sn are
# in the same subnet with CNs
fakeInterface $FAKE_NETWORK_INTF
series=`grep '^#SERIES#' $RUN_CMD_LIST | awk '{print $2}'`
if [ ! -z $series ]; then
series=${series//,/ }
fi
#echo $series
cmdlist=`cat $RUN_CMD_LIST`
IFS_BAK=$IFS
IFS=$'\n'
for line in $cmdlist
do
[ "x${line:0:1}" = "x#" ] && continue
# begin to run the command
IFS=$IFS_BAK
runTest "$line" "$series"
IFS=$'\n'
done
IFS=$IFS_BAK
IFS_BAK=
rm -f $PERFORMANCE_NODE_TMPL
rm -f $PERFORMANCE_STANZ
fakeInterface $FAKE_NETWORK_INTF del
if [ -z $PERF_DRYRUN ]; then
echo
echo "Done. Check the performance result in $PERFORMANCE_REPORT"
fi