Example #1
0
  def _get_failed_targets_from_junitxml(self, junitxml, targets, pytest_rootdir):
    relsrc_to_target = self._map_relsrc_to_targets(targets)
    buildroot_relpath = os.path.relpath(pytest_rootdir, get_buildroot())

    # Now find the sources that contained failing tests.
    failed_targets = set()

    try:
      xml = XmlParser.from_file(junitxml)
      failures = int(xml.get_attribute('testsuite', 'failures'))
      errors = int(xml.get_attribute('testsuite', 'errors'))
      if failures or errors:
        for testcase in xml.parsed.getElementsByTagName('testcase'):
          test_failed = testcase.getElementsByTagName('failure')
          test_errored = testcase.getElementsByTagName('error')
          if test_failed or test_errored:
            # The file attribute is always relative to the py.test rootdir.
            pytest_relpath = testcase.getAttribute('file')
            relsrc = os.path.join(buildroot_relpath, pytest_relpath)
            failed_target = relsrc_to_target.get(relsrc)
            failed_targets.add(failed_target)
    except (XmlParser.XmlError, ValueError) as e:
      raise TaskError('Error parsing xml file at {}: {}'.format(junitxml, e))

    return failed_targets
Example #2
0
  def _get_failed_targets(self, tests_and_targets):
    """Return a list of failed targets.

    Analyzes JUnit XML files to figure out which test had failed.

    :tests_and_targets: {test: target} mapping.
    """

    def get_test_filename(test):
      return os.path.join(self._task_exports.workdir, 'TEST-{0}.xml'.format(test))

    failed_targets = []

    for test, target in tests_and_targets.items():
      if target is None:
        self._context.log.warning('Unknown target for test %{0}'.format(test))

      filename = get_test_filename(test)

      if os.path.exists(filename):
        try:
          xml = XmlParser.from_file(filename)
          str_failures = xml.get_attribute('testsuite', 'failures')
          int_failures = int(str_failures)

          if target and (int_failures > 0):
            failed_targets.append(target)
        except (XmlParser.XmlError, ValueError) as e:
          self._context.log.error('Error parsing test result file {0}: {1}'.format(filename, e))

    return failed_targets
Example #3
0
def parse_failed_targets(test_registry, junit_xml_dir, error_handler):
  """Parses junit xml reports and maps targets to the set of individual tests that failed.

  Targets with no failed tests are omitted from the returned mapping.

  :param test_registry: A registry of tests that were run.
  :type test_registry: :class:`TestRegistry`
  :param string junit_xml_dir: A path to a directory containing test junit xml reports to analyze.
  :param error_handler: An error handler that will be called with any junit xml parsing errors.
  :type error_handler: callable that accepts a single :class:`ParseError` argument.
  :returns: A mapping from targets to the set of individual tests that failed.
  :rtype: dict from :class:`pants.build_graph.target.Target` to a set of :class:`Test`
  """
  failed_targets = defaultdict(set)
  for name in os.listdir(junit_xml_dir):
    if _JUNIT_XML_MATCHER.match(name):
      try:
        path = os.path.join(junit_xml_dir, name)
        xml = XmlParser.from_file(path)
        failures = int(xml.get_attribute('testsuite', 'failures'))
        errors = int(xml.get_attribute('testsuite', 'errors'))
        if failures or errors:
          for testcase in xml.parsed.getElementsByTagName('testcase'):
            test_failed = testcase.getElementsByTagName('failure')
            test_errored = testcase.getElementsByTagName('error')
            if test_failed or test_errored:
              test = Test(classname=testcase.getAttribute('classname'),
                          methodname=testcase.getAttribute('name'))
              target = test_registry.get_owning_target(test)
              failed_targets[target].add(test)
      except (XmlParser.XmlError, ValueError) as e:
        error_handler(ParseError(path, e))

  return dict(failed_targets)
Example #4
0
  def _get_failed_targets(self, test_registry, output_dir):
    """Return a mapping from targets to the set of individual tests that failed.

    Targets with no failed tests are omitted.

    :param test_registry: A registry of tests that were run.
    :type test_registry: :class:`_TestRegistry`
    :param string output_dir: A path to a directory containing test junit xml reports to analyze.
    :returns: A mapping from targets to the set of individual tests that failed.
    :rtype: dict from :class:`pants.build_graph.target.Target` to a set of :class:`_Test`
    """
    failed_targets = defaultdict(set)
    for path in os.listdir(output_dir):
      if self._JUNIT_XML_MATCHER.match(path):
        try:
          xml = XmlParser.from_file(os.path.join(output_dir, path))
          failures = int(xml.get_attribute('testsuite', 'failures'))
          errors = int(xml.get_attribute('testsuite', 'errors'))
          if failures or errors:
            for testcase in xml.parsed.getElementsByTagName('testcase'):
              test_failed = testcase.getElementsByTagName('failure')
              test_errored = testcase.getElementsByTagName('error')
              if test_failed or test_errored:
                test = _Test(classname=testcase.getAttribute('classname'),
                             methodname=testcase.getAttribute('name'))
                target = test_registry.get_owning_target(test)
                failed_targets[target].add(test)
        except (XmlParser.XmlError, ValueError) as e:
          self.context.log.error('Error parsing test result file {0}: {1}'.format(path, e))

    return dict(failed_targets)
Example #5
0
    def parse_xml_file(path):
      try:
        xml = XmlParser.from_file(path)
        for testcase in xml.parsed.getElementsByTagName('testcase'):
          test_info = {}

          try:
            test_info.update({'time': float(testcase.getAttribute('time'))})
          except:
            test_info.update({'time': None})

          for attribute in testcase_attributes:
            test_info[attribute] = testcase.getAttribute(attribute)

          test_error = testcase.getElementsByTagName('error')
          test_fail = testcase.getElementsByTagName('failure')
          test_skip = testcase.getElementsByTagName('skipped')

          if test_fail:
            test_info.update({'result_code': FAILURE})
          elif test_error:
            test_info.update({'result_code': ERROR})
          elif test_skip:
            test_info.update({'result_code': SKIPPED})
          else:
            test_info.update({'result_code': SUCCESS})

          tests_in_path.update({testcase.getAttribute('name'): test_info})

      except (XmlParser.XmlError, ValueError) as e:
        error_handler(ParseError(path, e))
Example #6
0
    def _get_failed_targets(self, tests_and_targets):
        """Return a mapping of target -> set of individual test cases that failed.

    Targets with no failed tests are omitted.

    Analyzes JUnit XML files to figure out which test had failed.

    The individual test cases are formatted strings of the form org.foo.bar.classname#methodName.

    :tests_and_targets: {test: target} mapping.
    """

        def get_test_filename(test_class_name):
            return os.path.join(self.workdir, "TEST-{0}.xml".format(test_class_name.replace("$", "-")))

        xml_filenames_to_targets = defaultdict()
        for test, target in tests_and_targets.items():
            if target is None:
                self.context.log.warn("Unknown target for test %{0}".format(test))

            # Look for a TEST-*.xml file that matches the classname or a containing classname
            test_class_name = test
            for _part in test.split("$"):
                filename = get_test_filename(test_class_name)
                if os.path.exists(filename):
                    xml_filenames_to_targets[filename] = target
                    break
                else:
                    test_class_name = test_class_name.rsplit("$", 1)[0]

        failed_targets = defaultdict(set)
        for xml_filename, target in xml_filenames_to_targets.items():
            try:
                xml = XmlParser.from_file(xml_filename)
                failures = int(xml.get_attribute("testsuite", "failures"))
                errors = int(xml.get_attribute("testsuite", "errors"))

                if target and (failures or errors):
                    for testcase in xml.parsed.getElementsByTagName("testcase"):
                        test_failed = testcase.getElementsByTagName("failure")
                        test_errored = testcase.getElementsByTagName("error")
                        if test_failed or test_errored:
                            failed_targets[target].add(
                                "{testclass}#{testname}".format(
                                    testclass=testcase.getAttribute("classname"), testname=testcase.getAttribute("name")
                                )
                            )
            except (XmlParser.XmlError, ValueError) as e:
                self.context.log.error("Error parsing test result file {0}: {1}".format(xml_filename, e))

        return dict(failed_targets)
