Commit 6afccea4 authored by Mikhail Khokhlov's avatar Mikhail Khokhlov Committed by Commit Bot

[tools/perf] Implement csv_output result formatter

Bug: 981349
Change-Id: I8faa2aa790327a838978d3f002ad706db70e9d18
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1829337
Commit-Queue: Mikhail Khokhlov <khokhlov@google.com>
Reviewed-by: default avatarJuan Antonio Navarro Pérez <perezju@chromium.org>
Cr-Commit-Position: refs/heads/master@{#701167}
parent 3a413f06
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
# Use of this source code is governed by a BSD-style license that can be # Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file. # found in the LICENSE file.
from core.results_processor.formatters import csv_output
from core.results_processor.formatters import histograms_output from core.results_processor.formatters import histograms_output
from core.results_processor.formatters import html_output from core.results_processor.formatters import html_output
from core.results_processor.formatters import json3_output from core.results_processor.formatters import json3_output
...@@ -11,4 +12,5 @@ FORMATTERS = { ...@@ -11,4 +12,5 @@ FORMATTERS = {
'json-test-results': json3_output, 'json-test-results': json3_output,
'histograms': histograms_output, 'histograms': histograms_output,
'html': html_output, 'html': html_output,
'csv': csv_output,
} }
# Copyright 2019 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Output formatter for CSV format."""
import collections
import csv
import json
import os
from core.results_processor.formatters import histograms_output
from py_utils import tempfile_ext
from tracing.value import histograms_to_csv
OUTPUT_FILENAME = 'results.csv'
def _ReadCsv(input_stream):
dicts = []
header = None
for row in csv.reader(input_stream):
if header is None:
header = row
elif row:
dicts.append(collections.OrderedDict(zip(header, row)))
return dicts
def _WriteCsv(dicts, output_stream):
header = []
for d in dicts:
for k in d.iterkeys():
if k not in header:
header.append(k)
rows = [header]
for d in dicts:
rows.append([d.get(k, '') for k in header])
csv.writer(output_stream).writerows(rows)
def Process(intermediate_results, options):
"""Process intermediate results and write output in output_dir."""
histogram_dicts = histograms_output.Convert(intermediate_results,
options.results_label)
with tempfile_ext.NamedTemporaryFile() as hist_file:
json.dump(histogram_dicts, hist_file)
hist_file.close()
vinn_result = histograms_to_csv.HistogramsToCsv(hist_file.name)
csv_dicts = _ReadCsv(vinn_result.stdout.splitlines())
output_file = os.path.join(options.output_dir, OUTPUT_FILENAME)
if not options.reset_results and os.path.isfile(output_file):
with open(output_file) as input_stream:
csv_dicts += _ReadCsv(input_stream)
with open(output_file, 'w') as output_stream:
_WriteCsv(csv_dicts, output_stream)
...@@ -9,12 +9,14 @@ standalone results processor on them to check that output files are produced ...@@ -9,12 +9,14 @@ standalone results processor on them to check that output files are produced
with their expected contents. with their expected contents.
""" """
import csv
import json import json
import os import os
import shutil import shutil
import tempfile import tempfile
import unittest import unittest
from core.results_processor.formatters import csv_output
from core.results_processor.formatters import json3_output from core.results_processor.formatters import json3_output
from core.results_processor.formatters import histograms_output from core.results_processor.formatters import histograms_output
from core.results_processor.formatters import html_output from core.results_processor.formatters import html_output
...@@ -328,3 +330,121 @@ class ResultsProcessorIntegrationTests(unittest.TestCase): ...@@ -328,3 +330,121 @@ class ResultsProcessorIntegrationTests(unittest.TestCase):
diag_values = [list(v) for v in out_histograms.shared_diagnostics] diag_values = [list(v) for v in out_histograms.shared_diagnostics]
self.assertIn(['label1'], diag_values) self.assertIn(['label1'], diag_values)
self.assertIn(['label2'], diag_values) self.assertIn(['label2'], diag_values)
def testCsvOutput(self):
hist_file = os.path.join(self.output_dir,
histograms_output.HISTOGRAM_DICTS_NAME)
test_hist = histogram.Histogram('a', 'ms')
test_hist.AddSample(3000)
with open(hist_file, 'w') as f:
json.dump([test_hist.AsDict()], f)
self.SerializeIntermediateResults(
test_results=[
testing.TestResult(
'benchmark/story',
artifacts={'histogram_dicts.json': testing.Artifact(hist_file)},
),
],
diagnostics={
'benchmarks': ['benchmark'],
'osNames': ['linux'],
'documentationUrls': [['documentation', 'url']],
},
)
processor.main([
'--output-format', 'csv',
'--output-dir', self.output_dir,
'--intermediate-dir', self.intermediate_dir,
'--results-label', 'label',
])
with open(os.path.join(self.output_dir, csv_output.OUTPUT_FILENAME)) as f:
lines = [line for line in f]
actual = list(zip(*csv.reader(lines)))
expected = [
('name', 'a'), ('unit', 'ms'), ('avg', '3000'), ('count', '1'),
('max', '3000'), ('min', '3000'), ('std', '0'), ('sum', '3000'),
('architectures', ''), ('benchmarks', 'benchmark'),
('benchmarkStart', ''), ('bots', ''),
('builds', ''), ('deviceIds', ''), ('displayLabel', 'label'),
('masters', ''), ('memoryAmounts', ''), ('osNames', 'linux'),
('osVersions', ''), ('productVersions', ''),
('stories', ''), ('storysetRepeats', ''),
('traceStart', ''), ('traceUrls', '')
]
self.assertEqual(actual, expected)
def testCsvOutputResetResults(self):
hist_file = os.path.join(self.output_dir,
histograms_output.HISTOGRAM_DICTS_NAME)
with open(hist_file, 'w') as f:
json.dump([histogram.Histogram('a', 'unitless').AsDict()], f)
self.SerializeIntermediateResults(
test_results=[
testing.TestResult(
'benchmark/story',
artifacts={'histogram_dicts.json': testing.Artifact(hist_file)},
),
],
)
processor.main([
'--output-format', 'csv',
'--output-dir', self.output_dir,
'--intermediate-dir', self.intermediate_dir,
'--results-label', 'label1',
])
processor.main([
'--output-format', 'csv',
'--output-dir', self.output_dir,
'--intermediate-dir', self.intermediate_dir,
'--results-label', 'label2',
'--reset-results',
])
with open(os.path.join(self.output_dir, csv_output.OUTPUT_FILENAME)) as f:
lines = [line for line in f]
self.assertEqual(len(lines), 2)
self.assertIn('label2', lines[1])
def testCsvOutputAppendResults(self):
hist_file = os.path.join(self.output_dir,
histograms_output.HISTOGRAM_DICTS_NAME)
with open(hist_file, 'w') as f:
json.dump([histogram.Histogram('a', 'unitless').AsDict()], f)
self.SerializeIntermediateResults(
test_results=[
testing.TestResult(
'benchmark/story',
artifacts={'histogram_dicts.json': testing.Artifact(hist_file)},
),
],
)
processor.main([
'--output-format', 'csv',
'--output-dir', self.output_dir,
'--intermediate-dir', self.intermediate_dir,
'--results-label', 'label1',
])
processor.main([
'--output-format', 'csv',
'--output-dir', self.output_dir,
'--intermediate-dir', self.intermediate_dir,
'--results-label', 'label2',
])
with open(os.path.join(self.output_dir, csv_output.OUTPUT_FILENAME)) as f:
lines = [line for line in f]
self.assertEqual(len(lines), 3)
self.assertIn('label2', lines[1])
self.assertIn('label1', lines[2])
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment