blob: ccd472baabad639d05a29e8ce240060680170a97 [file] [log] [blame]
/*
* 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.api.java.utils;
import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
/**
* Tests for {@link ParameterTool}.
*/
public class ParameterToolTest extends AbstractParameterToolTest {
@Rule
public final ExpectedException exception = ExpectedException.none();
// ----- Parser tests -----------------
@Test(expected = RuntimeException.class)
public void testIllegalArgs() {
ParameterTool.fromArgs(new String[]{"berlin"});
}
@Test
public void testNoVal() {
ParameterTool parameter = ParameterTool.fromArgs(new String[]{"-berlin"});
Assert.assertEquals(1, parameter.getNumberOfParameters());
Assert.assertTrue(parameter.has("berlin"));
}
@Test
public void testNoValDouble() {
ParameterTool parameter = ParameterTool.fromArgs(new String[]{"--berlin"});
Assert.assertEquals(1, parameter.getNumberOfParameters());
Assert.assertTrue(parameter.has("berlin"));
}
@Test
public void testMultipleNoVal() {
ParameterTool parameter = ParameterTool.fromArgs(new String[]{"--a", "--b", "--c", "--d", "--e", "--f"});
Assert.assertEquals(6, parameter.getNumberOfParameters());
Assert.assertTrue(parameter.has("a"));
Assert.assertTrue(parameter.has("b"));
Assert.assertTrue(parameter.has("c"));
Assert.assertTrue(parameter.has("d"));
Assert.assertTrue(parameter.has("e"));
Assert.assertTrue(parameter.has("f"));
}
@Test
public void testMultipleNoValMixed() {
ParameterTool parameter = ParameterTool.fromArgs(new String[]{"--a", "-b", "-c", "-d", "--e", "--f"});
Assert.assertEquals(6, parameter.getNumberOfParameters());
Assert.assertTrue(parameter.has("a"));
Assert.assertTrue(parameter.has("b"));
Assert.assertTrue(parameter.has("c"));
Assert.assertTrue(parameter.has("d"));
Assert.assertTrue(parameter.has("e"));
Assert.assertTrue(parameter.has("f"));
}
@Test(expected = IllegalArgumentException.class)
public void testEmptyVal() {
ParameterTool.fromArgs(new String[]{"--a", "-b", "--"});
}
@Test(expected = IllegalArgumentException.class)
public void testEmptyValShort() {
ParameterTool.fromArgs(new String[]{"--a", "-b", "-"});
}
@Test
public void testFromCliArgs() {
ParameterTool parameter = ParameterTool.fromArgs(new String[]{"--input", "myInput", "-expectedCount", "15", "--withoutValues",
"--negativeFloat", "-0.58", "-isWorking", "true", "--maxByte", "127", "-negativeShort", "-1024"});
Assert.assertEquals(7, parameter.getNumberOfParameters());
validate(parameter);
Assert.assertTrue(parameter.has("withoutValues"));
Assert.assertEquals(-0.58, parameter.getFloat("negativeFloat"), 0.1);
Assert.assertTrue(parameter.getBoolean("isWorking"));
Assert.assertEquals(127, parameter.getByte("maxByte"));
Assert.assertEquals(-1024, parameter.getShort("negativeShort"));
}
@Test
public void testFromPropertiesFile() throws IOException {
File propertiesFile = tmp.newFile();
Properties props = new Properties();
props.setProperty("input", "myInput");
props.setProperty("expectedCount", "15");
try (final OutputStream out = new FileOutputStream(propertiesFile)) {
props.store(out, "Test properties");
}
ParameterTool parameter = ParameterTool.fromPropertiesFile(propertiesFile.getAbsolutePath());
Assert.assertEquals(2, parameter.getNumberOfParameters());
validate(parameter);
parameter = ParameterTool.fromPropertiesFile(propertiesFile);
Assert.assertEquals(2, parameter.getNumberOfParameters());
validate(parameter);
try (FileInputStream fis = new FileInputStream(propertiesFile)) {
parameter = ParameterTool.fromPropertiesFile(fis);
}
Assert.assertEquals(2, parameter.getNumberOfParameters());
validate(parameter);
}
@Test
public void testFromMapOrProperties() {
Properties props = new Properties();
props.setProperty("input", "myInput");
props.setProperty("expectedCount", "15");
ParameterTool parameter = ParameterTool.fromMap((Map) props);
Assert.assertEquals(2, parameter.getNumberOfParameters());
validate(parameter);
}
/**
* This is mainly meant to be used with -D arguments against the JVM.
*/
@Test
public void testSystemProperties() {
System.setProperty("input", "myInput");
System.setProperty("expectedCount", "15");
ParameterTool parameter = ParameterTool.fromSystemProperties();
validate(parameter);
}
@Test
public void testMerged() {
ParameterTool parameter1 = ParameterTool.fromArgs(new String[]{"--input", "myInput"});
System.setProperty("expectedCount", "15");
ParameterTool parameter2 = ParameterTool.fromSystemProperties();
ParameterTool parameter = parameter1.mergeWith(parameter2);
validate(parameter);
}
// Boolean
@Test
public void testUnrequestedBoolean() {
ParameterTool parameter = ParameterTool.fromArgs(new String[]{"-boolean", "true"});
Assert.assertEquals(createHashSet("boolean"), parameter.getUnrequestedParameters());
// test parameter access
Assert.assertTrue(parameter.getBoolean("boolean"));
Assert.assertEquals(Collections.emptySet(), parameter.getUnrequestedParameters());
// test repeated access
Assert.assertTrue(parameter.getBoolean("boolean"));
Assert.assertEquals(Collections.emptySet(), parameter.getUnrequestedParameters());
}
@Test
public void testUnrequestedBooleanWithDefaultValue() {
ParameterTool parameter = ParameterTool.fromArgs(new String[]{"-boolean", "true"});
Assert.assertEquals(createHashSet("boolean"), parameter.getUnrequestedParameters());
// test parameter access
Assert.assertTrue(parameter.getBoolean("boolean", false));
Assert.assertEquals(Collections.emptySet(), parameter.getUnrequestedParameters());
// test repeated access
Assert.assertTrue(parameter.getBoolean("boolean", false));
Assert.assertEquals(Collections.emptySet(), parameter.getUnrequestedParameters());
}
@Test
public void testUnrequestedBooleanWithMissingValue() {
ParameterTool parameter = ParameterTool.fromArgs(new String[]{"-boolean"});
Assert.assertEquals(createHashSet("boolean"), parameter.getUnrequestedParameters());
parameter.getBoolean("boolean");
Assert.assertEquals(Collections.emptySet(), parameter.getUnrequestedParameters());
}
// Byte
@Test
public void testUnrequestedByte() {
ParameterTool parameter = ParameterTool.fromArgs(new String[]{"-byte", "1"});
Assert.assertEquals(createHashSet("byte"), parameter.getUnrequestedParameters());
// test parameter access
Assert.assertEquals(1, parameter.getByte("byte"));
Assert.assertEquals(Collections.emptySet(), parameter.getUnrequestedParameters());
// test repeated access
Assert.assertEquals(1, parameter.getByte("byte"));
Assert.assertEquals(Collections.emptySet(), parameter.getUnrequestedParameters());
}
@Test
public void testUnrequestedByteWithDefaultValue() {
ParameterTool parameter = ParameterTool.fromArgs(new String[]{"-byte", "1"});
Assert.assertEquals(createHashSet("byte"), parameter.getUnrequestedParameters());
// test parameter access
Assert.assertEquals(1, parameter.getByte("byte", (byte) 0));
Assert.assertEquals(Collections.emptySet(), parameter.getUnrequestedParameters());
// test repeated access
Assert.assertEquals(1, parameter.getByte("byte", (byte) 0));
Assert.assertEquals(Collections.emptySet(), parameter.getUnrequestedParameters());
}
@Test
public void testUnrequestedByteWithMissingValue() {
ParameterTool parameter = ParameterTool.fromArgs(new String[]{"-byte"});
Assert.assertEquals(createHashSet("byte"), parameter.getUnrequestedParameters());
exception.expect(RuntimeException.class);
exception.expectMessage("For input string: \"__NO_VALUE_KEY\"");
parameter.getByte("byte");
}
// Short
@Test
public void testUnrequestedShort() {
ParameterTool parameter = ParameterTool.fromArgs(new String[]{"-short", "2"});
Assert.assertEquals(createHashSet("short"), parameter.getUnrequestedParameters());
// test parameter access
Assert.assertEquals(2, parameter.getShort("short"));
Assert.assertEquals(Collections.emptySet(), parameter.getUnrequestedParameters());
// test repeated access
Assert.assertEquals(2, parameter.getShort("short"));
Assert.assertEquals(Collections.emptySet(), parameter.getUnrequestedParameters());
}
@Test
public void testUnrequestedShortWithDefaultValue() {
ParameterTool parameter = ParameterTool.fromArgs(new String[]{"-short", "2"});
Assert.assertEquals(createHashSet("short"), parameter.getUnrequestedParameters());
// test parameter access
Assert.assertEquals(2, parameter.getShort("short", (short) 0));
Assert.assertEquals(Collections.emptySet(), parameter.getUnrequestedParameters());
// test repeated access
Assert.assertEquals(2, parameter.getShort("short", (short) 0));
Assert.assertEquals(Collections.emptySet(), parameter.getUnrequestedParameters());
}
@Test
public void testUnrequestedShortWithMissingValue() {
ParameterTool parameter = ParameterTool.fromArgs(new String[]{"-short"});
Assert.assertEquals(createHashSet("short"), parameter.getUnrequestedParameters());
exception.expect(RuntimeException.class);
exception.expectMessage("For input string: \"__NO_VALUE_KEY\"");
parameter.getShort("short");
}
// Int
@Test
public void testUnrequestedInt() {
ParameterTool parameter = ParameterTool.fromArgs(new String[]{"-int", "4"});
Assert.assertEquals(createHashSet("int"), parameter.getUnrequestedParameters());
// test parameter access
Assert.assertEquals(4, parameter.getInt("int"));
Assert.assertEquals(Collections.emptySet(), parameter.getUnrequestedParameters());
// test repeated access
Assert.assertEquals(4, parameter.getInt("int"));
Assert.assertEquals(Collections.emptySet(), parameter.getUnrequestedParameters());
}
@Test
public void testUnrequestedIntWithDefaultValue() {
ParameterTool parameter = ParameterTool.fromArgs(new String[]{"-int", "4"});
Assert.assertEquals(createHashSet("int"), parameter.getUnrequestedParameters());
// test parameter access
Assert.assertEquals(4, parameter.getInt("int", 0));
Assert.assertEquals(Collections.emptySet(), parameter.getUnrequestedParameters());
// test repeated access
Assert.assertEquals(4, parameter.getInt("int", 0));
Assert.assertEquals(Collections.emptySet(), parameter.getUnrequestedParameters());
}
@Test
public void testUnrequestedIntWithMissingValue() {
ParameterTool parameter = ParameterTool.fromArgs(new String[]{"-int"});
Assert.assertEquals(createHashSet("int"), parameter.getUnrequestedParameters());
exception.expect(RuntimeException.class);
exception.expectMessage("For input string: \"__NO_VALUE_KEY\"");
parameter.getInt("int");
}
// Long
@Test
public void testUnrequestedLong() {
ParameterTool parameter = ParameterTool.fromArgs(new String[]{"-long", "8"});
Assert.assertEquals(createHashSet("long"), parameter.getUnrequestedParameters());
// test parameter access
Assert.assertEquals(8, parameter.getLong("long"));
Assert.assertEquals(Collections.emptySet(), parameter.getUnrequestedParameters());
// test repeated access
Assert.assertEquals(8, parameter.getLong("long"));
Assert.assertEquals(Collections.emptySet(), parameter.getUnrequestedParameters());
}
@Test
public void testUnrequestedLongWithDefaultValue() {
ParameterTool parameter = ParameterTool.fromArgs(new String[]{"-long", "8"});
Assert.assertEquals(createHashSet("long"), parameter.getUnrequestedParameters());
// test parameter access
Assert.assertEquals(8, parameter.getLong("long", 0));
Assert.assertEquals(Collections.emptySet(), parameter.getUnrequestedParameters());
// test repeated access
Assert.assertEquals(8, parameter.getLong("long", 0));
Assert.assertEquals(Collections.emptySet(), parameter.getUnrequestedParameters());
}
@Test
public void testUnrequestedLongWithMissingValue() {
ParameterTool parameter = ParameterTool.fromArgs(new String[]{"-long"});
Assert.assertEquals(createHashSet("long"), parameter.getUnrequestedParameters());
exception.expect(RuntimeException.class);
exception.expectMessage("For input string: \"__NO_VALUE_KEY\"");
parameter.getLong("long");
}
// Float
@Test
public void testUnrequestedFloat() {
ParameterTool parameter = ParameterTool.fromArgs(new String[]{"-float", "4"});
Assert.assertEquals(createHashSet("float"), parameter.getUnrequestedParameters());
// test parameter access
Assert.assertEquals(4.0, parameter.getFloat("float"), 0.00001);
Assert.assertEquals(Collections.emptySet(), parameter.getUnrequestedParameters());
// test repeated access
Assert.assertEquals(4.0, parameter.getFloat("float"), 0.00001);
Assert.assertEquals(Collections.emptySet(), parameter.getUnrequestedParameters());
}
@Test
public void testUnrequestedFloatWithDefaultValue() {
ParameterTool parameter = ParameterTool.fromArgs(new String[]{"-float", "4"});
Assert.assertEquals(createHashSet("float"), parameter.getUnrequestedParameters());
// test parameter access
Assert.assertEquals(4.0, parameter.getFloat("float", 0.0f), 0.00001);
Assert.assertEquals(Collections.emptySet(), parameter.getUnrequestedParameters());
// test repeated access
Assert.assertEquals(4.0, parameter.getFloat("float", 0.0f), 0.00001);
Assert.assertEquals(Collections.emptySet(), parameter.getUnrequestedParameters());
}
@Test
public void testUnrequestedFloatWithMissingValue() {
ParameterTool parameter = ParameterTool.fromArgs(new String[]{"-float"});
Assert.assertEquals(createHashSet("float"), parameter.getUnrequestedParameters());
exception.expect(RuntimeException.class);
exception.expectMessage("For input string: \"__NO_VALUE_KEY\"");
parameter.getFloat("float");
}
// Double
@Test
public void testUnrequestedDouble() {
ParameterTool parameter = ParameterTool.fromArgs(new String[]{"-double", "8"});
Assert.assertEquals(createHashSet("double"), parameter.getUnrequestedParameters());
// test parameter access
Assert.assertEquals(8.0, parameter.getDouble("double"), 0.00001);
Assert.assertEquals(Collections.emptySet(), parameter.getUnrequestedParameters());
// test repeated access
Assert.assertEquals(8.0, parameter.getDouble("double"), 0.00001);
Assert.assertEquals(Collections.emptySet(), parameter.getUnrequestedParameters());
}
@Test
public void testUnrequestedDoubleWithDefaultValue() {
ParameterTool parameter = ParameterTool.fromArgs(new String[]{"-double", "8"});
Assert.assertEquals(createHashSet("double"), parameter.getUnrequestedParameters());
// test parameter access
Assert.assertEquals(8.0, parameter.getDouble("double", 0.0), 0.00001);
Assert.assertEquals(Collections.emptySet(), parameter.getUnrequestedParameters());
// test repeated access
Assert.assertEquals(8.0, parameter.getDouble("double", 0.0), 0.00001);
Assert.assertEquals(Collections.emptySet(), parameter.getUnrequestedParameters());
}
@Test
public void testUnrequestedDoubleWithMissingValue() {
ParameterTool parameter = ParameterTool.fromArgs(new String[]{"-double"});
Assert.assertEquals(createHashSet("double"), parameter.getUnrequestedParameters());
exception.expect(RuntimeException.class);
exception.expectMessage("For input string: \"__NO_VALUE_KEY\"");
parameter.getDouble("double");
}
// String
@Test
public void testUnrequestedString() {
ParameterTool parameter = ParameterTool.fromArgs(new String[]{"-string", "∞"});
Assert.assertEquals(createHashSet("string"), parameter.getUnrequestedParameters());
// test parameter access
Assert.assertEquals("∞", parameter.get("string"));
Assert.assertEquals(Collections.emptySet(), parameter.getUnrequestedParameters());
// test repeated access
Assert.assertEquals("∞", parameter.get("string"));
Assert.assertEquals(Collections.emptySet(), parameter.getUnrequestedParameters());
}
@Test
public void testUnrequestedStringWithDefaultValue() {
ParameterTool parameter = ParameterTool.fromArgs(new String[]{"-string", "∞"});
Assert.assertEquals(createHashSet("string"), parameter.getUnrequestedParameters());
// test parameter access
Assert.assertEquals("∞", parameter.get("string", "0.0"));
Assert.assertEquals(Collections.emptySet(), parameter.getUnrequestedParameters());
// test repeated access
Assert.assertEquals("∞", parameter.get("string", "0.0"));
Assert.assertEquals(Collections.emptySet(), parameter.getUnrequestedParameters());
}
@Test
public void testUnrequestedStringWithMissingValue() {
ParameterTool parameter = ParameterTool.fromArgs(new String[]{"-string"});
Assert.assertEquals(createHashSet("string"), parameter.getUnrequestedParameters());
parameter.get("string");
Assert.assertEquals(Collections.emptySet(), parameter.getUnrequestedParameters());
}
// Additional methods
@Test
public void testUnrequestedHas() {
ParameterTool parameter = ParameterTool.fromArgs(new String[]{"-boolean"});
Assert.assertEquals(createHashSet("boolean"), parameter.getUnrequestedParameters());
// test parameter access
Assert.assertTrue(parameter.has("boolean"));
Assert.assertEquals(Collections.emptySet(), parameter.getUnrequestedParameters());
// test repeated access
Assert.assertTrue(parameter.has("boolean"));
Assert.assertEquals(Collections.emptySet(), parameter.getUnrequestedParameters());
}
@Test
public void testUnrequestedRequired() {
ParameterTool parameter = ParameterTool.fromArgs(new String[]{"-required", "∞"});
Assert.assertEquals(createHashSet("required"), parameter.getUnrequestedParameters());
// test parameter access
Assert.assertEquals("∞", parameter.getRequired("required"));
Assert.assertEquals(Collections.emptySet(), parameter.getUnrequestedParameters());
// test repeated access
Assert.assertEquals("∞", parameter.getRequired("required"));
Assert.assertEquals(Collections.emptySet(), parameter.getUnrequestedParameters());
}
@Test
public void testUnrequestedMultiple() {
ParameterTool parameter = ParameterTool.fromArgs(new String[]{"-boolean", "true", "-byte", "1",
"-short", "2", "-int", "4", "-long", "8", "-float", "4.0", "-double", "8.0", "-string", "∞"});
Assert.assertEquals(createHashSet("boolean", "byte", "short", "int", "long", "float", "double", "string"),
parameter.getUnrequestedParameters());
Assert.assertTrue(parameter.getBoolean("boolean"));
Assert.assertEquals(createHashSet("byte", "short", "int", "long", "float", "double", "string"),
parameter.getUnrequestedParameters());
Assert.assertEquals(1, parameter.getByte("byte"));
Assert.assertEquals(createHashSet("short", "int", "long", "float", "double", "string"),
parameter.getUnrequestedParameters());
Assert.assertEquals(2, parameter.getShort("short"));
Assert.assertEquals(createHashSet("int", "long", "float", "double", "string"),
parameter.getUnrequestedParameters());
Assert.assertEquals(4, parameter.getInt("int"));
Assert.assertEquals(createHashSet("long", "float", "double", "string"),
parameter.getUnrequestedParameters());
Assert.assertEquals(8, parameter.getLong("long"));
Assert.assertEquals(createHashSet("float", "double", "string"),
parameter.getUnrequestedParameters());
Assert.assertEquals(4.0, parameter.getFloat("float"), 0.00001);
Assert.assertEquals(createHashSet("double", "string"),
parameter.getUnrequestedParameters());
Assert.assertEquals(8.0, parameter.getDouble("double"), 0.00001);
Assert.assertEquals(createHashSet("string"),
parameter.getUnrequestedParameters());
Assert.assertEquals("∞", parameter.get("string"));
Assert.assertEquals(Collections.emptySet(), parameter.getUnrequestedParameters());
}
@Test
public void testUnrequestedUnknown() {
ParameterTool parameter = ParameterTool.fromArgs(new String[]{});
Assert.assertEquals(Collections.emptySet(), parameter.getUnrequestedParameters());
Assert.assertTrue(parameter.getBoolean("boolean", true));
Assert.assertEquals(0, parameter.getByte("byte", (byte) 0));
Assert.assertEquals(0, parameter.getShort("short", (short) 0));
Assert.assertEquals(0, parameter.getInt("int", 0));
Assert.assertEquals(0, parameter.getLong("long", 0));
Assert.assertEquals(0, parameter.getFloat("float", 0), 0.00001);
Assert.assertEquals(0, parameter.getDouble("double", 0), 0.00001);
Assert.assertEquals("0", parameter.get("string", "0"));
Assert.assertEquals(Collections.emptySet(), parameter.getUnrequestedParameters());
}
/**
* Tests that we can concurrently serialize and access the ParameterTool. See FLINK-7943
*/
@Test
public void testConcurrentExecutionConfigSerialization() throws ExecutionException, InterruptedException {
final int numInputs = 10;
Collection<String> input = new ArrayList<>(numInputs);
for (int i = 0; i < numInputs; i++) {
input.add("--" + UUID.randomUUID());
input.add(UUID.randomUUID().toString());
}
final String[] args = input.toArray(new String[0]);
final ParameterTool parameterTool = ParameterTool.fromArgs(args);
final int numThreads = 5;
final int numSerializations = 100;
final Collection<CompletableFuture<Void>> futures = new ArrayList<>(numSerializations);
final ExecutorService executorService = Executors.newFixedThreadPool(numThreads);
try {
for (int i = 0; i < numSerializations; i++) {
futures.add(
CompletableFuture.runAsync(
() -> {
try {
serializeDeserialize(parameterTool);
} catch (Exception e) {
throw new CompletionException(e);
}
},
executorService));
}
for (CompletableFuture<Void> future : futures) {
future.get();
}
} finally {
executorService.shutdownNow();
executorService.awaitTermination(1000L, TimeUnit.MILLISECONDS);
}
}
/**
* Accesses parameter tool parameters and then serializes the given parameter tool and deserializes again.
* @param parameterTool to serialize/deserialize
*/
private void serializeDeserialize(ParameterTool parameterTool) throws IOException, ClassNotFoundException {
// weirdly enough, this call has side effects making the ParameterTool serialization fail if not
// using a concurrent data structure.
parameterTool.get(UUID.randomUUID().toString());
try (
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos)) {
oos.writeObject(parameterTool);
oos.close();
baos.close();
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bais);
// this should work :-)
ParameterTool deserializedParameterTool = ((ParameterTool) ois.readObject());
}
}
private static <T> Set<T> createHashSet(T... elements) {
Set<T> set = new HashSet<>();
for (T element : elements) {
set.add(element);
}
return set;
}
}