passt/test/lib/perf_report
Stefano Brivio 2c1554c994 test/lib/perf_report: Fix up table highlight for pasta's local flows
As commit 2926970523 ("test/perf: Small MTUs for spliced TCP
aren't interesting") drops all columns for TCP test MTUs except for
one, in throughput test for pasta's local flows, the first column we
need to highlight in that table is now the second one.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2023-11-10 06:35:54 +01:00

280 lines
8.8 KiB
Bash
Executable file

#!/bin/sh
#
# SPDX-License-Identifier: GPL-2.0-or-later
#
# PASST - Plug A Simple Socket Transport
# for qemu/UNIX domain socket mode
#
# PASTA - Pack A Subtle Tap Abstraction
# for network namespace/tap device mode
#
# test/lib/perf_report - Prepare JavaScript report for performance tests
#
# Copyright (c) 2021 Red Hat GmbH
# Author: Stefano Brivio <sbrivio@redhat.com>
PERF_INIT=0
PERF_LINK_COUNT=0
PERF_JS="${LOGDIR}/web/perf.js"
PERF_TEMPLATE_HTML="document.write('"'
Throughput in Gbps, latency in µs. Threads are <span style="font-family: monospace;">iperf3</span> processes, <i>passt</i> and <i>pasta</i> are currently single-threaded.<br/>
Click on numbers to show test execution. Measured at head, commit <span style="font-family: monospace;">__commit__</span>.
<style type="text/CSS">
table.passt td { border: 0px solid; padding: 6px; line-height: 1; }
table.passt td { text-align: right; }
table.passt th { text-align: center; font-weight: bold; }
table.passt tr:not(:first-of-type) td:not(:first-of-type) { font-family: monospace; font-weight: bolder; }
table.passt tr:nth-child(3n+0) { background-color: #112315; }
table.passt tr:not(:nth-child(3n+0)) td { background-color: #101010; }
table.passt td:nth-child(6n+7) { background-color: #603302; }
table.passt tr:nth-child(1) { background-color: #363e61; }
td:empty { visibility: hidden; }
</style>
<ul>
<li><p>passt</p>
<table class="passt" width="70%">
<tr>
<th/>
<th id="perf_passt_tcp" colspan="__passt_tcp_cols__">TCP, __passt_tcp_threads__ at __passt_tcp_freq__ GHz</th>
<th id="perf_passt_udp" colspan="__passt_udp_cols__">UDP, __passt_udp_threads__ at __passt_udp_freq__ GHz</th>
</tr>
<tr>
<td align="right">MTU:</td>
__passt_tcp_header__
__passt_udp_header__
</tr>
__passt_tcp_LINE__ __passt_udp_LINE__
</table>
<style type="text/CSS">
table.pasta_local td { border: 0px solid; padding: 6px; line-height: 1; }
table.pasta_local td { text-align: right; }
table.pasta_local th { text-align: center; font-weight: bold; }
table.pasta_local tr:not(:first-of-type) td:not(:first-of-type) { font-family: monospace; font-weight: bolder; }
table.pasta_local tr:nth-child(3n+0) { background-color: #112315; }
table.pasta_local tr:not(:nth-child(3n+0)) td { background-color: #101010; }
table.pasta_local td:nth-child(3n+2) { background-color: #603302; }
table.pasta_local tr:nth-child(1) { background-color: #363e61; }
table.pasta td { border: 0px solid; padding: 6px; line-height: 1; }
table.pasta td { text-align: right; }
table.pasta th { text-align: center; font-weight: bold; }
table.pasta tr:not(:first-of-type) td:not(:first-of-type) { font-family: monospace; font-weight: bolder; }
table.pasta tr:nth-child(3n+0) { background-color: #112315; }
table.pasta tr:not(:nth-child(3n+0)) td { background-color: #101010; }
table.pasta td:nth-child(4n+5) { background-color: #603302; }
table.pasta tr:nth-child(1) { background-color: #363e61; }
td:empty { visibility: hidden; }
</style>
</li><li><p>pasta: local connections/traffic</p>
<table class="pasta_local" width="70%">
<tr>
<th/>
<th id="perf_pasta_lo_tcp" colspan="__pasta_lo_tcp_cols__">TCP, __pasta_lo_tcp_threads__ at __pasta_lo_tcp_freq__ GHz</th>
<th id="perf_pasta_lo_udp" colspan="__pasta_lo_udp_cols__">UDP, __pasta_lo_udp_threads__ at __pasta_lo_udp_freq__ GHz</th>
</th>
<tr>
<td align="right">MTU:</td>
__pasta_lo_tcp_header__
__pasta_lo_udp_header__
</tr>
__pasta_lo_tcp_LINE__ __pasta_lo_udp_LINE__
</table>
</li><li><p>pasta: connections/traffic via tap</p>
<table class="pasta" width="70%">
<tr>
<th/>
<th id="perf_pasta_tap_tcp" colspan="__pasta_tap_tcp_cols__">TCP, __pasta_tap_tcp_threads__ at __pasta_tap_tcp_freq__ GHz</th>
<th id="perf_pasta_tap_udp" colspan="__pasta_tap_udp_cols__">UDP, __pasta_tap_udp_threads__ at __pasta_tap_udp_freq__ GHz</th>
</tr>
<tr>
<td align="right">MTU:</td>
__pasta_tap_tcp_header__
__pasta_tap_udp_header__
</tr>
__pasta_tap_tcp_LINE__ __pasta_tap_udp_LINE__
</table>
</li></ul>'
PERF_TEMPLATE_JS="');
var perf_links = [
"
PERF_TEMPLATE_POST='];
for (var i = 0; i < perf_links.length; i++) {
var obj = document.getElementById(perf_links[i][0]);
obj.addEventListener("click", function(event) {
var ci_video = document.getElementById("ci");
var top = ci_video.offsetTop - 5;
var seek;
for (var i = 0; i < perf_links.length; i++) {
if (this.id == perf_links[i][0]) {
seek = perf_links[i][1];
}
}
event.preventDefault();
ci_player.dispose();
ci_player = AsciinemaPlayer.create("/builds/latest/web/ci.cast",
ci_video,
{ cols: 240, rows: 51, poster: "npt:999:0", startAt: seek, autoplay: true });
window.scrollTo({ top: top, behavior: "smooth" })
}, false);
}
'
# perf_init() - Process first part of template
perf_init() {
mkdir -p "$(dirname "${PERF_JS}")"
echo "${PERF_TEMPLATE_HTML}" > "${PERF_JS}"
perf_report_sub commit "$(echo ${COMMIT} | sed "s/'/\\\'/g")"
PERF_INIT=1
}
# perf_fill_lines() - Fill multiple "LINE" directives in template, matching rows
perf_fill_lines() {
while true; do
__file_line="$(sed -n '/__.*_LINE__/{=;q}' "${PERF_JS}")"
[ -z "${__file_line}" ] && break
__line_no=0
__done=0
__line_buf="<tr>"
while true; do
__match_first_td=0
for __t in $(sed -n '/__.*_LINE__/{p;q}' "${PERF_JS}"); do
if [ ${__match_first_td} -eq 1 ]; then
__matching_line_no=0
while true; do
__line_part=
__var_name="$(echo $__t | sed -n 's/__\(.*\)__/\1_'"${__matching_line_no}"'/p')"
[ -z "$(eval echo \$${__var_name})" ] && break
__line_part="$(eval echo \$${__var_name})"
__td_check="$(echo "${__line_part}" | sed -n 's/^<td>\([^>]*\)<\/td>.*$/\1/p')"
if [ "${__td_check}" = "${__td_match}" ]; then
__line_part="$(echo "${__line_part}" | sed -n 's/^<td>[^>]*<\/td>\(.*\)$/\1/p')"
break
fi
__matching_line_no=$((__matching_line_no + 1))
done
else
__var_name="$(echo $__t | sed -n 's/__\(.*\)__/\1_'"${__line_no}"'/p')"
[ -z "$(eval echo \$${__var_name})" ] && __done=1 && break
__line_part="$(eval echo \$${__var_name})"
__td_match="$(echo "${__line_part}" | sed -n 's/^<td>\([^>]*\)<\/td>.*$/\1/p')"
fi
__line_buf="${__line_buf}${__line_part}"
__match_first_td=1
done
[ ${__done} -eq 1 ] && break
__line_no=$((__line_no + 1))
__line_buf="${__line_buf}</tr><tr>"
done
__line_buf="${__line_buf}</tr>"
__line_buf="$(printf '%s\n' "${__line_buf}" | sed -e 's/[]\/$*.^[]/\\&/g')"
sed -i "${__file_line}s/.*/${__line_buf}/" "${PERF_JS}"
done
}
# perf_finish() - Add trailing backslashes and process ending templates
perf_finish() {
PERF_INIT=0
perf_fill_lines
sed -i 's/^.*$/&\\/g' "${PERF_JS}"
echo "${PERF_TEMPLATE_JS}" >> "${PERF_JS}"
echo "${PERF_TEMPLATE_POST}" >> "${PERF_JS}"
}
# perf_report_sub() - Apply simple substitutions in template
perf_report_sub() {
__et="$(printf '%s\n' "${1}" | sed -e 's/[\/&]/\\&/g')"
__es="$(printf '%s\n' "${2}" | sed -e 's/[]\/$*.^[]/\\&/g')"
sed -i 's/__'"${__et}"'__/'"${__es}"'/g' "${PERF_JS}"
}
# perf_report_append_js() - Append generic string to current template buffer
perf_report_append_js() {
PERF_TEMPLATE_JS="${PERF_TEMPLATE_JS}${@}"
}
# perf_report() - Start of single test report
perf_report() {
__mode="${1}"
__proto="${2}"
__threads="${3}"
__freq="${4}"
REPORT_IN="${__mode}_${__proto}"
[ ${__threads} -eq 1 ] && __threads="one thread" || __threads="${__threads} threads"
perf_report_sub "${__mode}_${__proto}_threads" "${__threads}"
perf_report_sub "${__mode}_${__proto}_freq" "${__freq}"
perf_report_append_js "[ 'perf_${__mode}_${__proto}', $(video_time_now) ],"
}
# perf_th() - Table header for a set of tests
perf_th() {
[ ${PERF_INIT} -eq 0 ] && return
shift
__th_buf=
__cols_count=0
for __arg; do
__th_buf="${__th_buf}<td>${__arg}</td>"
__cols_count=$((__cols_count + 1))
done
perf_report_sub "${REPORT_IN}_header" "${__th_buf}"
perf_report_sub "${REPORT_IN}_cols" ${__cols_count}
}
# perf_tr() - Main table row
perf_tr() {
[ ${PERF_INIT} -eq 0 ] && return
__line_no=0
shift
while true; do
[ -z "$(eval echo \$${REPORT_IN}_LINE_${__line_no})" ] && break
__line_no=$((__line_no + 1))
done
eval ${REPORT_IN}_LINE_${__line_no}="\"<td>${@}</td>\""
}
# perf_td() - Single cell with test result
perf_td() {
[ ${PERF_INIT} -eq 0 ] && return
__rewind="${1}"
shift
__line_no=0
while true; do
[ -z "$(eval echo \$${REPORT_IN}_LINE_${__line_no})" ] && break
__line_no=$((__line_no + 1))
done
__line_no=$((__line_no - 1))
[ -z "${1}" ] && __id=0 || __id="perf_${PERF_LINK_COUNT}"
eval ${REPORT_IN}_LINE_${__line_no}=\""\${${REPORT_IN}_LINE_${__line_no}}<td id=\"${__id}\">${1}</td>"\"
[ -z "${1}" ] && return
perf_report_append_js "[ '${__id}', $(($(video_time_now) - ${__rewind})) ],"
PERF_LINK_COUNT=$((PERF_LINK_COUNT + 1))
}
# perf_te() - End of a table, currently unused
pert_te() {
:
}