Index: build/android/valgrind_tools.py |
diff --git a/build/android/valgrind_tools.py b/build/android/valgrind_tools.py |
new file mode 100644 |
index 0000000000000000000000000000000000000000..bd008ddd90abfecd40a6e4c4fbe217b5c7da8cba |
--- /dev/null |
+++ b/build/android/valgrind_tools.py |
@@ -0,0 +1,186 @@ |
+#!/usr/bin/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) |