xref: /aosp_15_r20/external/deqp/scripts/log/bottleneck_report.py (revision 35238bce31c2a825756842865a792f8cf7f89930)
1*35238bceSAndroid Build Coastguard Worker# -*- coding: utf-8 -*-
2*35238bceSAndroid Build Coastguard Worker
3*35238bceSAndroid Build Coastguard Worker#-------------------------------------------------------------------------
4*35238bceSAndroid Build Coastguard Worker# Quality Program utilities
5*35238bceSAndroid Build Coastguard Worker# --------------------------------------
6*35238bceSAndroid Build Coastguard Worker#
7*35238bceSAndroid Build Coastguard Worker# Copyright 2018
8*35238bceSAndroid Build Coastguard Worker#
9*35238bceSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License");
10*35238bceSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License.
11*35238bceSAndroid Build Coastguard Worker# You may obtain a copy of the License at
12*35238bceSAndroid Build Coastguard Worker#
13*35238bceSAndroid Build Coastguard Worker#      http://www.apache.org/licenses/LICENSE-2.0
14*35238bceSAndroid Build Coastguard Worker#
15*35238bceSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software
16*35238bceSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS,
17*35238bceSAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18*35238bceSAndroid Build Coastguard Worker# See the License for the specific language governing permissions and
19*35238bceSAndroid Build Coastguard Worker# limitations under the License.
20*35238bceSAndroid Build Coastguard Worker#
21*35238bceSAndroid Build Coastguard Worker#-------------------------------------------------------------------------
22*35238bceSAndroid Build Coastguard Worker
23*35238bceSAndroid Build Coastguard Workerimport os
24*35238bceSAndroid Build Coastguard Workerimport copy
25*35238bceSAndroid Build Coastguard Workerimport sys
26*35238bceSAndroid Build Coastguard Workerimport xml.sax
27*35238bceSAndroid Build Coastguard Workerimport xml.sax.handler
28*35238bceSAndroid Build Coastguard Workerfrom log_parser import BatchResultParser, StatusCode
29*35238bceSAndroid Build Coastguard Worker
30*35238bceSAndroid Build Coastguard Workerclass TimeOfExecutionGroups() :
31*35238bceSAndroid Build Coastguard Worker    def __init__(self):
32*35238bceSAndroid Build Coastguard Worker        self.path = ""
33*35238bceSAndroid Build Coastguard Worker        self.numberOfTests = 0
34*35238bceSAndroid Build Coastguard Worker        self.timeOfExecution = 0
35*35238bceSAndroid Build Coastguard Worker
36*35238bceSAndroid Build Coastguard Workerclass TimeOfExecutionTests() :
37*35238bceSAndroid Build Coastguard Worker    def __init__(self):
38*35238bceSAndroid Build Coastguard Worker        self.path = ""
39*35238bceSAndroid Build Coastguard Worker        self.timeOfExecution = 0
40*35238bceSAndroid Build Coastguard Worker
41*35238bceSAndroid Build Coastguard Workerdef sortKey (element ) :
42*35238bceSAndroid Build Coastguard Worker    return int(element.timeOfExecution)
43*35238bceSAndroid Build Coastguard Worker
44*35238bceSAndroid Build Coastguard Workerdef sortKeyTimePerTest (element) :
45*35238bceSAndroid Build Coastguard Worker    return int(int(element.timeOfExecution)/int(element.numberOfTests))
46*35238bceSAndroid Build Coastguard Worker
47*35238bceSAndroid Build Coastguard Workerclass XMLLogHandlerTests(xml.sax.handler.ContentHandler) :
48*35238bceSAndroid Build Coastguard Worker    def __init__ (self):
49*35238bceSAndroid Build Coastguard Worker        self.list = []
50*35238bceSAndroid Build Coastguard Worker        self.element = TimeOfExecutionTests()
51*35238bceSAndroid Build Coastguard Worker        self.testTime = False
52*35238bceSAndroid Build Coastguard Worker
53*35238bceSAndroid Build Coastguard Worker    def startElement (self, name, attrs):
54*35238bceSAndroid Build Coastguard Worker        if name == "TestCaseResult" :
55*35238bceSAndroid Build Coastguard Worker            self.element.path = attrs.getValue("CasePath")
56*35238bceSAndroid Build Coastguard Worker        if name == "Number" and "TestDuration" == attrs.getValue("Name") :
57*35238bceSAndroid Build Coastguard Worker            self.testTime = True
58*35238bceSAndroid Build Coastguard Worker
59*35238bceSAndroid Build Coastguard Worker    def characters(self, content) :
60*35238bceSAndroid Build Coastguard Worker        if self.testTime :
61*35238bceSAndroid Build Coastguard Worker            self.testTime = False
62*35238bceSAndroid Build Coastguard Worker            self.element.timeOfExecution = content
63*35238bceSAndroid Build Coastguard Worker            self.list.append(copy.deepcopy(self.element))
64*35238bceSAndroid Build Coastguard Worker
65*35238bceSAndroid Build Coastguard Worker    def bottleneck (self, resultCount) :
66*35238bceSAndroid Build Coastguard Worker        print("The biggest tests time of execution")
67*35238bceSAndroid Build Coastguard Worker        print('%-4s%12s\t%12s' % ("Index", "Time", "Full name"))
68*35238bceSAndroid Build Coastguard Worker        self.list.sort(key = sortKey, reverse = True)
69*35238bceSAndroid Build Coastguard Worker        ndx = 1
70*35238bceSAndroid Build Coastguard Worker        for test in self.list :
71*35238bceSAndroid Build Coastguard Worker            print('%-4i%12i\t%12s' % (int(ndx), int(test.timeOfExecution), test.path))
72*35238bceSAndroid Build Coastguard Worker            ndx+=1
73*35238bceSAndroid Build Coastguard Worker            if int(ndx) > int(resultCount) :
74*35238bceSAndroid Build Coastguard Worker                break
75*35238bceSAndroid Build Coastguard Worker
76*35238bceSAndroid Build Coastguard Workerclass XMLLogHandlerGroups(xml.sax.handler.ContentHandler) :
77*35238bceSAndroid Build Coastguard Worker    def __init__ (self, testList) :
78*35238bceSAndroid Build Coastguard Worker        self.list = []
79*35238bceSAndroid Build Coastguard Worker        self.testList = testList
80*35238bceSAndroid Build Coastguard Worker        self.element = TimeOfExecutionGroups()
81*35238bceSAndroid Build Coastguard Worker        self.addIt = False
82*35238bceSAndroid Build Coastguard Worker
83*35238bceSAndroid Build Coastguard Worker    def startElement (self, name, attrs) :
84*35238bceSAndroid Build Coastguard Worker        self.element.numberOfTests = 0
85*35238bceSAndroid Build Coastguard Worker        if name == "Number" :
86*35238bceSAndroid Build Coastguard Worker            self.element.path = attrs.getValue("Name")
87*35238bceSAndroid Build Coastguard Worker            if self.element.path == "dEQP-VK" :
88*35238bceSAndroid Build Coastguard Worker                self.addIt = True
89*35238bceSAndroid Build Coastguard Worker                self.element.numberOfTests = len(self.testList)
90*35238bceSAndroid Build Coastguard Worker            else :
91*35238bceSAndroid Build Coastguard Worker                for test in self.testList :
92*35238bceSAndroid Build Coastguard Worker                    if test.path[:test.path.rfind(".")] in self.element.path :
93*35238bceSAndroid Build Coastguard Worker                        self.addIt = True
94*35238bceSAndroid Build Coastguard Worker                        self.element.numberOfTests += 1
95*35238bceSAndroid Build Coastguard Worker
96*35238bceSAndroid Build Coastguard Worker    def characters(self, content) :
97*35238bceSAndroid Build Coastguard Worker        if self.addIt :
98*35238bceSAndroid Build Coastguard Worker            self.addIt = False
99*35238bceSAndroid Build Coastguard Worker            self.element.timeOfExecution = content
100*35238bceSAndroid Build Coastguard Worker            self.list.append(copy.deepcopy(self.element))
101*35238bceSAndroid Build Coastguard Worker
102*35238bceSAndroid Build Coastguard Worker    def bottleneck (self, resultCount) :
103*35238bceSAndroid Build Coastguard Worker        self.list.sort(key = sortKey, reverse = True)
104*35238bceSAndroid Build Coastguard Worker        print("\nGroups Statistics")
105*35238bceSAndroid Build Coastguard Worker        print("Total time of execution:\t", self.list[0].timeOfExecution)
106*35238bceSAndroid Build Coastguard Worker        print("Number of executed tests:\t", self.list[0].numberOfTests)
107*35238bceSAndroid Build Coastguard Worker        print("\nThe biggest total time of execution")
108*35238bceSAndroid Build Coastguard Worker        print('%-4s%15s%15s\t%-30s' % ("Index", "Time", "Test count", "Full name"))
109*35238bceSAndroid Build Coastguard Worker        ndx = 1
110*35238bceSAndroid Build Coastguard Worker        for test in self.list :
111*35238bceSAndroid Build Coastguard Worker            if test.path == "dEQP-VK" :
112*35238bceSAndroid Build Coastguard Worker                continue
113*35238bceSAndroid Build Coastguard Worker            print('%-4s%15s%15s\t%-30s' % (ndx, test.timeOfExecution, test.numberOfTests, test.path))
114*35238bceSAndroid Build Coastguard Worker            ndx+=1
115*35238bceSAndroid Build Coastguard Worker            if int(ndx) > int(resultCount) :
116*35238bceSAndroid Build Coastguard Worker                break
117*35238bceSAndroid Build Coastguard Worker        self.list.sort(key = sortKeyTimePerTest, reverse = True)
118*35238bceSAndroid Build Coastguard Worker        print("\nThe biggest time of execution per test")
119*35238bceSAndroid Build Coastguard Worker        print('%-4s%15s%15s%15s\t%-30s' % ("Index", "Time", "Test count", "\tAvg. test time", "Full name"))
120*35238bceSAndroid Build Coastguard Worker        ndx = 1
121*35238bceSAndroid Build Coastguard Worker        for test in self.list :
122*35238bceSAndroid Build Coastguard Worker            if test.path == "dEQP-VK" :
123*35238bceSAndroid Build Coastguard Worker                continue
124*35238bceSAndroid Build Coastguard Worker            print('%-4s%15s%15s%15i\t%-30s' % (ndx, test.timeOfExecution, test.numberOfTests, int(test.timeOfExecution)/int(test.numberOfTests), test.path))
125*35238bceSAndroid Build Coastguard Worker            ndx+=1
126*35238bceSAndroid Build Coastguard Worker            if int(ndx) > int(resultCount) :
127*35238bceSAndroid Build Coastguard Worker                break
128*35238bceSAndroid Build Coastguard Worker
129*35238bceSAndroid Build Coastguard Workerclass LogErrorHandler(xml.sax.handler.ErrorHandler) :
130*35238bceSAndroid Build Coastguard Worker    def __init__ (self) :
131*35238bceSAndroid Build Coastguard Worker        pass
132*35238bceSAndroid Build Coastguard Worker
133*35238bceSAndroid Build Coastguard Worker    def error (self, err) :
134*35238bceSAndroid Build Coastguard Worker        #print("error(%s)" % str(err))
135*35238bceSAndroid Build Coastguard Worker        pass
136*35238bceSAndroid Build Coastguard Worker
137*35238bceSAndroid Build Coastguard Worker    def fatalError (self, err) :
138*35238bceSAndroid Build Coastguard Worker        #print("fatalError(%s)" % str(err))
139*35238bceSAndroid Build Coastguard Worker        pass
140*35238bceSAndroid Build Coastguard Worker
141*35238bceSAndroid Build Coastguard Worker    def warning (self, warn) :
142*35238bceSAndroid Build Coastguard Worker        #print("warning(%s)" % str(warn))
143*35238bceSAndroid Build Coastguard Worker        pass
144*35238bceSAndroid Build Coastguard Worker
145*35238bceSAndroid Build Coastguard Workerdef findFirstElementByName (nodes, name) :
146*35238bceSAndroid Build Coastguard Worker    for node in nodes:
147*35238bceSAndroid Build Coastguard Worker        if node.nodeName == name :
148*35238bceSAndroid Build Coastguard Worker            return node
149*35238bceSAndroid Build Coastguard Worker        chFound = findFirstElementByName(node.childNodes, name)
150*35238bceSAndroid Build Coastguard Worker        if chFound != None :
151*35238bceSAndroid Build Coastguard Worker            return chFound
152*35238bceSAndroid Build Coastguard Worker    return None
153*35238bceSAndroid Build Coastguard Worker
154*35238bceSAndroid Build Coastguard Workerdef printTimes (inFile, resultCount) :
155*35238bceSAndroid Build Coastguard Worker    #Test section
156*35238bceSAndroid Build Coastguard Worker    parser = BatchResultParser()
157*35238bceSAndroid Build Coastguard Worker    results = parser.parseFile(inFile)
158*35238bceSAndroid Build Coastguard Worker    handler = XMLLogHandlerTests()
159*35238bceSAndroid Build Coastguard Worker    errHandler = LogErrorHandler()
160*35238bceSAndroid Build Coastguard Worker    for result in results :
161*35238bceSAndroid Build Coastguard Worker        xml.sax.parseString(result.log, handler, errHandler)
162*35238bceSAndroid Build Coastguard Worker    handler.bottleneck(resultCount)
163*35238bceSAndroid Build Coastguard Worker
164*35238bceSAndroid Build Coastguard Worker    #Group section
165*35238bceSAndroid Build Coastguard Worker    startRecordLines = False
166*35238bceSAndroid Build Coastguard Worker    lines = ""
167*35238bceSAndroid Build Coastguard Worker    f = open(inFile, 'rb')
168*35238bceSAndroid Build Coastguard Worker    for line in f :
169*35238bceSAndroid Build Coastguard Worker        if "#endTestsCasesTime" in line :
170*35238bceSAndroid Build Coastguard Worker            break
171*35238bceSAndroid Build Coastguard Worker        if startRecordLines :
172*35238bceSAndroid Build Coastguard Worker            lines += line
173*35238bceSAndroid Build Coastguard Worker        if "#beginTestsCasesTime" in line :
174*35238bceSAndroid Build Coastguard Worker            startRecordLines = True
175*35238bceSAndroid Build Coastguard Worker    f.close()
176*35238bceSAndroid Build Coastguard Worker    handlerGroups = XMLLogHandlerGroups(handler.list)
177*35238bceSAndroid Build Coastguard Worker    xml.sax.parseString(lines, handlerGroups, errHandler)
178*35238bceSAndroid Build Coastguard Worker    handlerGroups.bottleneck(resultCount)
179*35238bceSAndroid Build Coastguard Worker
180*35238bceSAndroid Build Coastguard Workerif __name__ == "__main__" :
181*35238bceSAndroid Build Coastguard Worker    if len(sys.argv) != 3:
182*35238bceSAndroid Build Coastguard Worker        print("%s: [test log] [count of result to display]" % sys.argv[0])
183*35238bceSAndroid Build Coastguard Worker        print("example: python %s TestResults.qpa 10" % sys.argv[0])
184*35238bceSAndroid Build Coastguard Worker        sys.exit(-1)
185*35238bceSAndroid Build Coastguard Worker    printTimes(sys.argv[1], sys.argv[2])
186