blob: ee1b89066c3739f225950479c4a44aed62a917a0 [file] [log] [blame]
# Copyright 2021 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Routines for reading performance results from a directory.
The directory should match the format created by the 'bootperf'
script; see comments in that script for a summary of the layout.
"""
import fnmatch
import json
import os
import re
import resultset
_PERF_KEYVAL_PATTERN = re.compile('(.*){perf}=(.*)\n')
def _ReadResultsJSONFile(results, file_):
"""Read a tast results-chart.json file and process the results.
The `file_` parameter is a file object with contents in tast
perf results-chart.json format:
{ <keyname>: { "summary": { "values": [<values (a list)>] } } }
Each iteration's results are appended to the `results` parameter,
which should be an instance of TestResultSet.
Args:
results: A TestResultSet where the result data will be
collected.
file_: File object for the results file to be read.
"""
# kvd: a dict of key => value dictionary.
# Example: {'seconds_chrome_exec_to_login':'1.75', ...}.
# Key and value are both string.
# kvd_list is a list of kvd.
kvd_list = []
# Sample results-chart.json data:
# {
# "seconds_kernel_to_startup": {
# "summary": {
# "units": "seconds",
# "improvement_direction": "down",
# "type": "list_of_scalar_values",
# "values": [
# 1.4,
# 1.41
# ]
# }
# },
# }
result_chart_json = json.load(file_)
for key, res in result_chart_json.items():
values = res['summary']['values']
for i, val in enumerate(values):
if i >= len(kvd_list):
kvd_list.append({})
kvd_list[i][key] = val
for kvd in kvd_list:
results.AddIterationResults(kvd)
_RESULTS_CHART = 'summary/tests/platform.BootPerf/results-chart.json'
def _ReadKeyvalFile(results, file_):
"""Read an autotest keyval file, and process the results.
The `file_` parameter is a file object with contents in autotest
perf keyval format:
<keyname>{perf}=<value>
Each iteration of the test is terminated with a single blank line,
including the last iteration. Each iteration's results are added
to the `results` parameter, which should be an instance of
TestResultSet.
Args:
results: A TestResultSet where the result data will be collected.
file_: File object for the results file to be read.
"""
kvd = {}
for line in file_:
if line == '\n':
results.AddIterationResults(kvd)
kvd = {}
continue
m = _PERF_KEYVAL_PATTERN.match(line)
if m is None:
continue
kvd[m.group(1)] = m.group(2)
_RESULTS_KEYVAL = 'summary/platform_BootPerfServer/results/keyval'
def ReadResultsDirectory(dir_):
"""Process results from a 'bootperf' output directory.
The accumulated results are returned in a newly created
TestResultSet object.
Args:
dir_: The directory containing the test results keyval file.
Returns:
The TestResultSet object.
"""
res_set = resultset.TestResultSet(dir_)
dirlist = fnmatch.filter(os.listdir(dir_), 'run.???')
dirlist.sort()
for rundir in dirlist:
keyval_path = os.path.join(dir_, rundir, _RESULTS_CHART)
# Test if the run.??? dir contains a tast result-chart.json file.
if os.path.exists(keyval_path):
reader = _ReadResultsJSONFile
else:
# The directory is generated using autotest.
keyval_path = os.path.join(dir_, rundir, _RESULTS_KEYVAL)
reader = _ReadKeyvalFile
try:
kvf = open(keyval_path)
except IOError as e:
print('Warning: error in reading the test result: ', e)
continue
reader(res_set, kvf)
res_set.FinalizeResults()
return res_set