Chromium Code Reviews| Index: build/android/pylib/instrumentation/instrumentation_test_instance.py |
| diff --git a/build/android/pylib/instrumentation/instrumentation_test_instance.py b/build/android/pylib/instrumentation/instrumentation_test_instance.py |
| index cb5d691f33fd4c07c189faf92606617e1a7e3827..c4665290bbdba7c56a2efdc2367fa622385e845b 100644 |
| --- a/build/android/pylib/instrumentation/instrumentation_test_instance.py |
| +++ b/build/android/pylib/instrumentation/instrumentation_test_instance.py |
| @@ -36,6 +36,14 @@ _EXCLUDE_UNLESS_REQUESTED_ANNOTATIONS = [ |
| 'DisabledTest', 'FlakyTest'] |
| _VALID_ANNOTATIONS = set(['Manual'] + _DEFAULT_ANNOTATIONS + |
| _EXCLUDE_UNLESS_REQUESTED_ANNOTATIONS) |
| + |
| +# These test methods are inherited from android.test base test class and |
| +# should be permitted for not having size annotation. For more, please check |
| +# https://developer.android.com/reference/android/test/AndroidTestCase.html |
| +# https://developer.android.com/reference/android/test/ServiceTestCase.html |
| +_TEST_WITHOUT_SIZE_ANNOTATIONS = [ |
| + 'testAndroidTestCaseSetupProperly', 'testServiceTestCaseSetUpProperly'] |
| + |
| _EXTRA_DRIVER_TEST_LIST = ( |
| 'org.chromium.test.driver.OnDeviceInstrumentationDriver.TestList') |
| _EXTRA_DRIVER_TEST_LIST_FILE = ( |
| @@ -67,7 +75,7 @@ class TestListPickleException(test_exception.TestException): |
| # TODO(jbudorick): Make these private class methods of |
| -# InstrumentationTestInstance once the instrumentation test_runner is |
| +# InstrumentationTestInstance once the instrumentation junit3_runner_class is |
| # deprecated. |
| def ParseAmInstrumentRawOutput(raw_output): |
| """Parses the output of an |am instrument -r| call. |
| @@ -163,8 +171,8 @@ def FilterTests(tests, test_filter=None, annotations=None, |
| Args: |
| tests: a list of tests. e.g. [ |
| - {'annotations": {}, 'class': 'com.example.TestA', 'methods':[]}, |
| - {'annotations": {}, 'class': 'com.example.TestB', 'methods':[]}] |
| + {'annotations": {}, 'class': 'com.example.TestA', 'method':'test1'}, |
| + {'annotations": {}, 'class': 'com.example.TestB', 'method':'test2'}] |
| test_filter: googletest-style filter string. |
| annotations: a dict of wanted annotations for test methods. |
| exclude_annotations: a dict of annotations to exclude. |
| @@ -186,6 +194,12 @@ def FilterTests(tests, test_filter=None, annotations=None, |
| GetUniqueTestName(t, sep='.') |
| ] |
| + if t['is_junit4']: |
| + names += [ |
| + GetTestNameWithoutParameterPostfix(t, sep='.'), |
| + GetTestNameWithoutParameterPostfix(unqualified_class_test, sep='.') |
| + ] |
| + |
| pattern_groups = test_filter.split('-') |
| if len(pattern_groups) > 1: |
| negative_filter = pattern_groups[1] |
| @@ -228,7 +242,8 @@ def FilterTests(tests, test_filter=None, annotations=None, |
| continue |
| # Enforce that all tests declare their size. |
| - if not any(a in _VALID_ANNOTATIONS for a in t['annotations']): |
| + if (not any(a in _VALID_ANNOTATIONS for a in t['annotations']) |
| + and t['method'] not in _TEST_WITHOUT_SIZE_ANNOTATIONS): |
| raise MissingSizeAnnotationError(GetTestName(t)) |
| if (not annotation_filter(t['annotations']) |
| @@ -240,6 +255,12 @@ def FilterTests(tests, test_filter=None, annotations=None, |
| return filtered_tests |
| +def _GetAllTestsFromRunnerPickle(test_apk): |
|
jbudorick
2017/07/21 19:35:08
Why is this a separate function?
the real yoland
2017/07/21 22:24:09
42
|
| + pickle_path = '%s-runner.pickle' % test_apk.path |
| + return _GetTestsFromPickle(pickle_path, test_apk.path) |
| + |
| + |
| +# TODO(yolandyan): remove this once the tests are converted to junit4 |
| def GetAllTestsFromJar(test_jar): |
| pickle_path = '%s-proguard.pickle' % test_jar |
| try: |
| @@ -338,7 +359,6 @@ def _GetTestsFromDexdump(test_apk): |
| }) |
| return tests |
| - |
| def _SaveTestsToPickle(pickle_path, jar_path, tests): |
| jar_md5 = md5sum.CalculateHostMd5Sums(jar_path)[jar_path] |
| pickle_data = { |
| @@ -381,6 +401,28 @@ def GetTestName(test, sep='#'): |
| return '%s%s%s' % (test['class'], sep, test['method']) |
| +def GetTestNameWithoutParameterPostfix( |
| + test, sep='#', parameterization_sep='__'): |
| + """Gets the name of the given JUnit4 test without parameter postfix. |
| + |
| + For most WebView JUnit4 javatests, each test is parameterizatized with |
| + "__sandboxed_mode" to run in both non-sandboxed mode and sandboxed mode. |
| + |
| + This function returns the name of the test without parameterization |
| + so test filters can match both parameterized and non-parameterized tests. |
| + |
| + Args: |
| + test: the instrumentation test dict. |
| + sep: the character(s) that should join the class name and the method name. |
| + parameterization_sep: the character(s) that seperate method name and method |
| + parameterization postfix. |
| + Returns: |
| + The test name without parameter postfix as a string. |
| + """ |
| + name = GetTestName(test, sep=sep) |
| + return name.split(parameterization_sep)[0] |
| + |
| + |
| def GetUniqueTestName(test, sep='#'): |
| """Gets the unique name of the given test. |
| @@ -413,8 +455,8 @@ class InstrumentationTestInstance(test_instance.TestInstance): |
| self._test_apk_incremental_install_script = None |
| self._test_jar = None |
| self._test_package = None |
| - self._test_runner = None |
| - self._test_runner_junit4 = None |
| + self._junit3_runner_class = None |
| + self._junit4_runner_class = None |
| self._test_support_apk = None |
| self._initializeApkAttributes(args, error_func) |
| @@ -428,6 +470,8 @@ class InstrumentationTestInstance(test_instance.TestInstance): |
| self._test_filter = None |
| self._initializeTestFilterAttributes(args) |
| + self._tests_from_runner = None |
| + |
| self._flags = None |
| self._initializeFlagAttributes(args) |
| @@ -521,23 +565,25 @@ class InstrumentationTestInstance(test_instance.TestInstance): |
| self._test_package = self._test_apk.GetPackageName() |
| all_instrumentations = self._test_apk.GetAllInstrumentations() |
| - test_runners = [ |
| + all_junit3_runner_classes = [ |
| x for x in all_instrumentations if ('true' not in x.get( |
| 'chromium-junit4', ''))] |
| - test_runners_junit4 = [ |
| + all_junit4_test_runner_classes = [ |
| x for x in all_instrumentations if ('true' in x.get( |
| 'chromium-junit4', ''))] |
| - if len(test_runners) > 1: |
| + if len(all_junit3_runner_classes) > 1: |
| logging.warning('This test apk has more than one JUnit3 instrumentation') |
| - if len(test_runners_junit4) > 1: |
| + if len(all_junit4_test_runner_classes) > 1: |
| logging.warning('This test apk has more than one JUnit4 instrumentation') |
| - self._test_runner = ( |
| - test_runners[0]['android:name'] if test_runners else |
| - self.test_apk.GetInstrumentationName()) |
| - self._test_runner_junit4 = ( |
| - test_runners_junit4[0]['android:name'] if test_runners_junit4 else None) |
| + self._junit3_runner_class = ( |
| + all_junit3_runner_classes[0]['android:name'] |
| + if all_junit3_runner_classes else self.test_apk.GetInstrumentationName()) |
| + |
| + self._junit4_runner_class = ( |
| + all_junit4_test_runner_classes[0]['android:name'] |
| + if all_junit4_test_runner_classes else None) |
| self._package_info = None |
| if self._apk_under_test: |
| @@ -690,6 +736,14 @@ class InstrumentationTestInstance(test_instance.TestInstance): |
| def gs_results_bucket(self): |
| return self._gs_results_bucket |
| + @property |
| + def junit3_runner_class(self): |
| + return self._junit3_runner_class |
| + |
| + @property |
| + def junit4_runner_class(self): |
| + return self._junit4_runner_class |
| + |
| @property |
| def should_save_logcat(self): |
| return self._should_save_logcat |
| @@ -739,12 +793,8 @@ class InstrumentationTestInstance(test_instance.TestInstance): |
| return self._test_package |
| @property |
| - def test_runner(self): |
| - return self._test_runner |
| - |
| - @property |
| - def test_runner_junit4(self): |
| - return self._test_runner_junit4 |
| + def tests_from_runner(self): |
| + return self._tests_from_runner |
| @property |
| def timeout_scale(self): |
| @@ -771,12 +821,16 @@ class InstrumentationTestInstance(test_instance.TestInstance): |
| return self._data_deps |
| def GetTests(self): |
| - if self.test_jar: |
| + if self.junit4_runner_class: |
| + if self.tests_from_runner is None: |
| + raise Exception('Failed to list out tests from junit4 runner') |
| + tests = self.tests_from_runner |
| + elif self.test_jar: |
| tests = GetAllTestsFromJar(self.test_jar) |
| else: |
| tests = GetAllTestsFromApk(self.test_apk.path) |
| inflated_tests = self._ParameterizeTestsWithFlags(self._InflateTests(tests)) |
| - if self._test_runner_junit4 is None and any( |
| + if self._junit4_runner_class is None and any( |
| t['is_junit4'] for t in inflated_tests): |
| raise MissingJUnit4RunnerException() |
| filtered_tests = FilterTests( |
| @@ -788,6 +842,9 @@ class InstrumentationTestInstance(test_instance.TestInstance): |
| raise UnmatchedFilterException(self._test_filter) |
| return filtered_tests |
| + def SetTestsFromRunner(self, raw_tests): |
| + self._tests_from_runner = raw_tests |
| + |
| # pylint: disable=no-self-use |
| def _InflateTests(self, tests): |
| inflated_tests = [] |
| @@ -823,7 +880,7 @@ class InstrumentationTestInstance(test_instance.TestInstance): |
| self, test_list=None, test_list_file_path=None): |
| env = { |
| _EXTRA_DRIVER_TARGET_PACKAGE: self.test_package, |
| - _EXTRA_DRIVER_TARGET_CLASS: self.test_runner, |
| + _EXTRA_DRIVER_TARGET_CLASS: self.junit3_runner_class, |
| _EXTRA_TIMEOUT_SCALE: self._timeout_scale, |
| } |
| @@ -836,6 +893,13 @@ class InstrumentationTestInstance(test_instance.TestInstance): |
| return env |
| + def GetAllTestsFromRunnerPickle(self): |
|
jbudorick
2017/07/21 19:35:08
I think this should just be GetTestsFromPickle. Le
the real yoland
2017/07/21 22:24:09
Done
|
| + return _GetAllTestsFromRunnerPickle(self.test_apk) |
| + |
| + def SaveTestsToPickle(self, raw_tests): |
| + pickle_path = '%s-runner.pickle' % self.test_apk.path |
| + _SaveTestsToPickle(pickle_path, self.test_apk.path, raw_tests) |
| + |
| @staticmethod |
| def ParseAmInstrumentRawOutput(raw_output): |
| return ParseAmInstrumentRawOutput(raw_output) |