OLD | NEW |
1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 | 4 |
5 """ | 5 """ |
6 Classes in this file define additional actions that need to be taken to run a | 6 Classes in this file define additional actions that need to be taken to run a |
7 test under some kind of runtime error detection tool. | 7 test under some kind of runtime error detection tool. |
8 | 8 |
9 The interface is intended to be used as follows. | 9 The interface is intended to be used as follows. |
10 | 10 |
11 1. For tests that simply run a native process (i.e. no activity is spawned): | 11 1. For tests that simply run a native process (i.e. no activity is spawned): |
12 | 12 |
13 Call tool.CopyFiles(). | 13 Call tool.CopyFiles(). |
14 Prepend test command line with tool.GetTestWrapper(). | 14 Prepend test command line with tool.GetTestWrapper(). |
15 | 15 |
16 2. For tests that spawn an activity: | 16 2. For tests that spawn an activity: |
17 | 17 |
18 Call tool.CopyFiles(). | 18 Call tool.CopyFiles(). |
19 Call tool.SetupEnvironment(). | 19 Call tool.SetupEnvironment(). |
20 Run the test as usual. | 20 Run the test as usual. |
21 Call tool.CleanUpEnvironment(). | 21 Call tool.CleanUpEnvironment(). |
22 """ | 22 """ |
23 | 23 |
24 import os.path | 24 import os.path |
25 import sys | 25 import sys |
26 | 26 |
27 from run_tests_helper import CHROME_DIR | 27 from constants import CHROME_DIR |
28 | 28 |
29 | 29 |
30 class BaseTool(object): | 30 class BaseTool(object): |
31 """A tool that does nothing.""" | 31 """A tool that does nothing.""" |
32 | 32 |
33 def __init__(self, *args, **kwargs): | 33 def __init__(self, *args, **kwargs): |
34 pass | 34 pass |
35 | 35 |
36 def GetTestWrapper(self): | 36 def GetTestWrapper(self): |
37 """Returns a string that is to be prepended to the test command line.""" | 37 """Returns a string that is to be prepended to the test command line.""" |
38 return '' | 38 return '' |
39 | 39 |
| 40 def GetUtilWrapper(self): |
| 41 """Returns a string that is to be prepended to the command line of utility |
| 42 processes (forwarder, etc.)""" |
| 43 return '' |
| 44 |
40 def CopyFiles(self): | 45 def CopyFiles(self): |
41 """Copies tool-specific files to the device, create directories, etc.""" | 46 """Copies tool-specific files to the device, create directories, etc.""" |
42 pass | 47 pass |
43 | 48 |
44 def SetupEnvironment(self): | 49 def SetupEnvironment(self): |
45 """Sets up the system environment for a test. | 50 """Sets up the system environment for a test. |
46 | 51 |
47 This is a good place to set system properties. | 52 This is a good place to set system properties. |
48 """ | 53 """ |
49 pass | 54 pass |
50 | 55 |
51 def CleanUpEnvironment(self): | 56 def CleanUpEnvironment(self): |
52 """Cleans up environment.""" | 57 """Cleans up environment.""" |
53 pass | 58 pass |
54 | 59 |
55 def GetTimeoutScale(self): | 60 def GetTimeoutScale(self): |
56 """Returns a multiplier that should be applied to timeout values.""" | 61 """Returns a multiplier that should be applied to timeout values.""" |
57 return 1.0 | 62 return 1.0 |
58 | 63 |
59 def NeedsDebugInfo(self): | 64 def NeedsDebugInfo(self): |
60 """Whether this tool requires debug info. | 65 """Whether this tool requires debug info. |
61 | 66 |
62 Returns True if this tool can not work with stripped binaries. | 67 Returns True if this tool can not work with stripped binaries. |
63 """ | 68 """ |
64 return False | 69 return False |
65 | 70 |
66 | 71 |
| 72 class AddressSanitizerTool(BaseTool): |
| 73 """AddressSanitizer tool.""" |
| 74 |
| 75 WRAPPER_PATH = "/system/bin/asanwrapper" |
| 76 |
| 77 def __init__(self, adb): |
| 78 self.adb = adb |
| 79 self.wrap_properties = ['wrap.com.google.android.apps.ch', |
| 80 'wrap.org.chromium.native_test'] |
| 81 |
| 82 def CopyFiles(self): |
| 83 """Copies ASan tools to the device.""" |
| 84 files = ['system/lib/libasan_preload.so', |
| 85 'system/bin/asanwrapper', |
| 86 'system/bin/asan/app_process', |
| 87 'system/bin/linker'] |
| 88 android_product_out = os.environ['ANDROID_PRODUCT_OUT'] |
| 89 self.adb.MakeSystemFolderWritable() |
| 90 for f in files: |
| 91 self.adb.PushIfNeeded(os.path.join(android_product_out, f), |
| 92 os.path.join('/', f)) |
| 93 |
| 94 def GetTestWrapper(self): |
| 95 return AddressSanitizerTool.WRAPPER_PATH |
| 96 |
| 97 def GetUtilWrapper(self): |
| 98 """ AddressSanitizer wrapper must be added to all instrumented binaries, |
| 99 including forwarder and the like. This can be removed if such binaries |
| 100 were built without instrumentation. """ |
| 101 return AddressSanitizerTool.WRAPPER_PATH |
| 102 |
| 103 def SetupEnvironment(self): |
| 104 for prop in self.wrap_properties: |
| 105 self.adb.RunShellCommand('setprop %s "logwrapper %s"' % ( |
| 106 prop, self.GetTestWrapper())) |
| 107 self.adb.RunShellCommand('setprop chrome.timeout_scale %f' % ( |
| 108 self.GetTimeoutScale())) |
| 109 |
| 110 def CleanUpEnvironment(self): |
| 111 for prop in self.wrap_properties: |
| 112 self.adb.RunShellCommand('setprop %s ""' % (prop,)) |
| 113 self.adb.RunShellCommand('setprop chrome.timeout_scale ""') |
| 114 |
| 115 def GetTimeoutScale(self): |
| 116 # Very slow startup. |
| 117 return 20.0 |
| 118 |
| 119 |
67 class ValgrindTool(BaseTool): | 120 class ValgrindTool(BaseTool): |
68 """Base abstract class for Valgrind tools.""" | 121 """Base abstract class for Valgrind tools.""" |
69 | 122 |
70 VG_DIR = '/data/local/tmp/valgrind' | 123 VG_DIR = '/data/local/tmp/valgrind' |
71 VGLOGS_DIR = '/data/local/tmp/vglogs' | 124 VGLOGS_DIR = '/data/local/tmp/vglogs' |
72 | 125 |
73 def __init__(self, adb, renderer=False): | 126 def __init__(self, adb, renderer=False): |
74 self.adb = adb | 127 self.adb = adb |
75 if renderer: | 128 # exactly 31 chars, SystemProperties::PROP_NAME_MAX |
76 # exactly 31 chars, SystemProperties::PROP_NAME_MAX | 129 self.wrap_properties = ['wrap.com.google.android.apps.ch', |
77 self.wrap_property = 'wrap.com.android.chrome:sandbox' | 130 'wrap.org.chromium.native_test'] |
78 else: | |
79 self.wrap_property = 'wrap.com.android.chrome' | |
80 | 131 |
81 def CopyFiles(self): | 132 def CopyFiles(self): |
82 """Copies Valgrind tools to the device.""" | 133 """Copies Valgrind tools to the device.""" |
83 self.adb.RunShellCommand('rm -r %s; mkdir %s' % | 134 self.adb.RunShellCommand('rm -r %s; mkdir %s' % |
84 (ValgrindTool.VG_DIR, ValgrindTool.VG_DIR)) | 135 (ValgrindTool.VG_DIR, ValgrindTool.VG_DIR)) |
85 self.adb.RunShellCommand('rm -r %s; mkdir %s' % | 136 self.adb.RunShellCommand('rm -r %s; mkdir %s' % |
86 (ValgrindTool.VGLOGS_DIR, ValgrindTool.VGLOGS_DIR)) | 137 (ValgrindTool.VGLOGS_DIR, ValgrindTool.VGLOGS_DIR)) |
87 files = self.GetFilesForTool() | 138 files = self.GetFilesForTool() |
88 for f in files: | 139 for f in files: |
89 self.adb.PushIfNeeded(os.path.join(CHROME_DIR, f), | 140 self.adb.PushIfNeeded(os.path.join(CHROME_DIR, f), |
90 os.path.join(ValgrindTool.VG_DIR, | 141 os.path.join(ValgrindTool.VG_DIR, |
91 os.path.basename(f))) | 142 os.path.basename(f))) |
92 | 143 |
93 def SetupEnvironment(self): | 144 def SetupEnvironment(self): |
94 """Sets up device environment.""" | 145 """Sets up device environment.""" |
95 self.adb.RunShellCommand('chmod 777 /data/local/tmp') | 146 self.adb.RunShellCommand('chmod 777 /data/local/tmp') |
96 self.adb.RunShellCommand('setprop %s "logwrapper %s"' % ( | 147 for prop in self.wrap_properties: |
97 self.wrap_property, self.GetTestWrapper())) | 148 self.adb.RunShellCommand('setprop %s "logwrapper %s"' % ( |
| 149 prop, self.GetTestWrapper())) |
98 self.adb.RunShellCommand('setprop chrome.timeout_scale %f' % ( | 150 self.adb.RunShellCommand('setprop chrome.timeout_scale %f' % ( |
99 self.GetTimeoutScale())) | 151 self.GetTimeoutScale())) |
100 | 152 |
101 def CleanUpEnvironment(self): | 153 def CleanUpEnvironment(self): |
102 """Cleans up device environment.""" | 154 """Cleans up device environment.""" |
103 self.adb.RunShellCommand('setprop %s ""' % (self.wrap_property,)) | 155 for prop in self.wrap_properties: |
| 156 self.adb.RunShellCommand('setprop %s ""' % (prop,)) |
104 self.adb.RunShellCommand('setprop chrome.timeout_scale ""') | 157 self.adb.RunShellCommand('setprop chrome.timeout_scale ""') |
105 | 158 |
106 def GetFilesForTool(self): | 159 def GetFilesForTool(self): |
107 """Returns a list of file names for the tool.""" | 160 """Returns a list of file names for the tool.""" |
108 raise NotImplementedError() | 161 raise NotImplementedError() |
109 | 162 |
110 def NeedsDebugInfo(self): | 163 def NeedsDebugInfo(self): |
111 """Whether this tool requires debug info. | 164 """Whether this tool requires debug info. |
112 | 165 |
113 Returns True if this tool can not work with stripped binaries. | 166 Returns True if this tool can not work with stripped binaries. |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
155 | 208 |
156 def GetTimeoutScale(self): | 209 def GetTimeoutScale(self): |
157 """Returns a multiplier that should be applied to timeout values.""" | 210 """Returns a multiplier that should be applied to timeout values.""" |
158 return 30 | 211 return 30 |
159 | 212 |
160 | 213 |
161 TOOL_REGISTRY = { | 214 TOOL_REGISTRY = { |
162 'memcheck': lambda x: MemcheckTool(x, False), | 215 'memcheck': lambda x: MemcheckTool(x, False), |
163 'memcheck-renderer': lambda x: MemcheckTool(x, True), | 216 'memcheck-renderer': lambda x: MemcheckTool(x, True), |
164 'tsan': lambda x: TSanTool(x, False), | 217 'tsan': lambda x: TSanTool(x, False), |
165 'tsan-renderer': lambda x: TSanTool(x, True) | 218 'tsan-renderer': lambda x: TSanTool(x, True), |
| 219 'asan': lambda x: AddressSanitizerTool(x) |
166 } | 220 } |
167 | 221 |
168 | 222 |
169 def CreateTool(tool_name, adb): | 223 def CreateTool(tool_name, adb): |
170 """Creates a tool with the specified tool name. | 224 """Creates a tool with the specified tool name. |
171 | 225 |
172 Args: | 226 Args: |
173 tool_name: Name of the tool to create. | 227 tool_name: Name of the tool to create. |
174 adb: ADB interface the tool will use. | 228 adb: ADB interface the tool will use. |
175 """ | 229 """ |
176 if not tool_name: | 230 if not tool_name: |
177 return BaseTool() | 231 return BaseTool() |
178 | 232 |
179 ctor = TOOL_REGISTRY.get(tool_name) | 233 ctor = TOOL_REGISTRY.get(tool_name) |
180 if ctor: | 234 if ctor: |
181 return ctor(adb) | 235 return ctor(adb) |
182 else: | 236 else: |
183 print 'Unknown tool %s, available tools: %s' % ( | 237 print 'Unknown tool %s, available tools: %s' % ( |
184 tool_name, ', '.join(sorted(TOOL_REGISTRY.keys()))) | 238 tool_name, ', '.join(sorted(TOOL_REGISTRY.keys()))) |
185 sys.exit(1) | 239 sys.exit(1) |
OLD | NEW |