summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xci/build-vsperf.sh22
-rwxr-xr-xci/plot-results.sh146
-rw-r--r--testcases/testcase.py11
-rw-r--r--tools/systeminfo.py9
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