blob: 3f2487033ba3314b2599aee05ec35d917d48fab2 [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
Daniel Wagnerfd3a2142020-08-27 15:58:46 +020032def print_res(res, key):
Benjamin Copeland15d743e2021-02-22 08:35:10 +000033 print("t{}-{}-latency pass {} us".format(res["t"], key, res[key]))
Daniel Wagner611b5412019-07-22 11:24:20 +020034
35
Daniel Wagner72624fd2019-07-23 09:38:10 +020036def get_block(filename):
37 # Fetch a text block from the file iterating backwards. Each block
38 # starts with an escape sequence which starts with '\x1b'.
Benjamin Copeland15d743e2021-02-22 08:35:10 +000039 with open(filename, "rb") as f:
Daniel Wagner611b5412019-07-22 11:24:20 +020040 try:
Daniel Wagner72624fd2019-07-23 09:38:10 +020041 f.seek(0, os.SEEK_END)
42 while True:
43 pe = f.tell()
44
Daniel Wagner611b5412019-07-22 11:24:20 +020045 f.seek(-2, os.SEEK_CUR)
Benjamin Copeland15d743e2021-02-22 08:35:10 +000046 while f.read(1) != b"\x1b":
Daniel Wagner72624fd2019-07-23 09:38:10 +020047 f.seek(-2, os.SEEK_CUR)
48 pa = f.tell()
49
50 blk = f.read(pe - pa)
51
52 # Remove escape sequence at the start of the block
53 # The control sequence ends in 'A'
Benjamin Copeland15d743e2021-02-22 08:35:10 +000054 i = blk.find("A") + 1
Daniel Wagner72624fd2019-07-23 09:38:10 +020055 yield blk[i:]
56
57 # Jump back to next block
58 f.seek(pa - 1, os.SEEK_SET)
Daniel Wagner611b5412019-07-22 11:24:20 +020059 except IOError:
Daniel Wagner72624fd2019-07-23 09:38:10 +020060 # No escape sequence found
Daniel Wagner611b5412019-07-22 11:24:20 +020061 f.seek(0, os.SEEK_SET)
Daniel Wagner72624fd2019-07-23 09:38:10 +020062 yield f.read()
63
64
65def get_lastlines(filename):
66 for b in get_block(filename):
67 # Ignore empty blocks
Benjamin Copeland15d743e2021-02-22 08:35:10 +000068 if len(b.strip("\n")) == 0:
Daniel Wagner72624fd2019-07-23 09:38:10 +020069 continue
70
Benjamin Copeland15d743e2021-02-22 08:35:10 +000071 return b.split("\n")
Daniel Wagner611b5412019-07-22 11:24:20 +020072
73
Daniel Wagnerfd3a2142020-08-27 15:58:46 +020074def parse_cyclictest(filename):
Benjamin Copeland15d743e2021-02-22 08:35:10 +000075 fields = ["t", "min", "avg", "max"]
Daniel Wagner611b5412019-07-22 11:24:20 +020076
Benjamin Copeland15d743e2021-02-22 08:35:10 +000077 r = re.compile("[ :\n]+")
Daniel Wagner611b5412019-07-22 11:24:20 +020078 for line in get_lastlines(filename):
Benjamin Copeland15d743e2021-02-22 08:35:10 +000079 if not line.startswith("T:"):
Daniel Wagner611b5412019-07-22 11:24:20 +020080 continue
81
82 data = [x.lower() for x in r.split(line)]
83 res = {}
84 it = iter(data)
85 for e in it:
86 if e in fields:
87 res[e] = next(it)
88
Benjamin Copeland15d743e2021-02-22 08:35:10 +000089 print_res(res, "min")
90 print_res(res, "avg")
91 print_res(res, "max")
Daniel Wagner611b5412019-07-22 11:24:20 +020092
93
Daniel Wagnerfd3a2142020-08-27 15:58:46 +020094def parse_pmqtest(filename):
Benjamin Copeland15d743e2021-02-22 08:35:10 +000095 fields = ["min", "avg", "max"]
Daniel Wagner611b5412019-07-22 11:24:20 +020096
Benjamin Copeland15d743e2021-02-22 08:35:10 +000097 rl = re.compile("[ ,:\n]+")
98 rt = re.compile("[ ,#]+")
Daniel Wagner611b5412019-07-22 11:24:20 +020099 for line in get_lastlines(filename):
100 data = [x.lower() for x in rl.split(line)]
101 res = {}
102 it = iter(data)
103 for e in it:
104 if e in fields:
105 res[e] = next(it)
106
107 if not res:
108 continue
109
110 # The id is constructed from the '#FROM -> #TO' output, e.g.
111 # #1 -> #0, Min 1, Cur 3, Avg 4, Max 119
112 data = rt.split(line)
Benjamin Copeland15d743e2021-02-22 08:35:10 +0000113 res["t"] = "{}-{}".format(data[1], data[3])
Daniel Wagner611b5412019-07-22 11:24:20 +0200114
Benjamin Copeland15d743e2021-02-22 08:35:10 +0000115 print_res(res, "min")
116 print_res(res, "avg")
117 print_res(res, "max")
Daniel Wagner611b5412019-07-22 11:24:20 +0200118
119
120def main():
121 tool = sys.argv[1]
Daniel Wagnerfd3a2142020-08-27 15:58:46 +0200122 logfile = sys.argv[2]
Benjamin Copeland15d743e2021-02-22 08:35:10 +0000123 if tool in ["cyclictest", "signaltest", "cyclicdeadline"]:
Daniel Wagnerfd3a2142020-08-27 15:58:46 +0200124 parse_cyclictest(logfile)
Benjamin Copeland15d743e2021-02-22 08:35:10 +0000125 elif tool in ["pmqtest", "ptsematest", "sigwaittest", "svsematest"]:
Daniel Wagnerfd3a2142020-08-27 15:58:46 +0200126 parse_pmqtest(logfile)
Daniel Wagner611b5412019-07-22 11:24:20 +0200127
128
Benjamin Copeland15d743e2021-02-22 08:35:10 +0000129if __name__ == "__main__":
Daniel Wagner611b5412019-07-22 11:24:20 +0200130 main()