Example #7
0
  def _get_failed_targets(self, tests_and_targets):
    """Return a mapping of target -> set of individual test cases that failed.

    Targets with no failed tests are omitted.

    Analyzes JUnit XML files to figure out which test had failed.

    The individual test cases are formatted strings of the form org.foo.bar.classname#methodName.

    :tests_and_targets: {test: target} mapping.
    """

    def get_test_filename(test):
      return os.path.join(self.workdir, 'TEST-{0}.xml'.format(test))

    failed_targets = defaultdict(set)

    for test, target in tests_and_targets.items():
      if target is None:
        self.context.log.warn('Unknown target for test %{0}'.format(test))

      filename = get_test_filename(test)
      if os.path.exists(filename):
        try:
          xml = XmlParser.from_file(filename)
          str_failures = xml.get_attribute('testsuite', 'failures')
          int_failures = int(str_failures)

          str_errors = xml.get_attribute('testsuite', 'errors')
          int_errors = int(str_errors)

          if target and (int_failures or int_errors):
            for testcase in xml.parsed.getElementsByTagName('testcase'):
              test_failed = testcase.getElementsByTagName('failure')
              test_errored = testcase.getElementsByTagName('error')
              if test_failed or test_errored:
                failed_targets[target].add('{testclass}#{testname}'.format(
                  testclass=testcase.getAttribute('classname'),
                  testname=testcase.getAttribute('name'),
                ))
        except (XmlParser.XmlError, ValueError) as e:
          self.context.log.error('Error parsing test result file {0}: {1}'.format(filename, e))
      else:
        # If the test file doesn't exist, then it must have failed before running the tests, so we should
        # ensure this target is in failed_targets, but we don't have details about which testclass#testname
        # failed. Instead we just use the 'test' up to the first '$'.
        test_split = test.split('$')
        failed_targets[target].add(test_split[0])

    return dict(failed_targets)
  def parse_manifest(cls, manifest_path):
    """Parse the file at manifest_path and instantiate the AndroidManifestParser object.

    :param string manifest_path: File path that points to an xml file.
    :return: Object created from the parsed xml.
    :rtype: AndroidManifest
    """
    try:
      manifest = XmlParser.from_file(manifest_path)
      package_name = manifest.get_attribute('manifest', 'package')
    except XmlParser.XmlError as e:
      raise cls.BadManifestError("AndroidManifest.xml parsing error: {}".format(e))
    target_sdk = manifest.get_optional_attribute('uses-sdk', 'android:targetSdkVersion')

    return AndroidManifest(manifest.xml_path, target_sdk, package_name)
Example #9
0
 def parse_junit_xml_file(path):
   try:
     xml = XmlParser.from_file(path)
     failures = int(xml.get_attribute('testsuite', 'failures'))
     errors = int(xml.get_attribute('testsuite', 'errors'))
     if failures or errors:
       for testcase in xml.parsed.getElementsByTagName('testcase'):
         test_failed = testcase.getElementsByTagName('failure')
         test_errored = testcase.getElementsByTagName('error')
         if test_failed or test_errored:
           test = Test(classname=testcase.getAttribute('classname'),
                       methodname=testcase.getAttribute('name'))
           target = test_registry.get_owning_target(test)
           failed_targets[target].add(test)
   except (XmlParser.XmlError, ValueError) as e:
     error_handler(ParseError(path, e))
Example #10
0
    def _get_failed_targets(self, tests_and_targets):
        """Return a mapping of target -> set of individual test cases that failed.

    Targets with no failed tests are omitted.

    Analyzes JUnit XML files to figure out which test had failed.

    The individual test cases are formatted strings of the form org.foo.bar.classname#methodName.

    :tests_and_targets: {test: target} mapping.
    """

        def get_test_filename(test):
            return os.path.join(self._task_exports.workdir, "TEST-{0}.xml".format(test))

        failed_targets = defaultdict(set)

        for test, target in tests_and_targets.items():
            if target is None:
                self._context.log.warn("Unknown target for test %{0}".format(test))

            filename = get_test_filename(test)

            if os.path.exists(filename):
                try:
                    xml = XmlParser.from_file(filename)
                    str_failures = xml.get_attribute("testsuite", "failures")
                    int_failures = int(str_failures)

                    str_errors = xml.get_attribute("testsuite", "errors")
                    int_errors = int(str_errors)

                    if target and (int_failures or int_errors):
                        for testcase in xml.parsed.getElementsByTagName("testcase"):
                            test_failed = testcase.getElementsByTagName("failure")
                            test_errored = testcase.getElementsByTagName("error")
                            if test_failed or test_errored:
                                failed_targets[target].add(
                                    "{testclass}#{testname}".format(
                                        testclass=testcase.getAttribute("classname"),
                                        testname=testcase.getAttribute("name"),
                                    )
                                )
                except (XmlParser.XmlError, ValueError) as e:
                    self._context.log.error("Error parsing test result file {0}: {1}".format(filename, e))

        return dict(failed_targets)
