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