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

com.github.jjYBdx4IL.junit.runners.RetryRunner Maven / Gradle / Ivy

/*
 * Copyright (C) 2016 jjYBdx4IL (https://github.com/jjYBdx4IL)
 *
 * 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 com.github.jjYBdx4IL.junit.runners;

import org.junit.Ignore;
import org.junit.internal.AssumptionViolatedException;
import org.junit.internal.runners.model.EachTestNotifier;
import org.junit.runner.Description;
import org.junit.runner.notification.RunNotifier;
import org.junit.runner.notification.StoppedByUserException;
import org.junit.runners.BlockJUnit4ClassRunner;
import org.junit.runners.model.FrameworkMethod;
import org.junit.runners.model.InitializationError;
import org.junit.runners.model.Statement;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 *
 * @author jjYBdx4IL
 */
public class RetryRunner extends BlockJUnit4ClassRunner {

    private static final Logger log = LoggerFactory.getLogger(RetryRunner.class);
    private final long delayMillis;
    private final int maxRetries;

    public RetryRunner(Class klass) throws InitializationError {
        super(klass);
        RetryRunnerConfig config = klass.getAnnotation(RetryRunnerConfig.class);
        if (config == null) {
            delayMillis = RetryRunnerConfig.DEFAULT_DELAY_MILLIS;
            maxRetries = RetryRunnerConfig.DEFAULT_RETRIES;
        } else {
            delayMillis = config.delayMillis();
            maxRetries = config.retries();
        }
    }

    @Override
    public void run(final RunNotifier notifier) {
        log.info("run()");
        EachTestNotifier testNotifier = new EachTestNotifier(notifier,
                getDescription());
        try {
            Statement statement = classBlock(notifier);
            statement.evaluate();
        } catch (AssumptionViolatedException e) {
            testNotifier.fireTestIgnored();
        } catch (StoppedByUserException e) {
            throw e;
        } catch (Throwable e) {
            testNotifier.addFailure(e);
        }
    }

    @Override
    protected void runChild(final FrameworkMethod method, RunNotifier notifier) {
        log.info("runChild()");
        Description description = describeChild(method);
        if (method.getAnnotation(Ignore.class) != null) {
            notifier.fireTestIgnored(description);
        } else {
            runTestUnit(methodBlock(method), description, notifier);
        }
    }
    /**
     * Runs a {@link Statement} that represents a leaf (aka atomic) test.
     */
    protected final void runTestUnit(Statement statement, Description description,
            RunNotifier notifier) {
        EachTestNotifier eachNotifier = new EachTestNotifier(notifier, description);
        log.info("runTestUnit()");
        eachNotifier.fireTestStarted();
        try {
            int retryCounter = 0;
            for (;;) {
                try {
                    statement.evaluate();
                } catch (AssumptionViolatedException e) {
                    eachNotifier.addFailedAssumption(e);
                } catch (Throwable e) {
                    if (retryCounter < maxRetries) {
                        retryCounter++;
                        log.info(String.format("retrying after %.3f seconds (retry %d/%d)",
                                delayMillis / 1000., retryCounter, maxRetries));
                        if (delayMillis > 0) {
                            try {
                                Thread.sleep(delayMillis);
                            } catch (InterruptedException ex) {
                                throw new RuntimeException(ex);
                            }
                        }
                        continue;
                    }
                    eachNotifier.addFailure(e);
                }
                break;
            }
        } finally {
            eachNotifier.fireTestFinished();
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy