001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.activemq.junit; 018 019import org.junit.runners.model.Statement; 020import org.slf4j.Logger; 021import org.slf4j.LoggerFactory; 022 023public final class RepeatStatement extends Statement { 024 025 private static final Logger LOG = LoggerFactory.getLogger(RepeatStatement.class); 026 027 private final int repetitions; 028 private final boolean untilFailure; 029 private final Statement statement; 030 031 public static Builder builder() { 032 return new Builder(); 033 } 034 035 public RepeatStatement(int times, boolean untilFailure, Statement statement) { 036 this.repetitions = times; 037 this.untilFailure = untilFailure; 038 this.statement = statement; 039 } 040 041 protected RepeatStatement(Builder builder, Statement next) { 042 this.repetitions = builder.getRepetitions(); 043 this.untilFailure = builder.isUntilFailure(); 044 this.statement = next; 045 } 046 047 @Override 048 public void evaluate() throws Throwable { 049 for (int i = 0; i < repetitions && !untilFailure; i++) { 050 if (untilFailure) { 051 LOG.info("Running test iteration: {}.", i + 1); 052 } else { 053 LOG.info("Running test iteration: {} of configured repetitions: {}", i + 1, repetitions); 054 } 055 statement.evaluate(); 056 } 057 } 058 059 /** 060 * Builder for {@link Repeat}. 061 */ 062 public static class Builder { 063 private int repetitions = 1; 064 private boolean untilFailure = false; 065 066 protected Builder() {} 067 068 /** 069 * Specifies the number of times to run the test. 070 * 071 * @param repetitions 072 * The number of times to run the test. 073 * 074 * @return {@code this} for method chaining. 075 */ 076 public Builder withRepetitions(int repetitions) { 077 if (repetitions <= 0) { 078 throw new IllegalArgumentException("repetitions must be greater than zero"); 079 } 080 081 this.repetitions = repetitions; 082 return this; 083 } 084 085 /** 086 * Specifies the number of times to run the test. 087 * 088 * @param untilFailure 089 * true if the test should run until a failure occurs. 090 * 091 * @return {@code this} for method chaining. 092 */ 093 public Builder withRunUntilFailure(boolean untilFailure) { 094 this.untilFailure = untilFailure; 095 return this; 096 } 097 098 protected int getRepetitions() { 099 return repetitions; 100 } 101 102 protected boolean isUntilFailure() { 103 return untilFailure; 104 } 105 106 /** 107 * Builds a {@link RepeatStatement} instance using the values in this builder. 108 * 109 * @param next 110 * The statement instance to wrap with the newly create repeat statement. 111 * 112 * @return a new {@link RepeatStatement} that wraps the given {@link Statement}. 113 */ 114 public RepeatStatement build(Statement next) { 115 if (next == null) { 116 throw new NullPointerException("statement cannot be null"); 117 } 118 119 return new RepeatStatement(this, next); 120 } 121 122 /** 123 * Builds a {@link RepeatStatement} instance using the values in this builder. 124 * 125 * @param annotation 126 * The {@link Repeat} annotation that triggered this statement being created. 127 * @param next 128 * The statement instance to wrap with the newly create repeat statement. 129 * 130 * @return a new {@link RepeatStatement} that wraps the given {@link Statement}. 131 */ 132 public RepeatStatement build(Repeat annotation, Statement next) { 133 if (next == null) { 134 throw new NullPointerException("statement cannot be null"); 135 } 136 137 if (annotation == null) { 138 throw new NullPointerException("annotation cannot be null"); 139 } 140 141 withRepetitions(annotation.repetitions()); 142 withRunUntilFailure(annotation.untilFailure()); 143 144 return new RepeatStatement(this, next); 145 } 146 } 147}