Skip to content

Commit 3c561c5

Browse files
committed
selftests: drv-net: add helper/wrapper for bpftrace
bpftrace is very useful for low level driver testing. perf or trace-cmd would also do for collecting data from tracepoints, but they require much more post-processing. Add a wrapper for running bpftrace and sanitizing its output. bpftrace has JSON output, which is great, but it prints loose objects and in a slightly inconvenient format. We have to read the objects line by line, and while at it return them indexed by the map name. Reviewed-by: Breno Leitao <[email protected]> Signed-off-by: Breno Leitao <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 6c628ed commit 3c561c5

File tree

2 files changed

+35
-2
lines changed

2 files changed

+35
-2
lines changed

tools/testing/selftests/drivers/net/lib/py/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414
from net.lib.py import EthtoolFamily, NetdevFamily, NetshaperFamily, \
1515
NlError, RtnlFamily, DevlinkFamily
1616
from net.lib.py import CmdExitFailure
17-
from net.lib.py import bkg, cmd, defer, ethtool, fd_read_timeout, ip, \
18-
rand_port, tool, wait_port_listen, bpftool
17+
from net.lib.py import bkg, cmd, bpftool, bpftrace, defer, ethtool, \
18+
fd_read_timeout, ip, rand_port, tool, wait_port_listen
1919
from net.lib.py import fd_read_timeout
2020
from net.lib.py import KsftSkipEx, KsftFailEx, KsftXfailEx
2121
from net.lib.py import ksft_disruptive, ksft_exit, ksft_pr, ksft_run, \

tools/testing/selftests/net/lib/py/utils.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,39 @@ def ethtool(args, json=None, ns=None, host=None):
189189
return tool('ethtool', args, json=json, ns=ns, host=host)
190190

191191

192+
def bpftrace(expr, json=None, ns=None, host=None, timeout=None):
193+
"""
194+
Run bpftrace and return map data (if json=True).
195+
The output of bpftrace is inconvenient, so the helper converts
196+
to a dict indexed by map name, e.g.:
197+
{
198+
"@": { ... },
199+
"@map2": { ... },
200+
}
201+
"""
202+
cmd_arr = ['bpftrace']
203+
# Throw in --quiet if json, otherwise the output has two objects
204+
if json:
205+
cmd_arr += ['-f', 'json', '-q']
206+
if timeout:
207+
expr += ' interval:s:' + str(timeout) + ' { exit(); }'
208+
cmd_arr += ['-e', expr]
209+
cmd_obj = cmd(cmd_arr, ns=ns, host=host, shell=False)
210+
if json:
211+
# bpftrace prints objects as lines
212+
ret = {}
213+
for l in cmd_obj.stdout.split('\n'):
214+
if not l.strip():
215+
continue
216+
one = _json.loads(l)
217+
if one.get('type') != 'map':
218+
continue
219+
for k, v in one["data"].items():
220+
ret[k] = v
221+
return ret
222+
return cmd_obj
223+
224+
192225
def rand_port(type=socket.SOCK_STREAM):
193226
"""
194227
Get a random unprivileged port.

0 commit comments

Comments
 (0)