Example #11
0
  def _get_failed_targets_from_junitxml(self, junitxml, targets):
    relsrc_to_target = self._map_relsrc_to_targets(targets)

    # Now find the sources that contained failing tests.
    failed_targets = set()

    try:
      xml = XmlParser.from_file(junitxml)
      failures = int(xml.get_attribute('testsuite', 'failures'))
      errors = int(xml.get_attribute('testsuite', 'errors'))
      if failures or errors:
        for testcase in xml.parsed.getElementsByTagName('testcase'):
          test_failed = testcase.getElementsByTagName('failure')
          test_errored = testcase.getElementsByTagName('error')
          if test_failed or test_errored:
            # The 'file' attribute is a relsrc, because that's what we passed in to pytest.
            failed_targets.add(relsrc_to_target.get(testcase.getAttribute('file')))
    except (XmlParser.XmlError, ValueError) as e:
      raise TaskError('Error parsing xml file at {}: {}'.format(junitxml, e))

    return failed_targets
Example #12
0
  def findbugs(self, target):
    runtime_classpaths = self.context.products.get_data('runtime_classpath')
    runtime_classpath = runtime_classpaths.get_for_targets(target.closure(bfs=True))
    aux_classpath = OrderedSet(jar for conf, jar in runtime_classpath if conf == 'default')

    target_jars = OrderedSet(jar for conf, jar in runtime_classpaths.get_for_target(target) if conf == 'default')

    bug_counts = { 'error': 0, 'high': 0, 'normal': 0, 'low': 0 }

    if not target_jars:
      self.context.log.info('  No jars to be analyzed')
      return bug_counts

    output_dir = os.path.join(self.workdir, target.id)
    safe_mkdir(output_dir)
    output_file = os.path.join(output_dir, 'findbugsXml.xml')

    args = [
      '-auxclasspath', ':'.join(aux_classpath - target_jars),
      '-projectName', target.address.spec,
      '-xml:withMessages',
      '-effort:{}'.format(self.get_options().effort),
      '-{}'.format(self.get_options().threshold),
      '-nested:{}'.format('true' if self.get_options().nested else 'false'),
      '-output', output_file,
      '-noClassOk'
    ]

    if self.get_options().exclude_filter_file:
      args.extend(['-exclude', os.path.join(get_buildroot(), self.get_options().exclude_filter_file)])

    if self.get_options().include_filter_file:
      args.extend(['-include', os.path.join(get_buildroot(), self.get_options().include_filter_file)])

    if self.get_options().max_rank:
      args.extend(['-maxRank', str(self.get_options().max_rank)])

    if self.get_options().relaxed:
      args.extend(['-relaxed'])

    if self.get_options().level == 'debug':
      args.extend(['-progress'])

    args.extend(target_jars)
    result = self.runjava(classpath=self.tool_classpath('findbugs'),
                          main=self._FINDBUGS_MAIN,
                          jvm_options=self.get_options().jvm_options,
                          args=args,
                          workunit_name='findbugs',
                          workunit_labels=[WorkUnitLabel.LINT])
    if result != 0:
      raise TaskError('java {main} ... exited non-zero ({result})'.format(
          main=self._FINDBUGS_MAIN, result=result))

    xml = XmlParser.from_file(output_file)
    for error in xml.parsed.getElementsByTagName('Error'):
      self.context.log.warn('Error: {msg}'.format(
        msg=error.getElementsByTagName('ErrorMessage')[0].firstChild.data))
      bug_counts['error'] += 1

    for bug_instance in xml.parsed.getElementsByTagName('BugInstance'):
      bug_rank = bug_instance.getAttribute('rank')
      if int(bug_rank) <= self._HIGH_PRIORITY_LOWEST_RANK:
        priority = 'high'
      elif int(bug_rank) <= self._NORMAL_PRIORITY_LOWEST_RANK:
        priority = 'normal'
      else:
        priority = 'low'
      bug_counts[priority] += 1

      source_line = bug_instance.getElementsByTagName('Class')[0].getElementsByTagName('SourceLine')[0]
      self.context.log.warn('Bug[{priority}]: {type} {desc} {line}'.format(
        priority=priority,
        type=bug_instance.getAttribute('type'),
        desc=bug_instance.getElementsByTagName('LongMessage')[0].firstChild.data,
        line=source_line.getElementsByTagName('Message')[0].firstChild.data))

    return bug_counts
