lin
2025-08-20 171e08343a9b6df6c31197f5b4800e8004800f5b
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
#!/usr/bin/python
 
import copy
import datetime
import logging
import os
import pprint
import sys
import time
 
THIS_YEAR = datetime.datetime.now().year
 
 
def AnalyzeJavaLog(line):
    """Analyzes a log line printed by VTS Java harness.
 
    Args:
        line: string for a log line.
 
    Returns:
        boolean (True if it's a Java log line, False otherwise)
        string (module type)
        string (phase name)
        float (timestamp)
    """
    tokens = line.split()
    timestamp = 0
    if len(tokens) < 4:
        return False, None, None, 0
    # Example
    # 05-12 07:51:45 I/VtsMultiDeviceTest:
    date_time_str = "%s-%s %s" % (THIS_YEAR, tokens[0], tokens[1])
    try:
        timestamp = time.mktime(datetime.datetime.strptime(
            date_time_str, "%Y-%m-%d %H:%M:%S").timetuple())
    except ValueError as e:
        timestamp = -1
 
    if (len(tokens[2]) > 2 and tokens[2] == "D/ModuleDef:" and
            tokens[3][-1] == ":"):
        return True, tokens[3][:-1], tokens[4], timestamp
    return False, None, None, timestamp
 
 
def AnalyzePythonLog(line):
    """Analyzes a log line printed by VTS Python runner.
 
    Args:
        line: string for a log line.
 
    Returns:
        boolean (True if it's a Python log line, False otherwise)
        string (test module name)
        string (test case name)
        string ('begin' or 'end')
        float (timestamp)
    """
    tokens = line.split()
    timestamp = 0
    test_module_name = None
    if len(tokens) < 7:
        return False, test_module_name, None, None, timestamp
    # Example
    # [VtsKernelSelinuxFileApi] 05-12 07:51:32.916 INFO ...
    if len(tokens[0]) > 2 and tokens[0][0] == "[" and tokens[0][-1] == "]":
        test_module_name = tokens[0][1:-1]
 
        date_time_str = "%s-%s %s" % (THIS_YEAR, tokens[1], tokens[2])
        try:
            timestamp = time.mktime(datetime.datetime.strptime(
                date_time_str, "%Y-%m-%d %H:%M:%S.%f").timetuple())
        except ValueError as e:
            timestamp = -1
        if tokens[4] == "[Test" and tokens[5] == "Case]":
            test_case_name = tokens[7]
            if len(tokens) == 9 and tokens[8] in ["PASS", "FAIL", "SKIP", "ERROR"]:
                return True, test_module_name, test_case_name, "end", timestamp
            elif len(tokens) == 8:
                return True, test_module_name, test_case_name, "begin", timestamp
            else:
                assert False, "Error at '%s'" % line
        return True, test_module_name, None, None, timestamp
    return False, test_module_name, None, None, timestamp
 
# Java harness's execution stats.
java_exec_stats = {}
# Python runner's execution stats.
python_exec_stats = {}
flag_show_samples = False
 
 
def ProcessEvent(module_type, module_name, timestamp):
    """Processes a given Java log event."""
    if module_type in java_exec_stats:
        java_exec_stats[module_type]["sum"] += timestamp
        java_exec_stats[module_type]["count"] += 1
        if module_name in java_exec_stats[module_type]:
            java_exec_stats[module_type][module_name]["sum"] += timestamp
            java_exec_stats[module_type][module_name]["count"] += 1
            if flag_show_samples:
                java_exec_stats[module_type][module_name]["samples"].append(
                    timestamp)
        else:
            java_exec_stats[module_type][module_name] = {}
            java_exec_stats[module_type][module_name]["sum"] = timestamp
            java_exec_stats[module_type][module_name]["count"] = 1
            if flag_show_samples:
                java_exec_stats[module_type][module_name]["samples"] = [
                    timestamp
                ]
    else:
        java_exec_stats[module_type] = {}
        java_exec_stats[module_type]["sum"] = timestamp
        java_exec_stats[module_type]["count"] = 1
 
 
def FilterDict(input_dict, threashold):
    """Filters items in input_dict whose values are greater than threshold."""
    result_dict = {}
    org_dict = copy.copy(input_dict)
    for key, value in input_dict.iteritems():
        if value["value"] > threashold and value["state"] == "end":
            result_dict[key] = value["value"]
            del org_dict[key]
    return org_dict, result_dict
 
 
def main(log_file_path):
    """Analyzes the phases of an execution caught in the log.
 
    Args:
        log_file_path: string, log file path.
    """
    print "Log File:", log_file_path
 
    prev_java_module_type = None
    prev_java_module_name = None
    prev_timestamp = 0
    last_timestamp = 0
    python_exec_stats = {}
 
    with open(log_file_path, "r") as log_file:
        for line in log_file:
            (is_java_log, java_module_type, java_module_name,
             timestamp) = AnalyzeJavaLog(line)
            if is_java_log:
                last_timestamp = timestamp
                if prev_java_module_type:
                    ProcessEvent(prev_java_module_type, prev_java_module_name,
                                 timestamp - prev_timestamp)
                prev_java_module_type = java_module_type
                prev_java_module_name = java_module_name
                prev_timestamp = timestamp
            else:
                (is_python_log, test_module_name, test_case_name, event_type,
                 timestamp) = AnalyzePythonLog(line)
                if is_python_log:
                    last_timestamp = timestamp
                    if test_case_name:
                        if event_type == "begin":
                            if test_case_name not in python_exec_stats:
                                python_exec_stats[test_case_name] = {}
                                python_exec_stats[test_case_name][
                                    "value"] = timestamp
                                python_exec_stats[test_case_name][
                                    "state"] = "begin"
                            else:
                                for count in range(1, 1000):
                                    new_test_case_name = "%s_%s" % (
                                        test_case_name, str(count))
                                    if new_test_case_name not in python_exec_stats:
                                        python_exec_stats[
                                            new_test_case_name] = {}
                                        python_exec_stats[new_test_case_name][
                                            "value"] = timestamp
                                        python_exec_stats[new_test_case_name][
                                            "state"] = "begin"
                                        break
                                python_exec_stats[test_case_name] = {}
                                python_exec_stats[test_case_name][
                                    "value"] = timestamp
                                python_exec_stats[test_case_name][
                                    "state"] = "begin"
                        elif event_type == "end":
                            assert python_exec_stats[test_case_name][
                                "state"] == "begin"
                            python_exec_stats[test_case_name]["state"] = "end"
                            python_exec_stats[test_case_name]["value"] = (
                                timestamp -
                                python_exec_stats[test_case_name]["value"])
                            assert python_exec_stats[test_case_name] >= 0, (
                                "%s >= 0 ?" %
                                python_exec_stats[test_case_name])
 
    if prev_java_module_type:
        ProcessEvent(prev_java_module_type, prev_java_module_name,
                     last_timestamp - prev_timestamp)
 
    for threshold in [600, 300, 180, 120, 60, 30]:
        python_exec_stats, filtered_dict = FilterDict(python_exec_stats,
                                                      threshold)
        print "Python test cases took >%s seconds:" % threshold
        print filtered_dict.keys()
    print "Total Execution Time Breakdown:"
    pprint.pprint(java_exec_stats, width=1)
 
 
def usage():
    """Prints usage and exits."""
    print "Script to analyze the total execution of a VTS run."
    print "Usage: <this script> <VTS host log file path>"
    exit(-1)
 
 
if __name__ == "__main__":
    if len(sys.argv) != 2:
        usage()
    main(sys.argv[1])