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

org.jboss.cdi.tck.util.Timer Maven / Gradle / Ivy

There is a newer version: 3.0.3
Show newest version
/*
 * JBoss, Home of Professional Open Source
 * Copyright 2010, Red Hat, Inc., and individual contributors
 * by the @authors tag. See the copyright.txt in the distribution for a
 * full listing of individual 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.jboss.cdi.tck.util;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

import org.jboss.cdi.tck.api.Configuration;
import org.jboss.cdi.tck.impl.ConfigurationFactory;

/**
 * Delays thread execution for specified time or unless stop conditions are satisfied according to the actual {@link ResolutionLogic}. This class is not
 * thread-safe.
 * 

* Setting the sleep interval to the value less than 15 ms is questionable since some operating systems do not provide such precision. Moreover such values may * impact test performance. *

*

* In case of no stop conditions are specified (not recommended), the timer logic corresponds to the regular {@link Thread#sleep(long)} execution. *

*/ public class Timer { private static final long DEFAULT_SLEEP_INTERVAL = 50l; private static final ResolutionLogic DEFAULT_RESOLUTION_LOGIC = ResolutionLogic.DISJUNCTION; /** * Delay in ms */ private long delay; /** * Thread sleep interval */ private long sleepInterval; /** * Stop conditions */ private List stopConditions = null; /** * Stop conditions resolution logic */ private ResolutionLogic resolutionLogic; private boolean stopConditionsSatisfiedBeforeTimeout; /** * Create new timer with default delay, sleep interval and stop conditions resolution logic. */ public Timer() { reset(); } /** * Set the delay value. The value is automatically adjusted according to the {@link Configuration#getTestTimeoutFactor()} so that it's possible to configure * timeouts according to the testing runtime performance and throughput. * * @param delay The delay in milliseconds * @return self */ public Timer setDelay(long delay) { return setDelay(delay, TimeUnit.MILLISECONDS); } /** * Set the delay value. The value is automatically adjusted according to the {@link Configuration#getTestTimeoutFactor()} so that it's possible to configure * timeouts according to the testing runtime performance and throughput. * * @param delay * @param timeUnit * @return self */ public Timer setDelay(long delay, TimeUnit timeUnit) { if (delay <= 0) { throw new IllegalArgumentException("Delay must be greater than zero"); } this.delay = (timeUnit.toMillis(delay) * ConfigurationFactory.get().getTestTimeoutFactor() -1) / 100 + 1; return this; } /** * Set new sleep interval value. * * @param sleepInterval * @return self */ public Timer setSleepInterval(long sleepInterval) { this.sleepInterval = sleepInterval; return this; } /** * Set new resolution logic. * * @param resolutionLogic * @return self */ public Timer setResolutionLogic(ResolutionLogic resolutionLogic) { this.resolutionLogic = resolutionLogic; return this; } /** * Add new stop condition. * * @param condition * @return self */ public Timer addStopCondition(StopCondition condition) { return addStopCondition(condition, false); } /** * Add new stop condition. * * @param condition * @param clear Clear stop conditions and reset {@link #stopConditionsSatisfiedBeforeTimeout} * @return self */ public Timer addStopCondition(StopCondition condition, boolean clear) { if (condition != null) { if (stopConditions == null) { stopConditions = new ArrayList(5); } else if (clear) { clearStopConditions(); } stopConditions.add(condition); } return this; } /** * Start the timer. * * @throws InterruptedException */ public Timer start() throws InterruptedException { checkConfiguration(); if (stopConditions == null || stopConditions.isEmpty()) { Thread.sleep(delay); } else { long start = System.currentTimeMillis(); while (resolveSleepConditions(start)) { Thread.sleep(sleepInterval); } } return this; } /** * Reset to default values. */ public void reset() { this.delay = -1; this.sleepInterval = DEFAULT_SLEEP_INTERVAL; this.resolutionLogic = DEFAULT_RESOLUTION_LOGIC; clearStopConditions(); } /** * Clear stop conditions and reset {@link #stopConditionsSatisfiedBeforeTimeout}. */ public void clearStopConditions() { if (stopConditions != null) { stopConditions.clear(); } this.stopConditionsSatisfiedBeforeTimeout = false; } /** * @return true if stop conditions are satisfied according to actual {@link #resolutionLogic} before timeout occurs, false * otherwise */ public boolean isStopConditionsSatisfiedBeforeTimeout() { return stopConditionsSatisfiedBeforeTimeout; } /** * @return the current delay in ms */ public long getDelay() { return delay; } /** * @return the current sleep interval in ms */ public long getSleepInterval() { return sleepInterval; } /** * Start a new timer with specified delay. * * @param delay * @return finished timer * @throws InterruptedException */ public static Timer startNew(long delay) throws InterruptedException { return new Timer().setDelay(delay).start(); } /** * Start a new timer with specified delay and sleep interval. * * @param delay * @return finished timer * @throws InterruptedException */ public static Timer startNew(long delay, long sleepInterval) throws InterruptedException { return new Timer().setDelay(delay).setSleepInterval(sleepInterval).start(); } private boolean resolveSleepConditions(long start) { if (hasConditionsSatisfied()) { stopConditionsSatisfiedBeforeTimeout = true; return false; } if (isTimeoutExpired(start)) { return false; } return true; } private void checkConfiguration() { if (delay < 0 || sleepInterval < 0 || delay < sleepInterval) throw new IllegalStateException("Invalid timer configuration"); } private boolean hasConditionsSatisfied() { switch (resolutionLogic) { case DISJUNCTION: return hasAtLeastOneConditionsSatisfied(); case CONJUNCTION: return hasAllConditionsSatisfied(); default: throw new IllegalStateException("Unsupported condition resolution logic"); } } private boolean hasAtLeastOneConditionsSatisfied() { for (StopCondition condition : stopConditions) { if (condition.isSatisfied()) return true; } return false; } private boolean hasAllConditionsSatisfied() { for (StopCondition condition : stopConditions) { if (!condition.isSatisfied()) return false; } return true; } private boolean isTimeoutExpired(long start) { return (System.currentTimeMillis() - start) >= delay; } /** * */ public static interface StopCondition { /** * @return true if stop condition satisfied, false otherwise */ public boolean isSatisfied(); } public static enum ResolutionLogic { /** * At least one condition must be satisfied */ DISJUNCTION, /** * All conditions must be satisfied */ CONJUNCTION, ; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy