OLD | NEW |
| (Empty) |
1 # Copyright (c) 2011 The Chromium Authors. All rights reserved. | |
2 # Use of this source code is governed by a BSD-style license that can be | |
3 # found in the LICENSE file. | |
4 | |
5 """ | |
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. | |
8 | |
9 The interface is intended to be used as follows. | |
10 | |
11 1. For tests that simply run a native process (i.e. no activity is spawned): | |
12 | |
13 Call tool.CopyFiles(). | |
14 Prepend test command line with tool.GetTestWrapper(). | |
15 | |
16 2. For tests that spawn an activity: | |
17 | |
18 Call tool.CopyFiles(). | |
19 Call tool.SetupEnvironment(). | |
20 Run the test as usual. | |
21 Call tool.CleanUpEnvironment(). | |
22 """ | |
23 | |
24 import os.path | |
25 import sys | |
26 | |
27 from run_tests_helper import CHROME_DIR | |
28 | |
29 | |
30 class BaseTool(object): | |
31 """A tool that does nothing.""" | |
32 | |
33 def __init__(self, *args, **kwargs): | |
34 pass | |
35 | |
36 def GetTestWrapper(self): | |
37 """Returns a string that is to be prepended to the test command line.""" | |
38 return '' | |
39 | |
40 def CopyFiles(self): | |
41 """Copies tool-specific files to the device, create directories, etc.""" | |
42 pass | |
43 | |
44 def SetupEnvironment(self): | |
45 """Sets up the system environment for a test. | |
46 | |
47 This is a good place to set system properties. | |
48 """ | |
49 pass | |
50 | |
51 def CleanUpEnvironment(self): | |
52 """Cleans up environment.""" | |
53 pass | |
54 | |
55 def GetTimeoutScale(self): | |
56 """Returns a multiplier that should be applied to timeout values.""" | |
57 return 1.0 | |
58 | |
59 def NeedsDebugInfo(self): | |
60 """Whether this tool requires debug info. | |
61 | |
62 Returns True if this tool can not work with stripped binaries. | |
63 """ | |
64 return False | |
65 | |
66 | |
67 class ValgrindTool(BaseTool): | |
68 """Base abstract class for Valgrind tools.""" | |
69 | |
70 VG_DIR = '/data/local/tmp/valgrind' | |
71 VGLOGS_DIR = '/data/local/tmp/vglogs' | |
72 | |
73 def __init__(self, adb, renderer=False): | |
74 self.adb = adb | |
75 if renderer: | |
76 # exactly 31 chars, SystemProperties::PROP_NAME_MAX | |
77 self.wrap_property = 'wrap.com.android.chrome:sandbox' | |
78 else: | |
79 self.wrap_property = 'wrap.com.android.chrome' | |
80 | |
81 def CopyFiles(self): | |
82 """Copies Valgrind tools to the device.""" | |
83 self.adb.RunShellCommand('rm -r %s; mkdir %s' % | |
84 (ValgrindTool.VG_DIR, ValgrindTool.VG_DIR)) | |
85 self.adb.RunShellCommand('rm -r %s; mkdir %s' % | |
86 (ValgrindTool.VGLOGS_DIR, ValgrindTool.VGLOGS_DIR)) | |
87 files = self.GetFilesForTool() | |
88 for f in files: | |
89 self.adb.PushIfNeeded(os.path.join(CHROME_DIR, f), | |
90 os.path.join(ValgrindTool.VG_DIR, | |
91 os.path.basename(f))) | |
92 | |
93 def SetupEnvironment(self): | |
94 """Sets up device environment.""" | |
95 self.adb.RunShellCommand('chmod 777 /data/local/tmp') | |
96 self.adb.RunShellCommand('setprop %s "logwrapper %s"' % ( | |
97 self.wrap_property, self.GetTestWrapper())) | |
98 self.adb.RunShellCommand('setprop chrome.timeout_scale %f' % ( | |
99 self.GetTimeoutScale())) | |
100 | |
101 def CleanUpEnvironment(self): | |
102 """Cleans up device environment.""" | |
103 self.adb.RunShellCommand('setprop %s ""' % (self.wrap_property,)) | |
104 self.adb.RunShellCommand('setprop chrome.timeout_scale ""') | |
105 | |
106 def GetFilesForTool(self): | |
107 """Returns a list of file names for the tool.""" | |
108 raise NotImplementedError() | |
109 | |
110 def NeedsDebugInfo(self): | |
111 """Whether this tool requires debug info. | |
112 | |
113 Returns True if this tool can not work with stripped binaries. | |
114 """ | |
115 return True | |
116 | |
117 | |
118 class MemcheckTool(ValgrindTool): | |
119 """Memcheck tool.""" | |
120 | |
121 def __init__(self, adb, renderer=False): | |
122 super(MemcheckTool, self).__init__(adb, renderer) | |
123 | |
124 def GetFilesForTool(self): | |
125 """Returns a list of file names for the tool.""" | |
126 return ['tools/valgrind/android/vg-chrome-wrapper.sh', | |
127 'tools/valgrind/memcheck/suppressions.txt', | |
128 'tools/valgrind/memcheck/suppressions_android.txt'] | |
129 | |
130 def GetTestWrapper(self): | |
131 """Returns a string that is to be prepended to the test command line.""" | |
132 return ValgrindTool.VG_DIR + '/' + 'vg-chrome-wrapper.sh' | |
133 | |
134 def GetTimeoutScale(self): | |
135 """Returns a multiplier that should be applied to timeout values.""" | |
136 return 30 | |
137 | |
138 | |
139 class TSanTool(ValgrindTool): | |
140 """ThreadSanitizer tool. See http://code.google.com/p/data-race-test .""" | |
141 | |
142 def __init__(self, adb, renderer=False): | |
143 super(TSanTool, self).__init__(adb, renderer) | |
144 | |
145 def GetFilesForTool(self): | |
146 """Returns a list of file names for the tool.""" | |
147 return ['tools/valgrind/android/vg-chrome-wrapper-tsan.sh', | |
148 'tools/valgrind/tsan/suppressions.txt', | |
149 'tools/valgrind/tsan/suppressions_android.txt', | |
150 'tools/valgrind/tsan/ignores.txt'] | |
151 | |
152 def GetTestWrapper(self): | |
153 """Returns a string that is to be prepended to the test command line.""" | |
154 return ValgrindTool.VG_DIR + '/' + 'vg-chrome-wrapper-tsan.sh' | |
155 | |
156 def GetTimeoutScale(self): | |
157 """Returns a multiplier that should be applied to timeout values.""" | |
158 return 30 | |
159 | |
160 | |
161 TOOL_REGISTRY = { | |
162 'memcheck': lambda x: MemcheckTool(x, False), | |
163 'memcheck-renderer': lambda x: MemcheckTool(x, True), | |
164 'tsan': lambda x: TSanTool(x, False), | |
165 'tsan-renderer': lambda x: TSanTool(x, True) | |
166 } | |
167 | |
168 | |
169 def CreateTool(tool_name, adb): | |
170 """Creates a tool with the specified tool name. | |
171 | |
172 Args: | |
173 tool_name: Name of the tool to create. | |
174 adb: ADB interface the tool will use. | |
175 """ | |
176 if not tool_name: | |
177 return BaseTool() | |
178 | |
179 ctor = TOOL_REGISTRY.get(tool_name) | |
180 if ctor: | |
181 return ctor(adb) | |
182 else: | |
183 print 'Unknown tool %s, available tools: %s' % ( | |
184 tool_name, ', '.join(sorted(TOOL_REGISTRY.keys()))) | |
185 sys.exit(1) | |
OLD | NEW |