Example #13
0
  def findbugs(self, targets):
    runtime_classpaths = self.context.products.get_data('runtime_classpath')

    for target in targets:
      if not isinstance(target, (JavaLibrary, JavaTests)):
        self.context.log.debug('Skipping [{}] becuase it is not a java library or java test'.format(target.address.spec))
        continue

      if target.is_synthetic:
        self.context.log.debug('Skipping [{}] because it is a synthetic target'.format(target.address.spec))
        continue

      if self.get_options().exclude_patterns:
        combined_patterns = "(" + ")|(".join(self.get_options().exclude_patterns) + ")"
        if re.match(combined_patterns, target.address.spec):
          self.context.log.debug('Skipping [{}] because it matches exclude pattern'.format(target.address.spec))
          continue

      self.context.log.info(target.address.spec)

      runtime_classpath = runtime_classpaths.get_for_targets(target.closure(bfs=True))
      aux_classpath = OrderedSet(jar for conf, jar in runtime_classpath if conf == 'default')

      target_jars = OrderedSet(jar for conf, jar in runtime_classpaths.get_for_target(target) if conf == 'default')

      if not target_jars:
        self.context.log.info('No jars to be analyzed')
        continue

      output_dir = os.path.join(self.workdir, target.id)
      safe_mkdir(output_dir)
      output_file = os.path.join(output_dir, 'findbugsXml.xml')

      args = [
        '-auxclasspath', ':'.join(aux_classpath - target_jars),
        '-projectName', target.address.spec,
        '-xml:withMessages',
        '-effort:{}'.format(self.get_options().effort),
        '-{}'.format(self.get_options().threshold),
        '-nested:{}'.format('true' if self.get_options().nested else 'false'),
        '-output', output_file,
      ]

      if self.get_options().exclude_filter_file:
        args.extend(['-exclude', os.path.join(get_buildroot(), self.get_options().exclude_filter_file)])

      if self.get_options().include_filter_file:
        args.extend(['-include', os.path.join(get_buildroot(), self.get_options().include_filter_file)])

      if self.get_options().max_rank:
        args.extend(['-maxRank', str(self.get_options().max_rank)])

      if self.get_options().relaxed:
        args.extend(['-relaxed'])

      if self.get_options().level == 'debug':
        args.extend(['-progress'])

      args.extend(target_jars)
      result = self.runjava(classpath=self.tool_classpath('findbugs'),
                            main=self._FINDBUGS_MAIN,
                            jvm_options=self.get_options().jvm_options,
                            args=args,
                            workunit_name='findbugs-command',
                            workunit_labels=[WorkUnitLabel.PREP])
      if result != 0:
        raise TaskError('java {main} ... exited non-zero ({result})'.format(
            main=self._FINDBUGS_MAIN, result=result))

      prioritized_bugs = { 'high': 0, 'normal': 0, 'low': 0 }
      xml = XmlParser.from_file(output_file)
      for bug_instance in xml.parsed.getElementsByTagName('BugInstance'):
        bug_rank = bug_instance.getAttribute('rank')
        if int(bug_rank) <= self._HIGH_PRIORITY_LOWEST_RANK:
          priority = 'high'
        elif int(bug_rank) <= self._NORMAL_PRIORITY_LOWEST_RANK:
          priority = 'normal'
        else:
          priority = 'low'
        prioritized_bugs[priority] += 1

        source_line = bug_instance.getElementsByTagName('Class')[0].getElementsByTagName('SourceLine')[0]
        self.context.log.info('Bug[{priority}]: {type} {desc} {line}'.format(
          priority=priority,
          type=bug_instance.getAttribute('type'),
          desc=bug_instance.getElementsByTagName('LongMessage')[0].firstChild.data,
          src=source_line.getAttribute('classname'),
          line=source_line.getElementsByTagName('Message')[0].firstChild.data))

      prioritized_bugs['total'] = sum(prioritized_bugs.values())
      error_count = len(xml.parsed.getElementsByTagName('Error'))
      if error_count + prioritized_bugs['total'] > 0:
        if self.get_options().fail_on_error:
          raise TaskError('failed with {bug} bugs and {err} errors'.format(
              bug=bug_count, err=error_count))
        if error_count > 0:
          self.context.log.info('Errors: {}'.format(error_count))
        if prioritized_bugs['total'] > 0:
          self.context.log.info("Bugs: {total} (High: {high}, Normal: {normal}, Low: {low})".format(**prioritized_bugs))
