blob: c846f2dc5a72d313021579f6efcdf6602e7a96ce [file] [log] [blame]
Daniel Wagner611b5412019-07-22 11:24:20 +02001#!/usr/bin/env python
2# SPDX-License-Identifier: MIT
3#
4# MIT License
5#
6# Copyright (c) Daniel Wagner
7#
8# Permission is hereby granted, free of charge, to any person obtaining a copy
9# of this software and associated documentation files (the "Software"), to deal
10# in the Software without restriction, including without limitation the rights
11# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12# copies of the Software, and to permit persons to whom the Software is
13# furnished to do so, subject to the following conditions:
14#
15# The above copyright notice and this permission notice shall be included in
16# all copies or substantial portions of the Software.
17#
18# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24# SOFTWARE.
25#
26
27import os
28import re
29import sys
30
31
32def print_res(res, key, thr):
33 val = res[key]
34 label = 'pass'
35 if key == 'max':
36 if int(val) >= int(thr):
37 label = 'fail'
38 print('t{}-{}-latency {} {} us'.format(res['t'], key, label, val))
39
40
Daniel Wagner72624fd2019-07-23 09:38:10 +020041def get_block(filename):
42 # Fetch a text block from the file iterating backwards. Each block
43 # starts with an escape sequence which starts with '\x1b'.
Daniel Wagner611b5412019-07-22 11:24:20 +020044 with open(filename, 'rb') as f:
45 try:
Daniel Wagner72624fd2019-07-23 09:38:10 +020046 f.seek(0, os.SEEK_END)
47 while True:
48 pe = f.tell()
49
Daniel Wagner611b5412019-07-22 11:24:20 +020050 f.seek(-2, os.SEEK_CUR)
Daniel Wagner72624fd2019-07-23 09:38:10 +020051 while f.read(1) != b'\x1b':
52 f.seek(-2, os.SEEK_CUR)
53 pa = f.tell()
54
55 blk = f.read(pe - pa)
56
57 # Remove escape sequence at the start of the block
58 # The control sequence ends in 'A'
59 i = blk.find('A') + 1
60 yield blk[i:]
61
62 # Jump back to next block
63 f.seek(pa - 1, os.SEEK_SET)
Daniel Wagner611b5412019-07-22 11:24:20 +020064 except IOError:
Daniel Wagner72624fd2019-07-23 09:38:10 +020065 # No escape sequence found
Daniel Wagner611b5412019-07-22 11:24:20 +020066 f.seek(0, os.SEEK_SET)
Daniel Wagner72624fd2019-07-23 09:38:10 +020067 yield f.read()
68
69
70def get_lastlines(filename):
71 for b in get_block(filename):
72 # Ignore empty blocks
73 if len(b.strip('\n')) == 0:
74 continue
75
76 return b.split('\n')
Daniel Wagner611b5412019-07-22 11:24:20 +020077
78
79def parse_cyclictest(filename, thr):
80 fields = ['t', 'min', 'avg', 'max']
81
82 r = re.compile('[ :\n]+')
83 for line in get_lastlines(filename):
84 if not line.startswith('T:'):
85 continue
86
87 data = [x.lower() for x in r.split(line)]
88 res = {}
89 it = iter(data)
90 for e in it:
91 if e in fields:
92 res[e] = next(it)
93
94 print_res(res, 'min', thr)
95 print_res(res, 'avg', thr)
96 print_res(res, 'max', thr)
97
98
99def parse_pmqtest(filename, thr):
100 fields = ['min', 'avg', 'max']
101
102 rl = re.compile('[ ,:\n]+')
103 rt = re.compile('[ ,#]+')
104 for line in get_lastlines(filename):
105 data = [x.lower() for x in rl.split(line)]
106 res = {}
107 it = iter(data)
108 for e in it:
109 if e in fields:
110 res[e] = next(it)
111
112 if not res:
113 continue
114
115 # The id is constructed from the '#FROM -> #TO' output, e.g.
116 # #1 -> #0, Min 1, Cur 3, Avg 4, Max 119
117 data = rt.split(line)
118 res['t'] = '{}-{}'.format(data[1], data[3])
119
120 print_res(res, 'min', thr)
121 print_res(res, 'avg', thr)
122 print_res(res, 'max', thr)
123
124
125def main():
126 tool = sys.argv[1]
Daniel Wagner72624fd2019-07-23 09:38:10 +0200127 if tool in ['cyclictest', 'signaltest', 'cyclicdeadline']:
Daniel Wagner611b5412019-07-22 11:24:20 +0200128 parse_cyclictest(sys.argv[2], int(sys.argv[3]))
Daniel Wagner6c7fd5a2019-07-22 20:49:43 +0200129 elif tool in ['pmqtest', 'ptsematest', 'sigwaittest', 'svsematest']:
Daniel Wagner611b5412019-07-22 11:24:20 +0200130 parse_pmqtest(sys.argv[2], int(sys.argv[3]))
131
132
133if __name__ == '__main__':
134 main()