2 # SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
3 # Basic sanity check of perf JSON output as specified in the man page.
9 ap
= argparse
.ArgumentParser()
10 ap
.add_argument('--no-args', action
='store_true')
11 ap
.add_argument('--interval', action
='store_true')
12 ap
.add_argument('--system-wide-no-aggr', action
='store_true')
13 ap
.add_argument('--system-wide', action
='store_true')
14 ap
.add_argument('--event', action
='store_true')
15 ap
.add_argument('--per-core', action
='store_true')
16 ap
.add_argument('--per-thread', action
='store_true')
17 ap
.add_argument('--per-cache', action
='store_true')
18 ap
.add_argument('--per-cluster', action
='store_true')
19 ap
.add_argument('--per-die', action
='store_true')
20 ap
.add_argument('--per-node', action
='store_true')
21 ap
.add_argument('--per-socket', action
='store_true')
22 ap
.add_argument('--file', type=argparse
.FileType('r'), default
=sys
.stdin
)
23 args
= ap
.parse_args()
25 Lines
= args
.file.readlines()
42 def is_counter_value(num
):
43 return isfloat(num
) or num
== '<not counted>' or num
== '<not supported>'
45 def check_json_output(expected_items
):
47 'aggregate-number': lambda x
: isfloat(x
),
48 'core': lambda x
: True,
49 'counter-value': lambda x
: is_counter_value(x
),
50 'cgroup': lambda x
: True,
51 'cpu': lambda x
: isint(x
),
52 'cache': lambda x
: True,
53 'cluster': lambda x
: True,
54 'die': lambda x
: True,
55 'event': lambda x
: True,
56 'event-runtime': lambda x
: isfloat(x
),
57 'interval': lambda x
: isfloat(x
),
58 'metric-unit': lambda x
: True,
59 'metric-value': lambda x
: isfloat(x
),
60 'metric-threshold': lambda x
: x
in ['unknown', 'good', 'less good', 'nearly bad', 'bad'],
61 'metricgroup': lambda x
: True,
62 'node': lambda x
: True,
63 'pcnt-running': lambda x
: isfloat(x
),
64 'socket': lambda x
: True,
65 'thread': lambda x
: True,
66 'unit': lambda x
: True,
68 input = '[\n' + ','.join(Lines
) + '\n]'
69 for item
in json
.loads(input):
70 if expected_items
!= -1:
72 if count
!= expected_items
and count
>= 1 and count
<= 7 and 'metric-value' in item
:
73 # Events that generate >1 metric may have isolated metric
74 # values and possibly other prefixes like interval, core,
75 # aggregate-number, or event-runtime/pcnt-running from multiplexing.
77 elif count
!= expected_items
and count
>= 1 and count
<= 5 and 'metricgroup' in item
:
79 elif count
== expected_items
+ 1 and 'metric-threshold' in item
:
81 elif count
!= expected_items
:
82 raise RuntimeError(f
'wrong number of fields. counted {count} expected {expected_items}'
84 for key
, value
in item
.items():
86 raise RuntimeError(f
'Unexpected key: key={key} value={value}')
87 if not checks
[key
](value
):
88 raise RuntimeError(f
'Check failed for: key={key} value={value}')
92 if args
.no_args
or args
.system_wide
or args
.event
:
94 elif args
.interval
or args
.per_thread
or args
.system_wide_no_aggr
:
96 elif args
.per_core
or args
.per_socket
or args
.per_node
or args
.per_die
or args
.per_cluster
or args
.per_cache
:
99 # If no option is specified, don't check the number of items.
101 check_json_output(expected_items
)
103 print('Test failed for input:\n' + '\n'.join(Lines
))