blob: bc917e62546e92739b7e484b667b860a925e2346 [file] [log] [blame]
# 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)