All Downloads are FREE. Search and download functionalities are using the official Maven repository.

patterntesting.runtime.junit.internal.TestOn Maven / Gradle / Ivy

/*
 * $Id: TestOn.java,v 1.25 2016/03/22 22:28:00 oboehm Exp $
 *
 * Copyright (c) 2010 by Oliver Boehm
 *
 * 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 orimplied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * (c)reated 23.04.2010 by oliver ([email protected])
 */

package patterntesting.runtime.junit.internal;

import java.net.*;
import java.sql.Time;
import java.util.*;

import org.apache.commons.lang3.*;
import org.slf4j.*;

import patterntesting.runtime.net.Localhost;
import patterntesting.runtime.util.*;

/**
 * This is a local helper class for the RunTestOn and SkipTestOn annotation.
 * So most of the methods are package default because there is no need to
 * access from somewhere else.
 *
 * @author oliver
 * @since 1.0 (23.04.2010)
 */
public final class TestOn {

    private static final Logger LOG = LoggerFactory.getLogger(TestOn.class);
    private static final String[] EMPTY_STRINGS = { "" };

    private final Environment env;
    private String[] osNames = EMPTY_STRINGS;
    private String[] osArchs = EMPTY_STRINGS;
    private String[] osVersions = EMPTY_STRINGS;
    private String[] hosts = EMPTY_STRINGS;
    private String[] javaVersions = EMPTY_STRINGS;
    private String[] javaVendors = EMPTY_STRINGS;
    private String[] users = EMPTY_STRINGS;
    private String[] systemProps = EMPTY_STRINGS;
    private int[] days = { };
    private String[] times = EMPTY_STRINGS;
    /** Contains the reason of the last match. */
    private String reason;

    /**
     * Instantiates a new object with the default environment.
     */
    public TestOn() {
        this(Environment.INSTANCE);
    }

    /**
     * Instantiates a new object. For test you instantiate it now with your
     * "own" environment.
     *
     * @param env the env
     */
    public TestOn(final Environment env) {
        this.env = env;
    }

    /**
     * Sets the os names.
     *
     * @param osNames the osNames to set
     */
    public void setOsNames(final String[] osNames) {
        this.osNames = osNames.clone();
    }

    /**
     * Sets the os names.
     *
     * @param fallback the values for fallback if parameter os is empty
     * @param os the osNames to set
     */
    public void setOsNames(final String[] fallback, final String[] os) {
        this.osNames = StringUtils.isEmpty(os[0]) ? fallback : os;
    }

    /**
     * Sets the os archs.
     *
     * @param osArchs the osArchs to set
     */
    public void setOsArchs(final String[] osArchs) {
        this.osArchs = osArchs.clone();
    }

    /**
     * Sets the os versions.
     *
     * @param osVersions the osVersions to set
     */
    public void setOsVersions(final String[] osVersions) {
        this.osVersions = osVersions.clone();
    }

    /**
     * Sets the hosts.
     *
     * @param hosts the hosts to set
     */
    public void setHosts(final String[] hosts) {
        this.hosts = hosts.clone();
    }

    /**
     * Sets the java versions.
     *
     * @param javaVersions the javaVersions to set
     */
    public void setJavaVersions(final String[] javaVersions) {
        this.javaVersions = javaVersions.clone();
    }

    /**
     * Sets the java vendors.
     *
     * @param javaVendors the javaVendors to set
     */
    public void setJavaVendors(final String[] javaVendors) {
        this.javaVendors = javaVendors.clone();
    }

    /**
     * Sets the users.
     *
     * @param users the users to set
     */
    public void setUsers(final String[] users) {
        this.users = users.clone();
    }

    /**
     * Sets the system props.
     *
     * @param systemProps the systemProps to set
     */
    public void setSystemProps(final String[] systemProps) {
        this.systemProps = systemProps.clone();
    }

    /**
     * Sets the days.
     *
     * @param days the days to set
     */
    public void setDays(final int[] days) {
        this.days = days.clone();
    }

    /**
     * Sets the times.
     *
     * @param times the times to set
     */
    public void setTimes(final String[] times) {
        this.times = times.clone();
    }

    /**
     * Sets the reason.
     *
     * @param reason the reason to set
     */
    public void setReason(final String reason) {
        this.reason = reason;
    }

    /**
     * Gets the reason.
     *
     * @return the reason
     */
    public String getReason() {
        return hasReason() ? this.reason + " detected" : "";
    }

    /**
     * Checks for reason.
     *
     * @return true, if reason is set
     */
    public boolean hasReason() {
        return StringUtils.isNotBlank(this.reason);
    }

    /**
     * If one of the attributes matches true will returned.
     *
     * @return true, if successful
     */
    public boolean matches() {
        if (!matches(this.osNames, this.env.getOsName())) {
            return false;
        }
        if (!matches(this.osArchs, this.env.getOsArch())) {
            return false;
        }
        if (!matches(this.osVersions, this.env.getOsVersion())) {
            return false;
        }
        if (!matches(this.javaVersions, this.env.getJavaVersion())) {
            return false;
        }
        if (!matches(this.javaVendors, this.env.getJavaVendor())) {
            return false;
        }
        if (!matches(this.users, this.env.getUserName())) {
            return false;
        }
        if (!Environment.matchesOneOf(systemProps)) {
            return false;
        }
        if (!isInDays()) {
            return false;
        }
        if (!isTimeInRange()) {
            return false;
        }
        // this call is expensive so we shift it to the end
        if (!runsOn(this.hosts)) {
            return false;
        }
        reason = (StringUtils.isEmpty(this.osNames[0]) ? "" : this.env.getOsName())
                + (StringUtils.isEmpty(this.osArchs[0]) ? "" : this.env.getOsArch())
                + (StringUtils.isEmpty(this.osVersions[0]) ? "" : this.env.getOsVersion())
                + (StringUtils.isEmpty(this.javaVersions[0]) ? "" : "JDK " + this.env.getJavaVersion())
                + (StringUtils.isEmpty(this.javaVendors[0]) ? "" : this.env.getJavaVendor() + " as vendor")
                + (StringUtils.isEmpty(this.users[0]) ? "" : this.env.getUserName() + " as user")
                + (StringUtils.isEmpty(this.systemProps[0]) ? "" : Converter.toString(systemProps))
                + (StringUtils.isEmpty(this.hosts[0]) ? "" : "host " + Converter.toString(this.hosts))
                + (this.days.length == 0 ? "" : " day " + Converter.toString(this.days))
                + (StringUtils.isEmpty(this.times[0]) ? "" : "time " + Converter.toString(this.times));
        return true;

    }

    /**
     * Checks if is value given.
     *
     * @return true, if is value given
     */
    public boolean isValueGiven() {
        return StringUtils.isNotEmpty(this.osNames[0])
                || StringUtils.isNotEmpty(this.osArchs[0])
                || StringUtils.isNotEmpty(this.osVersions[0])
                || StringUtils.isNotEmpty(this.hosts[0])
                || StringUtils.isNotEmpty(this.javaVersions[0])
                || StringUtils.isNotEmpty(this.javaVendors[0])
                || StringUtils.isNotEmpty(this.users[0])
                || StringUtils.isNotEmpty(this.systemProps[0])
                || this.days.length > 0
                || StringUtils.isNotEmpty(this.times[0]);
    }

    private static boolean matches(final String[] names, final String name) {
        if (StringUtils.isEmpty(names[0])) {
            LOG.trace("Empty names are ignored for matching of '{}'.", name);
            return true;
        }
        for (int i = 0; i < names.length; i++) {
            if (matches(names[i], name)) {
                return true;
            }
        }
        return false;
    }

