diff options
| author | Jakub Kicinski <kuba@kernel.org> | 2025-07-14 12:56:48 +0300 | 
|---|---|---|
| committer | Jakub Kicinski <kuba@kernel.org> | 2025-07-17 03:25:49 +0300 | 
| commit | 3c561c547c396038c7690645cff4f98181c62d49 (patch) | |
| tree | 5b3ef2705c6e5137d2965f24855b29ab7601d363 /tools/testing/selftests/net/lib/py/utils.py | |
| parent | 6c628ed95e1b41f98766268593196adb7a0cb9a7 (diff) | |
| download | linux-3c561c547c396038c7690645cff4f98181c62d49.tar.xz | |
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 <leitao@debian.org>
Signed-off-by: Breno Leitao <leitao@debian.org>
Link: https://patch.msgid.link/20250714-netpoll_test-v7-1-c0220cfaa63e@debian.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'tools/testing/selftests/net/lib/py/utils.py')
| -rw-r--r-- | tools/testing/selftests/net/lib/py/utils.py | 33 | 
1 files changed, 33 insertions, 0 deletions
| diff --git a/tools/testing/selftests/net/lib/py/utils.py b/tools/testing/selftests/net/lib/py/utils.py index acf0e2c38614..5950a643a533 100644 --- a/tools/testing/selftests/net/lib/py/utils.py +++ b/tools/testing/selftests/net/lib/py/utils.py @@ -189,6 +189,39 @@ def ethtool(args, json=None, ns=None, host=None):      return tool('ethtool', args, json=json, ns=ns, host=host) +def bpftrace(expr, json=None, ns=None, host=None, timeout=None): +    """ +    Run bpftrace and return map data (if json=True). +    The output of bpftrace is inconvenient, so the helper converts +    to a dict indexed by map name, e.g.: +     { +       "@":     { ... }, +       "@map2": { ... }, +     } +    """ +    cmd_arr = ['bpftrace'] +    # Throw in --quiet if json, otherwise the output has two objects +    if json: +        cmd_arr += ['-f', 'json', '-q'] +    if timeout: +        expr += ' interval:s:' + str(timeout) + ' { exit(); }' +    cmd_arr += ['-e', expr] +    cmd_obj = cmd(cmd_arr, ns=ns, host=host, shell=False) +    if json: +        # bpftrace prints objects as lines +        ret = {} +        for l in cmd_obj.stdout.split('\n'): +            if not l.strip(): +                continue +            one = _json.loads(l) +            if one.get('type') != 'map': +                continue +            for k, v in one["data"].items(): +                ret[k] = v +        return ret +    return cmd_obj + +  def rand_port(type=socket.SOCK_STREAM):      """      Get a random unprivileged port. | 
