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

Side by Side Diff: build/android/pylib/instrumentation/instrumentation_test_instance.py

Issue 1414403002: Add CommandLineArgumentParameter and use it for WebView tests (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@fix-cr-526885-read-nested-annotations
Patch Set: Comments addressed Created 5 years, 1 month 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 2015 The Chromium Authors. All rights reserved. 1 # Copyright 2015 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 import collections
6 import copy
5 import logging 7 import logging
6 import os 8 import os
7 import pickle 9 import pickle
8 import re 10 import re
9 import sys 11 import sys
10 12
11 from devil.android import apk_helper 13 from devil.android import apk_helper
12 from devil.android import md5sum 14 from devil.android import md5sum
13 from pylib import constants 15 from pylib import constants
14 from pylib.base import base_test_result 16 from pylib.base import base_test_result
15 from pylib.base import test_instance 17 from pylib.base import test_instance
16 from pylib.instrumentation import test_result 18 from pylib.instrumentation import test_result
17 from pylib.instrumentation import instrumentation_parser 19 from pylib.instrumentation import instrumentation_parser
18 from pylib.utils import proguard 20 from pylib.utils import proguard
19 21
20 sys.path.append( 22 sys.path.append(
21 os.path.join(constants.DIR_SOURCE_ROOT, 'build', 'util', 'lib', 'common')) 23 os.path.join(constants.DIR_SOURCE_ROOT, 'build', 'util', 'lib', 'common'))
22 import unittest_util # pylint: disable=import-error 24 import unittest_util # pylint: disable=import-error
23 25
24 # Ref: http://developer.android.com/reference/android/app/Activity.html 26 # Ref: http://developer.android.com/reference/android/app/Activity.html
25 _ACTIVITY_RESULT_CANCELED = 0 27 _ACTIVITY_RESULT_CANCELED = 0
26 _ACTIVITY_RESULT_OK = -1 28 _ACTIVITY_RESULT_OK = -1
27 29
30 _COMMAND_LINE_PARAMETER = 'cmdlinearg-parameter'
28 _DEFAULT_ANNOTATIONS = [ 31 _DEFAULT_ANNOTATIONS = [
29 'Smoke', 'SmallTest', 'MediumTest', 'LargeTest', 32 'Smoke', 'SmallTest', 'MediumTest', 'LargeTest',
30 'EnormousTest', 'IntegrationTest'] 33 'EnormousTest', 'IntegrationTest']
31 _EXCLUDE_UNLESS_REQUESTED_ANNOTATIONS = [ 34 _EXCLUDE_UNLESS_REQUESTED_ANNOTATIONS = [
32 'DisabledTest', 'FlakyTest'] 35 'DisabledTest', 'FlakyTest']
33 _EXTRA_ENABLE_HTTP_SERVER = ( 36 _EXTRA_ENABLE_HTTP_SERVER = (
34 'org.chromium.chrome.test.ChromeInstrumentationTestRunner.' 37 'org.chromium.chrome.test.ChromeInstrumentationTestRunner.'
35 + 'EnableTestHttpServer') 38 + 'EnableTestHttpServer')
36 _EXTRA_DRIVER_TEST_LIST = ( 39 _EXTRA_DRIVER_TEST_LIST = (
37 'org.chromium.test.driver.OnDeviceInstrumentationDriver.TestList') 40 'org.chromium.test.driver.OnDeviceInstrumentationDriver.TestList')
38 _EXTRA_DRIVER_TEST_LIST_FILE = ( 41 _EXTRA_DRIVER_TEST_LIST_FILE = (
39 'org.chromium.test.driver.OnDeviceInstrumentationDriver.TestListFile') 42 'org.chromium.test.driver.OnDeviceInstrumentationDriver.TestListFile')
40 _EXTRA_DRIVER_TARGET_PACKAGE = ( 43 _EXTRA_DRIVER_TARGET_PACKAGE = (
41 'org.chromium.test.driver.OnDeviceInstrumentationDriver.TargetPackage') 44 'org.chromium.test.driver.OnDeviceInstrumentationDriver.TargetPackage')
42 _EXTRA_DRIVER_TARGET_CLASS = ( 45 _EXTRA_DRIVER_TARGET_CLASS = (
43 'org.chromium.test.driver.OnDeviceInstrumentationDriver.TargetClass') 46 'org.chromium.test.driver.OnDeviceInstrumentationDriver.TargetClass')
47 _PARAMETERIZED_TEST_ANNOTATION = 'ParameterizedTest'
48 _PARAMETERIZED_TEST_SET_ANNOTATION = 'ParameterizedTest$Set'
44 _NATIVE_CRASH_RE = re.compile('native crash', re.IGNORECASE) 49 _NATIVE_CRASH_RE = re.compile('native crash', re.IGNORECASE)
45 _PICKLE_FORMAT_VERSION = 10 50 _PICKLE_FORMAT_VERSION = 10
46 51
47 52
48 # TODO(jbudorick): Make these private class methods of 53 # TODO(jbudorick): Make these private class methods of
49 # InstrumentationTestInstance once the instrumentation test_runner is 54 # InstrumentationTestInstance once the instrumentation test_runner is
50 # deprecated. 55 # deprecated.
51 def ParseAmInstrumentRawOutput(raw_output): 56 def ParseAmInstrumentRawOutput(raw_output):
52 """Parses the output of an |am instrument -r| call. 57 """Parses the output of an |am instrument -r| call.
53 58
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
127 and any(_NATIVE_CRASH_RE.search(l) 132 and any(_NATIVE_CRASH_RE.search(l)
128 for l in result_bundle.itervalues())) 133 for l in result_bundle.itervalues()))
129 if crashed: 134 if crashed:
130 current_result.SetType(base_test_result.ResultType.CRASH) 135 current_result.SetType(base_test_result.ResultType.CRASH)
131 136
132 results.append(current_result) 137 results.append(current_result)
133 138
134 return results 139 return results
135 140
136 141
142 def ParseCommandLineFlagParameters(annotations):
143 """Determines whether the test is parameterized to be run with different
144 command-line flags.
145
146 Args:
147 annotations: The annotations of the test.
148
149 Returns:
150 If the test is parameterized, returns a list of named tuples
151 with lists of flags, e.g.:
152
153 [(add=['--flag-to-add']), (remove=['--flag-to-remove']), ()]
154
155 That means, the test must be run three times, the first time with
156 "--flag-to-add" added to command-line, the second time with
157 "--flag-to-remove" to be removed from command-line, and the third time
158 with default command-line args. If the same flag is listed both for adding
159 and for removing, it is left unchanged.
160
161 If the test is not parametrized, returns None.
162
163 """
164 ParamsTuple = collections.namedtuple('ParamsTuple', ['add', 'remove'])
165 parameterized_tests = []
166 if _PARAMETERIZED_TEST_ANNOTATION in annotations:
167 parameterized_tests = [annotations[_PARAMETERIZED_TEST_ANNOTATION]]
168 elif _PARAMETERIZED_TEST_SET_ANNOTATION in annotations:
169 if annotations[_PARAMETERIZED_TEST_SET_ANNOTATION]:
170 parameterized_tests = annotations[
171 _PARAMETERIZED_TEST_SET_ANNOTATION].get('tests', [])
172 else:
173 return None
174
175 result = []
176 for pt in parameterized_tests:
177 if not pt:
178 continue
179 for p in pt['parameters']:
180 if p['tag'] == _COMMAND_LINE_PARAMETER:
181 to_add = []
182 to_remove = []
183 for a in p.get('arguments', []):
184 if a['name'] == 'add':
185 to_add = ['--%s' % f for f in a['stringArray']]
186 elif a['name'] == 'remove':
187 to_remove = ['--%s' % f for f in a['stringArray']]
188 result.append(ParamsTuple(to_add, to_remove))
189 return result if result else None
190
191
137 class InstrumentationTestInstance(test_instance.TestInstance): 192 class InstrumentationTestInstance(test_instance.TestInstance):
138 193
139 def __init__(self, args, isolate_delegate, error_func): 194 def __init__(self, args, isolate_delegate, error_func):
140 super(InstrumentationTestInstance, self).__init__() 195 super(InstrumentationTestInstance, self).__init__()
141 196
142 self._additional_apks = [] 197 self._additional_apks = []
143 self._apk_under_test = None 198 self._apk_under_test = None
144 self._apk_under_test_permissions = None 199 self._apk_under_test_permissions = None
145 self._package_info = None 200 self._package_info = None
146 self._suite = None 201 self._suite = None
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after
385 return self._data_deps 440 return self._data_deps
386 441
387 def GetTests(self): 442 def GetTests(self):
388 pickle_path = '%s-proguard.pickle' % self.test_jar 443 pickle_path = '%s-proguard.pickle' % self.test_jar
389 try: 444 try:
390 tests = self._GetTestsFromPickle(pickle_path, self.test_jar) 445 tests = self._GetTestsFromPickle(pickle_path, self.test_jar)
391 except self.ProguardPickleException as e: 446 except self.ProguardPickleException as e:
392 logging.info('Getting tests from JAR via proguard. (%s)', str(e)) 447 logging.info('Getting tests from JAR via proguard. (%s)', str(e))
393 tests = self._GetTestsFromProguard(self.test_jar) 448 tests = self._GetTestsFromProguard(self.test_jar)
394 self._SaveTestsToPickle(pickle_path, self.test_jar, tests) 449 self._SaveTestsToPickle(pickle_path, self.test_jar, tests)
395 return self._InflateTests(self._FilterTests(tests)) 450 return self._ParametrizeTestsWithFlags(
451 self._InflateTests(self._FilterTests(tests)))
396 452
397 class ProguardPickleException(Exception): 453 class ProguardPickleException(Exception):
398 pass 454 pass
399 455
400 def _GetTestsFromPickle(self, pickle_path, jar_path): 456 def _GetTestsFromPickle(self, pickle_path, jar_path):
401 if not os.path.exists(pickle_path): 457 if not os.path.exists(pickle_path):
402 raise self.ProguardPickleException('%s does not exist.' % pickle_path) 458 raise self.ProguardPickleException('%s does not exist.' % pickle_path)
403 if os.path.getmtime(pickle_path) <= os.path.getmtime(jar_path): 459 if os.path.getmtime(pickle_path) <= os.path.getmtime(jar_path):
404 raise self.ProguardPickleException( 460 raise self.ProguardPickleException(
405 '%s newer than %s.' % (jar_path, pickle_path)) 461 '%s newer than %s.' % (jar_path, pickle_path))
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
510 for m in c['methods']: 566 for m in c['methods']:
511 a = dict(c['annotations']) 567 a = dict(c['annotations'])
512 a.update(m['annotations']) 568 a.update(m['annotations'])
513 inflated_tests.append({ 569 inflated_tests.append({
514 'class': c['class'], 570 'class': c['class'],
515 'method': m['method'], 571 'method': m['method'],
516 'annotations': a, 572 'annotations': a,
517 }) 573 })
518 return inflated_tests 574 return inflated_tests
519 575
576 def _ParametrizeTestsWithFlags(self, tests):
577 new_tests = []
578 for t in tests:
579 parameters = ParseCommandLineFlagParameters(t['annotations'])
580 if parameters:
581 t['flags'] = parameters[0]
582 for p in parameters[1:]:
583 parameterized_t = copy.copy(t)
584 parameterized_t['flags'] = p
585 new_tests.append(parameterized_t)
586 return tests + new_tests
587
520 @staticmethod 588 @staticmethod
521 def GetHttpServerEnvironmentVars(): 589 def GetHttpServerEnvironmentVars():
522 return { 590 return {
523 _EXTRA_ENABLE_HTTP_SERVER: None, 591 _EXTRA_ENABLE_HTTP_SERVER: None,
524 } 592 }
525 593
526 def GetDriverEnvironmentVars( 594 def GetDriverEnvironmentVars(
527 self, test_list=None, test_list_file_path=None): 595 self, test_list=None, test_list_file_path=None):
528 env = { 596 env = {
529 _EXTRA_DRIVER_TARGET_PACKAGE: self.test_package, 597 _EXTRA_DRIVER_TARGET_PACKAGE: self.test_package,
(...skipping 17 matching lines...) Expand all
547 def GenerateTestResults( 615 def GenerateTestResults(
548 result_code, result_bundle, statuses, start_ms, duration_ms): 616 result_code, result_bundle, statuses, start_ms, duration_ms):
549 return GenerateTestResults(result_code, result_bundle, statuses, 617 return GenerateTestResults(result_code, result_bundle, statuses,
550 start_ms, duration_ms) 618 start_ms, duration_ms)
551 619
552 #override 620 #override
553 def TearDown(self): 621 def TearDown(self):
554 if self._isolate_delegate: 622 if self._isolate_delegate:
555 self._isolate_delegate.Clear() 623 self._isolate_delegate.Clear()
556 624
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698