def get_two_distributions(): try: java7 = Distribution.locate(minimum_version='1.7', maximum_version='1.7.9999') java8 = Distribution.locate(minimum_version='1.8', maximum_version='1.8.9999') return java7, java8 except Distribution.Error: return None
def test_locate_trumps_path(self): with self.java_home_exe() as (jdk1_home, jdk2_home): with distribution(executables=exe('bin/java', version='3')) as path_jdk: with env(PATH=os.path.join(path_jdk, 'bin')): dist = Distribution.locate() self.assertEqual(jdk1_home, dist.home) dist = Distribution.locate(minimum_version='3') self.assertEqual(path_jdk, dist.home)
def test_locate_java_home_trumps(self): with self.java_home_exe() as (jdk1_home, jdk2_home): with distribution(executables=exe('bin/java', version='3')) as java_home: with env(JAVA_HOME=java_home): dist = Distribution.locate() self.assertEqual(java_home, dist.home) dist = Distribution.locate(maximum_version='1.1') self.assertEqual(jdk1_home, dist.home) dist = Distribution.locate(minimum_version='1.1', maximum_version='2') self.assertEqual(jdk2_home, dist.home)
def test_validate_live(self): with pytest.raises(Distribution.Error): Distribution(bin_path=os.path.dirname(self.JAVA), minimum_version='999.9.9').validate() with pytest.raises(Distribution.Error): Distribution(bin_path=os.path.dirname(self.JAVA), maximum_version='0.0.1').validate() Distribution(bin_path=os.path.dirname(self.JAVA)).validate() Distribution(bin_path=os.path.dirname(self.JAVA), minimum_version='1.3.1').validate() Distribution(bin_path=os.path.dirname(self.JAVA), maximum_version='999.999.999').validate() Distribution(bin_path=os.path.dirname(self.JAVA), minimum_version='1.3.1', maximum_version='999.999.999').validate() Distribution.locate(jdk=False)
def test_validate_basic(self): with distribution() as dist_root: with self.assertRaises(ValueError): Distribution( bin_path=os.path.join(dist_root, 'bin')).validate() with distribution(files='bin/java') as dist_root: with self.assertRaises(Distribution.Error): Distribution( bin_path=os.path.join(dist_root, 'bin')).validate() with distribution(executables=EXE('bin/java')) as dist_root: Distribution(bin_path=os.path.join(dist_root, 'bin')).validate()
def _run_tests(self, tests_to_targets, main, extra_jvm_options=None, classpath_prepend=(), classpath_append=()): extra_jvm_options = extra_jvm_options or [] tests_by_properties = self._tests_by_properties(tests_to_targets, self._infer_workdir, lambda target: target.test_platform) result = 0 for (workdir, platform), tests in tests_by_properties.items(): for batch in self._partition(tests): # Batches of test classes will likely exist within the same targets: dedupe them. relevant_targets = set(map(tests_to_targets.get, batch)) classpath = self._task_exports.classpath(relevant_targets, cp=self._task_exports.tool_classpath('junit')) complete_classpath = OrderedSet() complete_classpath.update(classpath_prepend) complete_classpath.update(classpath) complete_classpath.update(classpath_append) if self._strict_jvm_version: max_version = Revision(*(platform.target_level.components + [9999])) distribution = Distribution.cached(minimum_version=platform.target_level, maximum_version=max_version) else: distribution = Distribution.cached(minimum_version=platform.target_level) with binary_util.safe_args(batch, self._task_exports.task_options) as batch_tests: self._context.log.debug('CWD = {}'.format(workdir)) self._context.log.debug('platform = {}'.format(platform)) result += abs(execute_java( classpath=complete_classpath, main=main, jvm_options=self._task_exports.jvm_options + extra_jvm_options, args=self._args + batch_tests + [u'-xmlreport'], workunit_factory=self._context.new_workunit, workunit_name='run', workunit_labels=[WorkUnitLabel.TEST], cwd=workdir, distribution=distribution, )) if result != 0 and self._fail_fast: break if result != 0: failed_targets = self._get_failed_targets(tests_to_targets) raise TestFailedTaskError( 'java {0} ... exited non-zero ({1}); {2} failed targets.' .format(main, result, len(failed_targets)), failed_targets=failed_targets )
def requirements(cls, tools): sdk_home = os.environ.get('ANDROID_HOME') android_sdk = os.path.abspath(sdk_home) if sdk_home else None if android_sdk: for tool in tools: if not os.path.isfile(os.path.join(android_sdk, tool)): return False else: return False try: Distribution.cached(minimum_version=cls.JAVA_MIN, maximum_version=cls.JAVA_MAX) except: return False return True
def requirements(cls, tools): sdk_home = os.environ.get('ANDROID_HOME') android_sdk = os.path.abspath(sdk_home) if sdk_home else None if android_sdk: for tool in tools: if not os.path.isfile(os.path.join(android_sdk, tool)): return False else: return False try: Distribution.cached(minimum_version=cls.JAVA_MIN, maximum_version=cls.JAVA_MAX) except Distribution.Error: return False return True
def test_validate_version(self): with distribution(executables=EXE('bin/java', '1.7.0_25')) as dist_root: with self.assertRaises(Distribution.Error): Distribution(bin_path=os.path.join(dist_root, 'bin'), minimum_version='1.7.0_45').validate() with distribution(executables=EXE('bin/java', '1.8.0_1')) as dist_root: with self.assertRaises(Distribution.Error): Distribution(bin_path=os.path.join(dist_root, 'bin'), maximum_version='1.8').validate() with distribution(executables=EXE('bin/java', '1.7.0_25')) as dist_root: Distribution(bin_path=os.path.join(dist_root, 'bin'), minimum_version='1.7.0_25').validate() Distribution(bin_path=os.path.join(dist_root, 'bin'), minimum_version=Revision.lenient('1.6')).validate() Distribution(bin_path=os.path.join(dist_root, 'bin'), minimum_version='1.7.0_25', maximum_version='1.7.999').validate()
def distribution(self): if self._dist is None: # Currently no Java 8 for Android. I considered max=1.7.0_50. See comment in _render_args(). self._dist = Distribution.cached(minimum_version='1.6.0_00', maximum_version='1.7.0_99', jdk=True) return self._dist
def dist(self): """Return the `Distribution` selected for Zinc based on execution strategy. :rtype: pants.java.distribution.distribution.Distribution """ underlying_dist = self.underlying_dist if self._execution_strategy != NailgunTaskBase.HERMETIC: # symlink .pants.d/.jdk -> /some/java/home/ jdk_home_symlink = os.path.relpath( os.path.join(self._zinc_factory.get_options().pants_workdir, '.jdk'), get_buildroot()) # Since this code can be run in multi-threading mode due to multiple # zinc workers, we need to make sure the file operations below is atomic. with self._lock: # Create the symlink if it does not exist if not os.path.exists(jdk_home_symlink): os.symlink(underlying_dist.home, jdk_home_symlink) # Recreate if the symlink exists but does not match `underlying_dist.home`. elif os.readlink(jdk_home_symlink) != underlying_dist.home: os.remove(jdk_home_symlink) os.symlink(underlying_dist.home, jdk_home_symlink) return Distribution(home_path=jdk_home_symlink) else: return underlying_dist
def test_validate_jdk(self): with distribution(executables=EXE('bin/java')) as dist_root: with self.assertRaises(Distribution.Error): Distribution(bin_path=os.path.join(dist_root, 'bin'), jdk=True).validate() with distribution(executables=[EXE('bin/java'), EXE('bin/javac')]) as dist_root: Distribution(bin_path=os.path.join(dist_root, 'bin'), jdk=True).validate() with distribution(executables=[EXE('jre/bin/java'), EXE('bin/javac')], java_home='jre') as dist_root: Distribution(bin_path=os.path.join(dist_root, 'jre/bin'), jdk=True).validate()
def _compile_schema(self, args): classpath = Distribution.cached(jdk=True).find_libs(['tools.jar']) java_main = 'com.sun.tools.internal.xjc.Driver' return self.runjava(classpath=classpath, main=java_main, args=args, workunit_name='xjc')
def test_validate_jdk(self): with distribution(executables=EXE("bin/java")) as dist_root: with self.assertRaises(Distribution.Error): Distribution(bin_path=os.path.join(dist_root, "bin"), jdk=True).validate() with distribution(executables=[EXE("bin/java"), EXE("bin/javac")]) as dist_root: Distribution(bin_path=os.path.join(dist_root, "bin"), jdk=True).validate() with distribution(executables=[EXE("jre/bin/java"), EXE("bin/javac")], java_home="jre") as dist_root: Distribution(bin_path=os.path.join(dist_root, "jre/bin"), jdk=True).validate()
def locate_tools_jar(): try: return Distribution.cached(jdk=True).find_libs(['tools.jar']) except Distribution.Error: self.context.log.info('Failed to locate tools.jar. ' 'Install a JDK to increase performance of Zinc.') return []
def dist(self): """Return the `Distribution` selected for Zinc based on execution strategy. :rtype: pants.java.distribution.distribution.Distribution """ underlying_dist = self.underlying_dist if self._execution_strategy != NailgunTaskBase.HERMETIC: # symlink .pants.d/.jdk -> /some/java/home/ jdk_home_symlink = os.path.relpath( os.path.join(self._zinc_factory.get_options().pants_workdir, '.jdk'), get_buildroot()) # Since this code can be run in multi-threading mode due to multiple # zinc workers, we need to make sure the file operations below are atomic. with self._lock: # Create the symlink if it does not exist, or points to a file that doesn't exist, # (e.g., a JDK that is no longer present), or points to the wrong JDK. if (not os.path.exists(jdk_home_symlink) or os.readlink(jdk_home_symlink) != underlying_dist.home): safe_delete( jdk_home_symlink ) # Safe-delete, in case it's a broken symlink. os.symlink(underlying_dist.home, jdk_home_symlink) return Distribution(home_path=jdk_home_symlink) else: return underlying_dist
def execute_junit_runner(self, content): # Create the temporary base test directory test_rel_path = 'tests/java/org/pantsbuild/foo' test_abs_path = os.path.join(self.build_root, test_rel_path) self.create_dir(test_rel_path) # Generate the temporary java test source code. test_java_file_rel_path = os.path.join(test_rel_path, 'FooTest.java') test_java_file_abs_path = os.path.join(self.build_root, test_java_file_rel_path) self.create_file(test_java_file_rel_path, content) # Invoke ivy to resolve classpath for junit. distribution = Distribution.cached(jdk=True) executor = SubprocessExecutor(distribution=distribution) classpath_file_abs_path = os.path.join(test_abs_path, 'junit.classpath') ivy = Bootstrapper.default_ivy() ivy.execute(args=['-cachepath', classpath_file_abs_path, '-dependency', 'junit', 'junit-dep', '4.10'], executor=executor) with open(classpath_file_abs_path) as fp: classpath = fp.read() # Now directly invoking javac to compile the test java code into java class # so later we can inject the class into products mapping for JUnitRun to execute # the test on. javac = distribution.binary('javac') subprocess.check_call( [javac, '-d', test_abs_path, '-cp', classpath, test_java_file_abs_path]) # Create a java_tests target and a synthetic resource target. java_tests = self.create_library(test_rel_path, 'java_tests', 'foo_test', ['FooTest.java']) resources = self.make_target('some_resources', Resources) # Set the context with the two targets, one java_tests target and # one synthetic resources target. # The synthetic resources target is to make sure we won't regress # in the future with bug like https://github.com/pantsbuild/pants/issues/508. Note # in that bug, the resources target must be the first one in the list. context = self.context(target_roots=[resources, java_tests]) # Before we run the task, we need to inject the "classes_by_target" with # the compiled test java classes that JUnitRun will know which test # classes to execute. In a normal run, this "classes_by_target" will be # populated by java compiling step. class_products = context.products.get_data( 'classes_by_target', lambda: defaultdict(MultipleRootedProducts)) java_tests_products = MultipleRootedProducts() java_tests_products.add_rel_paths(test_abs_path, ['FooTest.class']) class_products[java_tests] = java_tests_products # Also we need to add the FooTest.class's classpath to the compile_classpath # products data mapping so JUnitRun will be able to add that into the final # classpath under which the junit will be executed. self.populate_compile_classpath( context=context, classpath=[test_abs_path]) # Finally execute the task. self.execute(context)
def execute_junit_runner(self, content): # Create the temporary base test directory test_rel_path = 'tests/java/org/pantsbuild/foo' test_abs_path = os.path.join(self.build_root, test_rel_path) self.create_dir(test_rel_path) # Generate the temporary java test source code. test_java_file_rel_path = os.path.join(test_rel_path, 'FooTest.java') test_java_file_abs_path = os.path.join(self.build_root, test_java_file_rel_path) self.create_file(test_java_file_rel_path, content) # Invoke ivy to resolve classpath for junit. distribution = Distribution.cached(jdk=True) executor = SubprocessExecutor(distribution=distribution) classpath_file_abs_path = os.path.join(test_abs_path, 'junit.classpath') with subsystem_instance(IvySubsystem) as ivy_subsystem: ivy = Bootstrapper(ivy_subsystem=ivy_subsystem).ivy() ivy.execute(args=['-cachepath', classpath_file_abs_path, '-dependency', 'junit', 'junit-dep', '4.10'], executor=executor) with open(classpath_file_abs_path) as fp: classpath = fp.read() # Now directly invoking javac to compile the test java code into java class # so later we can inject the class into products mapping for JUnitRun to execute # the test on. javac = distribution.binary('javac') subprocess.check_call( [javac, '-d', test_abs_path, '-cp', classpath, test_java_file_abs_path]) # Create a java_tests target and a synthetic resource target. java_tests = self.create_library(test_rel_path, 'java_tests', 'foo_test', ['FooTest.java']) resources = self.make_target('some_resources', Resources) # Set the context with the two targets, one java_tests target and # one synthetic resources target. # The synthetic resources target is to make sure we won't regress # in the future with bug like https://github.com/pantsbuild/pants/issues/508. Note # in that bug, the resources target must be the first one in the list. context = self.context(target_roots=[resources, java_tests]) # Before we run the task, we need to inject the "classes_by_target" with # the compiled test java classes that JUnitRun will know which test # classes to execute. In a normal run, this "classes_by_target" will be # populated by java compiling step. class_products = context.products.get_data( 'classes_by_target', lambda: defaultdict(MultipleRootedProducts)) java_tests_products = MultipleRootedProducts() java_tests_products.add_rel_paths(test_abs_path, ['FooTest.class']) class_products[java_tests] = java_tests_products # Also we need to add the FooTest.class's classpath to the compile_classpath # products data mapping so JUnitRun will be able to add that into the final # classpath under which the junit will be executed. self.populate_compile_classpath(context=context, classpath=[test_abs_path]) # Finally execute the task. self.execute(context)
def test_validated_library(self): with distribution(executables=EXE('bin/java')) as dist_root: with self.assertRaises(Distribution.Error): Distribution(bin_path=os.path.join(dist_root, 'bin')).find_libs(['tools.jar']) with distribution(executables=EXE('bin/java'), files='lib/tools.jar') as dist_root: dist = Distribution(bin_path=os.path.join(dist_root, 'bin')) self.assertEqual([os.path.join(dist_root, 'lib', 'tools.jar')], dist.find_libs(['tools.jar'])) with distribution(executables=[EXE('jre/bin/java'), EXE('bin/javac')], files=['lib/tools.jar', 'jre/lib/rt.jar'], java_home='jre') as dist_root: dist = Distribution(bin_path=os.path.join(dist_root, 'jre/bin')) self.assertEqual([os.path.join(dist_root, 'lib', 'tools.jar'), os.path.join(dist_root, 'jre', 'lib', 'rt.jar')], dist.find_libs(['tools.jar', 'rt.jar']))
def locate_tools_jar(): try: return Distribution.cached(jdk=True).find_libs(['tools.jar']) except Distribution.Error: self.context.log.info( 'Failed to locate tools.jar. ' 'Install a JDK to increase performance of Zinc.') return []
def test_validated_library(self): with distribution(executables=EXE("bin/java")) as dist_root: with self.assertRaises(Distribution.Error): Distribution( bin_path=os.path.join(dist_root, "bin")).find_libs( ["tools.jar"]) with distribution(executables=EXE("bin/java"), files="lib/tools.jar") as dist_root: dist = Distribution(bin_path=os.path.join(dist_root, "bin")) self.assertEqual([os.path.join(dist_root, "lib", "tools.jar")], dist.find_libs(["tools.jar"])) with distribution( executables=[EXE("jre/bin/java"), EXE("bin/javac")], files=["lib/tools.jar", "jre/lib/rt.jar"], java_home="jre", ) as dist_root: dist = Distribution(bin_path=os.path.join(dist_root, "jre/bin")) self.assertEqual( [ os.path.join(dist_root, "lib", "tools.jar"), os.path.join(dist_root, "jre", "lib", "rt.jar"), ], dist.find_libs(["tools.jar", "rt.jar"]), )
def test_preferred_jvm_distributions(self): with temporary_dir() as strict_jdk_home: with temporary_dir() as non_strict_jdk_home: strict_cache_key = (Revision(1, 6), Revision(1, 6, 9999), False) non_strict_cache_key = (Revision(1, 6), None, False) DistributionLocator._CACHE[strict_cache_key] = Distribution( home_path=strict_jdk_home) DistributionLocator._CACHE[ non_strict_cache_key] = Distribution( home_path=non_strict_jdk_home) self.assertEqual( { 'strict': strict_jdk_home, 'non_strict': non_strict_jdk_home }, self.execute_export_json()['preferred_jvm_distributions'] ['java6'])
def java_sysprops(self): """The system properties of the JVM we use.""" # TODO: In the future we can use these to hermeticize the Java enivronment rather than relying # on whatever's on the shell's PATH. E.g., you either specify a path to the Java home via a # cmd-line flag or .pantsrc, or we infer one from java.home but verify that the java.version # is a supported version. if self._java_sysprops is None: # TODO(John Sirois): Plumb a sane default distribution through 1 point of control self._java_sysprops = Distribution.cached().system_properties return self._java_sysprops
def _fallback_platform(self): logger.warn('No default jvm platform is defined.') source_level = JvmPlatform.parse_java_version( Distribution.cached().version) target_level = source_level platform_name = '(Distribution.cached().version {})'.format( source_level) return JvmPlatformSettings(source_level, target_level, [], name=platform_name)
def set_distribution(self, minimum_version=None, maximum_version=None, jdk=False): try: self._dist = Distribution.cached(minimum_version=minimum_version, maximum_version=maximum_version, jdk=jdk) except Distribution.Error as e: raise TaskError(e)
def __init__(self, *args, **kwargs): """ :param context: inherited parameter from Task :param workdir: inherited parameter from Task """ super(JaxbGen, self).__init__(*args, **kwargs) self.gen_langs = set() lang = 'java' if self.context.products.isrequired(lang): self.gen_langs.add(lang) self.jar_location = os.path.join(Distribution.cached().home, '..', 'lib', 'tools.jar')
def test_validate_version(self): with pytest.raises(Distribution.Error): with self.distribution( executables=self.exe('java', '1.7.0_25')) as jdk: Distribution(bin_path=jdk, minimum_version='1.7.0_45').validate() with pytest.raises(Distribution.Error): with self.distribution( executables=self.exe('java', '1.8.0_1')) as jdk: Distribution(bin_path=jdk, maximum_version='1.7.9999').validate() with self.distribution( executables=self.exe('java', '1.7.0_25')) as jdk: Distribution(bin_path=jdk, minimum_version='1.7.0_25').validate() Distribution(bin_path=jdk, minimum_version=Revision.semver('1.6.0')).validate() Distribution(bin_path=jdk, minimum_version='1.7.0_25', maximum_version='1.7.999').validate()
def test_validated_binary(self): with distribution(files='bin/jar', executables=EXE('bin/java')) as dist_root: with self.assertRaises(Distribution.Error): Distribution(bin_path=os.path.join(dist_root, 'bin')).binary('jar') with distribution(executables=[EXE('bin/java'), EXE('bin/jar')]) as dist_root: Distribution(bin_path=os.path.join(dist_root, 'bin')).binary('jar') with distribution(executables=[EXE('jre/bin/java'), EXE('bin/jar')], java_home='jre') as dist_root: with self.assertRaises(Distribution.Error): Distribution(bin_path=os.path.join(dist_root, 'jre', 'bin')).binary('jar') with distribution(executables=[EXE('jre/bin/java'), EXE('bin/jar'), EXE('bin/javac')], java_home='jre') as dist_root: Distribution(bin_path=os.path.join(dist_root, 'jre', 'bin')).binary('jar') with distribution(executables=[EXE('jre/bin/java'), EXE('jre/bin/java_vm'), EXE('bin/javac')], java_home='jre') as dist_root: Distribution(bin_path=os.path.join(dist_root, 'jre', 'bin')).binary('java_vm')
def do_test_jre_env_var(self, env_var, env_value, scrubbed=True): with self.jre(env_var=env_var) as jre: executor = SubprocessExecutor(Distribution(bin_path=jre)) with environment_as(**{env_var: env_value}): self.assertEqual(env_value, os.getenv(env_var)) process = executor.spawn(classpath=['dummy/classpath'], main='dummy.main', stdout=subprocess.PIPE, stderr=subprocess.PIPE) _, stderr = process.communicate() self.assertEqual(0, process.returncode) self.assertEqual('' if scrubbed else env_value, stderr.decode().strip())
def test_validate_version(self): with distribution( executables=EXE("bin/java", "1.7.0_25")) as dist_root: with self.assertRaises(Distribution.Error): Distribution(bin_path=os.path.join(dist_root, "bin"), minimum_version="1.7.0_45").validate() with distribution(executables=EXE("bin/java", "1.8.0_1")) as dist_root: with self.assertRaises(Distribution.Error): Distribution(bin_path=os.path.join(dist_root, "bin"), maximum_version="1.8").validate() with distribution( executables=EXE("bin/java", "1.7.0_25")) as dist_root: Distribution(bin_path=os.path.join(dist_root, "bin"), minimum_version="1.7.0_25").validate() Distribution(bin_path=os.path.join(dist_root, "bin"), minimum_version=Revision.lenient("1.6")).validate() Distribution( bin_path=os.path.join(dist_root, "bin"), minimum_version="1.7.0_25", maximum_version="1.7.999", ).validate()
def __init__(self, distribution=None): """Constructs an Executor that can be used to launch java programs. :param distribution: an optional validated java distribution to use when launching java programs """ if distribution: if not isinstance(distribution, Distribution): raise ValueError('A valid distribution is required, given: %s' % distribution) distribution.validate() else: distribution = Distribution.cached() self._distribution = distribution
def __init__(self, context, workdir, minimum_version=None, maximum_version=None, jdk=False, nailgun_name=None): super(NailgunTaskBase, self).__init__(context, workdir) self._executor_workdir = os.path.join(context.config.getdefault('pants_workdir'), 'ng', nailgun_name or self.__class__.__name__) self._nailgun_bootstrap_key = 'nailgun' self.register_jvm_tool(self._nailgun_bootstrap_key, [':nailgun-server']) with self.context.new_workunit(name='jvm-locate'): try: self._dist = Distribution.cached(minimum_version=minimum_version, maximum_version=maximum_version, jdk=jdk) except Distribution.Error as e: raise TaskError(e)
def test_validated_binary(self): with distribution(files="bin/jar", executables=EXE("bin/java")) as dist_root: with self.assertRaises(Distribution.Error): Distribution( bin_path=os.path.join(dist_root, "bin")).binary("jar") with distribution( executables=[EXE("bin/java"), EXE("bin/jar")]) as dist_root: Distribution(bin_path=os.path.join(dist_root, "bin")).binary("jar") with distribution(executables=[EXE("jre/bin/java"), EXE("bin/jar")], java_home="jre") as dist_root: with self.assertRaises(Distribution.Error): Distribution(bin_path=os.path.join(dist_root, "jre", "bin")).binary("jar") with distribution(executables=[ EXE("jre/bin/java"), EXE("bin/jar"), EXE("bin/javac") ], java_home="jre") as dist_root: Distribution( bin_path=os.path.join(dist_root, "jre", "bin")).binary("jar") with distribution( executables=[ EXE("jre/bin/java"), EXE("jre/bin/java_vm"), EXE("bin/javac") ], java_home="jre", ) as dist_root: Distribution(bin_path=os.path.join(dist_root, "jre", "bin")).binary("java_vm")
def test_validate_live(self): with self.assertRaises(Distribution.Error): Distribution(bin_path=os.path.dirname(self.JAVA), minimum_version='999.9.9').validate() with self.assertRaises(Distribution.Error): Distribution(bin_path=os.path.dirname(self.JAVA), maximum_version='0.0.1').validate() Distribution(bin_path=os.path.dirname(self.JAVA)).validate() Distribution(bin_path=os.path.dirname(self.JAVA), minimum_version='1.3.1').validate() Distribution(bin_path=os.path.dirname(self.JAVA), maximum_version='999.999.999').validate() Distribution(bin_path=os.path.dirname(self.JAVA), minimum_version='1.3.1', maximum_version='999.999.999').validate() locator = global_subsystem_instance(DistributionLocator) locator.cached(jdk=False)
def create_javadoc_command(self, classpath, gendir, *targets): sources = [] for target in targets: sources.extend(target.sources_relative_to_buildroot()) if not sources: return None # Without a JDK/tools.jar we have no javadoc tool and cannot proceed, so check/acquire early. jdk = Distribution.cached(jdk=True) tool_classpath = jdk.find_libs(['tools.jar']) args = [ '-quiet', '-encoding', 'UTF-8', '-notimestamp', '-use', '-classpath', ':'.join(classpath), '-d', gendir ] # Always provide external linking for java API offlinelinks = {'http://download.oracle.com/javase/6/docs/api/'} def link(target): for jar in target.jar_dependencies: if jar.apidocs: offlinelinks.add(jar.apidocs) for target in targets: target.walk(link, lambda t: t.is_jvm) for link in offlinelinks: args.extend(['-linkoffline', link, link]) args.extend(self.args) args.extend(sources) java_executor = SubprocessExecutor(jdk) runner = java_executor.runner(jvm_options=self.jvm_options, classpath=tool_classpath, main='com.sun.tools.javadoc.Main', args=args) return runner.command
def dist(self) -> Distribution: """Return the `Distribution` selected for Zinc based on execution strategy.""" underlying_dist = self.underlying_dist if self._execution_strategy == NailgunTaskBase.HERMETIC: return underlying_dist # symlink .pants.d/.jdk -> /some/java/home/ jdk_home_symlink = Path( self._zinc_factory.get_options().pants_workdir, '.jdk' ).relative_to(get_buildroot()) # Since this code can be run in multi-threading mode due to multiple # zinc workers, we need to make sure the file operations below are atomic. with self._lock: # Create the symlink if it does not exist, or points to a file that doesn't exist, # (e.g., a JDK that is no longer present), or points to the wrong JDK. if not jdk_home_symlink.exists() or jdk_home_symlink.resolve() != Path(underlying_dist.home): safe_delete(str(jdk_home_symlink)) # Safe-delete, in case it's a broken symlink. safe_mkdir_for(jdk_home_symlink) jdk_home_symlink.symlink_to(underlying_dist.home) return Distribution(home_path=jdk_home_symlink)
def create_javadoc_command(self, classpath, gendir, *targets): sources = [] for target in targets: sources.extend(target.sources_relative_to_buildroot()) if not sources: return None # Without a JDK/tools.jar we have no javadoc tool and cannot proceed, so check/acquire early. jdk = Distribution.cached(jdk=True) tool_classpath = jdk.find_libs(["tools.jar"]) args = ["-quiet", "-encoding", "UTF-8", "-notimestamp", "-use", "-classpath", ":".join(classpath), "-d", gendir] # Always provide external linking for java API offlinelinks = {"http://download.oracle.com/javase/6/docs/api/"} def link(target): for jar in target.jar_dependencies: if jar.apidocs: offlinelinks.add(jar.apidocs) for target in targets: target.walk(link, lambda t: t.is_jvm) for link in offlinelinks: args.extend(["-linkoffline", link, link]) args.extend(self.args) args.extend(sources) java_executor = SubprocessExecutor(jdk) runner = java_executor.runner( jvm_options=self.jvm_options, classpath=tool_classpath, main="com.sun.tools.javadoc.Main", args=args ) return runner.command
def test_validate_live_jdk(self): Distribution(bin_path=os.path.dirname(self.JAVAC), jdk=True).validate() Distribution(bin_path=os.path.dirname(self.JAVAC), jdk=True).binary('javap') Distribution.locate(jdk=True)
def test_locate(self): with pytest.raises(Distribution.Error): with self.env(): Distribution.locate() with pytest.raises(Distribution.Error): with self.distribution(files='java') as jdk: with self.env(PATH=jdk): Distribution.locate() with pytest.raises(Distribution.Error): with self.distribution(executables=self.exe('java')) as jdk: with self.env(PATH=jdk): Distribution.locate(jdk=True) with pytest.raises(Distribution.Error): with self.distribution(executables=self.exe('java', '1.6.0')) as jdk: with self.env(PATH=jdk): Distribution.locate(minimum_version='1.7.0') with pytest.raises(Distribution.Error): with self.distribution(executables=self.exe('java', '1.8.0')) as jdk: with self.env(PATH=jdk): Distribution.locate(maximum_version='1.7.999') with pytest.raises(Distribution.Error): with self.distribution(executables=self.exe('java')) as jdk: with self.env(JDK_HOME=jdk): Distribution.locate() with pytest.raises(Distribution.Error): with self.distribution(executables=self.exe('java')) as jdk: with self.env(JAVA_HOME=jdk): Distribution.locate() with self.distribution(executables=self.exe('java')) as jdk: with self.env(PATH=jdk): Distribution.locate() with self.distribution(executables=[self.exe('java'), self.exe('javac')]) as jdk: with self.env(PATH=jdk): Distribution.locate(jdk=True) with self.distribution(executables=self.exe('java', '1.7.0')) as jdk: with self.env(PATH=jdk): Distribution.locate(minimum_version='1.6.0') with self.env(PATH=jdk): Distribution.locate(maximum_version='1.7.999') with self.env(PATH=jdk): Distribution.locate(minimum_version='1.6.0', maximum_version='1.7.999') with self.distribution(executables=self.exe('bin/java')) as jdk: with self.env(JDK_HOME=jdk): Distribution.locate() with self.distribution(executables=self.exe('bin/java')) as jdk: with self.env(JAVA_HOME=jdk): Distribution.locate()
def test_cached_good_bounds(self): with distribution(executables=exe('bin/java', '1.7.0_33')) as dist_root: with env(PATH=os.path.join(dist_root, 'bin')): Distribution.cached(minimum_version='1.6.0_35', maximum_version='1.7.0_55')
def test_cached_too_high(self): with distribution(executables=exe('bin/java', '1.7.0_83')) as dist_root: with env(PATH=os.path.join(dist_root, 'bin')): with self.assertRaises(Distribution.Error): Distribution.cached(maximum_version='1.7.0_55')
def test_subprocess_classpath_relativize(self): with self.jre("FOO") as jre: self.do_test_executor_classpath_relativize( SubprocessExecutor(Distribution(bin_path=jre)))
def test_cached_good_max(self): with self.distribution(executables=self.exe('java', '1.7.0_33')) as jdk: with self.env(PATH=jdk): Distribution.cached(maximum_version='1.7.0_50')
def test_cached_conflicting(self): with distribution(executables=exe('bin/java', '1.7.0_33')) as dist_root: with env(PATH=os.path.join(dist_root, 'bin')): with self.assertRaises(Distribution.Error): Distribution.cached(minimum_version='1.7.0_00', maximum_version='1.6.0_50')
def test_cached_good_bounds(self): with self.distribution(executables=self.exe('java', '1.7.0_33')) as jdk: with self.env(PATH=jdk): Distribution.cached(minimum_version='1.6.0_35', maximum_version='1.7.0_55')
def test_cached_bad_input(self): with distribution(executables=exe('bin/java', '1.7.0_33')) as dist_root: with env(PATH=os.path.join(dist_root, 'bin')): with self.assertRaises(ValueError): Distribution.cached(minimum_version=1.7, maximum_version=1.8)
def test_cached_too_high(self): with self.distribution(executables=self.exe('java', '1.7.0_83')) as jdk: with self.env(PATH=jdk): with self.assertRaises(Distribution.Error): Distribution.cached(maximum_version='1.7.0_55')
def test_cached_low_fault(self): with self.distribution(executables=self.exe('java', '1.7.0_33')) as jdk: with self.env(PATH=jdk): with self.assertRaises(Distribution.Error): Distribution.cached(minimum_version='1.7.0_35', maximum_version='1.7.0_55')
def test_cached_conflicting(self): with self.distribution(executables=self.exe('java', '1.7.0_33')) as jdk: with self.env(PATH=jdk): with self.assertRaises(Distribution.Error): Distribution.cached(minimum_version='1.7.0_00', maximum_version='1.6.0_50')
def test_cached_bad_input(self): with self.assertRaises(ValueError): with self.distribution(executables=self.exe('java', '1.7.0_33')) as jdk: with self.env(PATH=jdk): Distribution.cached(minimum_version=1.7, maximum_version=1.8)
def test_junit_runner(self): # Create the temporary base test directory test_rel_path = 'tests/java/com/pants/foo' test_abs_path = os.path.join(self.build_root, test_rel_path) self.create_dir(test_rel_path) # Generate the temporary java test source code. test_java_file_rel_path = os.path.join(test_rel_path, 'FooTest.java') test_java_file_abs_path = os.path.join(self.build_root, test_java_file_rel_path) self.create_file(test_java_file_rel_path, dedent(''' import org.junit.Test; import static org.junit.Assert.assertTrue; public class FooTest { @Test public void testFoo() { assertTrue(5 > 3); } } ''')) # Invoke ivy to resolve classpath for junit. distribution = Distribution.cached(jdk=True) executor = SubprocessExecutor(distribution=distribution) classpath_file_abs_path = os.path.join(test_abs_path, 'junit.classpath') ivy = Bootstrapper.default_ivy(java_executor=executor) ivy.execute(args=['-cachepath', classpath_file_abs_path, '-dependency', 'junit', 'junit-dep', '4.10']) with open(classpath_file_abs_path) as fp: classpath = fp.read() # Now directly invoking javac to compile the test java code into java class # so later we can inject the class into products mapping for JUnitRun to execute # the test on. javac = distribution.binary('javac') subprocess.check_call( [javac, '-d', test_abs_path, '-cp', classpath, test_java_file_abs_path]) # Create a java_tests target and a synthetic resource target. java_tests = self.create_library(test_rel_path, 'java_tests', 'foo_test', ['FooTest.java']) resources = self.make_target('some_resources', Resources) # Set the context with the two targets, one java_tests target and # one synthetic resources target. # The synthetic resources target is to make sure we won't regress # in the future with bug like https://github.com/pantsbuild/pants/issues/508. Note # in that bug, the resources target must be the first one in the list. context = self.context(target_roots=[resources, java_tests]) # Before we run the task, we need to inject the "classes_by_target" with # the compiled test java classes that JUnitRun will know which test # classes to execute. In a normal run, this "classes_by_target" will be # populated by java compiling step. class_products = context.products.get_data( 'classes_by_target', lambda: defaultdict(MultipleRootedProducts)) java_tests_products = MultipleRootedProducts() java_tests_products.add_rel_paths(test_abs_path, ['FooTest.class']) class_products[java_tests] = java_tests_products # Also we need to add the FooTest.class's classpath to the exclusive_groups # products data mapping so JUnitRun will be able to add that into the final # classpath under which the junit will be executed. self.populate_exclusive_groups( context=context, classpaths=[test_abs_path], # This is a bit hacky. The issue in https://github.com/pantsbuild/pants/issues/508 # is that normal resources specified in the BUILD targets are fine, but the # synthetic resources ones generated on the fly don't have exclusive_groups data # mapping entries thus later on in _JUnitRunner lookup it blows up. So we manually # exclude the synthetic resources target here to simulate that situation and ensure # the _JUnitRunner does filter out all the non-java-tests targets. target_predicate=lambda t: t != resources) # Finally execute the task. self.execute(context)
def test_locate(self): @contextmanager def env(**kwargs): environment = dict(JDK_HOME=None, JAVA_HOME=None, PATH=None) environment.update(**kwargs) with environment_as(**environment): yield with pytest.raises(Distribution.Error): with env(): Distribution.locate() with pytest.raises(Distribution.Error): with self.distribution(files='java') as jdk: with env(PATH=jdk): Distribution.locate() with pytest.raises(Distribution.Error): with self.distribution(executables=self.exe('java')) as jdk: with env(PATH=jdk): Distribution.locate(jdk=True) with pytest.raises(Distribution.Error): with self.distribution(executables=self.exe('java', '1.6.0')) as jdk: with env(PATH=jdk): Distribution.locate(minimum_version='1.7.0') with self.distribution(executables=self.exe('java', '1.8.0')) as jdk: with env(PATH=jdk): Distribution.locate(maximum_version='1.7.999') with pytest.raises(Distribution.Error): with self.distribution(executables=self.exe('java')) as jdk: with env(JDK_HOME=jdk): Distribution.locate() with pytest.raises(Distribution.Error): with self.distribution(executables=self.exe('java')) as jdk: with env(JAVA_HOME=jdk): Distribution.locate() with self.distribution(executables=self.exe('java')) as jdk: with env(PATH=jdk): Distribution.locate() with self.distribution(executables=[self.exe('java'), self.exe('javac')]) as jdk: with env(PATH=jdk): Distribution.locate(jdk=True) with self.distribution(executables=self.exe('java', '1.7.0')) as jdk: with env(PATH=jdk): Distribution.locate(minimum_version='1.6.0') with env(PATH=jdk): Distribution.locate(maximum_version='1.7.999') with env(PATH=jdk): Distribution.locate(minimum_version='1.6.0', maximum_version='1.7.999') with self.distribution(executables=self.exe('bin/java')) as jdk: with env(JDK_HOME=jdk): Distribution.locate() with self.distribution(executables=self.exe('bin/java')) as jdk: with env(JAVA_HOME=jdk): Distribution.locate()