package com.griddynamics.jagger.test.javabuilders.load;
import com.griddynamics.jagger.test.javabuilders.utils.JaggerPropertiesProvider;
import com.griddynamics.jagger.test.javabuilders.utils.LoadDurationMetric;
import com.griddynamics.jagger.user.test.configurations.JLoadTest;
import com.griddynamics.jagger.user.test.configurations.auxiliary.Id;
import com.griddynamics.jagger.user.test.configurations.limits.JLimit;
import com.griddynamics.jagger.user.test.configurations.limits.JLimitVsRefValue;
import com.griddynamics.jagger.user.test.configurations.limits.auxiliary.*;
import com.griddynamics.jagger.user.test.configurations.load.JLoadProfile;
import com.griddynamics.jagger.user.test.configurations.load.JLoadProfileInvocation;
import com.griddynamics.jagger.user.test.configurations.load.auxiliary.InvocationCount;
import com.griddynamics.jagger.user.test.configurations.load.auxiliary.ThreadCount;
import com.griddynamics.jagger.user.test.configurations.termination.JTerminationCriteria;
public class InvocationsLoadTests extends LoadTestsDefinition {
private final int invocationsCount;
private final double latency;
private final JLimit LATENCY_LIMIT;
private final int sleepDelay;
public InvocationsLoadTests(JaggerPropertiesProvider provider) {
super(provider);
this.sleepDelay = provider.getIntPropertyValue("inv.sleep.delay");
this.latency = (sleepDelay + provider.getIntPropertyValue("test.env.latency"))/1000.0;
this.invocationsCount = provider.getIntPropertyValue("inv.count");
this.LATENCY_LIMIT = deviationLimit(JMetricName.PERF_AVG_LATENCY, latency, 0.05, 0.1);
}
/**
* Simple invocations load in one thread.
* Make sure that
* - result samples count equals to specified invocations count
* - users are not more than 1 but about 1;
* - test duration is about expected - latency*invocations
*/
public JLoadTest testInvocationsInOneThread(){
int threadsCount = 1;
return test("Invocation in one thread",
invocationLoad(invocationsCount, threadsCount).build(),
iterTermination(invocationsCount),
SUCCESS_LIMIT, LATENCY_LIMIT,
exactValueLimit(JMetricName.PERF_ITERATION_SAMPLES, invocationsCount),
virtualUsersLimit(threadsCount),
deviationLimit(JMetricName.PERF_DURATION, latency * invocationsCount, 0.05, 0.1));
}
/**
* Simple invocations load in 5 thread.
* Make sure that
* - result samples count equals to specified invocations count
* - users are not more than 5 but about 5;
* - test duration is about expected - latency*invocations/5
*/
public JLoadTest testInvocationsSeveralThreads(){
int threadsCount = 5;
// need to increase default invocations count to reduce the impact of starting and stopping of the load
int invocationsCount = this.invocationsCount * 5;
double expectedDuration = latency * invocationsCount / threadsCount;
return test("Invocation in several thread",
invocationLoad(invocationsCount, threadsCount).build(),
iterTermination(invocationsCount),
SUCCESS_LIMIT, LATENCY_LIMIT,
exactValueLimit(JMetricName.PERF_ITERATION_SAMPLES, invocationsCount),
virtualUsersLimit(threadsCount),
deviationLimit(JMetricName.PERF_DURATION, expectedDuration, 0.05, 0.1));
}
/**
* Invocations load terminated by iterations count less than invocations count
* Make sure that
* - result samples count is about specified iterations count
* - test duration is about expected - latency*iterations
*/
public JLoadTest testInvocationsTerminatedByIterations(){
int threadsCount = 1;
int maxIterationToTerminate = invocationsCount*4/5;
double expectedDuration = latency * maxIterationToTerminate / threadsCount;
return test("Invocation terminated by iterations count less than invocations count",
invocationLoad(invocationsCount, threadsCount).build(),
iterTermination(maxIterationToTerminate),
SUCCESS_LIMIT, LATENCY_LIMIT,
deviationLimit(JMetricName.PERF_ITERATION_SAMPLES, maxIterationToTerminate, 0.05, 0.1),
virtualUsersLimit(threadsCount),
deviationLimit(JMetricName.PERF_DURATION, expectedDuration, 0.05, 0.1));
}
/**
* Invocations load terminated by duration before target invocations count reached.
* Make sure that
* - result samples count is less target invocations count
* - test duration is about specified by limit
*/
public JLoadTest testInvocationsTerminatedByDurationBeforeInvocationsReached(){
int threadsCount = 1;
double duration = latency * invocationsCount / threadsCount / 2;
return test("Invocation terminated by duration before target invocations count reached",
invocationLoad(invocationsCount, threadsCount).build(),
durationTermination((long) duration),
SUCCESS_LIMIT, LATENCY_LIMIT,
JLimitVsRefValue.builder(JMetricName.PERF_ITERATION_SAMPLES, RefValue.of((double) invocationsCount))
.withOnlyUpperThresholds(UpWarnThresh.of(0.9), UpErrThresh.of(1.0)).build(),
virtualUsersLimit(threadsCount),
deviationLimit(JMetricName.PERF_DURATION, duration, 0.05, 0.1));
}
/**
* Invocations load terminated by duration after target invocations count reached.
* Make sure that
* - result samples count equals to specified invocations count
* - test duration is about specified by limit
*/
public JLoadTest testInvocationsTerminatedByDurationAfterInvocationsReached(){
int threadsCount = 1;
double duration = latency * invocationsCount * 1.25/ threadsCount;
return test("Invocation terminated by duration after target invocations count reached",
invocationLoad(invocationsCount, threadsCount).build(),
durationTermination((long) duration),
SUCCESS_LIMIT, LATENCY_LIMIT,
exactValueLimit(JMetricName.PERF_ITERATION_SAMPLES, invocationsCount),
deviationLimit(JMetricName.PERF_DURATION, duration, 0.05, 0.1));
}
/**
* Invocations load with delays between invocations.
* Make sure that
* - result samples count equals to specified invocations count
* - test duration is about expected - (latency+delay)*invocations/threads
*/
public JLoadTest testInvocationsWithDelayBetweenInvocations(){
int threadsCount = 1;
int delayBetweenInvocations = provider.getIntPropertyValue("inv.delay.between.invocations");
int expectedDuration = 60;
int targetInvCount = (int) Math.round(expectedDuration*threadsCount/(latency + delayBetweenInvocations/1000));
return test("Invocation with delays between invocations",
invocationLoad(targetInvCount, threadsCount)
.withDelayBetweenInvocationsInMilliseconds(delayBetweenInvocations).build(),
iterTermination(targetInvCount),
SUCCESS_LIMIT, LATENCY_LIMIT,
exactValueLimit(JMetricName.PERF_ITERATION_SAMPLES, targetInvCount),
virtualUsersLimit(threadsCount),
deviationLimit(JMetricName.PERF_DURATION, expectedDuration, 0.05, 0.1),
deviationLimit(LoadDurationMetric.NAME, expectedDuration, 0.05, 0.1));
}
/**
* Invocations load is repeated periodically when invocation time less load period and execution is terminated by
* iterations count.
* load period
* |----------|
* invocation
* time
* |----|
* _____ ______
* | |
* | |
* |_____|
* Make sure that when load period = 2 * invocation time and termination by iteration count = 3*invocationsCount
* - virtual users count = 1/2 threads count
* - test duration = 5 invocations time
*/
public JLoadTest testInvocationsWithPeriodLoadingMaxIterations(){
int threadsCount = 5;
int invocationTime = (int) (invocationsCount*latency/threadsCount);
int loadPeriod = invocationTime*2;
int iterationsCount = invocationsCount*3;
int expectedDuration = 2*loadPeriod+invocationTime;
return test("Invocation repeated periodically max iterations",
invocationLoad(invocationsCount, threadsCount)
.withPeriodBetweenLoadInSeconds(loadPeriod).build(),
iterTermination(iterationsCount),
SUCCESS_LIMIT, LATENCY_LIMIT,
exactValueLimit(JMetricName.PERF_ITERATION_SAMPLES, iterationsCount),
deviationLimit(JMetricName.PERF_VIRTUAL_USERS, threadsCount*3/5, 0.05, 0.1),
deviationLimit(JMetricName.PERF_THROUGHPUT, iterationsCount/expectedDuration, 0.05, 0.1),
deviationLimit(JMetricName.PERF_DURATION, expectedDuration, 0.05, 0.1));
}
/**
* Invocations load is repeated periodically when invocation time less load period and execution is terminated by
* duration.
* load period
* |----------|
* invocation
* time
* |----|
* _____ ______
* | |
* | |
* |_____|
* Make sure that when load period = 2 * invocation time and termination duration = 3.5 invocation time
* - virtual users count = 1/2 threads count
* - iteration count = 2 * invocations count
*/
public JLoadTest testInvocationsWithPeriodLoadingMaxDuration(){
int threadsCount = 5;
int invocationTime = (int) (invocationsCount*latency/threadsCount);
int loadPeriod = 2 * invocationTime;
int duration = (int) (3.5 * invocationTime);
int expectedIterationsCount = 2*invocationsCount;
return test("Invocation repeated periodically max durations",
invocationLoad(invocationsCount, threadsCount)
.withPeriodBetweenLoadInSeconds(loadPeriod).build(),
durationTermination(duration),
SUCCESS_LIMIT, LATENCY_LIMIT,
exactValueLimit(JMetricName.PERF_ITERATION_SAMPLES, expectedIterationsCount),
deviationLimit(JMetricName.PERF_VIRTUAL_USERS, threadsCount*2/3.5, 0.05, 0.1),
deviationLimit(JMetricName.PERF_DURATION, duration, 0.05, 0.1));
}
/**
* Invocations load is repeated periodically when load period less invocation time
* duration.
* load period
* |----------|
* invocation
* time
* |----|
* _____ ______
* | |
* | |
* |_____|
* Make sure that
* - load period doesn't affect loading
*/
public JLoadTest testInvocationsWithSmallerLoadingPeriod(){
int threadsCount = 1;
int invocationTime = (int) (invocationsCount*latency/threadsCount);
int loadPeriod = (int) (0.5 * invocationTime);
int iterationsCount = 2*invocationsCount;
int expectedDuration = 2*invocationTime;
return test("Invocation repeated periodically smaller period",
invocationLoad(invocationsCount, threadsCount)
.withPeriodBetweenLoadInSeconds(loadPeriod).build(),
iterTermination(iterationsCount),
SUCCESS_LIMIT, LATENCY_LIMIT,
deviationLimit(JMetricName.PERF_ITERATION_SAMPLES, iterationsCount, 0.01, 0.05),
deviationLimit(JMetricName.PERF_VIRTUAL_USERS, threadsCount, 0.05, 0.1),
deviationLimit(JMetricName.PERF_DURATION, expectedDuration, 0.05, 0.1));
}
private JLoadProfileInvocation.Builder invocationLoad(int count, int threads){
return JLoadProfileInvocation.builder(InvocationCount.of(count), ThreadCount.of(threads));
}
private JLoadTest test(String id, JLoadProfile l, JTerminationCriteria t, JLimit... limits){
return JLoadTest.builder(Id.of(id), sleepTestDefinition(sleepDelay), l, t).withLimits(limits).build();
}
private JLimit virtualUsersLimit(double expected){
return JLimitVsRefValue.builder(JMetricName.PERF_VIRTUAL_USERS, RefValue.of(expected))
.withExactLimits(LowErrThresh.of(0.9), LowWarnThresh.of(0.95), UpWarnThresh.of(1.0), UpErrThresh.of(1.0))
.build();
}
}