Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(338)

Side by Side Diff: build/android/pylib/linker/test_case.py

Issue 221823011: [Android] Change object types from AndroidCommands to DeviceUtils in build/android/. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Address Frank's comments. Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 # Copyright 2013 The Chromium Authors. All rights reserved. 1 # Copyright 2013 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 """Base class for linker-specific test cases. 5 """Base class for linker-specific test cases.
6 6
7 The custom dynamic linker can only be tested through a custom test case 7 The custom dynamic linker can only be tested through a custom test case
8 for various technical reasons: 8 for various technical reasons:
9 9
10 - It's an 'invisible feature', i.e. it doesn't expose a new API or 10 - It's an 'invisible feature', i.e. it doesn't expose a new API or
(...skipping 23 matching lines...) Expand all
34 34
35 """ 35 """
36 # pylint: disable=R0201 36 # pylint: disable=R0201
37 37
38 import logging 38 import logging
39 import os 39 import os
40 import re 40 import re
41 import time 41 import time
42 42
43 from pylib import constants 43 from pylib import constants
44 from pylib import android_commands
45 from pylib.base import base_test_result 44 from pylib.base import base_test_result
46 45
47 46
48 ResultType = base_test_result.ResultType 47 ResultType = base_test_result.ResultType
49 48
50 _PACKAGE_NAME = 'org.chromium.chromium_linker_test_apk' 49 _PACKAGE_NAME = 'org.chromium.chromium_linker_test_apk'
51 _ACTIVITY_NAME = '.ChromiumLinkerTestActivity' 50 _ACTIVITY_NAME = '.ChromiumLinkerTestActivity'
52 _COMMAND_LINE_FILE = '/data/local/tmp/chromium-linker-test-command-line' 51 _COMMAND_LINE_FILE = '/data/local/tmp/chromium-linker-test-command-line'
53 52
54 # Path to the Linker.java source file. 53 # Path to the Linker.java source file.
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
102 return None 101 return None
103 102
104 if configs[0] not in ['NEVER', 'LOW_RAM_ONLY', 'ALWAYS']: 103 if configs[0] not in ['NEVER', 'LOW_RAM_ONLY', 'ALWAYS']:
105 logging.error('Unexpected browser config value: ' + configs[0]) 104 logging.error('Unexpected browser config value: ' + configs[0])
106 return None 105 return None
107 106
108 logging.info('Found linker browser shared RELRO config: ' + configs[0]) 107 logging.info('Found linker browser shared RELRO config: ' + configs[0])
109 return configs[0] 108 return configs[0]
110 109
111 110
112 def _WriteCommandLineFile(adb, command_line, command_line_file): 111 def _WriteCommandLineFile(device, command_line, command_line_file):
113 """Create a command-line file on the device. This does not use FlagChanger 112 """Create a command-line file on the device. This does not use FlagChanger
114 because its implementation assumes the device has 'su', and thus does 113 because its implementation assumes the device has 'su', and thus does
craigdh 2014/04/09 15:55:02 I believe I fixed FlagChanger a while back so the
jbudorick 2014/04/09 20:03:33 The only use of _WriteCommandLineFile attempts to
115 not work at all with production devices.""" 114 not work at all with production devices."""
116 adb.RunShellCommand('echo "%s" > %s' % (command_line, command_line_file)) 115 device.old_interface.RunShellCommand(
116 'echo "%s" > %s' % (command_line, command_line_file))
117 117
118 118
119 def _CheckLinkerTestStatus(logcat): 119 def _CheckLinkerTestStatus(logcat):
120 """Parse the content of |logcat| and checks for both a browser and 120 """Parse the content of |logcat| and checks for both a browser and
121 renderer status line. 121 renderer status line.
122 122
123 Args: 123 Args:
124 logcat: A string to parse. Can include line separators. 124 logcat: A string to parse. Can include line separators.
125 125
126 Returns: 126 Returns:
(...skipping 14 matching lines...) Expand all
141 else: 141 else:
142 assert False, 'Invalid process type ' + process_type 142 assert False, 'Invalid process type ' + process_type
143 143
144 if browser_found and renderer_found: 144 if browser_found and renderer_found:
145 return (True, browser_success, renderer_success) 145 return (True, browser_success, renderer_success)
146 146
147 # Didn't find anything. 147 # Didn't find anything.
148 return (False, None, None) 148 return (False, None, None)
149 149
150 150
151 def _StartActivityAndWaitForLinkerTestStatus(adb, timeout): 151 def _StartActivityAndWaitForLinkerTestStatus(device, timeout):
152 """Force-start an activity and wait up to |timeout| seconds until the full 152 """Force-start an activity and wait up to |timeout| seconds until the full
153 linker test status lines appear in the logcat, recorded through |adb|. 153 linker test status lines appear in the logcat, recorded through |device|.
154 Args: 154 Args:
155 adb: An AndroidCommands instance. 155 device: A DeviceUtils instance.
156 timeout: Timeout in seconds 156 timeout: Timeout in seconds
157 Returns: 157 Returns:
158 A (status, logs) tuple, where status is a ResultType constant, and logs 158 A (status, logs) tuple, where status is a ResultType constant, and logs
159 if the final logcat output as a string. 159 if the final logcat output as a string.
160 """ 160 """
161 # 1. Start recording logcat with appropriate filters. 161 # 1. Start recording logcat with appropriate filters.
162 adb.StartRecordingLogcat(clear=True, filters=_LOGCAT_FILTERS) 162 device.old_interface.StartRecordingLogcat(
163 clear=True, filters=_LOGCAT_FILTERS)
163 164
164 try: 165 try:
165 # 2. Force-start activity. 166 # 2. Force-start activity.
166 adb.StartActivity(package=_PACKAGE_NAME, 167 device.old_interface.StartActivity(
167 activity=_ACTIVITY_NAME, 168 package=_PACKAGE_NAME, activity=_ACTIVITY_NAME, force_stop=True)
168 force_stop=True)
169 169
170 # 3. Wait up to |timeout| seconds until the test status is in the logcat. 170 # 3. Wait up to |timeout| seconds until the test status is in the logcat.
171 num_tries = 0 171 num_tries = 0
172 max_tries = timeout 172 max_tries = timeout
173 found = False 173 found = False
174 while num_tries < max_tries: 174 while num_tries < max_tries:
175 time.sleep(1) 175 time.sleep(1)
176 num_tries += 1 176 num_tries += 1
177 found, browser_ok, renderer_ok = _CheckLinkerTestStatus( 177 found, browser_ok, renderer_ok = _CheckLinkerTestStatus(
178 adb.GetCurrentRecordedLogcat()) 178 device.old_interface.GetCurrentRecordedLogcat())
179 if found: 179 if found:
180 break 180 break
181 181
182 finally: 182 finally:
183 logs = adb.StopRecordingLogcat() 183 logs = device.old_interface.StopRecordingLogcat()
184 184
185 if num_tries >= max_tries: 185 if num_tries >= max_tries:
186 return ResultType.TIMEOUT, logs 186 return ResultType.TIMEOUT, logs
187 187
188 if browser_ok and renderer_ok: 188 if browser_ok and renderer_ok:
189 return ResultType.PASS, logs 189 return ResultType.PASS, logs
190 190
191 return ResultType.FAIL, logs 191 return ResultType.FAIL, logs
192 192
193 193
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
288 """ 288 """
289 self.is_low_memory = is_low_memory 289 self.is_low_memory = is_low_memory
290 if is_low_memory: 290 if is_low_memory:
291 test_suffix = 'ForLowMemoryDevice' 291 test_suffix = 'ForLowMemoryDevice'
292 else: 292 else:
293 test_suffix = 'ForRegularDevice' 293 test_suffix = 'ForRegularDevice'
294 class_name = self.__class__.__name__ 294 class_name = self.__class__.__name__
295 self.qualified_name = '%s.%s' % (class_name, test_suffix) 295 self.qualified_name = '%s.%s' % (class_name, test_suffix)
296 self.tagged_name = self.qualified_name 296 self.tagged_name = self.qualified_name
297 297
298 def _RunTest(self, _adb): 298 def _RunTest(self, _device):
299 """Run the test, must be overriden. 299 """Run the test, must be overriden.
300 Args: 300 Args:
301 _adb: An AndroidCommands instance to the device. 301 _device: A DeviceUtils interface.
302 Returns: 302 Returns:
303 A (status, log) tuple, where <status> is a ResultType constant, and <log> 303 A (status, log) tuple, where <status> is a ResultType constant, and <log>
304 is the logcat output captured during the test in case of error, or None 304 is the logcat output captured during the test in case of error, or None
305 in case of success. 305 in case of success.
306 """ 306 """
307 return ResultType.FAIL, 'Unimplemented _RunTest() method!' 307 return ResultType.FAIL, 'Unimplemented _RunTest() method!'
308 308
309 def Run(self, device): 309 def Run(self, device):
310 """Run the test on a given device. 310 """Run the test on a given device.
311 Args: 311 Args:
312 device: Name of target device where to run the test. 312 device: Name of target device where to run the test.
313 Returns: 313 Returns:
314 A base_test_result.TestRunResult() instance. 314 A base_test_result.TestRunResult() instance.
315 """ 315 """
316 margin = 8 316 margin = 8
317 print '[ %-*s ] %s' % (margin, 'RUN', self.tagged_name) 317 print '[ %-*s ] %s' % (margin, 'RUN', self.tagged_name)
318 logging.info('Running linker test: %s', self.tagged_name) 318 logging.info('Running linker test: %s', self.tagged_name)
319 adb = android_commands.AndroidCommands(device)
320 319
321 # Create command-line file on device. 320 # Create command-line file on device.
322 command_line_flags = '' 321 command_line_flags = ''
323 if self.is_low_memory: 322 if self.is_low_memory:
324 command_line_flags = '--low-memory-device' 323 command_line_flags = '--low-memory-device'
325 _WriteCommandLineFile(adb, command_line_flags, _COMMAND_LINE_FILE) 324 _WriteCommandLineFile(device, command_line_flags, _COMMAND_LINE_FILE)
326 325
327 # Run the test. 326 # Run the test.
328 status, logs = self._RunTest(adb) 327 status, logs = self._RunTest(device)
329 328
330 result_text = 'OK' 329 result_text = 'OK'
331 if status == ResultType.FAIL: 330 if status == ResultType.FAIL:
332 result_text = 'FAILED' 331 result_text = 'FAILED'
333 elif status == ResultType.TIMEOUT: 332 elif status == ResultType.TIMEOUT:
334 result_text = 'TIMEOUT' 333 result_text = 'TIMEOUT'
335 print '[ %*s ] %s' % (margin, result_text, self.tagged_name) 334 print '[ %*s ] %s' % (margin, result_text, self.tagged_name)
336 335
337 results = base_test_result.TestRunResults() 336 results = base_test_result.TestRunResults()
338 results.AddResult( 337 results.AddResult(
(...skipping 28 matching lines...) Expand all
367 where <status> can be either FAIL or SUCCESS. These lines can appear 366 where <status> can be either FAIL or SUCCESS. These lines can appear
368 in any order in the logcat. Once both browser and renderer status are 367 in any order in the logcat. Once both browser and renderer status are
369 found, stop the loop. Otherwise timeout after 30 seconds. 368 found, stop the loop. Otherwise timeout after 30 seconds.
370 369
371 Note that there can be other lines beginning with BROWSER_LINKER_TEST: 370 Note that there can be other lines beginning with BROWSER_LINKER_TEST:
372 and RENDERER_LINKER_TEST:, but are not followed by a <status> code. 371 and RENDERER_LINKER_TEST:, but are not followed by a <status> code.
373 372
374 - The test case passes if the <status> for both the browser and renderer 373 - The test case passes if the <status> for both the browser and renderer
375 process are SUCCESS. Otherwise its a fail. 374 process are SUCCESS. Otherwise its a fail.
376 """ 375 """
377 def _RunTest(self, adb): 376 def _RunTest(self, device):
378 # Wait up to 30 seconds until the linker test status is in the logcat. 377 # Wait up to 30 seconds until the linker test status is in the logcat.
379 return _StartActivityAndWaitForLinkerTestStatus(adb, timeout=30) 378 return _StartActivityAndWaitForLinkerTestStatus(device, timeout=30)
380 379
381 380
382 class LinkerLibraryAddressTest(LinkerTestCaseBase): 381 class LinkerLibraryAddressTest(LinkerTestCaseBase):
383 """A test case that verifies library load addresses. 382 """A test case that verifies library load addresses.
384 383
385 The point of this check is to ensure that the libraries are loaded 384 The point of this check is to ensure that the libraries are loaded
386 according to the following rules: 385 according to the following rules:
387 386
388 - For low-memory devices, they should always be loaded at the same address 387 - For low-memory devices, they should always be loaded at the same address
389 in both browser and renderer processes, both below 0x4000_0000. 388 in both browser and renderer processes, both below 0x4000_0000.
390 389
391 - For regular devices, the browser process should load libraries above 390 - For regular devices, the browser process should load libraries above
392 0x4000_0000, and renderer ones below it. 391 0x4000_0000, and renderer ones below it.
393 """ 392 """
394 def _RunTest(self, adb): 393 def _RunTest(self, device):
395 result, logs = _StartActivityAndWaitForLinkerTestStatus(adb, timeout=30) 394 result, logs = _StartActivityAndWaitForLinkerTestStatus(device, timeout=30)
396 395
397 # Return immediately in case of timeout. 396 # Return immediately in case of timeout.
398 if result == ResultType.TIMEOUT: 397 if result == ResultType.TIMEOUT:
399 return result, logs 398 return result, logs
400 399
401 # Collect the library load addresses in the browser and renderer processes. 400 # Collect the library load addresses in the browser and renderer processes.
402 browser_libs, renderer_libs = _ExtractLibraryLoadAddressesFromLogcat(logs) 401 browser_libs, renderer_libs = _ExtractLibraryLoadAddressesFromLogcat(logs)
403 402
404 logging.info('Browser libraries: %s', browser_libs) 403 logging.info('Browser libraries: %s', browser_libs)
405 logging.info('Renderer libraries: %s', renderer_libs) 404 logging.info('Renderer libraries: %s', renderer_libs)
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
471 470
472 This starts the activity several time (each time forcing a new process 471 This starts the activity several time (each time forcing a new process
473 creation) and compares the load addresses of the libraries in them to 472 creation) and compares the load addresses of the libraries in them to
474 detect that they have changed. 473 detect that they have changed.
475 474
476 In theory, two successive runs could (very rarely) use the same load 475 In theory, two successive runs could (very rarely) use the same load
477 address, so loop 5 times and compare the values there. It is assumed 476 address, so loop 5 times and compare the values there. It is assumed
478 that if there are more than one pair of identical addresses, then the 477 that if there are more than one pair of identical addresses, then the
479 load addresses are not random enough for this test. 478 load addresses are not random enough for this test.
480 """ 479 """
481 def _RunTest(self, adb): 480 def _RunTest(self, device):
482 max_loops = 5 481 max_loops = 5
483 browser_lib_map_list = [] 482 browser_lib_map_list = []
484 renderer_lib_map_list = [] 483 renderer_lib_map_list = []
485 logs_list = [] 484 logs_list = []
486 for _ in range(max_loops): 485 for _ in range(max_loops):
487 # Start the activity. 486 # Start the activity.
488 result, logs = _StartActivityAndWaitForLinkerTestStatus(adb, timeout=30) 487 result, logs = _StartActivityAndWaitForLinkerTestStatus(
488 device, timeout=30)
489 if result == ResultType.TIMEOUT: 489 if result == ResultType.TIMEOUT:
490 # Something bad happened. Return immediately. 490 # Something bad happened. Return immediately.
491 return result, logs 491 return result, logs
492 492
493 # Collect library addresses. 493 # Collect library addresses.
494 browser_libs, renderer_libs = _ExtractLibraryLoadAddressesFromLogcat(logs) 494 browser_libs, renderer_libs = _ExtractLibraryLoadAddressesFromLogcat(logs)
495 browser_lib_map_list.append(browser_libs) 495 browser_lib_map_list.append(browser_libs)
496 renderer_lib_map_list.append(renderer_libs) 496 renderer_lib_map_list.append(renderer_libs)
497 logs_list.append(logs) 497 logs_list.append(logs)
498 498
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
531 # Note that this behaviour doesn't seem to happen when starting an 531 # Note that this behaviour doesn't seem to happen when starting an
532 # application 'normally', i.e. when using the application launcher to 532 # application 'normally', i.e. when using the application launcher to
533 # start the activity. 533 # start the activity.
534 logging.info('Ignoring system\'s low randomization of browser libraries' + 534 logging.info('Ignoring system\'s low randomization of browser libraries' +
535 ' for regular devices') 535 ' for regular devices')
536 536
537 if not renderer_status: 537 if not renderer_status:
538 return ResultType.FAIL, renderer_logs 538 return ResultType.FAIL, renderer_logs
539 539
540 return ResultType.PASS, logs 540 return ResultType.PASS, logs
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698