blob: 0e6d694a8526ce0c7be31e0a6299556907290fb9 [file] [log] [blame]
# Copyright (c) 2015 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.
import json
import os
import re
import sys
import tempfile
import traceback
from perf_insights import value as value_module
import perf_insights_project
import vinn
class TemporaryMapScript(object):
def __init__(self, js):
self.file = tempfile.NamedTemporaryFile()
self.file.write("""
<!DOCTYPE html>
<link rel="import" href="/perf_insights/value/value.html">
<script>
%s
</script>
""" % js)
self.file.flush()
self.file.seek(0)
def __enter__(self):
return self
def __exit__(self, *args, **kwargs):
self.file.close()
@property
def filename(self):
return self.file.name
class MapFunctionLoadingErrorValue(value_module.FailureValue):
pass
class MapFunctionNotDefinedErrorValue(value_module.FailureValue):
pass
class MapFunctionErrorValue(value_module.FailureValue):
pass
class TraceImportErrorValue(value_module.FailureValue):
pass
class NoResultsAddedErrorValue(value_module.FailureValue):
pass
class InternalMapError(Exception):
pass
_FAILURE_NAME_TO_FAILURE_CONSTRUCTOR = {
'MapFunctionLoadingError': MapFunctionLoadingErrorValue,
'MapFunctionNotDefinedError': MapFunctionNotDefinedErrorValue,
'TraceImportError': TraceImportErrorValue,
'MapFunctionError': MapFunctionErrorValue,
'NoResultsAddedError': NoResultsAddedErrorValue
}
def MapSingleTrace(results, trace_handle, map_file):
# Catch all exceptions and return a failure so map_runner doesn't hang.
try:
MapSingleTraceImpl(results, trace_handle, map_file)
except Exception:
results.AddValue(value_module.FailureValue(
trace_handle.run_info,
'Error', 'Unexpected exception.', traceback.format_exc()))
def MapSingleTraceImpl(results, trace_handle, map_file):
project = perf_insights_project.PerfInsightsProject()
all_source_paths = list(project.source_paths)
pi_path = os.path.abspath(os.path.join(os.path.dirname(__file__),
'..'))
all_source_paths.append(pi_path)
run_info = trace_handle.run_info
with trace_handle.Open() as trace_file:
js_args = [
json.dumps(run_info.AsDict()),
os.path.abspath(map_file),
os.path.abspath(trace_file.name),
json.dumps(run_info.metadata)
]
res = vinn.RunFile(
os.path.join(pi_path, 'perf_insights', 'map_single_trace_cmdline.html'),
source_paths=all_source_paths,
js_args=js_args)
if res.returncode != 0:
sys.stderr.write(res.stdout)
results.AddValue(value_module.FailureValue(
run_info,
'Error', 'vinn runtime error while mapping trace.',
'vinn runtime error while mapping trace.', 'Unknown stack'))
return
found_at_least_one_result=False
for line in res.stdout.split('\n'):
m = re.match('^MAP_RESULT_VALUE: (.+)', line, re.DOTALL)
if m:
found_dict = json.loads(m.group(1))
if found_dict['type'] == 'failure':
cls = _FAILURE_NAME_TO_FAILURE_CONSTRUCTOR.get(found_dict['name'], None)
if not cls:
cls = value_module.FailureValue
else:
cls = value_module.Value
found_value = cls.FromDict(run_info, found_dict)
results.AddValue(found_value)
found_at_least_one_result = True
else:
sys.stderr.write(line)
sys.stderr.write('\n')
if found_at_least_one_result == False:
raise InternalMapError('Internal error: No results were produced!')