~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/testing/selftests/drivers/net/stats.py

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /tools/testing/selftests/drivers/net/stats.py (Architecture i386) and /tools/testing/selftests/drivers/net/stats.py (Architecture ppc)


  1 #!/usr/bin/env python3                              1 #!/usr/bin/env python3
  2 # SPDX-License-Identifier: GPL-2.0                  2 # SPDX-License-Identifier: GPL-2.0
  3                                                     3 
  4 import errno                                        4 import errno
  5 from lib.py import ksft_run, ksft_exit, ksft_p      5 from lib.py import ksft_run, ksft_exit, ksft_pr
  6 from lib.py import ksft_ge, ksft_eq, ksft_in,       6 from lib.py import ksft_ge, ksft_eq, ksft_in, ksft_true, ksft_raises, KsftSkipEx, KsftXfailEx
  7 from lib.py import ksft_disruptive                  7 from lib.py import ksft_disruptive
  8 from lib.py import EthtoolFamily, NetdevFamily      8 from lib.py import EthtoolFamily, NetdevFamily, RtnlFamily, NlError
  9 from lib.py import NetDrvEnv                        9 from lib.py import NetDrvEnv
 10 from lib.py import ip, defer                       10 from lib.py import ip, defer
 11                                                    11 
 12 ethnl = EthtoolFamily()                            12 ethnl = EthtoolFamily()
 13 netfam = NetdevFamily()                            13 netfam = NetdevFamily()
 14 rtnl = RtnlFamily()                                14 rtnl = RtnlFamily()
 15                                                    15 
 16                                                    16 
 17 def check_pause(cfg) -> None:                      17 def check_pause(cfg) -> None:
 18     global ethnl                                   18     global ethnl
 19                                                    19 
 20     try:                                           20     try:
 21         ethnl.pause_get({"header": {"dev-index     21         ethnl.pause_get({"header": {"dev-index": cfg.ifindex}})
 22     except NlError as e:                           22     except NlError as e:
 23         if e.error == errno.EOPNOTSUPP:            23         if e.error == errno.EOPNOTSUPP:
 24             raise KsftXfailEx("pause not suppo     24             raise KsftXfailEx("pause not supported by the device")
 25         raise                                      25         raise
 26                                                    26 
 27     data = ethnl.pause_get({"header": {"dev-in     27     data = ethnl.pause_get({"header": {"dev-index": cfg.ifindex,
 28                                        "flags"     28                                        "flags": {'stats'}}})
 29     ksft_true(data['stats'], "driver does not      29     ksft_true(data['stats'], "driver does not report stats")
 30                                                    30 
 31                                                    31 
 32 def check_fec(cfg) -> None:                        32 def check_fec(cfg) -> None:
 33     global ethnl                                   33     global ethnl
 34                                                    34 
 35     try:                                           35     try:
 36         ethnl.fec_get({"header": {"dev-index":     36         ethnl.fec_get({"header": {"dev-index": cfg.ifindex}})
 37     except NlError as e:                           37     except NlError as e:
 38         if e.error == errno.EOPNOTSUPP:            38         if e.error == errno.EOPNOTSUPP:
 39             raise KsftXfailEx("FEC not support     39             raise KsftXfailEx("FEC not supported by the device")
 40         raise                                      40         raise
 41                                                    41 
 42     data = ethnl.fec_get({"header": {"dev-inde     42     data = ethnl.fec_get({"header": {"dev-index": cfg.ifindex,
 43                                      "flags":      43                                      "flags": {'stats'}}})
 44     ksft_true(data['stats'], "driver does not      44     ksft_true(data['stats'], "driver does not report stats")
 45                                                    45 
 46                                                    46 
 47 def pkt_byte_sum(cfg) -> None:                     47 def pkt_byte_sum(cfg) -> None:
 48     global netfam, rtnl                            48     global netfam, rtnl
 49                                                    49 
 50     def get_qstat(test):                           50     def get_qstat(test):
 51         global netfam                              51         global netfam
 52         stats = netfam.qstats_get({}, dump=Tru     52         stats = netfam.qstats_get({}, dump=True)
 53         if stats:                                  53         if stats:
 54             for qs in stats:                       54             for qs in stats:
 55                 if qs["ifindex"]== test.ifinde     55                 if qs["ifindex"]== test.ifindex:
 56                     return qs                      56                     return qs
 57                                                    57 
 58     qstat = get_qstat(cfg)                         58     qstat = get_qstat(cfg)
 59     if qstat is None:                              59     if qstat is None:
 60         raise KsftSkipEx("qstats not supported     60         raise KsftSkipEx("qstats not supported by the device")
 61                                                    61 
 62     for key in ['tx-packets', 'tx-bytes', 'rx-     62     for key in ['tx-packets', 'tx-bytes', 'rx-packets', 'rx-bytes']:
 63         ksft_in(key, qstat, "Drivers should al     63         ksft_in(key, qstat, "Drivers should always report basic keys")
 64                                                    64 
 65     # Compare stats, rtnl stats and qstats mus     65     # Compare stats, rtnl stats and qstats must match,
 66     # but the interface may be up, so do a ser     66     # but the interface may be up, so do a series of dumps
 67     # each time the more "recent" stats must b     67     # each time the more "recent" stats must be higher or same.
 68     def stat_cmp(rstat, qstat):                    68     def stat_cmp(rstat, qstat):
 69         for key in ['tx-packets', 'tx-bytes',      69         for key in ['tx-packets', 'tx-bytes', 'rx-packets', 'rx-bytes']:
 70             if rstat[key] != qstat[key]:           70             if rstat[key] != qstat[key]:
 71                 return rstat[key] - qstat[key]     71                 return rstat[key] - qstat[key]
 72         return 0                                   72         return 0
 73                                                    73 
 74     for _ in range(10):                            74     for _ in range(10):
 75         rtstat = rtnl.getlink({"ifi-index": cf     75         rtstat = rtnl.getlink({"ifi-index": cfg.ifindex})['stats64']
 76         if stat_cmp(rtstat, qstat) < 0:            76         if stat_cmp(rtstat, qstat) < 0:
 77             raise Exception("RTNL stats are lo     77             raise Exception("RTNL stats are lower, fetched later")
 78         qstat = get_qstat(cfg)                     78         qstat = get_qstat(cfg)
 79         if stat_cmp(rtstat, qstat) > 0:            79         if stat_cmp(rtstat, qstat) > 0:
 80             raise Exception("Qstats are lower,     80             raise Exception("Qstats are lower, fetched later")
 81                                                    81 
 82                                                    82 
 83 def qstat_by_ifindex(cfg) -> None:                 83 def qstat_by_ifindex(cfg) -> None:
 84     global netfam                                  84     global netfam
 85     global rtnl                                    85     global rtnl
 86                                                    86 
 87     # Construct a map ifindex -> [dump, by-ind     87     # Construct a map ifindex -> [dump, by-index, dump]
 88     ifindexes = {}                                 88     ifindexes = {}
 89     stats = netfam.qstats_get({}, dump=True)       89     stats = netfam.qstats_get({}, dump=True)
 90     for entry in stats:                            90     for entry in stats:
 91         ifindexes[entry['ifindex']] = [entry,      91         ifindexes[entry['ifindex']] = [entry, None, None]
 92                                                    92 
 93     for ifindex in ifindexes.keys():               93     for ifindex in ifindexes.keys():
 94         entry = netfam.qstats_get({"ifindex":      94         entry = netfam.qstats_get({"ifindex": ifindex}, dump=True)
 95         ksft_eq(len(entry), 1)                     95         ksft_eq(len(entry), 1)
 96         ifindexes[entry[0]['ifindex']][1] = en     96         ifindexes[entry[0]['ifindex']][1] = entry[0]
 97                                                    97 
 98     stats = netfam.qstats_get({}, dump=True)       98     stats = netfam.qstats_get({}, dump=True)
 99     for entry in stats:                            99     for entry in stats:
100         ifindexes[entry['ifindex']][2] = entry    100         ifindexes[entry['ifindex']][2] = entry
101                                                   101 
102     if len(ifindexes) == 0:                       102     if len(ifindexes) == 0:
103         raise KsftSkipEx("No ifindex supports     103         raise KsftSkipEx("No ifindex supports qstats")
104                                                   104 
105     # Now make sure the stats match/make sense    105     # Now make sure the stats match/make sense
106     for ifindex, triple in ifindexes.items():     106     for ifindex, triple in ifindexes.items():
107         all_keys = triple[0].keys() | triple[1    107         all_keys = triple[0].keys() | triple[1].keys() | triple[2].keys()
108                                                   108 
109         for key in all_keys:                      109         for key in all_keys:
110             ksft_ge(triple[1][key], triple[0][    110             ksft_ge(triple[1][key], triple[0][key], comment="bad key: " + key)
111             ksft_ge(triple[2][key], triple[1][    111             ksft_ge(triple[2][key], triple[1][key], comment="bad key: " + key)
112                                                   112 
113     # Test invalid dumps                          113     # Test invalid dumps
114     # 0 is invalid                                114     # 0 is invalid
115     with ksft_raises(NlError) as cm:              115     with ksft_raises(NlError) as cm:
116         netfam.qstats_get({"ifindex": 0}, dump    116         netfam.qstats_get({"ifindex": 0}, dump=True)
117     ksft_eq(cm.exception.nl_msg.error, -34)       117     ksft_eq(cm.exception.nl_msg.error, -34)
118     ksft_eq(cm.exception.nl_msg.extack['bad-at    118     ksft_eq(cm.exception.nl_msg.extack['bad-attr'], '.ifindex')
119                                                   119 
120     # loopback has no stats                       120     # loopback has no stats
121     with ksft_raises(NlError) as cm:              121     with ksft_raises(NlError) as cm:
122         netfam.qstats_get({"ifindex": 1}, dump    122         netfam.qstats_get({"ifindex": 1}, dump=True)
123     ksft_eq(cm.exception.nl_msg.error, -errno.    123     ksft_eq(cm.exception.nl_msg.error, -errno.EOPNOTSUPP)
124     ksft_eq(cm.exception.nl_msg.extack['bad-at    124     ksft_eq(cm.exception.nl_msg.extack['bad-attr'], '.ifindex')
125                                                   125 
126     # Try to get stats for lowest unused ifind    126     # Try to get stats for lowest unused ifindex but not 0
127     devs = rtnl.getlink({}, dump=True)            127     devs = rtnl.getlink({}, dump=True)
128     all_ifindexes = set([dev["ifi-index"] for     128     all_ifindexes = set([dev["ifi-index"] for dev in devs])
129     lowest = 2                                    129     lowest = 2
130     while lowest in all_ifindexes:                130     while lowest in all_ifindexes:
131         lowest += 1                               131         lowest += 1
132                                                   132 
133     with ksft_raises(NlError) as cm:              133     with ksft_raises(NlError) as cm:
134         netfam.qstats_get({"ifindex": lowest},    134         netfam.qstats_get({"ifindex": lowest}, dump=True)
135     ksft_eq(cm.exception.nl_msg.error, -19)       135     ksft_eq(cm.exception.nl_msg.error, -19)
136     ksft_eq(cm.exception.nl_msg.extack['bad-at    136     ksft_eq(cm.exception.nl_msg.extack['bad-attr'], '.ifindex')
137                                                   137 
138                                                   138 
139 @ksft_disruptive                                  139 @ksft_disruptive
140 def check_down(cfg) -> None:                      140 def check_down(cfg) -> None:
141     try:                                          141     try:
142         qstat = netfam.qstats_get({"ifindex":     142         qstat = netfam.qstats_get({"ifindex": cfg.ifindex}, dump=True)[0]
143     except NlError as e:                          143     except NlError as e:
144         if e.error == errno.EOPNOTSUPP:           144         if e.error == errno.EOPNOTSUPP:
145             raise KsftSkipEx("qstats not suppo    145             raise KsftSkipEx("qstats not supported by the device")
146         raise                                     146         raise
147                                                   147 
148     ip(f"link set dev {cfg.dev['ifname']} down    148     ip(f"link set dev {cfg.dev['ifname']} down")
149     defer(ip, f"link set dev {cfg.dev['ifname'    149     defer(ip, f"link set dev {cfg.dev['ifname']} up")
150                                                   150 
151     qstat2 = netfam.qstats_get({"ifindex": cfg    151     qstat2 = netfam.qstats_get({"ifindex": cfg.ifindex}, dump=True)[0]
152     for k, v in qstat.items():                    152     for k, v in qstat.items():
153         ksft_ge(qstat2[k], qstat[k], comment=f    153         ksft_ge(qstat2[k], qstat[k], comment=f"{k} went backwards on device down")
154                                                   154 
155     # exercise per-queue API to make sure that    155     # exercise per-queue API to make sure that "device down" state
156     # is handled correctly and doesn't crash      156     # is handled correctly and doesn't crash
157     netfam.qstats_get({"ifindex": cfg.ifindex,    157     netfam.qstats_get({"ifindex": cfg.ifindex, "scope": "queue"}, dump=True)
158                                                   158 
159                                                   159 
160 def main() -> None:                               160 def main() -> None:
161     with NetDrvEnv(__file__) as cfg:              161     with NetDrvEnv(__file__) as cfg:
162         ksft_run([check_pause, check_fec, pkt_    162         ksft_run([check_pause, check_fec, pkt_byte_sum, qstat_by_ifindex,
163                   check_down],                    163                   check_down],
164                  args=(cfg, ))                    164                  args=(cfg, ))
165     ksft_exit()                                   165     ksft_exit()
166                                                   166 
167                                                   167 
168 if __name__ == "__main__":                        168 if __name__ == "__main__":
169     main()                                        169     main()
                                                      

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php