diff --git a/esrally/mechanic/java_resolver.py b/esrally/mechanic/java_resolver.py index b61409288..8fe0f5308 100644 --- a/esrally/mechanic/java_resolver.py +++ b/esrally/mechanic/java_resolver.py @@ -21,11 +21,10 @@ from esrally.utils import jvm -def java_home(car_runtime_jdks, cfg): +def java_home(car_runtime_jdks, specified_runtime_jdk=None, provides_bundled_jdk=False): def determine_runtime_jdks(): - override_runtime_jdk = cfg.opts("mechanic", "runtime.jdk") - if override_runtime_jdk: - return [override_runtime_jdk] + if specified_runtime_jdk: + return [specified_runtime_jdk] else: return allowed_runtime_jdks @@ -39,6 +38,9 @@ def determine_runtime_jdks(): runtime_jdk_versions = determine_runtime_jdks() if runtime_jdk_versions[0] == "bundled": + if not provides_bundled_jdk: + raise exceptions.SystemSetupError("This Elasticsearch version does not contain a bundled JDK. " + "Please specify a different runtime JDK.") logger.info("Using JDK bundled with Elasticsearch.") # assume that the bundled JDK is the highest available; the path is irrelevant return allowed_runtime_jdks[0], None diff --git a/esrally/mechanic/launcher.py b/esrally/mechanic/launcher.py index bd677cb9b..447898b99 100644 --- a/esrally/mechanic/launcher.py +++ b/esrally/mechanic/launcher.py @@ -139,7 +139,9 @@ def _start_node(self, node_configuration, node_count_on_host): data_paths = node_configuration.data_paths node_telemetry_dir = os.path.join(node_configuration.node_root_path, "telemetry") - java_major_version, java_home = java_resolver.java_home(node_configuration.car_runtime_jdks, self.cfg) + java_major_version, java_home = java_resolver.java_home(node_configuration.car_runtime_jdks, + self.cfg.opts("mechanic", "runtime.jdk"), + node_configuration.car_provides_bundled_jdk) self.logger.info("Starting node [%s].", node_name) diff --git a/esrally/mechanic/provisioner.py b/esrally/mechanic/provisioner.py index 40040265b..e45c4a5aa 100644 --- a/esrally/mechanic/provisioner.py +++ b/esrally/mechanic/provisioner.py @@ -34,11 +34,8 @@ def local(cfg, car, plugins, cluster_settings, ip, http_port, all_node_ips, all_ node_root_dir = os.path.join(target_root, node_name) runtime_jdk_bundled = convert.to_bool(car.mandatory_var("runtime.jdk.bundled")) - if runtime_jdk_bundled: - java_home = None - else: - runtime_jdk = car.mandatory_var("runtime.jdk") - _, java_home = java_resolver.java_home(runtime_jdk, cfg) + runtime_jdk = car.mandatory_var("runtime.jdk") + _, java_home = java_resolver.java_home(runtime_jdk, cfg.opts("mechanic", "runtime.jdk"), runtime_jdk_bundled) es_installer = ElasticsearchInstaller(car, java_home, node_name, node_root_dir, all_node_ips, all_node_names, ip, http_port) plugin_installers = [PluginInstaller(plugin, java_home) for plugin in plugins] @@ -57,10 +54,12 @@ def docker(cfg, car, cluster_settings, ip, http_port, target_root, node_name): class NodeConfiguration: - def __init__(self, build_type, car_env, car_runtime_jdks, ip, node_name, node_root_path, binary_path, data_paths): + def __init__(self, build_type, car_env, car_runtime_jdks, car_provides_bundled_jdk, ip, node_name, node_root_path, + binary_path, data_paths): self.build_type = build_type self.car_env = car_env self.car_runtime_jdks = car_runtime_jdks + self.car_provides_bundled_jdk = car_provides_bundled_jdk self.ip = ip self.node_name = node_name self.node_root_path = node_root_path @@ -72,6 +71,7 @@ def as_dict(self): "build-type": self.build_type, "car-env": self.car_env, "car-runtime-jdks": self.car_runtime_jdks, + "car-provides-bundled-jdk": self.car_provides_bundled_jdk, "ip": self.ip, "node-name": self.node_name, "node-root-path": self.node_root_path, @@ -81,8 +81,8 @@ def as_dict(self): @staticmethod def from_dict(d): - return NodeConfiguration(d["build-type"], d["car-env"], d["car-runtime-jdks"], d["ip"], d["node-name"], - d["node-root-path"], d["binary-path"], d["data-paths"]) + return NodeConfiguration(d["build-type"], d["car-env"], d["car-runtime-jdks"], d["car-provides-bundled-jdk"], d["ip"], + d["node-name"], d["node-root-path"], d["binary-path"], d["data-paths"]) def save_node_configuration(path, n): @@ -197,6 +197,7 @@ def prepare(self, binary): installer.invoke_install_hook(team.BootstrapPhase.post_install, provisioner_vars.copy()) return NodeConfiguration("tar", self.es_installer.car.env, self.es_installer.car.mandatory_var("runtime.jdk"), + convert.to_bool(self.es_installer.car.mandatory_var("runtime.jdk.bundled")), self.es_installer.node_ip, self.es_installer.node_name, self.es_installer.node_root_dir, self.es_installer.es_home_path, self.es_installer.data_paths) @@ -462,7 +463,8 @@ def prepare(self, binary): with open(os.path.join(self.binary_path, "docker-compose.yml"), mode="wt", encoding="utf-8") as f: f.write(docker_cfg) - return NodeConfiguration("docker", self.car.env, self.car.mandatory_var("runtime.jdk"), self.node_ip, + return NodeConfiguration("docker", self.car.env, self.car.mandatory_var("runtime.jdk"), + convert.to_bool(self.car.mandatory_var("runtime.jdk.bundled")), self.node_ip, self.node_name, self.node_root_dir, self.binary_path, self.data_paths) def docker_vars(self, mounts): diff --git a/tests/mechanic/java_resolver_test.py b/tests/mechanic/java_resolver_test.py index 8bcb07e13..052651bd4 100644 --- a/tests/mechanic/java_resolver_test.py +++ b/tests/mechanic/java_resolver_test.py @@ -18,7 +18,7 @@ import unittest.mock as mock from unittest import TestCase -from esrally import config +from esrally import exceptions from esrally.mechanic import java_resolver @@ -26,11 +26,9 @@ class JavaResolverTests(TestCase): @mock.patch("esrally.utils.jvm.resolve_path") def test_resolves_java_home_for_default_runtime_jdk(self, resolve_jvm_path): resolve_jvm_path.return_value = (12, "/opt/jdk12") - - cfg = config.Config() - cfg.add(config.Scope.application, "mechanic", "runtime.jdk", None) - - major, java_home = java_resolver.java_home("12,11,10,9,8", cfg) + major, java_home = java_resolver.java_home("12,11,10,9,8", + specified_runtime_jdk=None, + provides_bundled_jdk=True) self.assertEqual(major, 12) self.assertEqual(java_home, "/opt/jdk12") @@ -38,24 +36,26 @@ def test_resolves_java_home_for_default_runtime_jdk(self, resolve_jvm_path): @mock.patch("esrally.utils.jvm.resolve_path") def test_resolves_java_home_for_specific_runtime_jdk(self, resolve_jvm_path): resolve_jvm_path.return_value = (8, "/opt/jdk8") - - cfg = config.Config() - cfg.add(config.Scope.application, "mechanic", "runtime.jdk", 8) - - major, java_home = java_resolver.java_home("12,11,10,9,8", cfg) + major, java_home = java_resolver.java_home("12,11,10,9,8", + specified_runtime_jdk=8, + provides_bundled_jdk=True) self.assertEqual(major, 8) self.assertEqual(java_home, "/opt/jdk8") resolve_jvm_path.assert_called_with([8]) def test_resolves_java_home_for_bundled_jdk(self): - - cfg = config.Config() - cfg.add(config.Scope.application, "mechanic", "runtime.jdk", "bundled") - - major, java_home = java_resolver.java_home("12,11,10,9,8", cfg) + major, java_home = java_resolver.java_home("12,11,10,9,8", + specified_runtime_jdk="bundled", + provides_bundled_jdk=True) # assumes most recent JDK self.assertEqual(major, 12) # does not set JAVA_HOME for the bundled JDK self.assertEqual(java_home, None) + + def test_disallowed_bundled_jdk(self): + with self.assertRaises(exceptions.SystemSetupError) as ctx: + java_resolver.java_home("12,11,10,9,8", specified_runtime_jdk="bundled") + self.assertEqual("This Elasticsearch version does not contain a bundled JDK. Please specify a different runtime JDK.", + ctx.exception.args[0]) diff --git a/tests/mechanic/launcher_test.py b/tests/mechanic/launcher_test.py index cb52fdf96..297524671 100644 --- a/tests/mechanic/launcher_test.py +++ b/tests/mechanic/launcher_test.py @@ -168,6 +168,7 @@ def test_daemon_start_stop(self, wait_for_pidfile, chdir, get_size, supports, ja cfg = config.Config() cfg.add(config.Scope.application, "node", "root.dir", "test") cfg.add(config.Scope.application, "mechanic", "keep.running", False) + cfg.add(config.Scope.application, "mechanic", "runtime.jdk", None) cfg.add(config.Scope.application, "telemetry", "devices", []) cfg.add(config.Scope.application, "telemetry", "params", None) cfg.add(config.Scope.application, "system", "env.name", "test") @@ -177,7 +178,7 @@ def test_daemon_start_stop(self, wait_for_pidfile, chdir, get_size, supports, ja node_configs = [] for node in range(2): - node_configs.append(NodeConfiguration(build_type="tar", car_env={}, car_runtime_jdks="12,11", + node_configs.append(NodeConfiguration(build_type="tar", car_env={}, car_runtime_jdks="12,11", car_provides_bundled_jdk=True, ip="127.0.0.1", node_name="testnode-{}".format(node), node_root_path="/tmp", binary_path="/tmp", data_paths="/tmp")) @@ -363,8 +364,8 @@ def test_starts_container_successfully(self, run_subprocess_with_output, run_sub cfg = config.Config() docker = launcher.DockerLauncher(cfg) - node_config = NodeConfiguration(build_type="docker", car_env={}, car_runtime_jdks="12,11", ip="127.0.0.1", - node_name="testnode", node_root_path="/tmp", binary_path="/bin", + node_config = NodeConfiguration(build_type="docker", car_env={}, car_runtime_jdks="12,11", car_provides_bundled_jdk=True, + ip="127.0.0.1", node_name="testnode", node_root_path="/tmp", binary_path="/bin", data_paths="/tmp") nodes = docker.start([node_config]) @@ -395,8 +396,8 @@ def test_container_not_started(self, run_subprocess_with_output, run_subprocess_ stop_watch = IterationBasedStopWatch(max_iterations=2) docker = launcher.DockerLauncher(cfg, clock=TestClock(stop_watch=stop_watch)) - node_config = NodeConfiguration(build_type="docker", car_env={}, car_runtime_jdks="12,11", ip="127.0.0.1", - node_name="testnode", node_root_path="/tmp", binary_path="/bin", + node_config = NodeConfiguration(build_type="docker", car_env={}, car_runtime_jdks="12,11", car_provides_bundled_jdk=True, + ip="127.0.0.1", node_name="testnode", node_root_path="/tmp", binary_path="/bin", data_paths="/tmp") with self.assertRaisesRegex(exceptions.LaunchError, "No healthy running container after 600 seconds!"): diff --git a/tests/mechanic/provisioner_test.py b/tests/mechanic/provisioner_test.py index 40db3f926..96825dc85 100644 --- a/tests/mechanic/provisioner_test.py +++ b/tests/mechanic/provisioner_test.py @@ -42,7 +42,7 @@ def null_apply_config(source_root_path, target_root_path, config_vars): names="unit-test-car", root_path=None, config_paths=[HOME_DIR + "/.rally/benchmarks/teams/default/my-car"], - variables={"heap": "4g", "runtime.jdk": "8"}), + variables={"heap": "4g", "runtime.jdk": "8", "runtime.jdk.bundled": "true"}), java_home="/usr/local/javas/java8", node_name="rally-node-0", node_root_dir=HOME_DIR + "/.rally/benchmarks/races/unittest", @@ -73,6 +73,7 @@ def null_apply_config(source_root_path, target_root_path, config_vars): }, "heap": "4g", "runtime.jdk": "8", + "runtime.jdk.bundled": "true", "cluster_name": "rally-benchmark", "node_name": "rally-node-0", "data_paths": ["/opt/elasticsearch-5.0.0/data"], @@ -150,7 +151,7 @@ def null_apply_config(source_root_path, target_root_path, config_vars): names="unit-test-car", root_path=None, config_paths=[HOME_DIR + "/.rally/benchmarks/teams/default/my-car"], - variables={"heap": "4g", "runtime.jdk": "8"}), + variables={"heap": "4g", "runtime.jdk": "8", "runtime.jdk.bundled": "true"}), java_home="/usr/local/javas/java8", node_name="rally-node-0", node_root_dir=HOME_DIR + "/.rally/benchmarks/races/unittest", @@ -190,6 +191,7 @@ def null_apply_config(source_root_path, target_root_path, config_vars): }, "heap": "4g", "runtime.jdk": "8", + "runtime.jdk.bundled": "true", "cluster_name": "rally-benchmark", "node_name": "rally-node-0", "data_paths": ["/opt/elasticsearch-5.0.0/data"], @@ -230,7 +232,7 @@ def null_apply_config(source_root_path, target_root_path, config_vars): names="unit-test-car", root_path=None, config_paths=[HOME_DIR + "/.rally/benchmarks/teams/default/my-car"], - variables={"heap": "4g", "runtime.jdk": "8"}), + variables={"heap": "4g", "runtime.jdk": "8", "runtime.jdk.bundled": "true"}), java_home="/usr/local/javas/java8", node_name="rally-node-0", node_root_dir=HOME_DIR + "/.rally/benchmarks/races/unittest", @@ -270,6 +272,7 @@ def null_apply_config(source_root_path, target_root_path, config_vars): }, "heap": "4g", "runtime.jdk": "8", + "runtime.jdk.bundled": "true", "cluster_name": "rally-benchmark", "node_name": "rally-node-0", "data_paths": ["/opt/elasticsearch-6.3.0/data"],