/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.flink.yarn; import org.apache.flink.configuration.ConfigConstants; import org.apache.flink.configuration.Configuration; import org.apache.flink.configuration.CoreOptions; import org.apache.flink.configuration.IllegalConfigurationException; import org.apache.flink.yarn.cli.FlinkYarnSessionCli; import org.apache.hadoop.fs.Path; import org.apache.hadoop.yarn.api.ApplicationConstants; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; import java.io.File; import java.io.IOException; import static org.junit.Assert.fail; import static org.junit.Assert.assertEquals; public class YarnClusterDescriptorTest { @Rule public TemporaryFolder temporaryFolder = new TemporaryFolder(); private File flinkJar; private File flinkConf; @Before public void beforeTest() throws IOException { temporaryFolder.create(); flinkJar = temporaryFolder.newFile("flink.jar"); flinkConf = temporaryFolder.newFile("flink-conf.yaml"); } @Test public void testFailIfTaskSlotsHigherThanMaxVcores() { YarnClusterDescriptor clusterDescriptor = new YarnClusterDescriptor(); clusterDescriptor.setLocalJarPath(new Path(flinkJar.getPath())); clusterDescriptor.setFlinkConfiguration(new Configuration()); clusterDescriptor.setConfigurationDirectory(temporaryFolder.getRoot().getAbsolutePath()); clusterDescriptor.setConfigurationFilePath(new Path(flinkConf.getPath())); // configure slots too high clusterDescriptor.setTaskManagerSlots(Integer.MAX_VALUE); try { clusterDescriptor.deploy(); fail("The deploy call should have failed."); } catch (RuntimeException e) { // we expect the cause to be an IllegalConfigurationException if (!(e.getCause() instanceof IllegalConfigurationException)) { throw e; } } } @Test public void testConfigOverwrite() { YarnClusterDescriptor clusterDescriptor = new YarnClusterDescriptor(); Configuration configuration = new Configuration(); // overwrite vcores in config configuration.setInteger(ConfigConstants.YARN_VCORES, Integer.MAX_VALUE); clusterDescriptor.setLocalJarPath(new Path(flinkJar.getPath())); clusterDescriptor.setFlinkConfiguration(configuration); clusterDescriptor.setConfigurationDirectory(temporaryFolder.getRoot().getAbsolutePath()); clusterDescriptor.setConfigurationFilePath(new Path(flinkConf.getPath())); // configure slots clusterDescriptor.setTaskManagerSlots(1); try { clusterDescriptor.deploy(); fail("The deploy call should have failed."); } catch (RuntimeException e) { // we expect the cause to be an IllegalConfigurationException if (!(e.getCause() instanceof IllegalConfigurationException)) { throw e; } } } @Test public void testSetupApplicationMasterContainer() { YarnClusterDescriptor clusterDescriptor = new YarnClusterDescriptor(); final Configuration cfg = new Configuration(); clusterDescriptor.setFlinkConfiguration(cfg); final String java = "$JAVA_HOME/bin/java"; final String jvmmem = "-Xmx424m"; final String jvmOpts = "-Djvm"; // if set final String jmJvmOpts = "-DjmJvm"; // if set final String krb5 = "-Djava.security.krb5.conf=krb5.conf"; final String logfile = "-Dlog.file=\"" + ApplicationConstants.LOG_DIR_EXPANSION_VAR + "/jobmanager.log\""; // if set final String logback = "-Dlogback.configurationFile=file:" + FlinkYarnSessionCli.CONFIG_FILE_LOGBACK_NAME; // if set final String log4j = "-Dlog4j.configuration=file:" + FlinkYarnSessionCli.CONFIG_FILE_LOG4J_NAME; // if set final String mainClass = clusterDescriptor.getApplicationMasterClass().getName(); final String args = ""; final String redirects = "1> " + ApplicationConstants.LOG_DIR_EXPANSION_VAR + "/jobmanager.out " + "2> " + ApplicationConstants.LOG_DIR_EXPANSION_VAR + "/jobmanager.err"; // no logging, with/out krb5 assertEquals( java + " " + jvmmem + " " + // jvmOpts " " + // logging " " + mainClass + " " + args + " " + redirects, clusterDescriptor .setupApplicationMasterContainer(false, false, false) .getCommands().get(0)); assertEquals( java + " " + jvmmem + " " + " " + krb5 +// jvmOpts " " + // logging " " + mainClass + " " + args + " " + redirects, clusterDescriptor .setupApplicationMasterContainer(false, false, true) .getCommands().get(0)); // logback only, with/out krb5 assertEquals( java + " " + jvmmem + " " + // jvmOpts " " + logfile + " " + logback + " " + mainClass + " " + args + " " + redirects, clusterDescriptor .setupApplicationMasterContainer(true, false, false) .getCommands().get(0)); assertEquals( java + " " + jvmmem + " " + " " + krb5 +// jvmOpts " " + logfile + " " + logback + " " + mainClass + " " + args + " " + redirects, clusterDescriptor .setupApplicationMasterContainer(true, false, true) .getCommands().get(0)); // log4j, with/out krb5 assertEquals( java + " " + jvmmem + " " + // jvmOpts " " + logfile + " " + log4j + " " + mainClass + " " + args + " " + redirects, clusterDescriptor .setupApplicationMasterContainer(false, true, false) .getCommands().get(0)); assertEquals( java + " " + jvmmem + " " + " " + krb5 +// jvmOpts " " + logfile + " " + log4j + " " + mainClass + " " + args + " " + redirects, clusterDescriptor .setupApplicationMasterContainer(false, true, true) .getCommands().get(0)); // logback + log4j, with/out krb5 assertEquals( java + " " + jvmmem + " " + // jvmOpts " " + logfile + " " + logback + " " + log4j + " " + mainClass + " " + args + " " + redirects, clusterDescriptor .setupApplicationMasterContainer(true, true, false) .getCommands().get(0)); assertEquals( java + " " + jvmmem + " " + " " + krb5 +// jvmOpts " " + logfile + " " + logback + " " + log4j + " " + mainClass + " " + args + " " + redirects, clusterDescriptor .setupApplicationMasterContainer(true, true, true) .getCommands().get(0)); // logback + log4j, with/out krb5, different JVM opts cfg.setString(CoreOptions.FLINK_JVM_OPTIONS, jvmOpts); assertEquals( java + " " + jvmmem + " " + jvmOpts + " " + logfile + " " + logback + " " + log4j + " " + mainClass + " " + args + " "+ redirects, clusterDescriptor .setupApplicationMasterContainer(true, true, false) .getCommands().get(0)); assertEquals( java + " " + jvmmem + " " + jvmOpts + " " + krb5 +// jvmOpts " " + logfile + " " + logback + " " + log4j + " " + mainClass + " " + args + " "+ redirects, clusterDescriptor .setupApplicationMasterContainer(true, true, true) .getCommands().get(0)); // logback + log4j, with/out krb5, different JVM opts cfg.setString(CoreOptions.FLINK_JM_JVM_OPTIONS, jmJvmOpts); assertEquals( java + " " + jvmmem + " " + jvmOpts + " " + jmJvmOpts + " " + logfile + " " + logback + " " + log4j + " " + mainClass + " " + args + " "+ redirects, clusterDescriptor .setupApplicationMasterContainer(true, true, false) .getCommands().get(0)); assertEquals( java + " " + jvmmem + " " + jvmOpts + " " + jmJvmOpts + " " + krb5 +// jvmOpts " " + logfile + " " + logback + " " + log4j + " " + mainClass + " " + args + " "+ redirects, clusterDescriptor .setupApplicationMasterContainer(true, true, true) .getCommands().get(0)); // now try some configurations with different yarn.container-start-command-template cfg.setString(ConfigConstants.YARN_CONTAINER_START_COMMAND_TEMPLATE, "%java% 1 %jvmmem% 2 %jvmopts% 3 %logging% 4 %class% 5 %args% 6 %redirects%"); assertEquals( java + " 1 " + jvmmem + " 2 " + jvmOpts + " " + jmJvmOpts + " " + krb5 + // jvmOpts " 3 " + logfile + " " + logback + " " + log4j + " 4 " + mainClass + " 5 " + args + " 6 " + redirects, clusterDescriptor .setupApplicationMasterContainer(true, true, true) .getCommands().get(0)); cfg.setString(ConfigConstants.YARN_CONTAINER_START_COMMAND_TEMPLATE, "%java% %logging% %jvmopts% %jvmmem% %class% %args% %redirects%"); assertEquals( java + " " + logfile + " " + logback + " " + log4j + " " + jvmOpts + " " + jmJvmOpts + " " + krb5 + // jvmOpts " " + jvmmem + " " + mainClass + " " + args + " " + redirects, clusterDescriptor .setupApplicationMasterContainer(true, true, true) .getCommands().get(0)); } }