218 lines
8.2 KiB
Python
Executable file
218 lines
8.2 KiB
Python
Executable file
#!/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[6]
|
|
if len(tokens) == 8 and tokens[7] in ["PASS", "FAIL", "SKIP", "ERROR"]:
|
|
return True, test_module_name, test_case_name, "end", timestamp
|
|
elif len(tokens) == 7:
|
|
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])
|