/* * Copyright (C) 2006-2016 DLR, Germany * * All rights reserved * * http://www.rcenvironment.de/ */ package de.rcenvironment.core.utils.testing; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.util.Properties; import de.rcenvironment.core.utils.common.StringUtils; /** * Utility methods for parameterized unit, integration and manual tests. * * @author Robert Mischke */ public class ParameterizedTestUtils implements TestParametersProvider { private static final ThreadLocal<File> TEST_PARAMS_DIRECTORY_THREADLOCAL = new ThreadLocal<>(); private Properties properties; /** * Sets the directory to load test configuration files from. As tests may be run in parallel with different configuration directories, * this only sets it for tests run from the current thread. * * @param paramsDir the parameters directory; may be null */ public static void setTestParameterDirectoryForCurrentThread(File paramsDir) { TEST_PARAMS_DIRECTORY_THREADLOCAL.set(paramsDir); } /** * Reads a specific property file resource. * * @param paramFile the location of the parameter/properties file to load * @return 'self' (for easy command chaining) * @throws IOException on load failure, e.g. on a non-existing file */ public TestParametersProvider readPropertiesFile(File paramFile) throws IOException { properties = new Properties(); verifyAndLoadPropertiesFile(paramFile); return this; // for easy command chaining } /** * Reads a property file resouce with the name of the given class and a ".properties" suffix. If no such file is found, an * {@link IOException} is thrown. * * @param testClass the test class to load properties for * @return 'self' (for easy command chaining) * @throws IOException on load failure */ public TestParametersProvider readDefaultPropertiesFile(Class<?> testClass) throws IOException { File paramsDir = TEST_PARAMS_DIRECTORY_THREADLOCAL.get(); properties = new Properties(); String resourceName = testClass.getSimpleName() + ".properties"; if (paramsDir != null) { // standalone use case: read from file in parameter directory File paramFile = new File(paramsDir, resourceName); verifyAndLoadPropertiesFile(paramFile); } else { // development/IDE use case: read from workspace file as resource InputStream propertiesStream = testClass.getResourceAsStream("/" + resourceName); if (propertiesStream == null) { throw new IOException("Failed to load test configuration as resouce: " + resourceName); } properties.load(propertiesStream); } return this; // for easy command chaining } /** * Reads a property file resource with the specified name. If no such file is found, an {@link IOException} is thrown. * * @param resourceName the classpath location of the file resource * @return 'self' (for easy command chaining) * @throws IOException on load failure */ public TestParametersProvider readPropertiesFile(String resourceName) throws IOException { properties = new Properties(); File paramFile = new File(resourceName); verifyAndLoadPropertiesFile(paramFile); return this; // for easy command chaining } @Override public String getNonEmptyString(String key) { String value = properties.getProperty(key); if (value == null || value.isEmpty()) { throw new AssertionError(StringUtils.format("Required test property '%s' is undefined or empty", key)); } return value; } @Override public File getDefinedFileOrDir(String key) { String value = getNonEmptyString(key); return new File(value).getAbsoluteFile(); } @Override public File getExistingFile(String key) { File value = getDefinedFileOrDir(key); if (!value.isFile()) { throw new AssertionError(StringUtils.format("Configured test file '%s' does not exist", value.getAbsolutePath())); } return value; } @Override public File getExistingDir(String key) { File value = getDefinedFileOrDir(key); if (!value.isDirectory()) { throw new AssertionError(StringUtils.format("Configured test directory '%s' does not exist", value.getAbsolutePath())); } return value; } @Override public int getOptionalInteger(String key, int defaultValue) { return StringUtils.nullSafeParseInt(properties.getProperty(key), defaultValue); } @Override public int getExistingInteger(String key) { String value = getNonEmptyString(key); int intValue; try { intValue = Integer.parseInt(value); } catch (NumberFormatException e) { throw new AssertionError(StringUtils.format("Value %s for required test property %s is not an Integer.", key, value)); } return intValue; } private void verifyAndLoadPropertiesFile(File paramFile) throws IOException, FileNotFoundException { if (!paramFile.isFile()) { throw new IOException("Expected to find test parameter file " + paramFile.getAbsolutePath()); } try (InputStream is = new FileInputStream(paramFile)) { properties.load(is); } } @Override public String getOptionalString(String key) { return properties.getProperty(key); } }