Adds trace events from tests run in Java on the device to trace output file.

Creates new TestTraceEvent.java class, with some of the functionality of the old (unused) PerfTraceEvent.

This is used within the JUnit4 test runner to track tests, and added by the Python test runner code to its trace output.

Bug: 
Change-Id: Ie0b6c180a4c7f77a13e1bd08a4e641cc1a3db3ef
Reviewed-on: https://chromium-review.googlesource.com/578707
Reviewed-by: Michael Case <mikecase@chromium.org>
Reviewed-by: Tommy Nyquist <nyquist@chromium.org>
Commit-Queue: Nick Ward <npward@google.com>
Cr-Original-Commit-Position: refs/heads/master@{#493465}
Cr-Mirrored-From: https://chromium.googlesource.com/chromium/src
Cr-Mirrored-Commit: 85689988f176cc19c6274416b9fe45b284397ba1
This commit is contained in:
Nick Ward 2017-08-10 18:16:48 +00:00 коммит произвёл Commit Bot
Родитель fbfaa84241
Коммит c8576db966
1 изменённых файлов: 71 добавлений и 0 удалений

Просмотреть файл

@ -3,6 +3,7 @@
# found in the LICENSE file.
import contextlib
import hashlib
import json
import logging
import os
@ -30,6 +31,7 @@ from pylib.utils import instrumentation_tracing
from pylib.utils import logdog_helper
from pylib.utils import shared_preference_utils
from py_trace_event import trace_event
from py_trace_event import trace_time
from py_utils import contextlib_ext
from py_utils import tempfile_ext
import tombstones
@ -65,6 +67,8 @@ EXTRA_SCREENSHOT_FILE = (
EXTRA_UI_CAPTURE_DIR = (
'org.chromium.base.test.util.Screenshooter.ScreenshotDir')
EXTRA_TRACE_FILE = ('org.chromium.base.test.BaseJUnit4ClassRunner.TraceFile')
_EXTRA_TEST_LIST = (
'org.chromium.base.test.BaseChromiumAndroidJUnitRunner.TestList')
@ -353,6 +357,11 @@ class LocalDeviceInstrumentationTestRun(
extras[EXTRA_UI_CAPTURE_DIR] = self._ui_capture_dir[device]
if self._env.trace_output:
trace_device_file = device_temp_file.DeviceTempFile(
device.adb, suffix='.json', dir=device.GetExternalStoragePath())
extras[EXTRA_TRACE_FILE] = trace_device_file.name
if isinstance(test, list):
if not self._test_instance.driver_apk:
raise Exception('driver_apk does not exist. '
@ -436,6 +445,9 @@ class LocalDeviceInstrumentationTestRun(
logcat_url = logmon.GetLogcatURL()
duration_ms = time_ms() - start_ms
if self._env.trace_output:
self._SaveTraceData(trace_device_file, device, test['class'])
# TODO(jbudorick): Make instrumentation tests output a JSON so this
# doesn't have to parse the output.
result_code, result_bundle, statuses = (
@ -607,6 +619,65 @@ class LocalDeviceInstrumentationTestRun(
pickle_path, test_apk_path, raw_tests)
return raw_tests
def _SaveTraceData(self, trace_device_file, device, test_class):
trace_host_file = self._env.trace_output
if device.FileExists(trace_device_file.name):
try:
java_trace_json = device.ReadFile(trace_device_file.name)
except IOError:
raise Exception('error pulling trace file from device')
finally:
trace_device_file.close()
process_name = '%s (device %s)' % (test_class, device.serial)
process_hash = int(hashlib.md5(process_name).hexdigest()[:6], 16)
java_trace = json.loads(java_trace_json)
java_trace.sort(key=lambda event: event['ts'])
get_date_command = 'echo $EPOCHREALTIME'
device_time = device.RunShellCommand(get_date_command, single_line=True)
device_time = float(device_time) * 1e6
system_time = trace_time.Now()
time_difference = system_time - device_time
threads_to_add = set()
for event in java_trace:
# Ensure thread ID and thread name will be linked in the metadata.
threads_to_add.add((event['tid'], event['name']))
event['pid'] = process_hash
# Adjust time stamp to align with Python trace times (from
# trace_time.Now()).
event['ts'] += time_difference
for tid, thread_name in threads_to_add:
thread_name_metadata = {'pid': process_hash, 'tid': tid,
'ts': 0, 'ph': 'M', 'cat': '__metadata',
'name': 'thread_name',
'args': {'name': thread_name}}
java_trace.append(thread_name_metadata)
process_name_metadata = {'pid': process_hash, 'tid': 0, 'ts': 0,
'ph': 'M', 'cat': '__metadata',
'name': 'process_name',
'args': {'name': process_name}}
java_trace.append(process_name_metadata)
java_trace_json = json.dumps(java_trace)
java_trace_json = java_trace_json.rstrip(' ]')
with open(trace_host_file, 'r') as host_handle:
host_contents = host_handle.readline()
if host_contents:
java_trace_json = ',%s' % java_trace_json.lstrip(' [')
with open(trace_host_file, 'a') as host_handle:
host_handle.write(java_trace_json)
def _SaveScreenshot(self, device, screenshot_host_dir, screenshot_device_file,
test_name, results):
if screenshot_host_dir: