io.hyperfoil.api.config.Phase Maven / Gradle / Ivy
package io.hyperfoil.api.config;
import java.io.Serializable;
import java.util.Collection;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import io.hyperfoil.function.SerializableSupplier;
public final class Phase implements Serializable {
protected static final Logger log = LogManager.getLogger(Phase.class);
protected static final boolean trace = log.isTraceEnabled();
@Visitor.Ignore
protected final SerializableSupplier benchmark;
@Visitor.Ignore
public final int id;
public final int iteration;
@Visitor.Ignore
public final String name;
public final Scenario scenario;
public final long startTime;
public final Collection startAfter;
public final Collection startAfterStrict;
public final Collection terminateAfterStrict;
public final long duration;
public final long maxDuration;
// identifier for sharing resources across iterations
public final String sharedResources;
public final Model model;
public final boolean isWarmup;
public final Map customSlas;
public final StartWithDelay startWithDelay;
public Phase(SerializableSupplier benchmark, int id, int iteration, String name, Scenario scenario,
long startTime, Collection startAfter, Collection startAfterStrict,
Collection terminateAfterStrict, long duration, long maxDuration, String sharedResources, boolean isWarmup,
Model model, Map customSlas, StartWithDelay startWithDelay) {
this.benchmark = benchmark;
this.id = id;
this.iteration = iteration;
this.name = name;
this.terminateAfterStrict = terminateAfterStrict;
this.maxDuration = maxDuration;
this.startAfter = startAfter;
this.startAfterStrict = startAfterStrict;
this.scenario = scenario;
this.startTime = startTime;
this.duration = duration;
this.sharedResources = sharedResources;
this.isWarmup = isWarmup;
this.model = model;
this.customSlas = customSlas;
this.startWithDelay = startWithDelay;
if (scenario == null) {
throw new BenchmarkDefinitionException("Scenario was not set for phase '" + name + "'");
}
model.validate(this);
}
public int id() {
return id;
}
public String name() {
return name;
}
public Scenario scenario() {
return scenario;
}
/**
* @return Start time in milliseconds after benchmark start, or negative value if the phase should start immediately
* after its dependencies ({@link #startAfter()} and {@link #startAfterStrict()} are satisfied.
*/
public long startTime() {
return startTime;
}
/**
* @return Phases that must be finished (not starting any further user sessions) in order to start.
*/
public Collection startAfter() {
return startAfter;
}
/**
* @return Phases that must be terminated (not running any user sessions) in order to start.
*/
public Collection startAfterStrict() {
return startAfterStrict;
}
/**
* @return Phases that must be terminated in order to terminate this phase.
*/
public Collection terminateAfterStrict() {
return terminateAfterStrict;
}
/**
* @return Duration in milliseconds over which new user sessions should be started.
*/
public long duration() {
return duration;
}
/**
* @return Duration in milliseconds over which user sessions can run. After this time no more requests are allowed
* and the phase should terminate.
*/
public long maxDuration() {
return maxDuration;
}
public Benchmark benchmark() {
return benchmark.get();
}
public String description() {
return model.description();
}
/**
* @return Start with delay object defining the phase to which it is coupled, the current phase will start after a
* fixed time (delay) from the start of the coupled phase.
*/
public StartWithDelay startWithDelay() {
return startWithDelay;
}
/**
* Compute and return all phase's dependencies
*
* @return list of phase names
*/
public Collection getDependencies() {
Stream dependencies = Stream.concat(startAfter().stream(), startAfterStrict().stream());
if (startWithDelay() != null) {
dependencies = Stream.concat(dependencies, Stream.of(startWithDelay().phase));
}
return dependencies.collect(Collectors.toList());
}
}