    /**
     * If the given pattern parameter contains an asterisk ("*") it is
     * considered as pattern. Otherwise only the beginning with name
     * must match.
     *
     * @param pattern the pattern
     * @param name the name
     * @return true, if successful
     * @since 1.1
     */
    private static boolean matches(final String pattern, final String name) {
        if (name.startsWith(pattern)) {
            return true;
        }
        if (pattern.contains("*") || (pattern.contains("?"))) {
            String regex = wildcardToRegex(pattern);
            return name.matches(regex);
        }
        return false;
    }

    private boolean isInDays() {
        if (this.days.length == 0) {
            LOG.trace("Empty days are ignored for matching.");
            return true;
        }
        int d = getDayOfWeek();
        for (int i = 0; i < this.days.length; i++) {
            if (d == days[i]) {
                return true;
            }
        }
        return false;
    }

    private static int getDayOfWeek() {
        Calendar cal = Calendar.getInstance();
        cal.setTime(new Date());
        int dow = cal.get(Calendar.DAY_OF_WEEK);
        return ((dow + 5) % 7 + 1);
    }

    private boolean isTimeInRange() {
        if (StringUtils.isEmpty(this.times[0])) {
            LOG.trace("Empty time ranges are ignored for matching.");
            return true;
        }
        for (int i = 0; i < this.times.length; i++) {
            if (isTimeInRage(this.times[i])) {
                return true;
            }
        }
        return false;
    }

    /**
     * Checks if the given range matches the actual time. If midnight is int
     * the given range like "22:00-4:00" it is splitted into two parts,
     * "22:00-24:00" and "0:00"-"4:00" and then checked.
     *
     * @param fromTo the from to
     * @return true, if is time in rage
     */
    private static boolean isTimeInRage(final String fromTo) {
        String[] range = fromTo.split("-");
        Time t1 = Converter.toTime(range[0]);
        Time t2 = Converter.toTime(range[1]);
        String from = t1.toString();
        String to = t2.toString();
        if (t2.before(t1)) {
            String beforeMidnight = t1 + "-24:00";
            String afterMidnight = "0:00-" + t2;
            return isTimeInRage(beforeMidnight) || isTimeInRage(afterMidnight);
        }
        if (to.equals("00:00:00")) {
            to = "24:00:00";
        }
        Time tnow = new Time(System.currentTimeMillis());
        String now = tnow.toString();
        return (now.compareTo(from) >= 0) && (now.compareTo(to) <= 0);
    }

    private static boolean runsOn(final String[] hosts) {
        try {
            InetAddress localhost = InetAddress.getLocalHost();
            if (ArrayUtils.contains(hosts, localhost.getHostAddress())
                    || matches(hosts, localhost.getHostName())) {
                return true;
            }
            return Localhost.matches(hosts);
        } catch (UnknownHostException e) {
            LOG.debug("Cannot get local InetAddress - using localhost:", e);
            return runsOnLocalhost(hosts);
        }
    }

    private static boolean runsOnLocalhost(final String[] hosts) {
        return ArrayUtils.contains(hosts, "127.0.0.1")
                || StringHelper.containsIgnoreCase(hosts, "localhost"); //NOPMD
    }

    /**
     * Wildcard to regex.
     *
     * @param wildcard the wildcard
     * @return the string
     * @see "http://www.rgagnon.com/javadetails/java-0515.html"
     */
    private static String wildcardToRegex(final String wildcard) {
        StringBuilder s = new StringBuilder(wildcard.length());
        s.append('^');
        for (int i = 0, is = wildcard.length(); i < is; i++) {
            char c = wildcard.charAt(i);
            switch(c) {
                case '*':
                    s.append(".*");
                    break;
                case '?':
                    s.append(".");
                    break;
                    // escape special regexp-characters
                case '(': case ')': case '[': case ']': case '$':
                case '^': case '.': case '{': case '}': case '|':
                case '\\':
                    s.append("\\");
                    s.append(c);
                    break;
                default:
                    s.append(c);
                    break;
            }
        }
        s.append('$');
        return(s.toString());
    }

}





© 2015 - 2025 Weber Informatics LLC | Privacy Policy