Пример #1
0
class JunitRunIntegrationTest(PantsRunIntegrationTest):

  def _testjvms(self, spec_name):
    spec = 'testprojects/tests/java/org/pantsbuild/testproject/testjvms:{}'.format(spec_name)
    self.assert_success(self.run_pants(['clean-all', 'test.junit', '--strict-jvm-version', spec]))

  @skipIf(is_missing_jvm('1.8'), 'no java 1.8 installation on testing machine')
  def test_java_eight(self):
    self._testjvms('eight')

  @skipIf(is_missing_jvm('1.8'), 'no java 1.8 installation on testing machine')
  def test_with_test_platform(self):
    self._testjvms('eight-test-platform')

  def test_junit_run_against_class_succeeds(self):
    pants_run = self.run_pants(['clean-all',
                                'test.junit',
                                '--test=org.pantsbuild.testproject.matcher.MatcherTest',
                                'testprojects/tests/java/org/pantsbuild/testproject/matcher'])
    self.assert_success(pants_run)

  def report_file_path(self, relpath):
    return os.path.join(get_buildroot(), 'dist', relpath)

  def cucumber_coverage(self, processor, xml_path, html_path, tests=(), args=()):
    return self.coverage(
      processor,
      xml_path,
      html_path,
      'testprojects/tests/java/org/pantsbuild/testproject/unicode/cucumber',
      'org.pantsbuild.testproject.unicode.cucumber.CucumberTest',
      tests,
      args
    )

  @contextmanager
  def coverage(self, processor, xml_path, html_path, test_project, test_class='', tests=(), args=()):
    def test_specifier_arg(test):
      return '--test={}#{}'.format(test_class, test)

    with self.pants_results(['clean-all', 'test.junit'] + list(args) +
                            [test_specifier_arg(name) for name in tests] +
                            [test_project,
                             '--test-junit-coverage-processor={}'.format(processor),
                             '--test-junit-coverage']) as results:
      self.assert_success(results)

      coverage_xml = self.report_file_path(xml_path)
      self.assertTrue(os.path.isfile(coverage_xml))

      coverage_html = self.report_file_path(html_path)
      self.assertTrue(os.path.isfile(coverage_html))

      def read_utf8(path):
        with codecs.open(path, 'r', encoding='utf8') as fp:
          return fp.read()

      yield ET.parse(coverage_xml).getroot(), read_utf8(coverage_html)

  def do_test_junit_run_with_coverage_succeeds_cobertura(self, tests=(), args=()):
    html_path = ('test/junit/coverage/reports/html/'
                 'org.pantsbuild.testproject.unicode.cucumber.CucumberAnnotatedExample.html')
    with self.cucumber_coverage(processor='cobertura',
                                xml_path='test/junit/coverage/reports/xml/coverage.xml',
                                html_path=html_path,
                                tests=tests,
                                args=args) as (xml_report, html_report_string):

      # Validate 100% coverage; ie a line coverage rate of 1.
      self.assertEqual('coverage', xml_report.tag)
      self.assertEqual(1.0, float(xml_report.attrib['line-rate']))

      # Validate that the html report was able to find sources for annotation.
      self.assertIn('String pleasantry1()', html_report_string)
      self.assertIn('String pleasantry2()', html_report_string)
      self.assertIn('String pleasantry3()', html_report_string)

  def test_junit_run_with_coverage_succeeds_cobertura(self):
    self.do_test_junit_run_with_coverage_succeeds_cobertura()

  def test_junit_run_with_coverage_succeeds_cobertura_merged(self):
    self.do_test_junit_run_with_coverage_succeeds_cobertura(tests=['testUnicodeClass1',
                                                                   'testUnicodeClass2',
                                                                   'testUnicodeClass3'],
                                                            args=['--batch-size=2'])

  def do_test_junit_run_with_coverage_succeeds_jacoco(self, tests=(), args=()):
    html_path = ('test/junit/coverage/reports/html/'
                 'org.pantsbuild.testproject.unicode.cucumber/CucumberAnnotatedExample.html')
    with self.cucumber_coverage(processor='jacoco',
                                xml_path='test/junit/coverage/reports/xml',
                                html_path=html_path,
                                tests=tests,
                                args=args) as (xml_report, html_report_string):

      # Validate 100% coverage; ie: 0 missed instructions.
      self.assertEqual('report', xml_report.tag)
      counters = xml_report.findall('counter[@type="INSTRUCTION"]')
      self.assertEqual(1, len(counters))

      total_instruction_counter = counters[0]
      self.assertEqual(0, int(total_instruction_counter.attrib['missed']))
      self.assertGreater(int(total_instruction_counter.attrib['covered']), 0)

      # Validate that the html report was able to find sources for annotation.
      self.assertIn('class="el_method">pleasantry1()</a>', html_report_string)
      self.assertIn('class="el_method">pleasantry2()</a>', html_report_string)
      self.assertIn('class="el_method">pleasantry3()</a>', html_report_string)

  def test_junit_run_with_coverage_succeeds_jacoco(self):
    self.do_test_junit_run_with_coverage_succeeds_jacoco()

  def test_junit_run_with_coverage_succeeds_jacoco_merged(self):
    self.do_test_junit_run_with_coverage_succeeds_jacoco(tests=['testUnicodeClass1',
                                                                'testUnicodeClass2',
                                                                'testUnicodeClass3'],
                                                         args=['--batch-size=2'])

  def test_junit_run_with_coverage_filters_targets_jacoco(self):
    coverage_test_project = 'testprojects/tests/java/org/pantsbuild/testproject/coverage'
    html_path = ('test/junit/coverage/reports/html/'
                 'index.html')
    filter_arg = '--jacoco-target-filters=one'

    with self.coverage(processor='jacoco',
                       xml_path='test/junit/coverage/reports/xml',
                       html_path=html_path,
                       test_project=coverage_test_project,
                       args=[filter_arg]) as (xml_report, html_report_string):

      coverage_one = xml_report.find('package/class[@name="org/pantsbuild/testproject/coverage/one/CoverageClassOne"]')
      coverage_two = xml_report.find('package/class[@name="org/pantsbuild/testproject/coverage/two/CoverageClassTwo"]')
      self.assertNotEqual(None, coverage_one)
      self.assertEqual(None, coverage_two)

  def test_junit_run_against_invalid_class_fails(self):
    pants_run = self.run_pants(['clean-all',
                                'test.junit',
                                '--test=org.pantsbuild.testproject.matcher.MatcherTest_BAD_CLASS',
                                'testprojects/tests/java/org/pantsbuild/testproject/matcher'])
    self.assert_failure(pants_run)
    self.assertIn("No target found for test specifier", pants_run.stdout_data)

  def test_junit_run_timeout_succeeds(self):
    sleeping_target = 'testprojects/tests/java/org/pantsbuild/testproject/timeout:sleeping_target'
    pants_run = self.run_pants(['clean-all',
                                'test.junit',
                                '--timeouts',
                                '--timeout-default=5',
                                '--timeout-terminate-wait=1',
                                '--test=org.pantsbuild.testproject.timeout.ShortSleeperTest',
                                sleeping_target])
    self.assert_success(pants_run)

  def test_junit_run_timeout_fails(self):
    sleeping_target = 'testprojects/tests/java/org/pantsbuild/testproject/timeout:sleeping_target'
    start = time.time()
    pants_run = self.run_pants(['clean-all',
                                'test.junit',
                                '--timeouts',
                                '--timeout-default=5',
                                '--timeout-terminate-wait=1',
                                '--test=org.pantsbuild.testproject.timeout.LongSleeperTest',
                                sleeping_target])
    end = time.time()
    self.assert_failure(pants_run)

    # Ensure that the failure took less than 120 seconds to run.
    self.assertLess(end - start, 120)

    # Ensure that the timeout triggered.
    self.assertIn(" timed out after 5 seconds", pants_run.stdout_data)

  def test_junit_tests_using_cucumber(self):
    test_spec = 'testprojects/tests/java/org/pantsbuild/testproject/cucumber'
    with self.pants_results(['clean-all', 'test.junit', '--per-test-timer', test_spec]) as results:
      self.assert_success(results)

  def test_disable_synthetic_jar(self):
    synthetic_jar_target = 'testprojects/tests/java/org/pantsbuild/testproject/syntheticjar:test'
    output = self.run_pants(['test.junit', '--output-mode=ALL', synthetic_jar_target]).stdout_data
    self.assertIn('Synthetic jar run is detected', output)

    output = self.run_pants(['test.junit',
                             '--output-mode=ALL',
                             '--no-jvm-synthetic-classpath',
                             synthetic_jar_target]).stdout_data
    self.assertIn('Synthetic jar run is not detected', output)

  def do_test_junit_run_with_html_report(self, tests=(), args=()):
    def html_report_test(test):
      return '--test=org.pantsbuild.testproject.htmlreport.HtmlReportTest#{}'.format(test)

    with self.pants_results(['clean-all', 'test.junit'] + list(args) +
                            [html_report_test(name) for name in tests] +
                            ['testprojects/tests/java/org/pantsbuild/testproject/htmlreport::',
                             '--test-junit-html-report']) as results:
      self.assert_failure(results)
      report_html = self.report_file_path('test/junit/reports/junit-report.html')
      self.assertTrue(os.path.isfile(report_html))
      with codecs.open(report_html, 'r', encoding='utf8') as src:
        html = src.read()
        self.assertIn('testPasses', html)
        self.assertIn('testFails', html)
        self.assertIn('testErrors', html)
        self.assertIn('testSkipped', html)

  def test_junit_run_with_html_report(self):
    self.do_test_junit_run_with_html_report()

  def test_junit_run_with_html_report_merged(self):
    self.do_test_junit_run_with_html_report(tests=['testPasses',
                                                   'testFails',
                                                   'testErrors',
                                                   'testSkipped'],
                                            args=['--batch-size=3'])
# coding=utf-8
# Copyright 2014 Pants project contributors (see CONTRIBUTORS.md).
# Licensed under the Apache License, Version 2.0 (see LICENSE).

from __future__ import absolute_import, division, print_function, unicode_literals

from unittest import skipIf

from pants_test.backend.jvm.tasks.jvm_compile.base_compile_integration_test import BaseCompileIT
from pants_test.backend.jvm.tasks.missing_jvm_check import is_missing_jvm


