org.finra.herd.core.AbstractCoreTest.java Source code

Java tutorial

Introduction

Here is the source code for org.finra.herd.core.AbstractCoreTest.java

Source

/*
* Copyright 2015 herd contributors
*
* Licensed 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.finra.herd.core;

import static org.junit.Assert.assertEquals;

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.io.StringWriter;
import java.math.BigDecimal;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collection;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Random;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;
import org.junit.Assert;
import org.junit.Before;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.Environment;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.StandardEnvironment;
import org.springframework.core.io.ResourceLoader;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.transaction.TransactionConfiguration;

import org.finra.herd.core.config.CoreTestSpringModuleConfig;
import org.finra.herd.core.helper.ConfigurationHelper;
import org.finra.herd.core.helper.LogLevel;
import org.finra.herd.core.helper.LoggingHelper;

/**
 * Base class for all core and extending tests. We need to use a customized "loader" that stores the application context in an application context holder so
 * static bean creation methods don't fail. This is similar to what WarInitializer.java does for the WAR, but rather for the JUnits.
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = CoreTestSpringModuleConfig.class, loader = ContextHolderContextLoader.class)
@TransactionConfiguration
public abstract class AbstractCoreTest {
    public static final String BLANK_TEXT = "      \t\t ";

    public static final long FILE_SIZE_0_BYTE = 0L;

    public static final long FILE_SIZE_1_KB = 1024L;

    public static final long FILE_SIZE_2_KB = 2048L;

    public static final String INVALID_BOOLEAN_VALUE = "INVALID_BOOLEAN_VALUE";

    public static final String INVALID_INTEGER_VALUE = "INVALID_INTEGER_VALUE";

    public static final String RANDOM_SUFFIX = getRandomSuffix();

    public static final String RANDOM_SUFFIX_2 = getRandomSuffix();

    public static final long ROW_COUNT_1000 = 1000L;

    public static final String STRING_VALUE = "UT_SomeText" + RANDOM_SUFFIX;

    public static final String STRING_VALUE_2 = "UT_SomeText_2_" + RANDOM_SUFFIX;

    @Autowired
    protected ApplicationContext appContext;

    @Autowired
    protected ConfigurationHelper configurationHelper;

    @Autowired
    protected LoggingHelper loggingHelper;

    // The Spring environment.
    @Autowired
    protected Environment environment;

    @Autowired
    protected ResourceLoader resourceLoader;

    /**
     * Returns a random big decimal.
     */
    public static BigDecimal getRandomBigDecimal() {
        return new BigDecimal(Math.random() * Integer.MAX_VALUE).setScale(2, BigDecimal.ROUND_HALF_UP);
    }

    /**
     * Returns a random date.
     */
    public static Date getRandomDate() {
        Random rnd = new Random();
        return new Date(Math.abs(System.currentTimeMillis() - rnd.nextLong()));
    }

    /**
     * Returns a random date in future.
     */
    public static Date getRandomDateInFuture() {
        Random rnd = new Random();
        return new Date(Math.abs(System.currentTimeMillis() + rnd.nextLong()));
    }

    /**
     * Returns a random integer.
     */
    public static Integer getRandomInteger() {
        return (int) (Math.random() * Integer.MAX_VALUE);
    }

    /**
     * Returns a random long.
     */
    public static Long getRandomLong() {
        return (long) (Math.random() * Long.MAX_VALUE);
    }

    /**
     * Returns a random suffix.
     */
    public static String getRandomSuffix() {
        return String.format("%.5f", Math.random()).substring(2, 7);
    }

    /**
     * Same as {@link Assert#assertEquals(String, Object, Object)} but null and empty strings are considered equal. This method simply does not call assertion
     * if both expected and actual are null or empty.
     *
     * @param message - The message to display on assertion error
     * @param expected - The expected value
     * @param actual - The actual value
     *
     * @see StringUtils#isEmpty(CharSequence)
     */
    public static void assertEqualsIgnoreNullOrEmpty(String message, String expected, String actual) {
        if (!StringUtils.isEmpty(expected) || !StringUtils.isEmpty(actual)) {
            assertEquals(message, expected, actual);
        }
    }

    /**
     * Asserts that the given expected collection is equal to the actual collection ignoring the order of the elements. Two collections are equal as defined by
     * {@link Set#equals(Object)}. This assertion is {@code null} safe.
     *
     * @param message - message as defined by {@link Assert#assertEquals(String, Object, Object)}
     * @param expected - expected collection
     * @param actual - actual collection
     */
    public static void assertEqualsIgnoreOrder(String message, Collection<?> expected, Collection<?> actual) {
        if (expected != null && actual != null) {
            Set<?> expectedSet = new HashSet<Object>(expected);
            Set<?> actualSet = new HashSet<Object>(actual);
            assertEquals(message, expectedSet, actualSet);
        } else if (expected != actual) {
            assertEquals(message, expected, actual);
        }
    }

    /**
     * Creates a file of the specified size relative to the base directory.
     *
     * @param baseDirectory the local parent directory path, relative to which we want our file to be created
     * @param file the file path (including file name) relative to the base directory for the file to be created
     * @param size the file size in bytes
     *
     * @return the created file
     */
    public static File createLocalFile(String baseDirectory, String file, long size) throws IOException {
        Path filePath = Paths.get(baseDirectory, file);
        // We don't check the "mkdirs" response because the directory may already exist which would return false.
        // But we want to create sub-directories if they don't yet exist which is why we're calling "mkdirs" in the first place.
        // If an actual directory couldn't be created, then the new file below will throw an exception anyway.
        filePath.toFile().getParentFile().mkdirs();
        RandomAccessFile randomAccessFile = new RandomAccessFile(filePath.toString(), "rw");
        randomAccessFile.setLength(size);
        randomAccessFile.close();
        return filePath.toFile();
    }

    @Before
    public void setup() throws Exception {
        // Remove the system environment property source so system environment variables don't affect unit tests.
        getMutablePropertySources().remove(StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME);
    }

    /**
     * Gets the mutable property sources object from the environment.
     *
     * @return the mutable property sources.
     * @throws Exception if the mutable property sources couldn't be obtained.
     */
    protected MutablePropertySources getMutablePropertySources() throws Exception {
        // Ensure we have a configurable environment so we can remove the property source.
        if (!(environment instanceof ConfigurableEnvironment)) {
            throw new Exception(
                    "The environment is not an instance of ConfigurableEnvironment and needs to be for this test to work.");
        }

        // Return the property sources from the configurable environment.
        ConfigurableEnvironment configurableEnvironment = (ConfigurableEnvironment) environment;
        return configurableEnvironment.getPropertySources();
    }

    /**
     * Executes a command without logging. The logging will be temporarily turned off during the execution of the command and then restored once the command has
     * finished executing.
     *
     * @param loggingClass the logging class to turn off. If null is specified, the command will be executed with no logging changes
     * @param command the command to execute
     *
     * @throws Exception if any errors were encountered.
     */
    protected void executeWithoutLogging(Class<?> loggingClass, Command command) throws Exception {
        loggingHelper.executeWithoutLogging(loggingClass, command);
    }

    /**
     * Executes a command without logging. The logging will be temporarily turned off during the execution of the command and then restored once the command has
     * finished executing.
     *
     * @param loggingClasses the list of logging classes to turn off
     * @param command the command to execute
     *
     * @throws Exception if any errors were encountered
     */
    protected void executeWithoutLogging(List<Class<?>> loggingClasses, Command command) throws Exception {
        loggingHelper.executeWithoutLogging(loggingClasses, command);
    }

    /**
     * Adds a test appender.
     *
     * @param appenderName the appender name to add.
     *
     * @return the string writer associated with the writer appender.
     */
    protected StringWriter addLoggingWriterAppender(String appenderName) {
        return loggingHelper.addLoggingWriterAppender(appenderName);
    }

    /**
     * Removes a logging appender.
     *
     * @param appenderName the appender name.
     */
    protected void removeLoggingAppender(String appenderName) {
        loggingHelper.removeLoggingAppender(appenderName);
    }

    /**
     * Gets the log level for the specified logger.
     *
     * @param clazz the class for the logger.
     */
    protected LogLevel getLogLevel(Class clazz) {
        return loggingHelper.getLogLevel(clazz);
    }

    /**
     * Gets the log level for the specified logger.
     *
     * @param loggerName the logger name to get the level for.
     */
    protected LogLevel getLogLevel(String loggerName) {
        return loggingHelper.getLogLevel(loggerName);
    }

    /**
     * Sets the log level.
     *
     * @param clazz the class for the logger.
     * @param logLevel the log level to set.
     */
    protected void setLogLevel(Class clazz, LogLevel logLevel) {
        loggingHelper.setLogLevel(clazz, logLevel);
    }

    /**
     * Sets the log level.
     *
     * @param loggerName the logger name (e.g. Myclass.class.getName()).
     * @param logLevel the log level to set.
     */
    protected void setLogLevel(String loggerName, LogLevel logLevel) {
        loggingHelper.setLogLevel(loggerName, logLevel);
    }

    /**
     * Method to convert an input string to mixed case.  This method will make every other character a capitalized character followed by a lower case character.
     *
     * @param input String input that will be converted to a mixed case string.
     *
     * @return mixed case version of the input string
     */
    protected static String convertStringToMixedCase(final String input) {
        // Create a string builder to hold the new mixed case string.
        StringBuilder output = new StringBuilder();

        // For each character in the input string.
        for (int i = 0; i < input.length(); i++) {
            char ch = input.charAt(i);

            // Use modulo 2 to upper case every other letter and lower case the following letter
            if (i % 2 == 0) {
                output.append(Character.toUpperCase(ch));
            } else {
                output.append(Character.toLowerCase(ch));
            }
        }

        // Return the new mixed case string
        return output.toString();
    }
}