def _collect_test_targets(self, targets): """Return a test registry mapping the tests found in the given targets. If `self._tests_to_run` is set, return a registry of explicitly specified tests instead. :returns: A registry of tests to run. :rtype: :class:`pants.java.junit.junit_xml_parser.Test.TestRegistry` """ test_registry = TestRegistry(tuple(self._calculate_tests_from_targets(targets))) if targets and self._tests_to_run: # If there are some junit_test targets in the graph, find ones that match the requested # test(s). possible_test_to_target = {} unknown_tests = [] for possible_test in self._get_possible_tests_to_run(): target = test_registry.get_owning_target(possible_test) if target is None: unknown_tests.append(possible_test) else: possible_test_to_target[possible_test] = target if len(unknown_tests) > 0: raise TaskError("No target found for test specifier(s):\n\n '{}'\n\nPlease change " "specifier or bring in the proper target(s)." .format("'\n '".join(t.render_test_spec() for t in unknown_tests))) return TestRegistry(possible_test_to_target) else: return test_registry
def _collect_test_targets(self, targets): """Return a test registry mapping the tests found in the given targets. If `self._tests_to_run` is set, return a registry of explicitly specified tests instead. :returns: A registry of tests to run. :rtype: :class:`pants.java.junit.junit_xml_parser.Test.TestRegistry` """ test_registry = TestRegistry( tuple(self._calculate_tests_from_targets(targets))) if targets and self._tests_to_run: # If there are some junit_test targets in the graph, find ones that match the requested # test(s). possible_test_to_target = {} unknown_tests = [] for possible_test in self._get_possible_tests_to_run(): target = test_registry.get_owning_target(possible_test) if target is None: unknown_tests.append(possible_test) else: possible_test_to_target[possible_test] = target if len(unknown_tests) > 0: raise TaskError( "No target found for test specifier(s):\n\n '{}'\n\nPlease change " "specifier or bring in the proper target(s).".format( "'\n '".join(t.render_test_spec() for t in unknown_tests))) return TestRegistry(possible_test_to_target) else: return test_registry
def test_index_nominal(self): registry = TestRegistry({JUnitTest('class1'): (1, 'a'), JUnitTest('class2'): (2, 'b'), JUnitTest('class3', 'method1'): (1, 'a'), JUnitTest('class3', 'method2'): (4, 'b')}) actual_index = registry.index(lambda t: t[0], lambda t: t[1]) expected_index = {(1, 'a'): (JUnitTest('class1'), JUnitTest('class3', 'method1')), (2, 'b'): (JUnitTest('class2'),), (4, 'b'): (JUnitTest('class3', 'method2'),)} self._assert_index(expected_index, actual_index)
def test_parse_failed_targets_error_raise(self): registry = TestRegistry({}) with temporary_dir() as junit_xml_dir: junit_xml_file = os.path.join(junit_xml_dir, 'TEST-bad.xml') with open(junit_xml_file, 'w') as fp: fp.write('<invalid></xml>') with self.assertRaises(ParseError) as exc: parse_failed_targets(registry, junit_xml_dir, self._raise_handler) self.assertEqual(junit_xml_file, exc.exception.junit_xml_path) self.assertIsInstance(exc.exception.cause, XmlParser.XmlError)
def test_get_owning_target(self): registry = TestRegistry(((JUnitTest('class1'), 'Bob'), (JUnitTest('class2'), 'Jane'), (JUnitTest('class3', 'method1'), 'Heidi'))) self.assertEqual('Bob', registry.get_owning_target(JUnitTest('class1'))) self.assertEqual('Bob', registry.get_owning_target(JUnitTest('class1', 'method1'))) self.assertEqual('Jane', registry.get_owning_target(JUnitTest('class2'))) self.assertEqual('Jane', registry.get_owning_target(JUnitTest('class2', 'method1'))) self.assertIsNone(registry.get_owning_target(JUnitTest('class3'))) self.assertEqual('Heidi', registry.get_owning_target(JUnitTest('class3', 'method1')))
def _get_failed_targets_from_junitxml(self, junitxml, targets): # Note that unlike in Java, we can't easily map targets to test classnames up-front. # Instead we grab the classnames seen in practice and work backwards to the targets. # First map the dotted paths of the modules to their respective targets. pex_src_root = os.path.relpath( self.context.products.get_data( GatherSources.PYTHON_SOURCES).path(), get_buildroot()) dotted_module_path_to_target = {} for target in targets: for src in target.sources_relative_to_source_root(): pex_src = os.path.join(pex_src_root, src) dotted_path = os.path.splitext(pex_src)[0].replace( os.path.sep, '.') dotted_module_path_to_target[dotted_path] = target # Now grab the classnames from the xml file. xml = XmlParser.from_file(junitxml) classname_and_names = ( (testcase.getAttribute('classname'), testcase.getAttribute('name')) for testcase in xml.parsed.getElementsByTagName('testcase')) # Now find which module each classname belongs to, and map it to its target. test_target_pairs = [] for classname, name in classname_and_names: # if the classname is empty, it means that there was an error in the module body, # outside any class or method body. In this case the module name in its entirety # ends up in the 'name' attribute. dotted_path = classname or name while dotted_path and dotted_path not in dotted_module_path_to_target: dotted_path = dotted_path.rpartition('.')[0] if dotted_path: target = dotted_module_path_to_target[dotted_path] test_target_pairs.append((Test(classname), target)) # Now parse the junit xml the usual way. def error_handler(e): raise TaskError(e) failed_targets_map = parse_failed_targets( TestRegistry(test_target_pairs), junitxml, error_handler) return failed_targets_map.keys()
def test_parse_failed_targets_error_continue(self): registry = TestRegistry({}) with temporary_dir() as junit_xml_dir: bad_file1 = os.path.join(junit_xml_dir, 'TEST-bad1.xml') with open(bad_file1, 'w') as fp: fp.write('<testsuite failures="nan" errors="0"/>') with open(os.path.join(junit_xml_dir, 'TEST-good.xml'), 'w') as fp: fp.write(""" <testsuite failures="0" errors="1"> <testcase classname="org.pantsbuild.Error" name="testError"> <error/> </testcase> </testsuite> """) bad_file2 = os.path.join(junit_xml_dir, 'TEST-bad2.xml') with open(bad_file2, 'w') as fp: fp.write('<invalid></xml>') collect_handler = self.CollectHandler() failed_targets = parse_failed_targets(registry, junit_xml_dir, collect_handler) self.assertEqual(2, len(collect_handler.errors)) self.assertEqual({bad_file1, bad_file2}, {e.junit_xml_path for e in collect_handler.errors}) self.assertEqual({None: {JUnitTest('org.pantsbuild.Error', 'testError')}}, failed_targets)
def test_parse_failed_targets_nominal(self): registry = TestRegistry({JUnitTest('org.pantsbuild.Failure'): 'Bob', JUnitTest('org.pantsbuild.Error'): 'Jane', JUnitTest('org.pantsbuild.AnotherError'): 'Bob'}) with temporary_dir() as junit_xml_dir: with open(os.path.join(junit_xml_dir, 'TEST-a.xml'), 'w') as fp: fp.write(""" <testsuite failures="1" errors="1"> <testcase classname="org.pantsbuild.Green" name="testOK"/> <testcase classname="org.pantsbuild.Failure" name="testFailure"> <failure/> </testcase> <testcase classname="org.pantsbuild.Error" name="testError"> <error/> </testcase> </testsuite> """) with open(os.path.join(junit_xml_dir, 'TEST-b.xml'), 'w') as fp: fp.write(""" <testsuite failures="0" errors="1"> <testcase classname="org.pantsbuild.AnotherError" name="testAnotherError"> <error/> </testcase> </testsuite> """) with open(os.path.join(junit_xml_dir, 'random.xml'), 'w') as fp: fp.write('<invalid></xml>') with safe_open(os.path.join(junit_xml_dir, 'subdir', 'TEST-c.xml'), 'w') as fp: fp.write('<invalid></xml>') failed_targets = parse_failed_targets(registry, junit_xml_dir, self._raise_handler) self.assertEqual({'Bob': {JUnitTest('org.pantsbuild.Failure', 'testFailure'), JUnitTest('org.pantsbuild.AnotherError', 'testAnotherError')}, 'Jane': {JUnitTest('org.pantsbuild.Error', 'testError')}}, failed_targets)
def test_index_no_indexers(self): registry = TestRegistry({JUnitTest('class1'): (1, 'a'), JUnitTest('class2'): (2, 'b')}) self._assert_index({(): (JUnitTest('class1'), JUnitTest('class2'))}, registry.index())
def test_index_empty(self): self._assert_index({}, TestRegistry({}).index())
def test_empty(self): self.assertTrue(TestRegistry({}).empty) self.assertTrue(TestRegistry(()).empty) self.assertTrue(TestRegistry([]).empty)
def test_parse_failed_targets_no_files(self): registry = TestRegistry({}) with temporary_dir() as junit_xml_dir: failed_targets = parse_failed_targets(registry, junit_xml_dir, self._raise_handler) self.assertEqual({}, failed_targets)