@skipIf(is_missing_jvm('1.8'), 'no java 1.8 installation on testing machine')
class JavacPluginIntegrationTest(BaseCompileIT):
    example_dir = 'examples/src/java/org/pantsbuild/example/javac/plugin'

    def _do_test(self, expected_args, config, target):
        with self.temporary_workdir() as workdir:
            pants_run = self.run_pants_with_workdir(
                ['compile', '{}:{}'.format(self.example_dir, target)], workdir,
                config)
        self.assert_success(pants_run)
        self.assertIn(
            'SimpleJavacPlugin ran with {} args: {}'.format(
                len(expected_args), ' '.join(expected_args)),
            pants_run.stdout_data)

    # Note that in the terminology of this test, "global" means specified via options for
    # all targets, and "local" means specified on an individual target.
    def _do_test_global(self, args):
        config = {
# Copyright 2014 Pants project contributors (see CONTRIBUTORS.md).
# Licensed under the Apache License, Version 2.0 (see LICENSE).

from unittest import skipIf

from pants_test.backend.jvm.tasks.jvm_compile.base_compile_integration_test import BaseCompileIT
from pants_test.backend.jvm.tasks.missing_jvm_check import is_missing_jvm


@skipIf(is_missing_jvm("1.8"), "no java 1.8 installation on testing machine")
class JavacPluginIntegrationTest(BaseCompileIT):
    example_dir = "examples/src/java/org/pantsbuild/example/javac/plugin"

    def _do_test(self, expected_args, config, target):
        with self.temporary_workdir() as workdir:
            pants_run = self.run_pants_with_workdir(
                ["compile", f"{self.example_dir}:{target}"], workdir, config)
        self.assert_success(pants_run)
        self.assertIn(
            "SimpleJavacPlugin ran with {} args: {}".format(
                len(expected_args), " ".join(expected_args)),
            pants_run.stdout_data,
        )

    # Note that in the terminology of this test, "global" means specified via options for
    # all targets, and "local" means specified on an individual target.
    def _do_test_global(self, args):
        config = {
            "java": {
                "javac_plugins": ["simple_javac_plugin"],
                "javac_plugin_args": {
class ZincCompileIntegrationTest(BaseCompileIT):
    def test_java_src_zinc_compile(self):
        # TODO: Remove the --exclude-target-regexp once we're on Java 8 everywhere.
        with self.do_test_compile(
                'examples/src/java/::',
                extra_args=
            [
                '--exclude-target-regexp=examples/src/java/org/pantsbuild/example/plugin'
            ]):
            # run succeeded as expected
            pass
        with self.do_test_compile('examples/tests/java/::'):
            # run succeeded as expected
            pass

    def test_in_process(self):
        with self.temporary_workdir() as workdir:
            with self.temporary_cachedir() as cachedir:
                pants_run = self.run_test_compile(
                    workdir,
                    cachedir,
                    'examples/src/java/org/pantsbuild/example/hello/main',
                    extra_args=['-ldebug'],
                    clean_all=True)
                self.assertIn(
                    'Attempting to call com.sun.tools.javac.api.JavacTool',
                    pants_run.stdout_data)
                self.assertNotIn('Forking javac', pants_run.stdout_data)

    def test_log_level(self):
        with self.temporary_workdir() as workdir:
            with self.temporary_cachedir() as cachedir:
                target = 'testprojects/src/java/org/pantsbuild/testproject/dummies:compilation_failure_target'
                pants_run = self.run_test_compile(workdir,
                                                  cachedir,
                                                  target,
                                                  extra_args=['--no-colors'],
                                                  clean_all=True)
                self.assertIn('[warn] import sun.security.x509.X500Name;',
                              pants_run.stdout_data)
                self.assertIn(
                    '[error]     System2.out.println("Hello World!");',
                    pants_run.stdout_data)

    def test_unicode_source_symbol(self):
        with self.temporary_workdir() as workdir:
            with self.temporary_cachedir() as cachedir:
                target = 'testprojects/src/scala/org/pantsbuild/testproject/unicode/unicodedep/consumer'
                pants_run = self.run_test_compile(
                    workdir,
                    cachedir,
                    target,
                    extra_args=[
                        '--cache-compile-zinc-write-to=["{}/dummy_artifact_cache_dir"]'
                        .format(cachedir),
                    ],
                    clean_all=True,
                )
                self.assert_success(pants_run)

    def test_apt_compile(self):
        with self.do_test_compile(
                'testprojects/src/java/org/pantsbuild/testproject/annotation/processor',
                expected_files=[
                    'ResourceMappingProcessor.class',
                    'javax.annotation.processing.Processor'
                ]) as found:

            self.assertTrue(
                self.get_only(found, 'ResourceMappingProcessor.class').
                endswith(
                    'org/pantsbuild/testproject/annotation/processor/ResourceMappingProcessor.class'
                ))

            processor_service_files = found[
                'javax.annotation.processing.Processor']
            # There should be only a per-target service info file.
            self.assertEqual(1, len(processor_service_files))
            processor_service_file = list(processor_service_files)[0]
            self.assertTrue(
                processor_service_file.endswith(
                    'META-INF/services/javax.annotation.processing.Processor'))
            with open(processor_service_file) as fp:
                self.assertEqual(
                    'org.pantsbuild.testproject.annotation.processor.ResourceMappingProcessor',
                    fp.read().strip())

    def test_apt_compile_and_run(self):
        with self.do_test_compile(
                'testprojects/src/java/org/pantsbuild/testproject/annotation/main',
                expected_files=['Main.class',
                                'deprecation_report.txt']) as found:

            self.assertTrue(
                self.get_only(found, 'Main.class').endswith(
                    'org/pantsbuild/testproject/annotation/main/Main.class'))

            # This is the proof that the ResourceMappingProcessor annotation processor was compiled in a
            # round and then the Main was compiled in a later round with the annotation processor and its
            # service info file from on its compile classpath.
            with open(self.get_only(found, 'deprecation_report.txt')) as fp:
                self.assertIn(
                    'org.pantsbuild.testproject.annotation.main.Main',
                    fp.read().splitlines())

    def test_stale_apt_with_deps(self):
        """An annotation processor with a dependency doesn't pollute other annotation processors.

    At one point, when you added an annotation processor, it stayed configured for all subsequent
    compiles.  Meaning that if that annotation processor had a dep that wasn't on the classpath,
    subsequent compiles would fail with missing symbols required by the stale annotation processor.
    """

        # Demonstrate that the annotation processor is working
        with self.do_test_compile(
                'testprojects/src/java/org/pantsbuild/testproject/annotation/processorwithdep/main',
                expected_files=[
                    'Main.class', 'Main_HelloWorld.class',
                    'Main_HelloWorld.java'
                ]) as found:
            gen_file = self.get_only(found, 'Main_HelloWorld.java')
            self.assertTrue(gen_file.endswith(
                'org/pantsbuild/testproject/annotation/processorwithdep/main/Main_HelloWorld.java'
            ),
                            msg='{} does not match'.format(gen_file))

        # Try to reproduce second compile that fails with missing symbol
        with self.temporary_workdir() as workdir:
            with self.temporary_cachedir() as cachedir:
                # This annotation processor has a unique external dependency
                self.assert_success(
                    self.run_test_compile(
                        workdir, cachedir,
                        'testprojects/src/java/org/pantsbuild/testproject/annotation/processorwithdep::'
                    ))

                # When we run a second compile with annotation processors, make sure the previous annotation
                # processor doesn't stick around to spoil the compile
                self.assert_success(
                    self.run_test_compile(
                        workdir,
                        cachedir,
                        'testprojects/src/java/org/pantsbuild/testproject/annotation/processor::',
                        clean_all=False))

    def test_fatal_warning(self):
        def test_combination(target, default_fatal_warnings, expect_success):
            with self.temporary_workdir() as workdir:
                with self.temporary_cachedir() as cachedir:
                    if default_fatal_warnings:
                        arg = '--java-fatal-warnings'
                    else:
                        arg = '--no-java-fatal-warnings'
                    pants_run = self.run_test_compile(
                        workdir,
                        cachedir,
                        'testprojects/src/java/org/pantsbuild/testproject/compilation_warnings:{}'
                        .format(target),
                        extra_args=[
                            arg, '--compile-zinc-warning-args=-C-Xlint:all'
                        ])

                    if expect_success:
                        self.assert_success(pants_run)
                    else:
                        self.assert_failure(pants_run)

        test_combination('defaultfatal',
                         default_fatal_warnings=True,
                         expect_success=False)
        test_combination('defaultfatal',
                         default_fatal_warnings=False,
                         expect_success=True)
        test_combination('fatal',
                         default_fatal_warnings=True,
                         expect_success=False)
        test_combination('fatal',
                         default_fatal_warnings=False,
                         expect_success=False)
        test_combination('nonfatal',
                         default_fatal_warnings=True,
                         expect_success=True)
        test_combination('nonfatal',
                         default_fatal_warnings=False,
                         expect_success=True)

    def test_classpath_does_not_include_extra_classes_dirs(self):
        target_rel_spec = 'testprojects/src/java/org/pantsbuild/testproject/phrases:'
        classpath_file_by_target_id = {}
        for target_name in [
                'there-was-a-duck', 'lesser-of-two', 'once-upon-a-time',
                'ten-thousand'
        ]:
            target_id = Target.compute_target_id(
                Address.parse('{}{}'.format(target_rel_spec, target_name)))
            classpath_file_by_target_id[target_id] = '{}.txt'.format(target_id)

        with self.do_test_compile(
                target_rel_spec,
                expected_files=classpath_file_by_target_id.values(),
                extra_args=['--compile-zinc-capture-classpath']) as found:
            for target_id, filename in classpath_file_by_target_id.items():
                found_classpath_file = self.get_only(found, filename)
                with open(found_classpath_file, 'r') as f:
                    contents = f.read()

                    self.assertIn(target_id, contents)

                    other_target_ids = set(
                        classpath_file_by_target_id.keys()) - {target_id}
                    for other_id in other_target_ids:
                        self.assertNotIn(other_id, contents)

    def test_record_classpath(self):
        target_spec = 'testprojects/src/java/org/pantsbuild/testproject/printversion:printversion'
        target_id = Target.compute_target_id(Address.parse(target_spec))
        classpath_filename = '{}.txt'.format(target_id)
        with self.do_test_compile(
                target_spec,
                expected_files=[classpath_filename, 'PrintVersion.class'],
                extra_args=['--compile-zinc-capture-classpath']) as found:
            found_classpath_file = self.get_only(found, classpath_filename)
            self.assertTrue(
                found_classpath_file.endswith(
                    os.path.join('compile_classpath', classpath_filename)))
            with open(found_classpath_file, 'r') as f:
                self.assertIn(target_id, f.read())

    def test_no_record_classpath(self):
        target_spec = 'testprojects/src/java/org/pantsbuild/testproject/printversion:printversion'
        target_id = Target.compute_target_id(Address.parse(target_spec))
        classpath_filename = '{}.txt'.format(target_id)
        with self.do_test_compile(
                target_spec,
                expected_files=['PrintVersion.class'],
                extra_args=['--no-compile-zinc-capture-classpath']) as found:
            self.assertFalse(classpath_filename in found)

    @skipIf(is_missing_jvm('1.8'),
            'no java 1.8 installation on testing machine')
    def test_custom_javac(self):
        with self.temporary_workdir() as workdir:
            with self.temporary_cachedir() as cachedir:
                pants_run = self.run_test_compile(
                    workdir,
                    cachedir,
                    'examples/src/java/org/pantsbuild/example/hello/main',
                    extra_args=[
                        '--java-javac=testprojects/3rdparty/javactool:custom_javactool_for_testing'
                    ],
                    clean_all=True)
                self.assertNotEquals(
                    0,
                    pants_run.returncode)  # Our custom javactool always fails.
                self.assertIn('Pants caused Zinc to load a custom JavacTool',
                              pants_run.stdout_data)

    def test_no_zinc_file_manager(self):
        target_spec = 'testprojects/src/java/org/pantsbuild/testproject/bench:jmh'
        with self.temporary_workdir() as workdir:
            with self.temporary_cachedir() as cachedir:
                pants_run = self.run_test_compile(workdir,
                                                  cachedir,
                                                  target_spec,
                                                  clean_all=True)
                self.assertEquals(0, pants_run.returncode)
# coding=utf-8
# Copyright 2014 Pants project contributors (see CONTRIBUTORS.md).
# Licensed under the Apache License, Version 2.0 (see LICENSE).

from __future__ import (absolute_import, division, generators, nested_scopes, print_function,
                        unicode_literals, with_statement)

from unittest import skipIf

from pants_test.backend.jvm.tasks.jvm_compile.base_compile_integration_test import BaseCompileIT
from pants_test.backend.jvm.tasks.missing_jvm_check import is_missing_jvm


@skipIf(is_missing_jvm('1.8'), 'no java 1.8 installation on testing machine')
class JavacPluginIntegrationTest(BaseCompileIT):
  # A target without a dep on the plugin.
  independent_tgt = 'testprojects/src/java/org/pantsbuild/testproject/publish/hello/main'

  # A target with a dep on the plugin.
  dependent_tgt = 'examples/src/java/org/pantsbuild/example/plugin:hello_plugin'

  def _do_test_plugin(self, args, compile_tgt, global_plugin):
    config = {
      'compile.zinc': {
        'javac_plugins': 'simple_javac_plugin',
        'javac_plugin_args': {
          'simple_javac_plugin': args
        }
      }
    }
    if global_plugin:
Пример #6
0
class ZincCompileIntegrationTest(BaseCompileIT):

  def test_java_src_zinc_compile(self):
    with self.do_test_compile('examples/src/java/::'):
      # run succeeded as expected
      pass
    with self.do_test_compile('examples/tests/java/::'):
      # run succeeded as expected
      pass

  def test_in_process(self):
    with self.temporary_workdir() as workdir:
      with self.temporary_cachedir() as cachedir:
        pants_run = self.run_test_compile(
          workdir, cachedir, 'examples/src/java/org/pantsbuild/example/hello/main',
          extra_args=['-ldebug'], clean_all=True
        )
        self.assertIn('Attempting to call com.sun.tools.javac.api.JavacTool', pants_run.stdout_data)
        self.assertNotIn('Forking javac', pants_run.stdout_data)

  def test_log_level(self):
    with self.temporary_workdir() as workdir:
      with self.temporary_cachedir() as cachedir:
        target = 'testprojects/src/java/org/pantsbuild/testproject/dummies:compilation_failure_target'
        pants_run = self.run_test_compile(
          workdir, cachedir, target,
          extra_args=['--no-colors'], clean_all=True
        )
        self.assert_failure(pants_run)
        self.assertIn('[warn] import sun.security.x509.X500Name;', pants_run.stdout_data)
        self.assertIn('[error]     System2.out.println("Hello World!");', pants_run.stdout_data)

  def test_unicode_source_symbol(self):
    with self.temporary_workdir() as workdir:
      with self.temporary_cachedir() as cachedir:
        target = 'testprojects/src/scala/org/pantsbuild/testproject/unicode/unicodedep/consumer'
        pants_run = self.run_test_compile(
          workdir, cachedir, target,
          extra_args=[
            '--cache-compile-zinc-write-to=["{}/dummy_artifact_cache_dir"]'.format(cachedir),
          ],
          clean_all=True,
        )
        self.assert_success(pants_run)

  def test_fatal_warning(self):
    def test_combination(target, expect_success):
      with self.temporary_workdir() as workdir:
        with self.temporary_cachedir() as cachedir:
          pants_run = self.run_test_compile(
              workdir,
              cachedir,
              'testprojects/src/java/org/pantsbuild/testproject/compilation_warnings:{}'.format(target),
              extra_args=['--compile-zinc-warning-args=-C-Xlint:all'])

          if expect_success:
            self.assert_success(pants_run)
          else:
            self.assert_failure(pants_run)
    test_combination('fatal', expect_success=False)
    test_combination('nonfatal', expect_success=True)

  def test_classpath_does_not_include_extra_classes_dirs(self):
    target_rel_spec = 'testprojects/src/java/org/pantsbuild/testproject/phrases:'
    classpath_file_by_target_id = {}
    for target_name in ['there-was-a-duck',
      'lesser-of-two',
      'once-upon-a-time',
      'ten-thousand']:
      target_id = Target.compute_target_id(Address.parse('{}{}'
        .format(target_rel_spec, target_name)))
      classpath_file_by_target_id[target_id] = '{}.txt'.format(target_id)

    with self.do_test_compile(target_rel_spec,
      expected_files = list(classpath_file_by_target_id.values()),
      extra_args=['--compile-zinc-capture-classpath']) as found:
      for target_id, filename in classpath_file_by_target_id.items():
        found_classpath_file = self.get_only(found, filename)
        with open(found_classpath_file, 'r') as f:
          contents = f.read()

          self.assertIn(target_id, contents)

          other_target_ids = set(classpath_file_by_target_id.keys()) - {target_id}
          for other_id in other_target_ids:
            self.assertNotIn(other_id, contents)

  def test_record_classpath(self):
    target_spec = 'testprojects/src/java/org/pantsbuild/testproject/printversion:printversion'
    target_id = Target.compute_target_id(Address.parse(target_spec))
    classpath_filename = '{}.txt'.format(target_id)
    with self.do_test_compile(target_spec,
                              expected_files=[classpath_filename, 'PrintVersion.class'],
                              extra_args=['--compile-zinc-capture-classpath']) as found:
      found_classpath_file = self.get_only(found, classpath_filename)
      self.assertTrue(found_classpath_file
                      .endswith(os.path.join('compile_classpath', classpath_filename)))
      with open(found_classpath_file, 'r') as f:
        self.assertIn(target_id, f.read())

  def test_no_record_classpath(self):
    target_spec = 'testprojects/src/java/org/pantsbuild/testproject/printversion:printversion'
    target_id = Target.compute_target_id(Address.parse(target_spec))
    classpath_filename = '{}.txt'.format(target_id)
    with self.do_test_compile(target_spec,
                              expected_files=['PrintVersion.class'],
                              extra_args=['--no-compile-zinc-capture-classpath']) as found:
      self.assertFalse(classpath_filename in found)

  @skipIf(is_missing_jvm('1.8'), 'no java 1.8 installation on testing machine')
  def test_custom_javac(self):
    with self.temporary_workdir() as workdir:
      with self.temporary_cachedir() as cachedir:
        pants_run = self.run_test_compile(
            workdir, cachedir, 'examples/src/java/org/pantsbuild/example/hello/main',
            extra_args=['--java-javac=testprojects/3rdparty/javactool:custom_javactool_for_testing'],
            clean_all=True
        )
        self.assertNotEqual(0, pants_run.returncode)  # Our custom javactool always fails.
        self.assertIn('Pants caused Zinc to load a custom JavacTool', pants_run.stdout_data)

  def test_no_zinc_file_manager(self):
    target_spec = 'testprojects/src/java/org/pantsbuild/testproject/bench:jmh'
    with self.temporary_workdir() as workdir:
      with self.temporary_cachedir() as cachedir:
        pants_run = self.run_test_compile(workdir, cachedir, target_spec, clean_all=True)
        self.assertEqual(0, pants_run.returncode)

  def test_failed_hermetic_incremental_compile(self):
    with temporary_dir() as cache_dir:
      config = {
        'cache.compile.zinc': {'write_to': [cache_dir]},
        'compile.zinc': {
          'execution_strategy': 'hermetic',
          'use_classpath_jars': False,
          'incremental': True,
        }
      }

      with self.temporary_workdir() as workdir:
        pants_run = self.run_pants_with_workdir(
          [
            '-q',
            'run',
            'examples/src/scala/org/pantsbuild/example/hello/exe',
          ],
          workdir,
          config,
        )
        self.assert_failure(pants_run)
        self.assertIn('Please use --no-compile-zinc-incremental', pants_run.stdout_data)

  def test_failed_compile_with_hermetic(self):
    with temporary_dir() as cache_dir:
      config = {
        'cache.compile.zinc': {'write_to': [cache_dir]},
        'compile.zinc': {
          'execution_strategy': 'hermetic',
          'use_classpath_jars': False,
          'incremental': False,
        }
      }

      with self.temporary_workdir() as workdir:
        pants_run = self.run_pants_with_workdir(
          [
            '-q',
            'compile',
            'testprojects/src/java/org/pantsbuild/testproject/dummies:compilation_failure_target',
          ],
          workdir,
          config,
        )
        self.assert_failure(pants_run)
        self.assertIn('package System2 does not exist', pants_run.stderr_data)
        self.assertIn(
          'Failed jobs: compile(testprojects/src/java/org/pantsbuild/testproject/dummies:'
          'compilation_failure_target)',
          pants_run.stdout_data)

  def test_failed_compile_with_subprocess(self):
    with temporary_dir() as cache_dir:
      config = {
        'cache.compile.zinc': {'write_to': [cache_dir]},
        'compile.zinc': {
          'execution_strategy': 'subprocess',
          'use_classpath_jars': False,
          'incremental': False,
        }
      }

      with self.temporary_workdir() as workdir:
        pants_run = self.run_pants_with_workdir(
          [
            # NB: We don't use -q here because subprocess squashes the error output
            # See https://github.com/pantsbuild/pants/issues/5646
            'compile',
            'testprojects/src/java/org/pantsbuild/testproject/dummies:compilation_failure_target',
          ],
          workdir,
          config,
        )
        self.assert_failure(pants_run)
        self.assertIn('package System2 does not exist', pants_run.stdout_data)
        self.assertIn(
          'Failed jobs: compile(testprojects/src/java/org/pantsbuild/testproject/dummies:'
          'compilation_failure_target)',
          pants_run.stdout_data)

  def test_hermetic_binary_with_dependencies(self):
    with temporary_dir() as cache_dir:
      config = {
        'cache.compile.zinc': {'write_to': [cache_dir]},
        'compile.zinc': {
          'execution_strategy': 'hermetic',
          'use_classpath_jars': False,
          'incremental': False,
        }
      }

      with self.temporary_workdir() as workdir:
        pants_run = self.run_pants_with_workdir(
          [
            '-q',
            'run',
            'examples/src/scala/org/pantsbuild/example/hello/exe',
          ],
          workdir,
          config,
        )
        self.assert_success(pants_run)
        self.assertIn(
          'Num args passed: 0. Stand by for welcome...\nHello, Resource World!',
          pants_run.stdout_data,
        )

        compile_dir = os.path.join(workdir, 'compile', 'zinc', 'current')

        for path_suffix in [
          'examples.src.scala.org.pantsbuild.example.hello.exe.exe/current/classes/org/pantsbuild/example/hello/exe/Exe.class',
          'examples.src.scala.org.pantsbuild.example.hello.welcome.welcome/current/classes/org/pantsbuild/example/hello/welcome/WelcomeEverybody.class',
        ]:
          path = os.path.join(compile_dir, path_suffix)
          self.assertTrue(os.path.exists(path), "Want path {} to exist".format(path))

  def test_hermetic_binary_cache_with_dependencies(self):
    file_abs_path = os.path.join(get_buildroot(),
      'examples/src/scala/org/pantsbuild/example/hello/exe/Exe.scala')

    with temporary_dir() as cache_dir:
      config = {
        'cache.compile.zinc': {'write_to': [cache_dir]},
        'compile.zinc': {
          'execution_strategy': 'hermetic',
          'use_classpath_jars': False,
          'incremental': False,
        }
      }

      with self.temporary_workdir() as workdir:
        pants_run = self.run_pants_with_workdir(
          [
            '-q',
            'run',
            'examples/src/scala/org/pantsbuild/example/hello/exe',
          ],
          workdir,
          config,
        )
        self.assert_success(pants_run)
        self.assertIn(
          'Num args passed: 0. Stand by for welcome...\nHello, Resource World!',
          pants_run.stdout_data,
        )

        compile_dir = os.path.join(workdir, 'compile', 'zinc', 'current')

        for path_suffix in [
          'examples.src.scala.org.pantsbuild.example.hello.exe.exe/current/classes/org/pantsbuild/example/hello/exe/Exe.class',
          'examples.src.scala.org.pantsbuild.example.hello.welcome.welcome/current/classes/org/pantsbuild/example/hello/welcome/WelcomeEverybody.class',
        ]:
          path = os.path.join(compile_dir, path_suffix)
          self.assertTrue(os.path.exists(path), "Want path {} to exist".format(path))

        with self.with_overwritten_file_content(file_abs_path):

          new_temp_test = '''package org.pantsbuild.example.hello.exe
                              
                              import java.io.{BufferedReader, InputStreamReader}
                              
                              import org.pantsbuild.example.hello.welcome
                              
                              // A simple jvm binary to illustrate Scala BUILD targets
                              
                              object Exe {
                                /** Test that resources are properly namespaced. */
                                def getWorld: String = {
                                  val is =
                                    this.getClass.getClassLoader.getResourceAsStream(
                                      "org/pantsbuild/example/hello/world.txt"
                                    )
                                  try {
                                    new BufferedReader(new InputStreamReader(is)).readLine()
                                  } finally {
                                    is.close()
                                  }
                                }
                              
                                def main(args: Array[String]) {
                                  println("Num args passed: " + args.size + ". Stand by for welcome...")
                                  if (args.size <= 0) {
                                    println("Hello, and welcome to " + getWorld + "!")
                                  } else {
                                    val w = welcome.WelcomeEverybody(args)
                                    w.foreach(s => println(s))
                                  }
                                }
                              }'''

          with open(file_abs_path, 'w') as f:
            f.write(new_temp_test)

          pants_run = self.run_pants_with_workdir(
            [
              '-q',
              'run',
              'examples/src/scala/org/pantsbuild/example/hello/exe',
            ],
            workdir,
            config,
          )
          self.assert_success(pants_run)
          self.assertIn(
            'Num args passed: 0. Stand by for welcome...\nHello, and welcome to Resource World!',
            pants_run.stdout_data,
          )

          compile_dir = os.path.join(workdir, 'compile', 'zinc', 'current')

          for path_suffix in [
            'examples.src.scala.org.pantsbuild.example.hello.exe.exe/current/classes/org/pantsbuild/example/hello/exe/Exe.class',
            'examples.src.scala.org.pantsbuild.example.hello.welcome.welcome/current/classes/org/pantsbuild/example/hello/welcome/WelcomeEverybody.class',
          ]:
            path = os.path.join(compile_dir, path_suffix)
            self.assertTrue(os.path.exists(path), "Want path {} to exist".format(path))

  def test_hermetic_binary_with_3rdparty_dependencies(self):
    for resolver in ('ivy', 'coursier'):
      for use_classpath_jars in (False, True):
        config = {
          'resolve.ivy': {'capture_snapshots': True},
          'resolve.coursier': {'capture_snapshots': True},
          'compile.zinc': {
            'execution_strategy': 'hermetic',
            'use_classpath_jars': use_classpath_jars,
            'incremental': False,
          },
          'resolver': {
            'resolver': resolver,
          }
        }

        with self.temporary_workdir() as workdir:
          with self.temporary_file_content("readme.txt", b"yo"):
            pants_run = self.run_pants_with_workdir(
              [
                'run',
                'testprojects/src/java/org/pantsbuild/testproject/cwdexample',
              ],
              workdir,
              config,
            )
            self.assert_success(pants_run)
            self.assertIn(
              'Found readme.txt',
              pants_run.stdout_data,
            )
Пример #7
0
class ZincCompileIntegrationTest(BaseCompileIT):
    def test_in_process(self):
        with self.temporary_workdir() as workdir:
            with self.temporary_cachedir() as cachedir:
                pants_run = self.run_test_compile(
                    workdir,
                    cachedir,
                    'examples/src/java/org/pantsbuild/example/hello/main',
                    extra_args=['-ldebug'],
                    clean_all=True)
                self.assertIn(
                    'Attempting to call com.sun.tools.javac.api.JavacTool',
                    pants_run.stdout_data)
                self.assertNotIn('Forking javac', pants_run.stdout_data)

    def test_log_level(self):
        with self.temporary_workdir() as workdir:
            with self.temporary_cachedir() as cachedir:
                target = 'testprojects/src/java/org/pantsbuild/testproject/dummies:compilation_failure_target'
                pants_run = self.run_test_compile(workdir,
                                                  cachedir,
                                                  target,
                                                  extra_args=['--no-colors'],
                                                  clean_all=True)
                self.assert_failure(pants_run)
                self.assertIn('[warn] import sun.security.x509.X500Name;',
                              pants_run.stdout_data)
                self.assertIn(
                    '[error]     System2.out.println("Hello World!");',
                    pants_run.stdout_data)

    def test_unicode_source_symbol(self):
        with self.temporary_workdir() as workdir:
            with self.temporary_cachedir() as cachedir:
                target = 'testprojects/src/scala/org/pantsbuild/testproject/unicode/unicodedep/consumer'
                pants_run = self.run_test_compile(
                    workdir,
                    cachedir,
                    target,
                    extra_args=[
                        '--cache-compile-rsc-write-to=["{}/dummy_artifact_cache_dir"]'
                        .format(cachedir),
                    ],
                    clean_all=True,
                )
                self.assert_success(pants_run)

    def test_fatal_warning(self):
        def test_combination(target, expect_success):
            with self.temporary_workdir() as workdir:
                with self.temporary_cachedir() as cachedir:
                    pants_run = self.run_test_compile(
                        workdir,
                        cachedir,
                        'testprojects/src/java/org/pantsbuild/testproject/compilation_warnings:{}'
                        .format(target),
                        extra_args=['--compile-rsc-warning-args=-C-Xlint:all'])

                    if expect_success:
                        self.assert_success(pants_run)
                    else:
                        self.assert_failure(pants_run)

        test_combination('fatal', expect_success=False)
        test_combination('nonfatal', expect_success=True)

    def test_classpath_does_not_include_extra_classes_dirs(self):
        target_rel_spec = 'testprojects/src/java/org/pantsbuild/testproject/phrases:'
        classpath_file_by_target_id = {}
        for target_name in [
                'there-was-a-duck', 'lesser-of-two', 'once-upon-a-time',
                'ten-thousand'
        ]:
            target_id = Target.compute_target_id(
                Address.parse('{}{}'.format(target_rel_spec, target_name)))
            classpath_file_by_target_id[target_id] = '{}.txt'.format(target_id)

        with self.do_test_compile(
                target_rel_spec,
                expected_files=list(classpath_file_by_target_id.values()),
                extra_args=['--compile-rsc-capture-classpath']) as found:
            for target_id, filename in classpath_file_by_target_id.items():
                found_classpath_file = self.get_only(found, filename)
                with open(found_classpath_file, 'r') as f:
                    contents = f.read()

                    self.assertIn(target_id, contents)

                    other_target_ids = set(
                        classpath_file_by_target_id.keys()) - {target_id}
                    for other_id in other_target_ids:
                        self.assertNotIn(other_id, contents)

    def test_record_classpath(self):
        target_spec = 'testprojects/src/java/org/pantsbuild/testproject/printversion:printversion'
        target_id = Target.compute_target_id(Address.parse(target_spec))
        classpath_filename = '{}.txt'.format(target_id)
        with self.do_test_compile(
                target_spec,
                expected_files=[classpath_filename, 'PrintVersion.class'],
                extra_args=['--compile-rsc-capture-classpath']) as found:
            found_classpath_file = self.get_only(found, classpath_filename)
            self.assertTrue(
                found_classpath_file.endswith(
                    os.path.join('compile_classpath', classpath_filename)))
            with open(found_classpath_file, 'r') as f:
                self.assertIn(target_id, f.read())

    def test_no_record_classpath(self):
        target_spec = 'testprojects/src/java/org/pantsbuild/testproject/printversion:printversion'
        target_id = Target.compute_target_id(Address.parse(target_spec))
        classpath_filename = '{}.txt'.format(target_id)
        with self.do_test_compile(
                target_spec,
                expected_files=['PrintVersion.class'],
                extra_args=['--no-compile-rsc-capture-classpath']) as found:
            self.assertFalse(classpath_filename in found)

    @skipIf(is_missing_jvm('1.8'),
            'no java 1.8 installation on testing machine')
    def test_custom_javac(self):
        with self.temporary_workdir() as workdir:
            with self.temporary_cachedir() as cachedir:
                pants_run = self.run_test_compile(
                    workdir,
                    cachedir,
                    'examples/src/java/org/pantsbuild/example/hello/main',
                    extra_args=[
                        '--java-javac=testprojects/3rdparty/javactool:custom_javactool_for_testing'
                    ],
                    clean_all=True)
                self.assertNotEqual(
                    0,
                    pants_run.returncode)  # Our custom javactool always fails.
                self.assertIn('Pants caused Zinc to load a custom JavacTool',
                              pants_run.stdout_data)

    def test_no_zinc_file_manager(self):
        target_spec = 'testprojects/src/java/org/pantsbuild/testproject/bench:jmh'
        with self.temporary_workdir() as workdir:
            with self.temporary_cachedir() as cachedir:
                pants_run = self.run_test_compile(workdir,
                                                  cachedir,
                                                  target_spec,
                                                  clean_all=True)
                self.assertEqual(0, pants_run.returncode)

    def test_hermetic_incremental_compile(self):
        """
    1) create a target containing two scala files
    2) compile the target, which would be a full compile
    3) modify a scala file slightly
    4) recompile, and make sure the compile is incremental by checking the zinc outputs
    """
        with self.temporary_workdir(cleanup=False) as tmp_build_root:
            # Make sure the tmp build root is recognized by Pants as a build root
            # by touching BUILDROOT.
            with open(os.path.join(tmp_build_root, 'BUILDROOT'), 'w') as f:
                f.write('')

            def _create_file(relpath, contents='', mode='w'):
                """Writes to a file under the buildroot.

        :API: public

        relpath:  The relative path to the file from the build root.
        contents: A string containing the contents of the file - '' by default..
        mode:     The mode to write to the file in - over-write by default.
        """
                path = os.path.join(tmp_build_root, relpath)
                with safe_open(path, mode=mode) as fp:
                    fp.write(contents)
                return path

            def _create_a_target_containing_two_sources():
                _srcfile_a = 'org/pantsbuild/incr/A.scala'
                _srcfile_b = 'org/pantsbuild/incr/B.scala'
                _build_file = 'org/pantsbuild/incr/BUILD'
                _lib_spec = 'org/pantsbuild/incr/'
                _create_file(_build_file, 'scala_library()')
                _srcfile_content = dedent("""
                                package org.pantsbuild.cachetest
                                object A {
                                  def x(y: Option[Int] = None) = {
                                    println("hello");
                                  }
                                }
                                """)
                _create_file(_srcfile_a, _srcfile_content)
                _create_file(
                    _srcfile_b,
                    dedent("""
                                      package org.pantsbuild.cachetest
                                      object B extends App {
                                        A.x();
                                        System.exit(0);
                                      }
                                      """))
                return _lib_spec, _srcfile_a, _srcfile_content

            with temporary_dir() as cache_dir, \
              temporary_dir(root_dir=tmp_build_root, suffix='.pants.d') as workdir:
                config = {
                    'cache.compile.rsc': {
                        'write_to': [cache_dir]
                    },
                    'compile.rsc': {
                        'execution_strategy': 'hermetic',
                        'use_classpath_jars': True,
                        'incremental': True,
                    }
                }

                lib_spec, src_file_a, srcfile_content = _create_a_target_containing_two_sources(
                )

                pants_run = self.run_pants_with_workdir(
                    ['-ldebug', 'compile', lib_spec],
                    workdir=workdir,
                    config=config,
                    cwd=tmp_build_root)
                self.assert_success(pants_run)
                self.assertIn(
                    'Full compilation, no sources in previous analysis',
                    pants_run.stdout_data)
                self.assertIn('Compiling 2 Scala sources',
                              pants_run.stdout_data)

                # Modify the source file slightly
                _create_file(src_file_a,
                             srcfile_content.replace('hello', 'bye'))

                pants_run = self.run_pants_with_workdir(
                    ['-ldebug', 'compile', lib_spec],
                    workdir=workdir,
                    config=config,
                    cwd=tmp_build_root)
                self.assert_success(pants_run)
                self.assertIn('Compiling 1 Scala source',
                              pants_run.stdout_data)

    def test_failed_compile_with_hermetic(self):
        with temporary_dir() as cache_dir:
            config = {
                'cache.compile.rsc': {
                    'write_to': [cache_dir]
                },
                'compile.rsc': {
                    'execution_strategy': 'hermetic',
                    'use_classpath_jars': False,
                    'incremental': False,
                }
            }

            with self.temporary_workdir() as workdir:
                pants_run = self.run_pants_with_workdir(
                    [
                        '-q',
                        'compile',
                        'testprojects/src/java/org/pantsbuild/testproject/dummies:compilation_failure_target',
                    ],
                    workdir,
                    config,
                )
                self.assert_failure(pants_run)
                self.assertIn('package System2 does not exist',
                              pants_run.stderr_data)
                self.assertTrue(
                    re.search(
                        'Compilation failure.*testprojects/src/java/org/pantsbuild/testproject/dummies:compilation_failure_target',
                        pants_run.stdout_data))

    def test_failed_compile_with_subprocess(self):
        with temporary_dir() as cache_dir:
            config = {
                'cache.compile.rsc': {
                    'write_to': [cache_dir]
                },
                'compile.rsc': {
                    'execution_strategy': 'subprocess',
                    'use_classpath_jars': False,
                    'incremental': False,
                }
            }

            with self.temporary_workdir() as workdir:
                pants_run = self.run_pants_with_workdir(
                    [
                        # NB: We don't use -q here because subprocess squashes the error output
                        # See https://github.com/pantsbuild/pants/issues/5646
                        'compile',
                        'testprojects/src/java/org/pantsbuild/testproject/dummies:compilation_failure_target',
                    ],
                    workdir,
                    config,
                )
                self.assert_failure(pants_run)
                self.assertIn('package System2 does not exist',
                              pants_run.stdout_data)
                self.assertTrue(
                    re.search(
                        'Compilation failure.*testprojects/src/java/org/pantsbuild/testproject/dummies:compilation_failure_target',
                        pants_run.stdout_data))

    def test_hermetic_binary_with_dependencies(self):
        with temporary_dir() as cache_dir:
            config = {
                'cache.compile.rsc': {
                    'write_to': [cache_dir]
                },
                'compile.rsc': {
                    'execution_strategy': 'hermetic',
                    'use_classpath_jars': False,
                    'incremental': False,
                }
            }

            with self.temporary_workdir() as workdir:
                pants_run = self.run_pants_with_workdir(
                    [
                        '-q',
                        'run',
                        'examples/src/scala/org/pantsbuild/example/hello/exe',
                    ],
                    workdir,
                    config,
                )
                self.assert_success(pants_run)
                self.assertIn(
                    'Num args passed: 0. Stand by for welcome...\nHello, Resource World!',
                    pants_run.stdout_data,
                )

                compile_dir = os.path.join(workdir, 'compile', 'rsc',
                                           'current')

                for path_suffix in [
                        'examples.src.scala.org.pantsbuild.example.hello.exe.exe/current/zinc/classes/org/pantsbuild/example/hello/exe/Exe.class',
                        'examples.src.scala.org.pantsbuild.example.hello.welcome.welcome/current/zinc/classes/org/pantsbuild/example/hello/welcome/WelcomeEverybody.class',
                ]:
                    path = os.path.join(compile_dir, path_suffix)
                    self.assertTrue(os.path.exists(path),
                                    "Want path {} to exist".format(path))

    def test_hermetic_binary_cache_with_dependencies(self):
        file_abs_path = os.path.join(
            get_buildroot(),
            'examples/src/scala/org/pantsbuild/example/hello/exe/Exe.scala')

        with temporary_dir() as cache_dir:
            config = {
                'cache.compile.rsc': {
                    'write_to': [cache_dir],
                    'read_from': [cache_dir]
                },
                'compile.rsc': {
                    'execution_strategy': 'hermetic',
                    'use_classpath_jars': False,
                    'incremental': False,
                }
            }

            with self.temporary_workdir() as workdir:
                pants_run = self.run_pants_with_workdir(
                    [
                        '-q',
                        'run',
                        'examples/src/scala/org/pantsbuild/example/hello/exe',
                    ],
                    workdir,
                    config,
                )
                self.assert_success(pants_run)
                self.assertIn(
                    'Num args passed: 0. Stand by for welcome...\nHello, Resource World!',
                    pants_run.stdout_data,
                )

                compile_dir = os.path.join(workdir, 'compile', 'rsc',
                                           'current')

                for path_suffix in [
                        'examples.src.scala.org.pantsbuild.example.hello.exe.exe/current/zinc/classes/org/pantsbuild/example/hello/exe/Exe.class',
                        'examples.src.scala.org.pantsbuild.example.hello.welcome.welcome/current/zinc/classes/org/pantsbuild/example/hello/welcome/WelcomeEverybody.class',
                ]:
                    path = os.path.join(compile_dir, path_suffix)
                    self.assertTrue(os.path.exists(path),
                                    "Want path {} to exist".format(path))
                with self.with_overwritten_file_content(file_abs_path):

                    new_temp_test = '''package org.pantsbuild.example.hello.exe
                              
                              import java.io.{BufferedReader, InputStreamReader}
                              import org.pantsbuild.example.hello
                              import org.pantsbuild.example.hello.welcome
                              
                              // A simple jvm binary to illustrate Scala BUILD targets
                              
                              object Exe {
                                /** Test that resources are properly namespaced. */
                                def getWorld: String = {
                                  val is =
                                    this.getClass.getClassLoader.getResourceAsStream(
                                      "org/pantsbuild/example/hello/world.txt"
                                    )
                                  try {
                                    new BufferedReader(new InputStreamReader(is)).readLine()
                                  } finally {
                                    is.close()
                                  }
                                }
                              
                                def main(args: Array[String]) {
                                  println("Num args passed: " + args.size + ". Stand by for welcome...")
                                  if (args.size <= 0) {
                                    println("Hello, and welcome to " + getWorld + "!")
                                  } else {
                                    val w = welcome.WelcomeEverybody(args)
                                    w.foreach(s => println(s))
                                  }
                                }
                              }'''

                    with open(file_abs_path, 'w') as f:
                        f.write(new_temp_test)

                    pants_run = self.run_pants_with_workdir(
                        [
                            '-q',
                            'run',
                            'examples/src/scala/org/pantsbuild/example/hello/exe',
                        ],
                        workdir,
                        config,
                    )
                    self.assert_success(pants_run)
                    self.assertIn(
                        'Num args passed: 0. Stand by for welcome...\nHello, and welcome to Resource World!',
                        pants_run.stdout_data,
                    )

                    compile_dir = os.path.join(workdir, 'compile', 'rsc',
                                               'current')

                    for path_suffix in [
                            'examples.src.scala.org.pantsbuild.example.hello.exe.exe/current/zinc/classes/org/pantsbuild/example/hello/exe/Exe.class',
                            'examples.src.scala.org.pantsbuild.example.hello.welcome.welcome/current/zinc/classes/org/pantsbuild/example/hello/welcome/WelcomeEverybody.class',
                    ]:
                        path = os.path.join(compile_dir, path_suffix)
                        self.assertTrue(os.path.exists(path),
                                        "Want path {} to exist".format(path))
class JunitRunIntegrationTest(PantsRunIntegrationTest):

  def _testjvms(self, spec_name):
    spec = 'testprojects/tests/java/org/pantsbuild/testproject/testjvms:{}'.format(spec_name)
    self.assert_success(self.run_pants(['clean-all', 'test.junit', '--strict-jvm-version', spec]))

  @skipIf(is_missing_jvm('1.8'), 'no java 1.8 installation on testing machine')
  def test_java_eight(self):
    self._testjvms('eight')

  @skipIf(is_missing_jvm('1.8'), 'no java 1.8 installation on testing machine')
  def test_with_test_platform(self):
    self._testjvms('eight-test-platform')

  def test_junit_run_against_class_succeeds(self):
    pants_run = self.run_pants(['clean-all',
                                'test.junit',
                                '--test=org.pantsbuild.testproject.matcher.MatcherTest',
                                'testprojects/tests/java/org/pantsbuild/testproject/matcher'])
    self.assert_success(pants_run)

  def test_junit_run_with_cobertura_coverage_succeeds(self):
    with self.pants_results(['clean-all',
                             'test.junit',
                             'testprojects/tests/java/org/pantsbuild/testproject/unicode::',
                             '--test-junit-coverage-processor=cobertura',
                             '--test-junit-coverage']) as results:
      self.assert_success(results)
      # validate that the expected coverage file exists, and it reflects 100% line rate coverage
      coverage_xml = os.path.join(results.workdir, 'test/junit/coverage/xml/coverage.xml')
      self.assertTrue(os.path.isfile(coverage_xml))
      with codecs.open(coverage_xml, 'r', encoding='utf8') as xml:
        self.assertIn('line-rate="1.0"', xml.read())
      # validate that the html report was able to find sources for annotation
      cucumber_src_html = os.path.join(
          results.workdir,
          'test/junit/coverage/html/'
          'org.pantsbuild.testproject.unicode.cucumber.CucumberAnnotatedExample.html')
      self.assertTrue(os.path.isfile(cucumber_src_html))
      with codecs.open(cucumber_src_html, 'r', encoding='utf8') as src:
        self.assertIn('String pleasantry()', src.read())

  def test_junit_run_with_jacoco_coverage_succeeds(self):
    with self.pants_results(['clean-all',
                             'test.junit',
                             'testprojects/tests/java/org/pantsbuild/testproject/unicode::',
                             '--test-junit-coverage-processor=jacoco',
                             '--test-junit-coverage']) as results:
      self.assert_success(results)
      # validate that the expected coverage file exists, and it reflects 100% line rate coverage
      coverage_xml = os.path.join(results.workdir, 'test/junit/coverage/reports/xml')
      self.assertTrue(os.path.isfile(coverage_xml))
      with codecs.open(coverage_xml, 'r', encoding='utf8') as xml:
        self.assertIn('<class name="org/pantsbuild/testproject/unicode/cucumber/CucumberAnnotatedExample"><method name="&lt;init&gt;" desc="()V" line="13"><counter type="INSTRUCTION" missed="0" covered="3"/>', xml.read())
      # validate that the html report was able to find sources for annotation
      cucumber_src_html = os.path.join(
          results.workdir,
          'test/junit/coverage/reports/html/'
          'org.pantsbuild.testproject.unicode.cucumber/CucumberAnnotatedExample.html')
      self.assertTrue(os.path.isfile(cucumber_src_html))
      with codecs.open(cucumber_src_html, 'r', encoding='utf8') as src:
        self.assertIn('class="el_method">pleasantry()</a>', src.read())

  def test_junit_run_against_invalid_class_fails(self):
    pants_run = self.run_pants(['clean-all',
                                'test.junit',
                                '--test=org.pantsbuild.testproject.matcher.MatcherTest_BAD_CLASS',
                                'testprojects/tests/java/org/pantsbuild/testproject/matcher'])
    self.assert_failure(pants_run)
    self.assertIn("No target found for test specifier", pants_run.stdout_data)

  def test_junit_run_timeout_succeeds(self):
    sleeping_target = 'testprojects/tests/java/org/pantsbuild/testproject/timeout:sleeping_target'
    pants_run = self.run_pants(['clean-all',
                                'test.junit',
                                '--timeouts',
                                '--timeout-default=1',
                                '--timeout-terminate-wait=1',
                                '--test=org.pantsbuild.testproject.timeout.ShortSleeperTest',
                                sleeping_target])
    self.assert_success(pants_run)

  def test_junit_run_timeout_fails(self):
    sleeping_target = 'testprojects/tests/java/org/pantsbuild/testproject/timeout:sleeping_target'
    start = time.time()
    pants_run = self.run_pants(['clean-all',
                                'test.junit',
                                '--timeouts',
                                '--timeout-default=1',
                                '--timeout-terminate-wait=1',
                                '--test=org.pantsbuild.testproject.timeout.LongSleeperTest',
                                sleeping_target])
    end = time.time()
    self.assert_failure(pants_run)

    # Ensure that the failure took less than 120 seconds to run.
    self.assertLess(end - start, 120)

    # Ensure that the timeout triggered.
    self.assertIn(" timed out after 1 seconds", pants_run.stdout_data)

  def test_junit_tests_using_cucumber(self):
    test_spec = 'testprojects/tests/java/org/pantsbuild/testproject/cucumber'
    with self.pants_results(['clean-all', 'test.junit', '--per-test-timer', test_spec]) as results:
      self.assert_success(results)

  def test_disable_synthetic_jar(self):
    synthetic_jar_target = 'testprojects/tests/java/org/pantsbuild/testproject/syntheticjar:test'
    output = self.run_pants(['test.junit', '--output-mode=ALL', synthetic_jar_target]).stdout_data
    self.assertIn('Synthetic jar run is detected', output)

    output = self.run_pants(['test.junit',
                             '--output-mode=ALL',
                             '--no-jvm-synthetic-classpath',
                             synthetic_jar_target]).stdout_data
    self.assertIn('Synthetic jar run is not detected', output)

  def test_junit_run_with_html_report(self):
    with self.pants_results(['clean-all',
                             'test.junit',
                             'testprojects/tests/java/org/pantsbuild/testproject/htmlreport::',
                             '--test-junit-html-report']) as results:
      self.assert_failure(results)
      report_html = os.path.join(results.workdir, 'test/junit/reports/junit-report.html')
      self.assertTrue(os.path.isfile(report_html))
      with codecs.open(report_html, 'r', encoding='utf8') as src:
        html = src.read()
        self.assertIn('testPasses', html)
        self.assertIn('testFails', html)
        self.assertIn('testErrors', html)
        self.assertIn('testSkipped', html)
class ZincCompileIntegrationTest(BaseCompileIT):
    def test_java_src_zinc_compile(self):
        with self.do_test_compile('examples/src/java/::'):
            # run succeeded as expected
            pass
        with self.do_test_compile('examples/tests/java/::'):
            # run succeeded as expected
            pass

    def test_in_process(self):
        with self.temporary_workdir() as workdir:
            with self.temporary_cachedir() as cachedir:
                pants_run = self.run_test_compile(
                    workdir,
                    cachedir,
                    'examples/src/java/org/pantsbuild/example/hello/main',
                    extra_args=['-ldebug'],
                    clean_all=True)
                self.assertIn(
                    'Attempting to call com.sun.tools.javac.api.JavacTool',
                    pants_run.stdout_data)
                self.assertNotIn('Forking javac', pants_run.stdout_data)

    def test_log_level(self):
        with self.temporary_workdir() as workdir:
            with self.temporary_cachedir() as cachedir:
                target = 'testprojects/src/java/org/pantsbuild/testproject/dummies:compilation_failure_target'
                pants_run = self.run_test_compile(workdir,
                                                  cachedir,
                                                  target,
                                                  extra_args=['--no-colors'],
                                                  clean_all=True)
                self.assert_failure(pants_run)
                self.assertIn('[warn] import sun.security.x509.X500Name;',
                              pants_run.stdout_data)
                self.assertIn(
                    '[error]     System2.out.println("Hello World!");',
                    pants_run.stdout_data)

    def test_unicode_source_symbol(self):
        with self.temporary_workdir() as workdir:
            with self.temporary_cachedir() as cachedir:
                target = 'testprojects/src/scala/org/pantsbuild/testproject/unicode/unicodedep/consumer'
                pants_run = self.run_test_compile(
                    workdir,
                    cachedir,
                    target,
                    extra_args=[
                        '--cache-compile-zinc-write-to=["{}/dummy_artifact_cache_dir"]'
                        .format(cachedir),
                    ],
                    clean_all=True,
                )
                self.assert_success(pants_run)

    def test_apt_compile(self):
        with self.do_test_compile(
                'testprojects/src/java/org/pantsbuild/testproject/annotation/processor',
                expected_files=[
                    'ResourceMappingProcessor.class',
                    'javax.annotation.processing.Processor'
                ]) as found:

            self.assertTrue(
                self.get_only(found, 'ResourceMappingProcessor.class').
                endswith(
                    'org/pantsbuild/testproject/annotation/processor/ResourceMappingProcessor.class'
                ))

            processor_service_files = found[
                'javax.annotation.processing.Processor']
            # There should be only a per-target service info file.
            self.assertEqual(1, len(processor_service_files))
            processor_service_file = list(processor_service_files)[0]
            self.assertTrue(
                processor_service_file.endswith(
                    'META-INF/services/javax.annotation.processing.Processor'))
            with open(processor_service_file, 'r') as fp:
                self.assertEqual(
                    'org.pantsbuild.testproject.annotation.processor.ResourceMappingProcessor',
                    fp.read().strip())

    def test_apt_compile_and_run(self):
        with self.do_test_compile(
                'testprojects/src/java/org/pantsbuild/testproject/annotation/main',
                expected_files=['Main.class',
                                'deprecation_report.txt']) as found:

            self.assertTrue(
                self.get_only(found, 'Main.class').endswith(
                    'org/pantsbuild/testproject/annotation/main/Main.class'))

            # This is the proof that the ResourceMappingProcessor annotation processor was compiled in a
            # round and then the Main was compiled in a later round with the annotation processor and its
            # service info file from on its compile classpath.
            with open(self.get_only(found, 'deprecation_report.txt'),
                      'r') as fp:
                self.assertIn(
                    'org.pantsbuild.testproject.annotation.main.Main',
                    fp.read().splitlines())

    def test_stale_apt_with_deps(self):
        """An annotation processor with a dependency doesn't pollute other annotation processors.

    At one point, when you added an annotation processor, it stayed configured for all subsequent
    compiles.  Meaning that if that annotation processor had a dep that wasn't on the classpath,
    subsequent compiles would fail with missing symbols required by the stale annotation processor.
    """

        # Demonstrate that the annotation processor is working
        with self.do_test_compile(
                'testprojects/src/java/org/pantsbuild/testproject/annotation/processorwithdep/main',
                expected_files=[
                    'Main.class', 'Main_HelloWorld.class',
                    'Main_HelloWorld.java'
                ]) as found:
            gen_file = self.get_only(found, 'Main_HelloWorld.java')
            self.assertTrue(gen_file.endswith(
                'org/pantsbuild/testproject/annotation/processorwithdep/main/Main_HelloWorld.java'
            ),
                            msg='{} does not match'.format(gen_file))

        # Try to reproduce second compile that fails with missing symbol
        with self.temporary_workdir() as workdir:
            with self.temporary_cachedir() as cachedir:
                # This annotation processor has a unique external dependency
                self.assert_success(
                    self.run_test_compile(
                        workdir, cachedir,
                        'testprojects/src/java/org/pantsbuild/testproject/annotation/processorwithdep::'
                    ))

                # When we run a second compile with annotation processors, make sure the previous annotation
                # processor doesn't stick around to spoil the compile
                self.assert_success(
                    self.run_test_compile(
                        workdir,
                        cachedir,
                        'testprojects/src/java/org/pantsbuild/testproject/annotation/processor::',
                        clean_all=False))

    def test_fatal_warning(self):
        def test_combination(target, expect_success):
            with self.temporary_workdir() as workdir:
                with self.temporary_cachedir() as cachedir:
                    pants_run = self.run_test_compile(
                        workdir,
                        cachedir,
                        'testprojects/src/java/org/pantsbuild/testproject/compilation_warnings:{}'
                        .format(target),
                        extra_args=[
                            '--compile-zinc-warning-args=-C-Xlint:all'
                        ])

                    if expect_success:
                        self.assert_success(pants_run)
                    else:
                        self.assert_failure(pants_run)

        test_combination('fatal', expect_success=False)
        test_combination('nonfatal', expect_success=True)

    def test_classpath_does_not_include_extra_classes_dirs(self):
        target_rel_spec = 'testprojects/src/java/org/pantsbuild/testproject/phrases:'
        classpath_file_by_target_id = {}
        for target_name in [
                'there-was-a-duck', 'lesser-of-two', 'once-upon-a-time',
                'ten-thousand'
        ]:
            target_id = Target.compute_target_id(
                Address.parse('{}{}'.format(target_rel_spec, target_name)))
            classpath_file_by_target_id[target_id] = '{}.txt'.format(target_id)

        with self.do_test_compile(
                target_rel_spec,
                expected_files=list(classpath_file_by_target_id.values()),
                extra_args=['--compile-zinc-capture-classpath']) as found:
            for target_id, filename in classpath_file_by_target_id.items():
                found_classpath_file = self.get_only(found, filename)
                with open(found_classpath_file, 'r') as f:
                    contents = f.read()

                    self.assertIn(target_id, contents)

                    other_target_ids = set(
                        classpath_file_by_target_id.keys()) - {target_id}
                    for other_id in other_target_ids:
                        self.assertNotIn(other_id, contents)

    def test_record_classpath(self):
        target_spec = 'testprojects/src/java/org/pantsbuild/testproject/printversion:printversion'
        target_id = Target.compute_target_id(Address.parse(target_spec))
        classpath_filename = '{}.txt'.format(target_id)
        with self.do_test_compile(
                target_spec,
                expected_files=[classpath_filename, 'PrintVersion.class'],
                extra_args=['--compile-zinc-capture-classpath']) as found:
            found_classpath_file = self.get_only(found, classpath_filename)
            self.assertTrue(
                found_classpath_file.endswith(
                    os.path.join('compile_classpath', classpath_filename)))
            with open(found_classpath_file, 'r') as f:
                self.assertIn(target_id, f.read())

    def test_no_record_classpath(self):
        target_spec = 'testprojects/src/java/org/pantsbuild/testproject/printversion:printversion'
        target_id = Target.compute_target_id(Address.parse(target_spec))
        classpath_filename = '{}.txt'.format(target_id)
        with self.do_test_compile(
                target_spec,
                expected_files=['PrintVersion.class'],
                extra_args=['--no-compile-zinc-capture-classpath']) as found:
            self.assertFalse(classpath_filename in found)

    @skipIf(is_missing_jvm('1.8'),
            'no java 1.8 installation on testing machine')
    def test_custom_javac(self):
        with self.temporary_workdir() as workdir:
            with self.temporary_cachedir() as cachedir:
                pants_run = self.run_test_compile(
                    workdir,
                    cachedir,
                    'examples/src/java/org/pantsbuild/example/hello/main',
                    extra_args=[
                        '--java-javac=testprojects/3rdparty/javactool:custom_javactool_for_testing'
                    ],
                    clean_all=True)
                self.assertNotEqual(
                    0,
                    pants_run.returncode)  # Our custom javactool always fails.
                self.assertIn('Pants caused Zinc to load a custom JavacTool',
                              pants_run.stdout_data)

    def test_no_zinc_file_manager(self):
        target_spec = 'testprojects/src/java/org/pantsbuild/testproject/bench:jmh'
        with self.temporary_workdir() as workdir:
            with self.temporary_cachedir() as cachedir:
                pants_run = self.run_test_compile(workdir,
                                                  cachedir,
                                                  target_spec,
                                                  clean_all=True)
                self.assertEqual(0, pants_run.returncode)

    def test_failed_hermetic_incremental_compile(self):
        with temporary_dir() as cache_dir:
            config = {
                'cache.compile.zinc': {
                    'write_to': [cache_dir]
                },
                'compile.zinc': {
                    'execution_strategy': 'hermetic',
                    'use_classpath_jars': False,
                    'incremental': True,
                }
            }

            with self.temporary_workdir() as workdir:
                pants_run = self.run_pants_with_workdir(
                    [
                        '-q',
                        'run',
                        'examples/src/scala/org/pantsbuild/example/hello/exe',
                    ],
                    workdir,
                    config,
                )
                self.assert_failure(pants_run)

    def test_failed_compile_with_hermetic(self):
        with temporary_dir() as cache_dir:
            config = {
                'cache.compile.zinc': {
                    'write_to': [cache_dir]
                },
                'compile.zinc': {
                    'execution_strategy': 'hermetic',
                    'use_classpath_jars': False,
                    'incremental': False,
                }
            }

            with self.temporary_workdir() as workdir:
                pants_run = self.run_pants_with_workdir(
                    [
                        '-q',
                        'compile',
                        'testprojects/src/java/org/pantsbuild/testproject/dummies:compilation_failure_target',
                    ],
                    workdir,
                    config,
                )
                self.assert_failure(pants_run)
                self.assertIn(
                    'Failed jobs: compile(testprojects/src/java/org/pantsbuild/testproject/dummies:'
                    'compilation_failure_target)', pants_run.stdout_data)

    def test_hermetic_binary_with_dependencies(self):
        with temporary_dir() as cache_dir:
            config = {
                'cache.compile.zinc': {
                    'write_to': [cache_dir]
                },
                'compile.zinc': {
                    'execution_strategy': 'hermetic',
                    'use_classpath_jars': False,
                    'incremental': False,
                }
            }

            with self.temporary_workdir() as workdir:
                pants_run = self.run_pants_with_workdir(
                    [
                        '-q',
                        'run',
                        'examples/src/scala/org/pantsbuild/example/hello/exe',
                    ],
                    workdir,
                    config,
                )
                self.assert_success(pants_run)
                self.assertIn(
                    'Num args passed: 0. Stand by for welcome...\nHello, Resource World!',
                    pants_run.stdout_data,
                )

                compile_dir = os.path.join(workdir, 'compile', 'zinc',
                                           'current')

                for path_suffix in [
                        'examples.src.scala.org.pantsbuild.example.hello.exe.exe/current/classes/org/pantsbuild/example/hello/exe/Exe.class',
                        'examples.src.scala.org.pantsbuild.example.hello.welcome.welcome/current/classes/org/pantsbuild/example/hello/welcome/WelcomeEverybody.class',
                ]:
                    path = os.path.join(compile_dir, path_suffix)
                    self.assertTrue(os.path.exists(path),
                                    "Want path {} to exist".format(path))

    def test_hermetic_binary_cache_with_dependencies(self):
        file_abs_path = os.path.join(
            get_buildroot(),
            'examples/src/scala/org/pantsbuild/example/hello/exe/Exe.scala')

        with temporary_dir() as cache_dir:
            config = {
                'cache.compile.zinc': {
                    'write_to': [cache_dir]
                },
                'compile.zinc': {
                    'execution_strategy': 'hermetic',
                    'use_classpath_jars': False,
                    'incremental': False,
                }
            }

            with self.temporary_workdir() as workdir:
                pants_run = self.run_pants_with_workdir(
                    [
                        '-q',
                        'run',
                        'examples/src/scala/org/pantsbuild/example/hello/exe',
                    ],
                    workdir,
                    config,
                )
                self.assert_success(pants_run)
                self.assertIn(
                    'Num args passed: 0. Stand by for welcome...\nHello, Resource World!',
                    pants_run.stdout_data,
                )

                compile_dir = os.path.join(workdir, 'compile', 'zinc',
                                           'current')

                for path_suffix in [
                        'examples.src.scala.org.pantsbuild.example.hello.exe.exe/current/classes/org/pantsbuild/example/hello/exe/Exe.class',
                        'examples.src.scala.org.pantsbuild.example.hello.welcome.welcome/current/classes/org/pantsbuild/example/hello/welcome/WelcomeEverybody.class',
                ]:
                    path = os.path.join(compile_dir, path_suffix)
                    self.assertTrue(os.path.exists(path),
                                    "Want path {} to exist".format(path))

                with with_overwritten_file_content(file_abs_path):

                    new_temp_test = '''package org.pantsbuild.example.hello.exe
                              
                              import java.io.{BufferedReader, InputStreamReader}
                              
                              import org.pantsbuild.example.hello.welcome
                              
                              // A simple jvm binary to illustrate Scala BUILD targets
                              
                              object Exe {
                                /** Test that resources are properly namespaced. */
                                def getWorld: String = {
                                  val is =
                                    this.getClass.getClassLoader.getResourceAsStream(
                                      "org/pantsbuild/example/hello/world.txt"
                                    )
                                  try {
                                    new BufferedReader(new InputStreamReader(is)).readLine()
                                  } finally {
                                    is.close()
                                  }
                                }
                              
                                def main(args: Array[String]) {
                                  println("Num args passed: " + args.size + ". Stand by for welcome...")
                                  if (args.size <= 0) {
                                    println("Hello, and welcome to " + getWorld + "!")
                                  } else {
                                    val w = welcome.WelcomeEverybody(args)
                                    w.foreach(s => println(s))
                                  }
                                }
                              }'''

                    with open(file_abs_path, 'w') as f:
                        f.write(new_temp_test)

                    pants_run = self.run_pants_with_workdir(
                        [
                            '-q',
                            'run',
                            'examples/src/scala/org/pantsbuild/example/hello/exe',
                        ],
                        workdir,
                        config,
                    )
                    self.assert_success(pants_run)
                    self.assertIn(
                        'Num args passed: 0. Stand by for welcome...\nHello, and welcome to Resource World!',
                        pants_run.stdout_data,
                    )

                    compile_dir = os.path.join(workdir, 'compile', 'zinc',
                                               'current')

                    for path_suffix in [
                            'examples.src.scala.org.pantsbuild.example.hello.exe.exe/current/classes/org/pantsbuild/example/hello/exe/Exe.class',
                            'examples.src.scala.org.pantsbuild.example.hello.welcome.welcome/current/classes/org/pantsbuild/example/hello/welcome/WelcomeEverybody.class',
                    ]:
                        path = os.path.join(compile_dir, path_suffix)
                        self.assertTrue(os.path.exists(path),
                                        "Want path {} to exist".format(path))

    def test_hermetic_binary_with_3rdparty_dependencies(self):
        config = {
            'compile.zinc': {
                'execution_strategy': 'hermetic',
                'use_classpath_jars': False,
                'incremental': False,
            }
        }

        with self.temporary_workdir() as workdir:
            with self.temporary_file_content("readme.txt", "yo"):
                pants_run = self.run_pants_with_workdir(
                    [
                        'run',
                        'testprojects/src/java/org/pantsbuild/testproject/cwdexample',
                    ],
                    workdir,
                    config,
                )
                self.assert_success(pants_run)
                self.assertIn(
                    'Found readme.txt',
                    pants_run.stdout_data,
                )
Пример #10
0
class ZincCompileIntegrationTest(BaseCompileIT):
    def test_in_process(self):
        with self.temporary_workdir() as workdir:
            with self.temporary_cachedir() as cachedir:
                pants_run = self.run_test_compile(
                    workdir,
                    cachedir,
                    "examples/src/java/org/pantsbuild/example/hello/main",
                    extra_args=["-ldebug"],
                    clean_all=True,
                )
                self.assertIn(
                    "Attempting to call com.sun.tools.javac.api.JavacTool", pants_run.stdout_data
                )
                self.assertNotIn("Forking javac", pants_run.stdout_data)

    def test_log_level(self):
        with self.temporary_workdir() as workdir:
            with self.temporary_cachedir() as cachedir:
                target = "testprojects/src/java/org/pantsbuild/testproject/dummies:compilation_failure_target"
                pants_run = self.run_test_compile(
                    workdir, cachedir, target, extra_args=["--no-colors"], clean_all=True
                )
                self.assert_failure(pants_run)
                self.assertIn("[warn] import sun.security.x509.X500Name;", pants_run.stdout_data)
                self.assertIn(
                    '[error]     System2.out.println("Hello World!");', pants_run.stdout_data
                )

    def test_unicode_source_symbol(self):
        with self.temporary_workdir() as workdir:
            with self.temporary_cachedir() as cachedir:
                target = (
                    "testprojects/src/scala/org/pantsbuild/testproject/unicode/unicodedep/consumer"
                )
                pants_run = self.run_test_compile(
                    workdir,
                    cachedir,
                    target,
                    extra_args=[
                        f'--cache-compile-rsc-write-to=["{cachedir}/dummy_artifact_cache_dir"]',
                    ],
                    clean_all=True,
                )
                self.assert_success(pants_run)

    def test_fatal_warning(self):
        def test_combination(target, expect_success):
            with self.temporary_workdir() as workdir:
                with self.temporary_cachedir() as cachedir:
                    pants_run = self.run_test_compile(
                        workdir,
                        cachedir,
                        f"testprojects/src/java/org/pantsbuild/testproject/compilation_warnings:{target}",
                        extra_args=["--compile-rsc-warning-args=-C-Xlint:all"],
                    )

                    if expect_success:
                        self.assert_success(pants_run)
                    else:
                        self.assert_failure(pants_run)

        test_combination("fatal", expect_success=False)
        test_combination("nonfatal", expect_success=True)

    def test_classpath_does_not_include_extra_classes_dirs(self):
        target_rel_spec = "testprojects/src/java/org/pantsbuild/testproject/phrases:"
        classpath_file_by_target_id = {}
        for target_name in [
            "there-was-a-duck",
            "lesser-of-two",
            "once-upon-a-time",
            "ten-thousand",
        ]:
            target_id = Target.compute_target_id(
                Address.parse("{}{}".format(target_rel_spec, target_name))
            )
            classpath_file_by_target_id[target_id] = f"{target_id}.txt"

        with self.do_test_compile(
            target_rel_spec,
            expected_files=list(classpath_file_by_target_id.values()),
            extra_args=["--compile-rsc-capture-classpath"],
        ) as found:
            for target_id, filename in classpath_file_by_target_id.items():
                found_classpath_file = self.get_only(found, filename)
                with open(found_classpath_file, "r") as f:
                    contents = f.read()

                    self.assertIn(target_id, contents)

                    other_target_ids = set(classpath_file_by_target_id.keys()) - {target_id}
                    for other_id in other_target_ids:
                        self.assertNotIn(other_id, contents)

    def test_record_classpath(self):
        target_spec = "testprojects/src/java/org/pantsbuild/testproject/printversion:printversion"
        target_id = Target.compute_target_id(Address.parse(target_spec))
        classpath_filename = f"{target_id}.txt"
        with self.do_test_compile(
            target_spec,
            expected_files=[classpath_filename, "PrintVersion.class"],
            extra_args=["--compile-rsc-capture-classpath"],
        ) as found:
            found_classpath_file = self.get_only(found, classpath_filename)
            self.assertTrue(
                found_classpath_file.endswith(os.path.join("compile_classpath", classpath_filename))
            )
            with open(found_classpath_file, "r") as f:
                self.assertIn(target_id, f.read())

    def test_no_record_classpath(self):
        target_spec = "testprojects/src/java/org/pantsbuild/testproject/printversion:printversion"
        target_id = Target.compute_target_id(Address.parse(target_spec))
        classpath_filename = f"{target_id}.txt"
        with self.do_test_compile(
            target_spec,
            expected_files=["PrintVersion.class"],
            extra_args=["--no-compile-rsc-capture-classpath"],
        ) as found:
            self.assertFalse(classpath_filename in found)

    @skipIf(is_missing_jvm("1.8"), "no java 1.8 installation on testing machine")
    def test_custom_javac(self):
        with self.temporary_workdir() as workdir:
            with self.temporary_cachedir() as cachedir:
                pants_run = self.run_test_compile(
                    workdir,
                    cachedir,
                    "examples/src/java/org/pantsbuild/example/hello/main",
                    extra_args=[
                        "--java-javac=testprojects/3rdparty/javactool:custom_javactool_for_testing"
                    ],
                    clean_all=True,
                )
                self.assertNotEqual(0, pants_run.returncode)  # Our custom javactool always fails.
                self.assertIn("Pants caused Zinc to load a custom JavacTool", pants_run.stdout_data)

    def test_no_zinc_file_manager(self):
        target_spec = "testprojects/src/java/org/pantsbuild/testproject/bench:jmh"
        with self.temporary_workdir() as workdir:
            with self.temporary_cachedir() as cachedir:
                pants_run = self.run_test_compile(workdir, cachedir, target_spec, clean_all=True)
                self.assertEqual(0, pants_run.returncode)

    def test_failed_compile_with_hermetic(self):
        with temporary_dir() as cache_dir:
            config = {
                "cache.compile.rsc": {"write_to": [cache_dir]},
                "compile.rsc": {
                    "execution_strategy": "hermetic",
                    "use_classpath_jars": False,
                    "incremental": False,
                },
            }

            with self.temporary_workdir() as workdir:
                pants_run = self.run_pants_with_workdir(
                    [
                        "-q",
                        "compile",
                        "testprojects/src/java/org/pantsbuild/testproject/dummies:compilation_failure_target",
                    ],
                    workdir,
                    config,
                )
                self.assert_failure(pants_run)
                self.assertIn("package System2 does not exist", pants_run.stderr_data)
                self.assertTrue(
                    re.search(
                        "Compilation failure.*testprojects/src/java/org/pantsbuild/testproject/dummies:compilation_failure_target",
                        pants_run.stdout_data,
                    )
                )

    def test_failed_compile_with_subprocess(self):
        with temporary_dir() as cache_dir:
            config = {
                "cache.compile.rsc": {"write_to": [cache_dir]},
                "compile.rsc": {
                    "execution_strategy": "subprocess",
                    "use_classpath_jars": False,
                    "incremental": False,
                },
            }

            with self.temporary_workdir() as workdir:
                pants_run = self.run_pants_with_workdir(
                    [
                        # NB: We don't use -q here because subprocess squashes the error output
                        # See https://github.com/pantsbuild/pants/issues/5646
                        "compile",
                        "testprojects/src/java/org/pantsbuild/testproject/dummies:compilation_failure_target",
                    ],
                    workdir,
                    config,
                )
                self.assert_failure(pants_run)
                self.assertIn("package System2 does not exist", pants_run.stdout_data)
                self.assertTrue(
                    re.search(
                        "Compilation failure.*testprojects/src/java/org/pantsbuild/testproject/dummies:compilation_failure_target",
                        pants_run.stdout_data,
                    )
                )

    def test_hermetic_binary_with_dependencies(self):
        with temporary_dir() as cache_dir:
            config = {
                "cache.compile.rsc": {"write_to": [cache_dir]},
                "compile.rsc": {
                    "execution_strategy": "hermetic",
                    "use_classpath_jars": False,
                    "incremental": False,
                },
            }

            with self.temporary_workdir() as workdir:
                pants_run = self.run_pants_with_workdir(
                    ["-q", "run", "examples/src/scala/org/pantsbuild/example/hello/exe"],
                    workdir,
                    config,
                )
                self.assert_success(pants_run)
                self.assertIn(
                    "Num args passed: 0. Stand by for welcome...\nHello, Resource World!",
                    pants_run.stdout_data,
                )

                compile_dir = os.path.join(workdir, "compile", "rsc", "current")

                for path_suffix in [
                    "examples.src.scala.org.pantsbuild.example.hello.exe.exe/current/zinc/classes/org/pantsbuild/example/hello/exe/Exe.class",
                    "examples.src.scala.org.pantsbuild.example.hello.welcome.welcome/current/zinc/classes/org/pantsbuild/example/hello/welcome/WelcomeEverybody.class",
                ]:
                    path = os.path.join(compile_dir, path_suffix)
                    self.assertTrue(os.path.exists(path), f"Want path {path} to exist")

    def test_hermetic_binary_cache_with_dependencies(self):
        file_abs_path = os.path.join(
            get_buildroot(), "examples/src/scala/org/pantsbuild/example/hello/exe/Exe.scala"
        )

        with temporary_dir() as cache_dir:
            config = {
                "cache.compile.rsc": {"write_to": [cache_dir], "read_from": [cache_dir]},
                "compile.rsc": {
                    "execution_strategy": "hermetic",
                    "use_classpath_jars": False,
                    "incremental": False,
                },
            }

            with self.temporary_workdir() as workdir:
                pants_run = self.run_pants_with_workdir(
                    ["-q", "run", "examples/src/scala/org/pantsbuild/example/hello/exe"],
                    workdir,
                    config,
                )
                self.assert_success(pants_run)
                self.assertIn(
                    "Num args passed: 0. Stand by for welcome...\nHello, Resource World!",
                    pants_run.stdout_data,
                )

                compile_dir = os.path.join(workdir, "compile", "rsc", "current")

                for path_suffix in [
                    "examples.src.scala.org.pantsbuild.example.hello.exe.exe/current/zinc/classes/org/pantsbuild/example/hello/exe/Exe.class",
                    "examples.src.scala.org.pantsbuild.example.hello.welcome.welcome/current/zinc/classes/org/pantsbuild/example/hello/welcome/WelcomeEverybody.class",
                ]:
                    path = os.path.join(compile_dir, path_suffix)
                    self.assertTrue(os.path.exists(path), f"Want path {path} to exist")
                with self.with_overwritten_file_content(file_abs_path):

                    new_temp_test = """package org.pantsbuild.example.hello.exe

                              import java.io.{BufferedReader, InputStreamReader}
                              import org.pantsbuild.example.hello
                              import org.pantsbuild.example.hello.welcome

                              // A simple jvm binary to illustrate Scala BUILD targets

                              object Exe {
                                /** Test that resources are properly namespaced. */
                                def getWorld: String = {
                                  val is =
                                    this.getClass.getClassLoader.getResourceAsStream(
                                      "org/pantsbuild/example/hello/world.txt"
                                    )
                                  try {
                                    new BufferedReader(new InputStreamReader(is)).readLine()
                                  } finally {
                                    is.close()
                                  }
                                }

                                def main(args: Array[String]) {
                                  println("Num args passed: " + args.size + ". Stand by for welcome...")
                                  if (args.size <= 0) {
                                    println("Hello, and welcome to " + getWorld + "!")
                                  } else {
                                    val w = welcome.WelcomeEverybody(args)
                                    w.foreach(s => println(s))
                                  }
                                }
                              }"""

                    with open(file_abs_path, "w") as f:
                        f.write(new_temp_test)

                    pants_run = self.run_pants_with_workdir(
                        ["-q", "run", "examples/src/scala/org/pantsbuild/example/hello/exe"],
                        workdir,
                        config,
                    )
                    self.assert_success(pants_run)
                    self.assertIn(
                        "Num args passed: 0. Stand by for welcome...\nHello, and welcome to Resource World!",
                        pants_run.stdout_data,
                    )

                    compile_dir = os.path.join(workdir, "compile", "rsc", "current")

                    for path_suffix in [
                        "examples.src.scala.org.pantsbuild.example.hello.exe.exe/current/zinc/classes/org/pantsbuild/example/hello/exe/Exe.class",
                        "examples.src.scala.org.pantsbuild.example.hello.welcome.welcome/current/zinc/classes/org/pantsbuild/example/hello/welcome/WelcomeEverybody.class",
                    ]:
                        path = os.path.join(compile_dir, path_suffix)
                        self.assertTrue(os.path.exists(path), f"Want path {path} to exist")
Пример #11
0
class JunitRunIntegrationTest(PantsRunIntegrationTest):
    def _testjvms(self, spec_name):
        spec = 'testprojects/tests/java/org/pantsbuild/testproject/testjvms:{}'.format(
            spec_name)
        self.assert_success(
            self.run_pants(
                ['clean-all', 'test.junit', '--strict-jvm-version', spec]))

    # See https://github.com/pantsbuild/pants/issues/2894 for details on why this is
    # marked xfail.
    @expectedFailure
    @skipIf(is_missing_jvm('1.8'),
            'no java 1.8 installation on testing machine')
    def test_java_eight(self):
        self._testjvms('eight')

    @skipIf(is_missing_jvm('1.7'),
            'no java 1.7 installation on testing machine')
    def test_java_seven(self):
        self._testjvms('seven')

    @skipIf(is_missing_jvm('1.6'),
            'no java 1.6 installation on testing machine')
    def test_java_six(self):
        self._testjvms('six')

    @skipIf(is_missing_jvm('1.8'),
            'no java 1.8 installation on testing machine')
    def test_with_test_platform(self):
        self._testjvms('eight-test-platform')

    def test_junit_run_against_class_succeeds(self):
        self.assert_success(
            self.run_pants([
                'clean-all', 'test.junit',
                '--test=org.pantsbuild.testproject.matcher.MatcherTest',
                'testprojects/tests/java/org/pantsbuild/testproject/matcher'
            ]))

    def test_junit_run_with_cobertura_coverage_succeeds(self):
        with self.pants_results([
                'clean-all', 'test.junit',
                'testprojects/tests/java/org/pantsbuild/testproject/unicode::',
                '--test-junit-coverage-processor=cobertura',
                '--test-junit-coverage'
        ]) as results:
            self.assert_success(results)
            # validate that the expected coverage file exists, and it reflects 100% line rate coverage
            coverage_xml = os.path.join(
                results.workdir, 'test/junit/coverage/xml/coverage.xml')
            self.assertTrue(os.path.isfile(coverage_xml))
            with codecs.open(coverage_xml, 'r', encoding='utf8') as xml:
                self.assertIn('line-rate="1.0"', xml.read())
            # validate that the html report was able to find sources for annotation
            cucumber_src_html = os.path.join(
                results.workdir,
                'test/junit/coverage/html/org.pantsbuild.testproject.unicode.cucumber.CucumberAnnotatedExample.html'
            )
            self.assertTrue(os.path.isfile(cucumber_src_html))
            with codecs.open(cucumber_src_html, 'r', encoding='utf8') as src:
                self.assertIn('String pleasantry()', src.read())

    def test_junit_run_against_invalid_class_fails(self):
        pants_run = self.run_pants([
            'clean-all', 'test.junit',
            '--test=org.pantsbuild.testproject.matcher.MatcherTest_BAD_CLASS',
            'testprojects/tests/java/org/pantsbuild/testproject/matcher'
        ])
        self.assert_failure(pants_run)
        self.assertIn("No target found for test specifier",
                      pants_run.stdout_data)

    def test_junit_run_timeout_succeeds(self):
        pants_run = self.run_pants([
            'clean-all', 'test.junit', '--timeout-default=1',
            '--test=org.pantsbuild.testproject.timeout.SleeperTestShort',
            'testprojects/tests/java/org/pantsbuild/testproject/timeout:sleeping_target'
        ])
        self.assert_success(pants_run)

    def test_junit_run_timeout_fails(self):
        start = time.time()
        pants_run = self.run_pants([
            'clean-all', 'test.junit', '--timeout-default=1',
            '--test=org.pantsbuild.testproject.timeout.SleeperTestLong',
            'testprojects/tests/java/org/pantsbuild/testproject/timeout:sleeping_target'
        ])
        end = time.time()
        self.assert_failure(pants_run)

        # Ensure that the failure took less than 120 seconds to run.
        self.assertLess(end - start, 120)

        # Ensure that the timeout triggered.
        self.assertIn("FAILURE: Timeout of 1 seconds reached",
                      pants_run.stdout_data)

    @expectedFailure
    def test_junit_tests_using_cucumber(self):
        test_spec = 'testprojects/tests/java/org/pantsbuild/testproject/cucumber'
        with self.pants_results(
            ['clean-all', 'test.junit', '--per-test-timer',
             test_spec]) as results:
            self.assert_success(results)

    def test_disable_synthetic_jar(self):
        output = self.run_pants([
            'test.junit', '--output-mode=ALL',
            'testprojects/tests/java/org/pantsbuild/testproject/syntheticjar:test'
        ]).stdout_data
        self.assertIn('Synthetic jar run is detected', output)

        output = self.run_pants([
            'test.junit', '--output-mode=ALL', '--no-jvm-synthetic-classpath',
            'testprojects/tests/java/org/pantsbuild/testproject/syntheticjar:test'
        ]).stdout_data
        self.assertIn('Synthetic jar run is not detected', output)

    def test_junit_run_with_html_report(self):
        with self.pants_results([
                'clean-all', 'test.junit',
                'testprojects/tests/java/org/pantsbuild/testproject/htmlreport::',
                '--test-junit-html-report'
        ]) as results:
            self.assert_failure(results)
            report_html = os.path.join(results.workdir,
                                       'test/junit/reports/junit-report.html')
            self.assertTrue(os.path.isfile(report_html))
            with codecs.open(report_html, 'r', encoding='utf8') as src:
                html = src.read()
                self.assertIn('testPasses', html)
                self.assertIn('testFails', html)
                self.assertIn('testErrors', html)
                self.assertIn('testSkipped', html)