diff options
-rwxr-xr-x | ci/build-vsperf.sh | 22 | ||||
-rwxr-xr-x | ci/plot-results.sh | 146 | ||||
-rw-r--r-- | testcases/testcase.py | 11 | ||||
-rw-r--r-- | tools/systeminfo.py | 9 |
4 files changed, 179 insertions, 9 deletions
diff --git a/ci/build-vsperf.sh b/ci/build-vsperf.sh index 5a3ed8c1..5cc4385e 100755 --- a/ci/build-vsperf.sh +++ b/ci/build-vsperf.sh @@ -1,6 +1,6 @@ #!/bin/bash # -# Copyright 2015-2016 Intel Corporation. +# Copyright 2015-2017 Intel Corporation. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -40,6 +40,7 @@ LOG_FILE_PREFIX="/tmp/vsperf_build" DATE=$(date -u +"%Y-%m-%d_%H-%M-%S") BRANCH=${GIT_BRANCH##*/} VSPERFENV_DIR="$HOME/vsperfenv" +RESULTS_ARCHIVE="$HOME/ci_results_archive" # CI job specific configuration # VERIFY - run basic set of TCs with default settings @@ -282,8 +283,8 @@ function generate_report() { # prepare final tarball with all logs... tar --exclude "${TEST_REPORT_TARBALL}" -czf "${TEST_REPORT_LOG_DIR}/${TEST_REPORT_TARBALL}" $(find "${TEST_REPORT_LOG_DIR}" -mindepth 1 -maxdepth 1 -type d) - # ...and remove original log files - find "${TEST_REPORT_LOG_DIR}" -mindepth 1 -maxdepth 1 -type d -exec rm -rf \{\} \; + # ...and move original log files to the archive directory + find "${TEST_REPORT_LOG_DIR}" -mindepth 1 -maxdepth 1 -type d -exec mv \{\} ${RESULTS_ARCHIVE} \; # clone opnfvdocs repository echo "Cloning opnfvdocs repository..." @@ -304,6 +305,19 @@ function generate_report() { fi } +# generates graphs from recent test results +function generate_and_push_graphs() { + # create graphs from results in archive directory + ./ci/plot-results.sh "phy2phy_tput back2back pvp_tput pvvp_tput" ",OvsDpdkVhost," $RESULTS_ARCHIVE + + # push graphs into artifactory + if ls *png &> /dev/null ; then + gsutil cp *png gs://artifacts.opnfv.org/logs/vswitchperf/intel-pod12/graphs/ + else + echo "Graphs were not created." + fi +} + # pushes test report and logs collected during test execution into artifactory function push_results_to_artifactory() { # clone releng repository @@ -507,6 +521,8 @@ case $1 in push_results_to_artifactory + generate_and_push_graphs + cleanup exit $EXIT diff --git a/ci/plot-results.sh b/ci/plot-results.sh new file mode 100755 index 00000000..78855537 --- /dev/null +++ b/ci/plot-results.sh @@ -0,0 +1,146 @@ +#!/bin/bash +# +# Copyright 2017 Intel Corporation. +# +# 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. + +# Script for graphical representation of VSPERF results +# +# Usage: +# ./create_graph ["test names" [filter [directory]]] +# +# where: +# "test names" is a !!! quoted !!! string with vsperf testcase names separated +# by spaces +# Default value: "phy2phy_tput" +# +# "filter" is used to select matching VSPERF results; Its value +# will be used as PATTERN of grep command executed on selected +# csv result files. +# Default value: ",OvsDpdkVhost," +# +# "directory" is a directory name, where vsperf results (i.e. results_* +# subdirectories) are located +# Default value: "/tmp" +# +# Example of invocation: +# ./create_graph "phy2phy_tput phy2phy_cont pvp_cont pvvp_cont" ",OvsVanilla," + +TESTS="phy2phy_tput" # default set of TCs to be plotted +FILTER=",OvsDpdkVhost," # default filter to be applied on matching CSV files +NUMBER_OF_RESULTS=5 # max number of recent results to be compared in graph +CSV_RESULT_COL=2 # column number with result to be plotted, e.g. 2 for rx_throughput_fps +B2B_CSV_RESULT_COL=1 # column number with result to be plotted for back2back TCs +CSV_PKT_SIZE_COL=12 # column number with frame/packet size +B2B_CSV_PKT_SIZE_COL=4 # column number with frame/packet size for back2back TCs +NUMBER_OF_PKT_SIZES=0 # to be detected automatically +MAX_NUMBER_OF_PKT_SIZES=10 +DIR="/tmp" # directory where vsperf results are stored +PNG_PREFIX='vsperf_' + +function clean_data() { + rm -rf *csv + rm -rf *plot + rm -rf *png +} + +function prepare_data() { + for test_name in $TESTS; do + FIRST=1 + CSV_LIST=`grep -r ",${test_name}," ${DIR}/results_*/*csv | grep $FILTER | cut -d':' -f1 | uniq | sort | tail -n ${NUMBER_OF_RESULTS}` + for result_file in $CSV_LIST ; do + tmp_dir=`dirname $result_file` + TIMESTAMP=`basename $tmp_dir | cut -d'_' -f2-` + if [ $FIRST -eq 1 ] ; then + NUMBER_OF_PKT_SIZES=$((`wc -l ${result_file} | cut -d' ' -f1`-1)) + if [ $NUMBER_OF_PKT_SIZES -gt $MAX_NUMBER_OF_PKT_SIZES ] ; then + NUMBER_OF_PKT_SIZES=$MAX_NUMBER_OF_PKT_SIZES + fi + if grep back2back ${result_file} &> /dev/null ; then + PKT_SIZE_COL=$B2B_CSV_PKT_SIZE_COL + RES_COL=$B2B_CSV_RESULT_COL + else + PKT_SIZE_COL=$CSV_PKT_SIZE_COL + RES_COL=$CSV_RESULT_COL + fi + RESULT_HEADER=`tail -n+2 ${result_file} | head -n ${NUMBER_OF_PKT_SIZES} | cut -d',' -f${PKT_SIZE_COL} | paste -d',' -s` + echo "Date/PKT Size [B],${RESULT_HEADER}" > "${test_name}.csv" + FIRST=0 + fi + RESULT_4ALL_PKT_SIZES=`tail -n+2 ${result_file} | head -n ${NUMBER_OF_PKT_SIZES} | cut -d',' -f${RES_COL} | paste -d',' -s` + echo "${TIMESTAMP},${RESULT_4ALL_PKT_SIZES}" >> "${test_name}.csv" + done + done +} + +function plot_data() { + echo "Created graphs:" + SUFFIX=`echo $FILTER | tr -d -C [:alnum:]` + for TEST_CSV in *csv; do + [ ! -f $TEST_CSV ] && continue + TEST_NAME=`basename ${TEST_CSV} .csv`"_${SUFFIX}" + OUTPUT="$TEST_NAME.plot" + cat > $OUTPUT <<- EOM +set datafile separator "," +set xdata time +set timefmt "%Y-%m-%d_%H:%M:%S" +set format x "%m-%d" +set xlabel "date" +set format y "%8.0f" +set ylabel "fps" +set yrange [0:] +set term png size 1024,768 +EOM + iter=0 + echo "set title \"$TEST_NAME\"" >> $OUTPUT + echo "set output \"${PNG_PREFIX}${TEST_NAME}.png\"" >> $OUTPUT + echo -n "plot " >> $OUTPUT + SEP="" + while [ $iter -lt $NUMBER_OF_PKT_SIZES ] ; do + COL=$((2+$iter)) + echo $"$SEP '$TEST_CSV' using 1:$COL with linespoints title columnheader($COL) \\" >> $OUTPUT + iter=$(($iter+1)) + SEP="," + done + echo -e "\t${PNG_PREFIX}${TEST_NAME}.png" + gnuplot $OUTPUT + done +} + +# +# Main body +# + +# override default set of TESTS if specified by 1st parameter +if [ "$1" != "" ] ; then + TESTS="$1" +fi + +# override default filter if specified by 2nd parameter +if [ "$2" != "" ] ; then + FILTER="$2" +fi + +# override default directory with results by 3rd parameter +if [ "$3" != "" ] ; then + DIR="$3" +fi +clean_data + +echo -e "Plot data input:" +echo -e "\tTESTS: $TESTS" +echo -e "\tFilter: $FILTER" +echo -e "\tResults direcotry: $DIR" + +prepare_data +plot_data diff --git a/testcases/testcase.py b/testcases/testcase.py index 1537186f..17bce38e 100644 --- a/testcases/testcase.py +++ b/testcases/testcase.py @@ -45,14 +45,18 @@ class TestCase(object): In this basic form runs RFC2544 throughput test """ # pylint: disable=too-many-statements - def __init__(self, cfg): + def __init__(self, test_cfg): """Pull out fields from test config - :param cfg: A dictionary of string-value pairs describing the test + :param test_cfg: A dictionary of string-value pairs describing the test configuration. Both the key and values strings use well-known values. :param results_dir: Where the csv formatted results are written. """ + # make a local copy of test configuration to avoid modification of + # original content used in vsperf main script + cfg = copy.deepcopy(test_cfg) + self._testcase_start_time = time.time() self._hugepages_mounted = False self._traffic_ctl = None @@ -359,7 +363,8 @@ class TestCase(object): self.run_report() # restore original settings - S.load_from_dict(self._settings_original) + for key in self._settings_original: + S.setValue(key, self._settings_original[key]) def _update_settings(self, param, value): """ Check value of given configuration parameter diff --git a/tools/systeminfo.py b/tools/systeminfo.py index 575dd87e..20ba7ba7 100644 --- a/tools/systeminfo.py +++ b/tools/systeminfo.py @@ -227,8 +227,6 @@ def get_version(app_name): 'testpmd' : r'RTE Version: \'\S+ ([0-9.]+)', 'qemu' : r'QEMU emulator version ([0-9.]+)', 'loopback_l2fwd' : os.path.join(S.getValue('ROOT_DIR'), 'src/l2fwd/l2fwd.c'), - 'loopback_testpmd' : os.path.join(S.getValue('TOOLS')['dpdk_src'], - 'lib/librte_eal/common/include/rte_version.h'), 'ixnet' : os.path.join(S.getValue('TRAFFICGEN_IXNET_LIB_PATH'), 'pkgIndex.tcl'), 'ixia' : os.path.join(S.getValue('TRAFFICGEN_IXIA_ROOT_DIR'), 'lib/ixTcl1.0/ixTclHal.tcl'), } @@ -255,7 +253,12 @@ def get_version(app_name): # stored at TOOS['dpdk_src'] directory tmp_ver = ['', '', ''] dpdk_16 = False - with open(app_version_file['loopback_testpmd']) as file_: + # TOOLS dictionary is created during runtime and it is not + # available in some vsperf modes (e.g. -m trafficgen), thus + # following definition can't be part of app_version_file dict above + app_file = os.path.join(S.getValue('TOOLS')['dpdk_src'], + 'lib/librte_eal/common/include/rte_version.h') + with open(app_file) as file_: for line in file_: if not line.strip(): continue |