Example #14
0
    def findbugs(self, target):
        runtime_classpaths = self.context.products.get_data(
            "runtime_classpath")
        runtime_classpath = runtime_classpaths.get_for_targets(
            target.closure(bfs=True))
        aux_classpath = OrderedSet(jar for conf, jar in runtime_classpath
                                   if conf == "default")

        target_jars = OrderedSet(
            jar for conf, jar in runtime_classpaths.get_for_target(target)
            if conf == "default")

        bug_counts = {"error": 0, "high": 0, "normal": 0, "low": 0}

        if not target_jars:
            self.context.log.info("  No jars to be analyzed")
            return bug_counts

        output_dir = os.path.join(self.workdir, target.id)
        safe_mkdir(output_dir)
        output_file = os.path.join(output_dir, "findbugsXml.xml")

        aux_classpath_file = os.path.join(
            self.workdir, "{}.classpath".format(os.path.basename(output_dir)))
        with open(aux_classpath_file, "w") as f:
            f.write("\n".join(aux_classpath - target_jars))

        args = [
            "-auxclasspathFromFile",
            aux_classpath_file,
            "-projectName",
            target.address.spec,
            "-xml:withMessages",
            "-effort:{}".format(self.get_options().effort),
            "-{}".format(self.get_options().threshold),
            "-nested:{}".format(
                "true" if self.get_options().nested else "false"),
            "-output",
            output_file,
            "-noClassOk",
        ]

        if self.get_options().exclude_filter_file:
            args.extend([
                "-exclude",
                os.path.join(get_buildroot(),
                             self.get_options().exclude_filter_file)
            ])

        if self.get_options().include_filter_file:
            args.extend([
                "-include",
                os.path.join(get_buildroot(),
                             self.get_options().include_filter_file)
            ])

        if self.get_options().max_rank:
            args.extend(["-maxRank", str(self.get_options().max_rank)])

        if self.get_options().relaxed:
            args.extend(["-relaxed"])

        if self.debug:
            args.extend(["-progress"])

        args.extend(target_jars)

        # Try to run spotbugs with the same java version as the target
        # The minimum JDK for spotbugs is JDK 1.8
        min_jdk_version = max(target.platform.target_level,
                              Revision.lenient("1.8"))
        if min_jdk_version.components[0] == 1:
            max_jdk_version = Revision(min_jdk_version.components[0],
                                       min_jdk_version.components[1], "9999")
        else:
            max_jdk_version = Revision(min_jdk_version.components[0], "9999")

        self.set_distribution(minimum_version=min_jdk_version,
                              maximum_version=max_jdk_version,
                              jdk=True)

        result = self.runjava(
            classpath=self.tool_classpath("findbugs"),
            main=self._FINDBUGS_MAIN,
            jvm_options=self.get_options().jvm_options,
            args=args,
            workunit_name="findbugs",
            workunit_labels=[WorkUnitLabel.LINT],
        )
        if result != 0:
            raise TaskError(
                "java {main} ... exited non-zero ({result})".format(
                    main=self._FINDBUGS_MAIN, result=result))

        xml = XmlParser.from_file(output_file)
        for error in xml.parsed.getElementsByTagName("Error"):
            self.context.log.warn(
                "Error: {msg}".format(msg=error.getElementsByTagName(
                    "ErrorMessage")[0].firstChild.data))
            bug_counts["error"] += 1

        for bug_instance in xml.parsed.getElementsByTagName("BugInstance"):
            bug_rank = bug_instance.getAttribute("rank")
            if int(bug_rank) <= self._HIGH_PRIORITY_LOWEST_RANK:
                priority = "high"
            elif int(bug_rank) <= self._NORMAL_PRIORITY_LOWEST_RANK:
                priority = "normal"
            else:
                priority = "low"
            bug_counts[priority] += 1

            source_line = bug_instance.getElementsByTagName(
                "Class")[0].getElementsByTagName("SourceLine")[0]
            self.context.log.warn(
                "Bug[{priority}]: {type} {desc} {line}".format(
                    priority=priority,
                    type=bug_instance.getAttribute("type"),
                    desc=bug_instance.getElementsByTagName(
                        "LongMessage")[0].firstChild.data,
                    line=source_line.getElementsByTagName("Message")
                    [0].firstChild.data,
                ))

        return bug_counts
