186 строки
5.4 KiB
Python
186 строки
5.4 KiB
Python
# Copyright (c) 2011 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.
|
|
|
|
"""
|
|
Classes in this file define additional actions that need to be taken to run a
|
|
test under some kind of runtime error detection tool.
|
|
|
|
The interface is intended to be used as follows.
|
|
|
|
1. For tests that simply run a native process (i.e. no activity is spawned):
|
|
|
|
Call tool.CopyFiles().
|
|
Prepend test command line with tool.GetTestWrapper().
|
|
|
|
2. For tests that spawn an activity:
|
|
|
|
Call tool.CopyFiles().
|
|
Call tool.SetupEnvironment().
|
|
Run the test as usual.
|
|
Call tool.CleanUpEnvironment().
|
|
"""
|
|
|
|
import os.path
|
|
import sys
|
|
|
|
from run_tests_helper import CHROME_DIR
|
|
|
|
|
|
class BaseTool(object):
|
|
"""A tool that does nothing."""
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
pass
|
|
|
|
def GetTestWrapper(self):
|
|
"""Returns a string that is to be prepended to the test command line."""
|
|
return ''
|
|
|
|
def CopyFiles(self):
|
|
"""Copies tool-specific files to the device, create directories, etc."""
|
|
pass
|
|
|
|
def SetupEnvironment(self):
|
|
"""Sets up the system environment for a test.
|
|
|
|
This is a good place to set system properties.
|
|
"""
|
|
pass
|
|
|
|
def CleanUpEnvironment(self):
|
|
"""Cleans up environment."""
|
|
pass
|
|
|
|
def GetTimeoutScale(self):
|
|
"""Returns a multiplier that should be applied to timeout values."""
|
|
return 1.0
|
|
|
|
def NeedsDebugInfo(self):
|
|
"""Whether this tool requires debug info.
|
|
|
|
Returns True if this tool can not work with stripped binaries.
|
|
"""
|
|
return False
|
|
|
|
|
|
class ValgrindTool(BaseTool):
|
|
"""Base abstract class for Valgrind tools."""
|
|
|
|
VG_DIR = '/data/local/tmp/valgrind'
|
|
VGLOGS_DIR = '/data/local/tmp/vglogs'
|
|
|
|
def __init__(self, adb, renderer=False):
|
|
self.adb = adb
|
|
if renderer:
|
|
# exactly 31 chars, SystemProperties::PROP_NAME_MAX
|
|
self.wrap_property = 'wrap.com.android.chrome:sandbox'
|
|
else:
|
|
self.wrap_property = 'wrap.com.android.chrome'
|
|
|
|
def CopyFiles(self):
|
|
"""Copies Valgrind tools to the device."""
|
|
self.adb.RunShellCommand('rm -r %s; mkdir %s' %
|
|
(ValgrindTool.VG_DIR, ValgrindTool.VG_DIR))
|
|
self.adb.RunShellCommand('rm -r %s; mkdir %s' %
|
|
(ValgrindTool.VGLOGS_DIR, ValgrindTool.VGLOGS_DIR))
|
|
files = self.GetFilesForTool()
|
|
for f in files:
|
|
self.adb.PushIfNeeded(os.path.join(CHROME_DIR, f),
|
|
os.path.join(ValgrindTool.VG_DIR,
|
|
os.path.basename(f)))
|
|
|
|
def SetupEnvironment(self):
|
|
"""Sets up device environment."""
|
|
self.adb.RunShellCommand('chmod 777 /data/local/tmp')
|
|
self.adb.RunShellCommand('setprop %s "logwrapper %s"' % (
|
|
self.wrap_property, self.GetTestWrapper()))
|
|
self.adb.RunShellCommand('setprop chrome.timeout_scale %f' % (
|
|
self.GetTimeoutScale()))
|
|
|
|
def CleanUpEnvironment(self):
|
|
"""Cleans up device environment."""
|
|
self.adb.RunShellCommand('setprop %s ""' % (self.wrap_property,))
|
|
self.adb.RunShellCommand('setprop chrome.timeout_scale ""')
|
|
|
|
def GetFilesForTool(self):
|
|
"""Returns a list of file names for the tool."""
|
|
raise NotImplementedError()
|
|
|
|
def NeedsDebugInfo(self):
|
|
"""Whether this tool requires debug info.
|
|
|
|
Returns True if this tool can not work with stripped binaries.
|
|
"""
|
|
return True
|
|
|
|
|
|
class MemcheckTool(ValgrindTool):
|
|
"""Memcheck tool."""
|
|
|
|
def __init__(self, adb, renderer=False):
|
|
super(MemcheckTool, self).__init__(adb, renderer)
|
|
|
|
def GetFilesForTool(self):
|
|
"""Returns a list of file names for the tool."""
|
|
return ['tools/valgrind/android/vg-chrome-wrapper.sh',
|
|
'tools/valgrind/memcheck/suppressions.txt',
|
|
'tools/valgrind/memcheck/suppressions_android.txt']
|
|
|
|
def GetTestWrapper(self):
|
|
"""Returns a string that is to be prepended to the test command line."""
|
|
return ValgrindTool.VG_DIR + '/' + 'vg-chrome-wrapper.sh'
|
|
|
|
def GetTimeoutScale(self):
|
|
"""Returns a multiplier that should be applied to timeout values."""
|
|
return 30
|
|
|
|
|
|
class TSanTool(ValgrindTool):
|
|
"""ThreadSanitizer tool. See http://code.google.com/p/data-race-test ."""
|
|
|
|
def __init__(self, adb, renderer=False):
|
|
super(TSanTool, self).__init__(adb, renderer)
|
|
|
|
def GetFilesForTool(self):
|
|
"""Returns a list of file names for the tool."""
|
|
return ['tools/valgrind/android/vg-chrome-wrapper-tsan.sh',
|
|
'tools/valgrind/tsan/suppressions.txt',
|
|
'tools/valgrind/tsan/suppressions_android.txt',
|
|
'tools/valgrind/tsan/ignores.txt']
|
|
|
|
def GetTestWrapper(self):
|
|
"""Returns a string that is to be prepended to the test command line."""
|
|
return ValgrindTool.VG_DIR + '/' + 'vg-chrome-wrapper-tsan.sh'
|
|
|
|
def GetTimeoutScale(self):
|
|
"""Returns a multiplier that should be applied to timeout values."""
|
|
return 30
|
|
|
|
|
|
TOOL_REGISTRY = {
|
|
'memcheck': lambda x: MemcheckTool(x, False),
|
|
'memcheck-renderer': lambda x: MemcheckTool(x, True),
|
|
'tsan': lambda x: TSanTool(x, False),
|
|
'tsan-renderer': lambda x: TSanTool(x, True)
|
|
}
|
|
|
|
|
|
def CreateTool(tool_name, adb):
|
|
"""Creates a tool with the specified tool name.
|
|
|
|
Args:
|
|
tool_name: Name of the tool to create.
|
|
adb: ADB interface the tool will use.
|
|
"""
|
|
if not tool_name:
|
|
return BaseTool()
|
|
|
|
ctor = TOOL_REGISTRY.get(tool_name)
|
|
if ctor:
|
|
return ctor(adb)
|
|
else:
|
|
print 'Unknown tool %s, available tools: %s' % (
|
|
tool_name, ', '.join(sorted(TOOL_REGISTRY.keys())))
|
|
sys.exit(1)
|