xref: /linux/tools/testing/selftests/drivers/net/stats.py (revision 860a9bed265146b10311bcadbbcef59c3af4454d)
1#!/usr/bin/env python3
2# SPDX-License-Identifier: GPL-2.0
3
4from lib.py import ksft_run, ksft_in, ksft_true, KsftSkipEx, KsftXfailEx
5from lib.py import EthtoolFamily, NetdevFamily, RtnlFamily, NlError
6from lib.py import NetDrvEnv
7
8ethnl = EthtoolFamily()
9netfam = NetdevFamily()
10rtnl = RtnlFamily()
11
12
13def check_pause(cfg) -> None:
14    global ethnl
15
16    try:
17        ethnl.pause_get({"header": {"dev-index": cfg.ifindex}})
18    except NlError as e:
19        if e.error == 95:
20            raise KsftXfailEx("pause not supported by the device")
21        raise
22
23    data = ethnl.pause_get({"header": {"dev-index": cfg.ifindex,
24                                       "flags": {'stats'}}})
25    ksft_true(data['stats'], "driver does not report stats")
26
27
28def check_fec(cfg) -> None:
29    global ethnl
30
31    try:
32        ethnl.fec_get({"header": {"dev-index": cfg.ifindex}})
33    except NlError as e:
34        if e.error == 95:
35            raise KsftXfailEx("FEC not supported by the device")
36        raise
37
38    data = ethnl.fec_get({"header": {"dev-index": cfg.ifindex,
39                                     "flags": {'stats'}}})
40    ksft_true(data['stats'], "driver does not report stats")
41
42
43def pkt_byte_sum(cfg) -> None:
44    global netfam, rtnl
45
46    def get_qstat(test):
47        global netfam
48        stats = netfam.qstats_get({}, dump=True)
49        if stats:
50            for qs in stats:
51                if qs["ifindex"]== test.ifindex:
52                    return qs
53
54    qstat = get_qstat(cfg)
55    if qstat is None:
56        raise KsftSkipEx("qstats not supported by the device")
57
58    for key in ['tx-packets', 'tx-bytes', 'rx-packets', 'rx-bytes']:
59        ksft_in(key, qstat, "Drivers should always report basic keys")
60
61    # Compare stats, rtnl stats and qstats must match,
62    # but the interface may be up, so do a series of dumps
63    # each time the more "recent" stats must be higher or same.
64    def stat_cmp(rstat, qstat):
65        for key in ['tx-packets', 'tx-bytes', 'rx-packets', 'rx-bytes']:
66            if rstat[key] != qstat[key]:
67                return rstat[key] - qstat[key]
68        return 0
69
70    for _ in range(10):
71        rtstat = rtnl.getlink({"ifi-index": cfg.ifindex})['stats']
72        if stat_cmp(rtstat, qstat) < 0:
73            raise Exception("RTNL stats are lower, fetched later")
74        qstat = get_qstat(cfg)
75        if stat_cmp(rtstat, qstat) > 0:
76            raise Exception("Qstats are lower, fetched later")
77
78
79def main() -> None:
80    with NetDrvEnv(__file__) as cfg:
81        ksft_run([check_pause, check_fec, pkt_byte_sum],
82                 args=(cfg, ))
83
84
85if __name__ == "__main__":
86    main()
87