Example #15
0
 def test_get_attribute(self):
   with self.xml_file() as xml:
     parser = XmlParser.from_file(xml)
     self.assertEqual('com.pants.examples.hello', parser.get_attribute('manifest', 'package'))
Example #16
0
 def test_parsed(self):
     with self.xml_file() as xml:
         parser = XmlParser.from_file(xml)
         self.assertEqual(isinstance(parser.parsed, Document), True)
Example #17
0
 def test_undeclared_element(self):
     with self.assertRaises(XmlParser.XmlError):
         with self.xml_file(
                 android_name_attribute='undeclared:targetSdkVersion'
         ) as xml:
             XmlParser._parse(xml)
Example #18
0
 def test_bad_path(self):
     with self.assertRaises(XmlParser.XmlError):
         xml = '/no/file/here'
         XmlParser.from_file(xml)
Example #19
0
 def test_xml_path(self):
     with self.xml_file() as xml:
         parser = XmlParser.from_file(xml)
         self.assertEqual(xml, parser.xml_path)
Example #20
0
 def test_missing_element(self):
     with self.assertRaises(XmlParser.XmlError):
         with self.xml_file() as xml:
             parser = XmlParser.from_file(xml)
             self.assertEqual("not_present", parser.get_attribute("manifest", "missing_element"))
Example #21
0
 def test_get_attribute(self):
     with self.xml_file() as xml:
         parser = XmlParser.from_file(xml)
         self.assertEqual('org.pantsbuild.example.hello',
                          parser.get_attribute('manifest', 'package'))
Example #22
0
 def test_parse(self):
     with self.xml_file() as xml:
         parser = XmlParser.from_file(xml)
         self.assertEqual('manifest', parser.parsed.documentElement.tagName)
Example #23
0
 def test_parsed(self):
     with self.xml_file() as xml:
         parser = XmlParser.from_file(xml)
         self.assertEqual(isinstance(parser.parsed, Document), True)
Example #24
0
 def test_bad_path(self):
     with self.assertRaises(XmlParser.XmlError):
         xml = "/no/file/here"
         XmlParser.from_file(xml)
Example #25
0
 def test_from_file(self):
     with self.xml_file() as xml:
         parser = XmlParser.from_file(xml)
         self.assertEqual(isinstance(parser, XmlParser), True)
Example #26
0
 def test_empty_attribute(self):
     with self.assertRaises(XmlParser.XmlError):
         with self.xml_file(package_attribute='') as xml:
             XmlParser.from_file(xml)
Example #27
0
 def test_empty_attribute(self):
     with self.assertRaises(XmlParser.XmlError):
         with self.xml_file(package_attribute="") as xml:
             XmlParser.from_file(xml)
Example #28
0
 def test_empty_element(self):
     with self.assertRaises(XmlParser.XmlError):
         with self.xml_file(manifest_element='') as xml:
             XmlParser.from_file(xml)
Example #29
0
 def test_empty_element(self):
     with self.assertRaises(XmlParser.XmlError):
         with self.xml_file(manifest_element="") as xml:
             XmlParser.from_file(xml)
Example #30
0
 def test_from_file(self):
     with self.xml_file() as xml:
         parser = XmlParser.from_file(xml)
         self.assertEqual(isinstance(parser, XmlParser), True)
Example #31
0
 def test_undeclared_element(self):
     with self.assertRaises(XmlParser.XmlError):
         with self.xml_file(android_name_attribute="undeclared:targetSdkVersion") as xml:
             XmlParser._parse(xml)
Example #32
0
 def test_xml_path(self):
     with self.xml_file() as xml:
         parser = XmlParser.from_file(xml)
         self.assertEqual(xml, parser.xml_path)
