2 # Main WCBench script. WCBench wraps CBench in stuff to make it useful.
3 # This script supports installing ODL, installing CBench, starting and
4 # configuring ODL, running CBench against ODL, pinning ODL to a given
5 # number of CPUs, using given-length CBench runs, collecting CBench
6 # results and system stats, storing results in CSV format, stopping
7 # ODL and removing all source/binaries installed by this script.
8 # The main repo for WCBench is: https://github.com/dfarrell07/wcbench
9 # See README.md for more details.
17 # Output verbose debug info (true) or not (anything else)
20 # Params for CBench test and ODL config
21 NUM_SWITCHES=32 # Default number of switches for CBench to simulate
22 NUM_MACS=100000 # Default number of MACs for CBench to use
23 TESTS_PER_SWITCH=10 # Default number of CBench tests to do per CBench run
24 MS_PER_TEST=10000 # Default milliseconds to run each CBench test
25 CBENCH_WARMUP=1 # Default number of warmup cycles to run CBench
26 KARAF_SHELL_PORT=8101 # Port that the Karaf shell listens on
27 CONTROLLER="OpenDaylight" # Currently only support ODL
28 CONTROLLER_IP="localhost" # Change this to remote IP if running on two systems
29 CONTROLLER_PORT=6633 # Default port for OpenDaylight
30 SSH_HOSTNAME="cbenchc" # You'll need to update this to reflect ~/.ssh/config
32 # Paths used in this script
33 BASE_DIR=$HOME # Directory that code and such is dropped into
34 OF_DIR=$BASE_DIR/openflow # Directory that contains OpenFlow code
35 OFLOPS_DIR=$BASE_DIR/oflops # Directory that contains oflops repo
36 ODL_DIR=$BASE_DIR/distribution-karaf-0.2.1-Helium-SR1 # Directory with ODL code
37 ODL_ZIP="distribution-karaf-0.2.1-Helium-SR1.zip" # ODL zip name
38 ODL_ZIP_PATH=$BASE_DIR/$ODL_ZIP # Full path to ODL zip
39 PLUGIN_DIR=$ODL_DIR/plugins # ODL plugin directory
40 RESULTS_FILE=$BASE_DIR/"results.csv" # File that results are stored in
41 CBENCH_LOG=$BASE_DIR/"cbench.log" # Log file used to store strange error msgs
42 CBENCH_BIN="/usr/local/bin/cbench" # Path to CBench binary
43 OFLOPS_BIN="/usr/local/bin/oflops" # Path to oflops binary
44 FEATURES_FILE=$ODL_DIR/etc/org.apache.karaf.features.cfg # Karaf features to install
46 # Array that stores results in indexes defined by cols array
49 # The order of these array values determines column order in RESULTS_FILE
50 cols=(run_num cbench_min cbench_max cbench_avg start_time end_time
51 controller_ip human_time num_switches num_macs tests_per_switch
52 ms_per_test start_steal_time end_steal_time total_ram used_ram
53 free_ram cpus one_min_load five_min_load fifteen_min_load controller
54 start_iowait end_iowait)
56 # This two-stat-array system is needed until I find an answer to this question:
57 # http://goo.gl/e0M8Tp
59 # Associative array with stats-collecting commands for local system
60 declare -A local_stats_cmds
61 local_stats_cmds=([total_ram]="$(free -m | awk '/^Mem:/{print $2}')"
62 [used_ram]="$(free -m | awk '/^Mem:/{print $3}')"
63 [free_ram]="$(free -m | awk '/^Mem:/{print $4}')"
65 [one_min_load]="`uptime | awk -F'[a-z]:' '{print $2}' | awk -F "," '{print $1}' | tr -d " "`"
66 [five_min_load]="`uptime | awk -F'[a-z]:' '{print $2}' | awk -F "," '{print $2}' | tr -d " "`"
67 [fifteen_min_load]="`uptime | awk -F'[a-z]:' '{print $2}' | awk -F "," '{print $3}' | tr -d " "`"
68 [iowait]="`cat /proc/stat | awk 'NR==1 {print $6}'`"
69 [steal_time]="`cat /proc/stat | awk 'NR==1 {print $9}'`")
71 # Associative array with stats-collecting commands for remote system
72 # See this for explanation of horrible-looking quoting: http://goo.gl/PMI5ag
73 declare -A remote_stats_cmds
74 remote_stats_cmds=([total_ram]='free -m | awk '"'"'/^Mem:/{print $2}'"'"''
75 [used_ram]='free -m | awk '"'"'/^Mem:/{print $3}'"'"''
76 [free_ram]='free -m | awk '"'"'/^Mem:/{print $4}'"'"''
78 [one_min_load]='uptime | awk -F'"'"'[a-z]:'"'"' '"'"'{print $2}'"'"' | awk -F "," '"'"'{print $1}'"'"' | tr -d " "'
79 [five_min_load]='uptime | awk -F'"'"'[a-z]:'"'"' '"'"'{print $2}'"'"' | awk -F "," '"'"'{print $2}'"'"' | tr -d " "'
80 [fifteen_min_load]='uptime | awk -F'"'"'[a-z]:'"'"' '"'"'{print $2}'"'"' | awk -F "," '"'"'{print $3}'"'"' | tr -d " "'
81 [iowait]='cat /proc/stat | awk '"'"'NR==1 {print $6}'"'"''
82 [steal_time]='cat /proc/stat | awk '"'"'NR==1 {print $9}'"'"'')
84 ###############################################################################
85 # Prints usage message
92 ###############################################################################
98 Setup and/or run CBench and/or OpenDaylight.
102 -v Output verbose debug info
104 -t <time> Run CBench for given number of minutes
105 -r Run CBench against OpenDaylight
106 -i Install OpenDaylight Helium 0.2.1
107 -p <processors> Pin ODL to given number of processors
108 -o Start and configure OpenDaylight Helium 0.2.1
110 -d Delete local ODL and CBench code
114 ###############################################################################
115 # Checks if CBench is installed
122 # EX_OK if CBench is installed
123 # EX_NOT_FOUND if CBench isn't installed
124 ###############################################################################
127 # Checks if CBench is installed
128 if command -v cbench &>/dev/null; then
129 echo "CBench is installed"
132 echo "CBench is not installed"
137 ###############################################################################
138 # Installs CBench, including its dependencies
139 # This function is idempotent
140 # This has been tested on fresh cloud versions of Fedora 20 and CentOS 6.5
141 # Not currently building oflops/netfpga-packet-generator-c-library (optional)
151 # EX_OK if CBench is already installed or successfully installed
152 # EX_ERR if CBench fails to install
153 ###############################################################################
156 if cbench_installed; then
160 # Install required packages
161 echo "Installing CBench dependencies"
162 if "$VERBOSE" = true; then
163 sudo yum install -y net-snmp-devel libpcap-devel autoconf make automake libtool libconfig-devel git
165 sudo yum install -y net-snmp-devel libpcap-devel autoconf make automake libtool libconfig-devel git &> /dev/null
168 # Clone repo that contains CBench
169 echo "Cloning CBench repo into $OFLOPS_DIR"
170 if "$VERBOSE" = true; then
171 git clone https://github.com/andi-bigswitch/oflops.git $OFLOPS_DIR
173 git clone https://github.com/andi-bigswitch/oflops.git $OFLOPS_DIR &> /dev/null
176 # CBench requires the OpenFlow source code, clone it
177 echo "Cloning openflow source code into $OF_DIR"
178 if "$VERBOSE" = true; then
179 git clone git://gitosis.stanford.edu/openflow.git $OF_DIR
181 git clone git://gitosis.stanford.edu/openflow.git $OF_DIR &> /dev/null
184 # Build the oflops/configure file
187 echo "Building oflops/configure file"
188 if "$VERBOSE" = true; then
191 ./boot.sh &> /dev/null
195 echo "Building CBench"
196 if "$VERBOSE" = true; then
197 ./configure --with-openflow-src-dir=$OF_DIR
201 ./configure --with-openflow-src-dir=$OF_DIR &> /dev/null
203 sudo make install &> /dev/null
207 # Validate that the install worked
208 if ! cbench_installed; then
209 echo "Failed to install CBench" >&2
212 echo "Successfully installed CBench"
217 ###############################################################################
218 # Get the number of the next run, as found in results file
219 # Assumes that the results file hasn't had rows removed by a human
225 # The run number of the next run
226 ###############################################################################
229 # Check if there's actually a results file
230 if [ ! -s $RESULTS_FILE ]; then
235 # There should be one header row, then rows starting with 0, counting up
236 num_lines=`wc -l $RESULTS_FILE | awk '{print $1}'`
237 echo $(expr $num_lines - 1)
240 ###############################################################################
241 # Given the name of a results column, get its index in cols (therefore results)
245 # The name of the column to find the index of
247 # The index of the given column name in cols
248 ###############################################################################
252 for (( i = 0; i < ${#cols[@]}; i++ )); do
253 if [ "${cols[$i]}" = $name ]; then
260 ###############################################################################
261 # Accepts an array and writes it in CSV format to the results file
265 # Array to write to results file
268 ###############################################################################
271 # Creates var for array argument
272 declare -a array_to_write=("${!1}")
274 # Write all but the last column of the array to results file
275 while [ $i -lt $(expr ${#array_to_write[@]} - 1) ]; do
276 # Only use echo with comma and no newline for all but last col
277 echo -n "${array_to_write[$i]}," >> $RESULTS_FILE
280 # Finish CSV row with no comma and a newline
281 echo "${array_to_write[$i]}" >> $RESULTS_FILE
284 ###############################################################################
285 # Collects local or remote system stats that should be collected pre-CBench
286 # Pre and post-test collection is needed for computing the change in stats
291 # local_stats_commands
292 # remote_stats_commands
297 ###############################################################################
300 echo "Collecting pre-test stats"
301 results[$(name_to_index "start_time")]=`date +%s`
302 if [ $CONTROLLER_IP = "localhost" ]; then
303 results[$(name_to_index "start_iowait")]=${local_stats_cmds[iowait]}
304 results[$(name_to_index "start_steal_time")]=${local_stats_cmds[steal_time]}
306 results[$(name_to_index "start_iowait")]=$(ssh $SSH_HOSTNAME "${remote_stats_cmds[iowait]}" 2> /dev/null)
307 results[$(name_to_index "start_steal_time")]=$(ssh $SSH_HOSTNAME "${remote_stats_cmds[steal_time]}" 2> /dev/null)
311 ###############################################################################
312 # Collects local or remote system stats that should be collected post-CBench
313 # Pre and post-test collection is needed for computing the change in stats
318 # local_stats_commands
319 # remote_stats_commands
324 ###############################################################################
325 get_post_test_stats()
327 # Start by collecting always-local stats that are time-sensitive
328 echo "Collecting post-test stats"
329 results[$(name_to_index "end_time")]=`date +%s`
330 results[$(name_to_index "human_time")]=`date`
332 # Now collect local/remote stats that are time-sensative
333 if [ $CONTROLLER_IP = "localhost" ]; then
334 results[$(name_to_index "end_iowait")]=${local_stats_cmds[iowait]}
335 results[$(name_to_index "end_steal_time")]=${local_stats_cmds[steal_time]}
336 results[$(name_to_index "one_min_load")]=${local_stats_cmds[one_min_load]}
337 results[$(name_to_index "five_min_load")]=${local_stats_cmds[five_min_load]}
338 results[$(name_to_index "fifteen_min_load")]=${local_stats_cmds[fifteen_min_load]}
340 results[$(name_to_index "end_iowait")]=$(ssh $SSH_HOSTNAME "${remote_stats_cmds[iowait]}" 2> /dev/null)
341 results[$(name_to_index "end_steal_time")]=$(ssh $SSH_HOSTNAME "${remote_stats_cmds[steal_time]}" 2> /dev/null)
342 results[$(name_to_index "one_min_load")]=$(ssh $SSH_HOSTNAME "${remote_stats_cmds[one_min_load]}" 2> /dev/null)
343 results[$(name_to_index "five_min_load")]=$(ssh $SSH_HOSTNAME "${remote_stats_cmds[five_min_load]}" 2> /dev/null)
344 results[$(name_to_index "fifteen_min_load")]=$(ssh $SSH_HOSTNAME "${remote_stats_cmds[fifteen_min_load]}" 2> /dev/null)
348 ###############################################################################
349 # Collects local or remote system stats for which collection time is irrelevant
359 # local_stats_commands
360 # remote_stats_commands
365 ###############################################################################
366 get_time_irrelevant_stats()
368 # Collect always-local stats that aren't time-sensitive
369 echo "Collecting time-irrelevant stats"
370 results[$(name_to_index "run_num")]=$(next_run_num)
371 results[$(name_to_index "controller_ip")]=$CONTROLLER_IP
372 results[$(name_to_index "num_switches")]=$NUM_SWITCHES
373 results[$(name_to_index "num_macs")]=$NUM_MACS
374 results[$(name_to_index "tests_per_switch")]=$TESTS_PER_SWITCH
375 results[$(name_to_index "ms_per_test")]=$MS_PER_TEST
376 results[$(name_to_index "controller")]=$CONTROLLER
378 # Store local or remote stats that aren't time-sensitive
379 if [ $CONTROLLER_IP = "localhost" ]; then
380 results[$(name_to_index "total_ram")]=${local_stats_cmds[total_ram]}
381 results[$(name_to_index "used_ram")]=${local_stats_cmds[used_ram]}
382 results[$(name_to_index "free_ram")]=${local_stats_cmds[free_ram]}
383 results[$(name_to_index "cpus")]=${local_stats_cmds[cpus]}
385 results[$(name_to_index "total_ram")]=$(ssh $SSH_HOSTNAME "${remote_stats_cmds[total_ram]}" 2> /dev/null)
386 results[$(name_to_index "used_ram")]=$(ssh $SSH_HOSTNAME "${remote_stats_cmds[used_ram]}" 2> /dev/null)
387 results[$(name_to_index "free_ram")]=$(ssh $SSH_HOSTNAME "${remote_stats_cmds[free_ram]}" 2> /dev/null)
388 results[$(name_to_index "cpus")]=$(ssh $SSH_HOSTNAME "${remote_stats_cmds[cpus]}" 2> /dev/null)
392 ###############################################################################
393 # Write data stored in results array to results file
402 ###############################################################################
405 # Write header if this is a fresh results file
406 if [ ! -s $RESULTS_FILE ]; then
407 echo "$RESULTS_FILE not found or empty, building fresh one" >&2
408 write_csv_row cols[@]
410 write_csv_row results[@]
413 ###############################################################################
414 # Runs the CBench against the controller
430 ###############################################################################
434 echo "Running CBench against ODL on $CONTROLLER_IP:$CONTROLLER_PORT"
435 if "$VERBOSE" = true; then
436 cbench_output=`cbench -c $CONTROLLER_IP -p $CONTROLLER_PORT -m $MS_PER_TEST -l $TESTS_PER_SWITCH -s $NUM_SWITCHES -M $NUM_MACS -w $CBENCH_WARMUP`
438 cbench_output=`cbench -c $CONTROLLER_IP -p $CONTROLLER_PORT -m $MS_PER_TEST -l $TESTS_PER_SWITCH -s $NUM_SWITCHES -M $NUM_MACS -w $CBENCH_WARMUP 2>&1`
441 get_time_irrelevant_stats
443 # Parse out min, max and average responses/sec, log/handle errors
444 # See: https://github.com/dfarrell07/wcbench/issues/16
445 cbench_min=`echo "$cbench_output" | grep RESULT | awk '{print $8}' | awk -F'/' '{print $1}'`
446 cbench_max=`echo "$cbench_output" | grep RESULT | awk '{print $8}' | awk -F'/' '{print $2}'`
447 cbench_avg=`echo "$cbench_output" | grep RESULT | awk '{print $8}' | awk -F'/' '{print $3}'`
448 if [ -z "$cbench_avg" ]; then
449 echo "WARNING: Error occurred: Failed to parse CBench average" >&2
450 echo "This is an issue with CBench or ODL, not WCBench." >&2
451 echo "May need to reduce NUM_SWITCHES or allocate more CPU cores" >&2
452 echo "See: $CBENCH_LOG" >&2
453 echo "See: https://github.com/dfarrell07/wcbench/issues/16" >&2
454 echo "Run $(next_run_num) failed to record a CBench average. CBench details:" >> $CBENCH_LOG
455 echo "$cbench_output" >> $CBENCH_LOG
458 echo "Average responses/second: $cbench_avg"
459 results[$(name_to_index "cbench_min")]=$cbench_min
460 results[$(name_to_index "cbench_max")]=$cbench_max
461 results[$(name_to_index "cbench_avg")]=$cbench_avg
464 # Write results to results file
468 ###############################################################################
469 # Deletes OpenDaylight source (zipped and unzipped)
477 ###############################################################################
480 if [ -d $ODL_DIR ]; then
481 echo "Removing $ODL_DIR"
484 if [ -f $ODL_ZIP_PATH ]; then
485 echo "Removing $ODL_ZIP_PATH"
490 ###############################################################################
491 # Checks if the given feature is in list to be installed at boot
497 # Feature to search featuresBoot list for
499 # EX_OK if feature already in featuresBoot list
500 # EX_NOT_FOUND if feature isn't in featuresBoot list
501 ###############################################################################
506 # Check if feature is already set to be installed at boot
507 if $(grep featuresBoot= $FEATURES_FILE | grep -q $feature); then
514 ###############################################################################
515 # Adds features to be installed by Karaf at ODL boot
521 # Feature to append to end of featuresBoot CSV list
523 # EX_OK if feature already is installed or was successfully added
524 # EX_ERR if failed to add feature to group installed at boot
525 ###############################################################################
526 add_to_featuresBoot()
530 # Check if feature is already set to be installed at boot
531 if is_in_featuresBoot $feature; then
532 echo "$feature is already set to be installed at boot"
536 # Append feature to end of boot-install list
537 sed -i "/^featuresBoot=/ s/$/,$feature/" $FEATURES_FILE
539 # Check if feature was added to install list correctly
540 if is_in_featuresBoot $feature; then
541 echo "$feature added to features installed at boot"
544 echo "ERROR: Failed to add $feature to features installed at boot"
549 ###############################################################################
550 # Installs latest build of the OpenDaylight controller
551 # Note that the installed build is via an Integration team Jenkins job
563 # EX_ERR if ODL install fails
564 ###############################################################################
565 install_opendaylight()
567 # Only remove unzipped code, as zip is large and unlikely to have changed.
568 if [ -d $ODL_DIR ]; then
569 echo "Removing $ODL_DIR"
573 # Install required packages
574 echo "Installing OpenDaylight dependencies"
575 if "$VERBOSE" = true; then
576 sudo yum install -y java-1.7.0-openjdk unzip wget
578 sudo yum install -y java-1.7.0-openjdk unzip wget &> /dev/null
581 # If we already have the zip archive, use that.
582 if [ -f $ODL_ZIP_PATH ]; then
583 echo "Using local $ODL_ZIP_PATH. Pass -d flag to remove."
585 # Grab OpenDaylight Helium 0.2.1
586 echo "Downloading OpenDaylight Helium 0.2.1"
587 if "$VERBOSE" = true; then
588 wget -P $BASE_DIR "https://nexus.opendaylight.org/content/groups/public/org/opendaylight/integration/distribution-karaf/0.2.1-Helium-SR1/$ODL_ZIP"
590 wget -P $BASE_DIR "https://nexus.opendaylight.org/content/groups/public/org/opendaylight/integration/distribution-karaf/0.2.1-Helium-SR1/$ODL_ZIP" &> /dev/null
594 # Confirm that download was successful
595 if [ ! -f $ODL_ZIP_PATH ]; then
596 echo "WARNING: Failed to dl ODL. Version bumped? If so, update \$ODL_ZIP" >&2
601 echo "Unzipping OpenDaylight Helium 0.2.1"
602 if "$VERBOSE" = true; then
603 unzip -d $BASE_DIR $ODL_ZIP_PATH
605 unzip -d $BASE_DIR $ODL_ZIP_PATH &> /dev/null
608 # Add required features to list installed by Karaf at ODL boot
609 add_to_featuresBoot "odl-openflowplugin-flow-services"
610 add_to_featuresBoot "odl-openflowplugin-drop-test"
613 ###############################################################################
614 # Checks if OpenDaylight is installed
621 # EX_NOT_FOUND if ODL isn't installed
622 # 0 if ODL is installed
623 ###############################################################################
626 if [ ! -d $ODL_DIR ]; then
631 ###############################################################################
632 # Checks if OpenDaylight is running
633 # Assumes you've checked that ODL is installed
642 # EX_OK if ODL is running
643 # EX_NOT_FOUND if ODL isn't running
644 ###############################################################################
649 if "$VERBOSE" = true; then
652 ./bin/status &> /dev/null
662 ###############################################################################
663 # Starts the OpenDaylight controller
664 # Pins ODL process to given number of CPUs if `$processors` is non-zero
665 # Makes call to issue ODL config once ODL is up and running
674 # EX_OK if ODL is already running
675 ###############################################################################
681 echo "OpenDaylight is already running"
684 echo "Starting OpenDaylight"
685 if [ -z $processors ]; then
686 if "$VERBOSE" = true; then
689 ./bin/start &> /dev/null
692 echo "Pinning ODL to $processors processor(s)"
693 # Use taskset to pin ODL to a given number of processors
694 if "$VERBOSE" = true; then
695 taskset -c 0-$(expr $processors - 1) ./bin/start
697 taskset -c 0-$(expr $processors - 1) ./bin/start &> /dev/null
705 ###############################################################################
706 # Set `dropAllPackets on` and log level to DEBUG via Karaf shell
714 ###############################################################################
717 # This could be done with public key crypto, but sshpass is easier
718 if ! command -v sshpass &> /dev/null; then
719 echo "Installing sshpass. It's used for issuing ODL config."
720 if "$VERBOSE" = true; then
721 sudo yum install -y sshpass
723 sudo yum install -y sshpass &> /dev/null
727 # Set `dropAllPacketsRpc on`
728 echo "Will repeatedly attempt connecting to Karaf shell until it's ready"
729 # Loop until exit status 0 (success) given by Karaf shell
730 # Exit status 255 means Karaf shell isn't open for SSH connections yet
731 # Exit status 1 means `dropAllPacketsRpc on` isn't runnable yet
732 if "$VERBOSE" = true; then
733 until sshpass -p karaf ssh -p $KARAF_SHELL_PORT -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no karaf@localhost dropallpacketsrpc on
735 echo "Karaf shell isn't ready yet, sleeping 5 seconds..."
739 until sshpass -p karaf ssh -p $KARAF_SHELL_PORT -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no karaf@localhost dropallpacketsrpc on &> /dev/null
744 echo "Issued \`dropAllPacketsRpc on\` command via Karaf shell to localhost:$KARAF_SHELL_PORT"
746 # Change log level to ERROR
747 # Loop until exit status 0 (success) given by Karaf shell
748 # Exit status 255 means Karaf shell isn't open for SSH connections yet
749 if "$VERBOSE" = true; then
750 until sshpass -p karaf ssh -p $KARAF_SHELL_PORT -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no karaf@localhost log:set ERROR
752 echo "Karaf shell isn't ready yet, sleeping 5 seconds..."
756 until sshpass -p karaf ssh -p $KARAF_SHELL_PORT -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no karaf@localhost log:set ERROR &> /dev/null
761 echo "Issued \`log:set ERROR\` command via Karaf shell to localhost:$KARAF_SHELL_PORT"
764 ###############################################################################
773 ###############################################################################
779 echo "Told ODL to stop. Waiting on it to do so..."
780 echo "This check is useless if you have other Java processes running (ctrl+c it)."
781 if "$VERBOSE" = true; then
784 ./bin/stop &> /dev/null
786 # Loop until actually stopped
787 until ! pgrep java &> /dev/null
791 echo "OpenDaylight has stopped."
793 echo "OpenDaylight isn't running"
798 ###############################################################################
799 # Uninstall CBench binary and the code that built it
808 ###############################################################################
811 if [ -d $OF_DIR ]; then
812 echo "Removing $OF_DIR"
815 if [ -d $OFLOPS_DIR ]; then
816 echo "Removing $OFLOPS_DIR"
819 if [ -f $CBENCH_BIN ]; then
820 echo "Removing $CBENCH_BIN"
821 sudo rm -f $CBENCH_BIN
823 if [ -f $OFLOPS_BIN ]; then
824 echo "Removing $OFLOPS_BIN"
825 sudo rm -f $OFLOPS_BIN
829 # If executed with no options
830 if [ $# -eq 0 ]; then
835 # Used to output help if no valid action results from arguments
838 # Parse options given from command line
839 while getopts ":hvrcip:ot:kd" opt; do
847 # Output debug info verbosely
851 # Run CBench against OpenDaylight
852 if [ $CONTROLLER_IP = "localhost" ]; then
853 if ! odl_installed; then
854 echo "OpenDaylight isn't installed, can't run test"
857 if ! odl_started; then
858 echo "OpenDaylight isn't started, can't run test"
871 # Install OpenDaylight
876 # Pin a given number of processors
877 # Note that this option must be given before -o (start ODL)
879 echo "OpenDaylight is already running, can't adjust processors"
883 if [ $processors -lt 1 ]; then
884 echo "Can't pin ODL to less than one processor"
890 if ! odl_installed; then
891 echo "OpenDaylight isn't installed, can't start it"
898 # Set CBench run time in minutes
899 if ! odl_installed; then
900 echo "OpenDaylight isn't installed, can't start it"
903 # Convert minutes to milliseconds
904 MS_PER_TEST=$((${OPTARG} * 60 * 1000))
907 echo "Set MS_PER_TEST to $MS_PER_TEST, TESTS_PER_SWITCH to $TESTS_PER_SWITCH, CBENCH_WARMUP to $CBENCH_WARMUP"
911 if ! odl_installed; then
912 echo "OpenDaylight isn't installed, can't stop it"
915 if ! odl_started; then
916 echo "OpenDaylight isn't started, can't stop it"
923 # Delete local ODL and CBench code
929 # Print usage message
935 # Output help message if no valid action was taken
936 if ! "$action_taken" = true; then