Example #33
0
 def test_missing_attribute(self):
   with self.assertRaises(XmlParser.XmlError):
     with self.xml_file() as xml:
       parser = XmlParser.from_file(xml)
       self.assertEqual('not_present', parser.get_attribute('missing_attribute', 'package'))
Example #34
0
 def test_parse(self):
     with self.xml_file() as xml:
         parser = XmlParser.from_file(xml)
         self.assertEqual("manifest", parser.parsed.documentElement.tagName)
Example #35
0
 def test_get_attribute(self):
     with self.xml_file() as xml:
         parser = XmlParser.from_file(xml)
         self.assertEqual("org.pantsbuild.example.hello", parser.get_attribute("manifest", "package"))
Example #36
0
  def findbugs(self, target):
    runtime_classpaths = self.context.products.get_data('runtime_classpath')
    runtime_classpath = runtime_classpaths.get_for_targets(target.closure(bfs=True))
    aux_classpath = OrderedSet(jar for conf, jar in runtime_classpath if conf == 'default')

    target_jars = OrderedSet(jar for conf, jar in runtime_classpaths.get_for_target(target) if conf == 'default')

    bug_counts = { 'error': 0, 'high': 0, 'normal': 0, 'low': 0 }

    if not target_jars:
      self.context.log.info('No jars to be analyzed')
      return bug_counts

    output_dir = os.path.join(self.workdir, target.id)
    safe_mkdir(output_dir)
    output_file = os.path.join(output_dir, 'findbugsXml.xml')

    args = [
      '-auxclasspath', ':'.join(aux_classpath - target_jars),
      '-projectName', target.address.spec,
      '-xml:withMessages',
      '-effort:{}'.format(self.get_options().effort),
      '-{}'.format(self.get_options().threshold),
      '-nested:{}'.format('true' if self.get_options().nested else 'false'),
      '-output', output_file,
      '-noClassOk'
    ]

    if self.get_options().exclude_filter_file:
      args.extend(['-exclude', os.path.join(get_buildroot(), self.get_options().exclude_filter_file)])

    if self.get_options().include_filter_file:
      args.extend(['-include', os.path.join(get_buildroot(), self.get_options().include_filter_file)])

    if self.get_options().max_rank:
      args.extend(['-maxRank', str(self.get_options().max_rank)])

    if self.get_options().relaxed:
      args.extend(['-relaxed'])

    if self.get_options().level == 'debug':
      args.extend(['-progress'])

    args.extend(target_jars)
    result = self.runjava(classpath=self.tool_classpath('findbugs'),
                          main=self._FINDBUGS_MAIN,
                          jvm_options=self.get_options().jvm_options,
                          args=args,
                          workunit_name='findbugs',
                          workunit_labels=[WorkUnitLabel.PREP])
    self.context.log.info(target.address.spec)
    if result != 0:
      raise TaskError('java {main} ... exited non-zero ({result})'.format(
          main=self._FINDBUGS_MAIN, result=result))

    xml = XmlParser.from_file(output_file)
    for error in xml.parsed.getElementsByTagName('Error'):
      self.context.log.warn('Error: {msg}'.format(
        msg=error.getElementsByTagName('ErrorMessage')[0].firstChild.data))
      bug_counts['error'] += 1

    for bug_instance in xml.parsed.getElementsByTagName('BugInstance'):
      bug_rank = bug_instance.getAttribute('rank')
      if int(bug_rank) <= self._HIGH_PRIORITY_LOWEST_RANK:
        priority = 'high'
      elif int(bug_rank) <= self._NORMAL_PRIORITY_LOWEST_RANK:
        priority = 'normal'
      else:
        priority = 'low'
      bug_counts[priority] += 1

      source_line = bug_instance.getElementsByTagName('Class')[0].getElementsByTagName('SourceLine')[0]
      self.context.log.warn('Bug[{priority}]: {type} {desc} {line}'.format(
        priority=priority,
        type=bug_instance.getAttribute('type'),
        desc=bug_instance.getElementsByTagName('LongMessage')[0].firstChild.data,
        src=source_line.getAttribute('classname'),
        line=source_line.getElementsByTagName('Message')[0].firstChild.data))

    return bug_counts
Example #37
0
 def test_get_attribute(self):
     with self.xml_file() as xml:
         parser = XmlParser.from_file(xml)
         self.assertEqual("org.pantsbuild.example.hello",
                          parser.get_attribute("manifest", "package"))