mirror of
https://github.com/OpenAPITools/openapi-generator.git
synced 2025-06-05 08:20:53 +00:00
* Initial commit, Generates everything necessary to run a performnace test against a swagger api. Just have to fill out the CSV feeder files with your data. * adding samples and gatling-petstore.sh file * Extending the AbstractScalaCodeGen * Checking in the CodegenConfig file as it is needed to generate * removing escaped reserved words * Changed model to be able to make all variables utilize an underscore while json fields are still just the variable name * Changing underscore to var as interpolation can not start with a _ in scala * Fixing path params * allow you to pass in a system property to define which config to use as a workload profile, use rate and instance multipliers to scale up and down your test, added ramp down after the test is completed, added global assertions. * Addressing PR feedback * missed semi-colon * Bringing everything up to date with the renames that were suggested
This commit is contained in:
parent
97ad90578d
commit
6d2d4298df
31
bin/scala-gatling-petstore.sh
Executable file
31
bin/scala-gatling-petstore.sh
Executable file
@ -0,0 +1,31 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
SCRIPT="$0"
|
||||||
|
|
||||||
|
while [ -h "$SCRIPT" ] ; do
|
||||||
|
ls=`ls -ld "$SCRIPT"`
|
||||||
|
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||||
|
if expr "$link" : '/.*' > /dev/null; then
|
||||||
|
SCRIPT="$link"
|
||||||
|
else
|
||||||
|
SCRIPT=`dirname "$SCRIPT"`/"$link"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ ! -d "${APP_DIR}" ]; then
|
||||||
|
APP_DIR=`dirname "$SCRIPT"`/..
|
||||||
|
APP_DIR=`cd "${APP_DIR}"; pwd`
|
||||||
|
fi
|
||||||
|
|
||||||
|
executable="./modules/swagger-codegen-cli/target/swagger-codegen-cli.jar"
|
||||||
|
|
||||||
|
if [ ! -f "$executable" ]
|
||||||
|
then
|
||||||
|
mvn clean package
|
||||||
|
fi
|
||||||
|
|
||||||
|
# if you've executed sbt assembly previously it will use that instead.
|
||||||
|
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
|
||||||
|
ags="$@ generate -t modules/swagger-codegen/src/main/resources/ScalaGatling -i modules/swagger-codegen/src/test/resources/2_0/petstore.yaml -l scala-gatling -o samples/client/petstore/scala-gatling"
|
||||||
|
|
||||||
|
java $JAVA_OPTS -jar $executable $ags
|
@ -0,0 +1,345 @@
|
|||||||
|
package io.swagger.codegen.languages;
|
||||||
|
|
||||||
|
import io.swagger.codegen.*;
|
||||||
|
import io.swagger.models.*;
|
||||||
|
import io.swagger.models.parameters.*;
|
||||||
|
import io.swagger.models.properties.*;
|
||||||
|
import org.apache.commons.io.FileUtils;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.*;
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
public class ScalaGatlingCodegen extends AbstractScalaCodegen implements CodegenConfig {
|
||||||
|
|
||||||
|
// source folder where to write the files
|
||||||
|
protected String sourceFolder = "src" + File.separator + "gatling" + File.separator + "scala";
|
||||||
|
protected String resourceFolder = "src" + File.separator + "gatling" + File.separator + "resources";
|
||||||
|
protected String confFolder = resourceFolder + File.separator + "conf";
|
||||||
|
protected String dataFolder = resourceFolder + File.separator + "data";
|
||||||
|
protected String apiVersion = "1.0.0";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configures the type of generator.
|
||||||
|
*
|
||||||
|
* @return the CodegenType for this generator
|
||||||
|
* @see io.swagger.codegen.CodegenType
|
||||||
|
*/
|
||||||
|
public CodegenType getTag() {
|
||||||
|
return CodegenType.CLIENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configures a friendly name for the generator. This will be used by the generator
|
||||||
|
* to select the library with the -l flag.
|
||||||
|
*
|
||||||
|
* @return the friendly name for the generator
|
||||||
|
*/
|
||||||
|
public String getName() {
|
||||||
|
return "scala-gatling";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns human-friendly help for the generator. Provide the consumer with help
|
||||||
|
* tips, parameters here
|
||||||
|
*
|
||||||
|
* @return A string value for the help message
|
||||||
|
*/
|
||||||
|
public String getHelp() {
|
||||||
|
return "Generates a gatling simulation library.";
|
||||||
|
}
|
||||||
|
|
||||||
|
public ScalaGatlingCodegen() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
// set the output folder here
|
||||||
|
outputFolder = "generated-code/gatling";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Api classes. You can write classes for each Api file with the apiTemplateFiles map.
|
||||||
|
* as with models, add multiple entries with different extensions for multiple files per
|
||||||
|
* class
|
||||||
|
*/
|
||||||
|
apiTemplateFiles.put(
|
||||||
|
"api.mustache", // the template to use
|
||||||
|
"Simulation.scala"); // the extension for each file to write
|
||||||
|
|
||||||
|
modelTemplateFiles.put("model.mustache", ".scala");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Template Location. This is the location which templates will be read from. The generator
|
||||||
|
* will use the resource stream to attempt to read the templates.
|
||||||
|
*/
|
||||||
|
templateDir = "ScalaGatling";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Api Package. Optional, if needed, this can be used in templates
|
||||||
|
*/
|
||||||
|
apiPackage = "io.swagger.client.api";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Model Package. Optional, if needed, this can be used in templates
|
||||||
|
*/
|
||||||
|
modelPackage = "io.swagger.client.model";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Additional Properties. These values can be passed to the templates and
|
||||||
|
* are available in models, apis, and supporting files
|
||||||
|
*/
|
||||||
|
additionalProperties.put("apiVersion", apiVersion);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Supporting Files. You can write single files for the generator with the
|
||||||
|
* entire object tree available. If the input file has a suffix of `.mustache
|
||||||
|
* it will be processed by the template engine. Otherwise, it will be copied
|
||||||
|
*/
|
||||||
|
supportingFiles.add(new SupportingFile("build.gradle",
|
||||||
|
"",
|
||||||
|
"build.gradle"));
|
||||||
|
supportingFiles.add(new SupportingFile("logback.xml",
|
||||||
|
confFolder,
|
||||||
|
"logback.xml"));
|
||||||
|
supportingFiles.add(new SupportingFile("default.conf.mustache",
|
||||||
|
confFolder,
|
||||||
|
"default.conf"));
|
||||||
|
supportingFiles.add(new SupportingFile("default.conf.mustache",
|
||||||
|
confFolder,
|
||||||
|
"CI.conf"));
|
||||||
|
supportingFiles.add(new SupportingFile("default.conf.mustache",
|
||||||
|
confFolder,
|
||||||
|
"CD.conf"));
|
||||||
|
supportingFiles.add(new SupportingFile("default.conf.mustache",
|
||||||
|
confFolder,
|
||||||
|
"stress.conf"));
|
||||||
|
supportingFiles.add(new SupportingFile("default.conf.mustache",
|
||||||
|
confFolder,
|
||||||
|
"baseline.conf"));
|
||||||
|
supportingFiles.add(new SupportingFile("default.conf.mustache",
|
||||||
|
confFolder,
|
||||||
|
"longevity.conf"));
|
||||||
|
|
||||||
|
|
||||||
|
importMapping.remove("List");
|
||||||
|
importMapping.remove("Set");
|
||||||
|
importMapping.remove("Map");
|
||||||
|
|
||||||
|
importMapping.put("Date", "java.util.Date");
|
||||||
|
importMapping.put("ListBuffer", "scala.collection.mutable.ListBuffer");
|
||||||
|
|
||||||
|
typeMapping = new HashMap<String, String>();
|
||||||
|
typeMapping.put("enum", "NSString");
|
||||||
|
typeMapping.put("array", "List");
|
||||||
|
typeMapping.put("set", "Set");
|
||||||
|
typeMapping.put("boolean", "Boolean");
|
||||||
|
typeMapping.put("string", "String");
|
||||||
|
typeMapping.put("int", "Int");
|
||||||
|
typeMapping.put("long", "Long");
|
||||||
|
typeMapping.put("float", "Float");
|
||||||
|
typeMapping.put("byte", "Byte");
|
||||||
|
typeMapping.put("short", "Short");
|
||||||
|
typeMapping.put("char", "Char");
|
||||||
|
typeMapping.put("double", "Double");
|
||||||
|
typeMapping.put("object", "Any");
|
||||||
|
typeMapping.put("file", "File");
|
||||||
|
typeMapping.put("binary", "String");
|
||||||
|
typeMapping.put("ByteArray", "String");
|
||||||
|
typeMapping.put("date-time", "Date");
|
||||||
|
typeMapping.put("DateTime", "Date");
|
||||||
|
|
||||||
|
instantiationTypes.put("array", "ListBuffer");
|
||||||
|
instantiationTypes.put("map", "HashMap");
|
||||||
|
|
||||||
|
setReservedWordsLowerCase(
|
||||||
|
Arrays.asList(
|
||||||
|
// local variable names used in API methods (endpoints)
|
||||||
|
"path", "contentTypes", "contentType", "queryParams", "headerParams",
|
||||||
|
"formParams", "postBody", "mp", "basePath", "apiInvoker",
|
||||||
|
|
||||||
|
// scala reserved words
|
||||||
|
"abstract", "case", "catch", "class", "def", "do", "else", "extends",
|
||||||
|
"false", "final", "finally", "for", "forSome", "if", "implicit",
|
||||||
|
"import", "lazy", "match", "new", "null", "object", "override", "package",
|
||||||
|
"private", "protected", "return", "sealed", "super", "this", "throw",
|
||||||
|
"trait", "try", "true", "type", "val", "var", "while", "with", "yield")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gatling does not need the models to have escaped words as it builds models dynamically instead of through
|
||||||
|
* an instance of the object.
|
||||||
|
*
|
||||||
|
* @return the escaped term
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String escapeReservedWord(String name) {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Location to write model files. You can use the modelPackage() as defined when the class is
|
||||||
|
* instantiated
|
||||||
|
*/
|
||||||
|
public String modelFileFolder() {
|
||||||
|
return outputFolder + "/" + sourceFolder + "/" + modelPackage().replace('.', File.separatorChar);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Location to write api files. You can use the apiPackage() as defined when the class is
|
||||||
|
* instantiated
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String apiFileFolder() {
|
||||||
|
return outputFolder + "/" + sourceFolder + "/" + apiPackage().replace('.', File.separatorChar);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Modifies the swagger doc to make mustache easier to use
|
||||||
|
*
|
||||||
|
* @param swagger
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void preprocessSwagger(Swagger swagger) {
|
||||||
|
for (String pathname : swagger.getPaths().keySet()) {
|
||||||
|
Path path = swagger.getPath(pathname);
|
||||||
|
if (path.getOperations() == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (Operation operation : path.getOperations()) {
|
||||||
|
if (!operation.getVendorExtensions().keySet().contains("x-gatling-path")) {
|
||||||
|
if (pathname.contains("{")) {
|
||||||
|
String gatlingPath = pathname.replaceAll("\\{", "\\$\\{");
|
||||||
|
operation.setVendorExtension("x-gatling-path", gatlingPath);
|
||||||
|
} else {
|
||||||
|
operation.setVendorExtension("x-gatling-path", pathname);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Set<Parameter> headerParameters = new HashSet<>();
|
||||||
|
Set<Parameter> formParameters = new HashSet<>();
|
||||||
|
Set<Parameter> queryParameters = new HashSet<>();
|
||||||
|
Set<Parameter> pathParameters = new HashSet<>();
|
||||||
|
|
||||||
|
for (Parameter parameter : operation.getParameters()) {
|
||||||
|
if (parameter.getIn().equalsIgnoreCase("header")) {
|
||||||
|
headerParameters.add(parameter);
|
||||||
|
}
|
||||||
|
if (parameter.getIn().equalsIgnoreCase("formData")) {
|
||||||
|
formParameters.add(parameter);
|
||||||
|
}
|
||||||
|
if (parameter.getIn().equalsIgnoreCase("query")) {
|
||||||
|
queryParameters.add(parameter);
|
||||||
|
}
|
||||||
|
if (parameter.getIn().equalsIgnoreCase("path")) {
|
||||||
|
pathParameters.add(parameter);
|
||||||
|
}
|
||||||
|
if (parameter.getIn().equalsIgnoreCase("body")) {
|
||||||
|
BodyParameter bodyParameter = (BodyParameter) parameter;
|
||||||
|
Model model = bodyParameter.getSchema();
|
||||||
|
if (model instanceof RefModel) {
|
||||||
|
String[] refArray = model.getReference().split("\\/");
|
||||||
|
operation.setVendorExtension("x-gatling-body-object", refArray[refArray.length - 1] + ".toStringBody");
|
||||||
|
Set<String> bodyFeederParams = new HashSet<>();
|
||||||
|
Set<String> sessionBodyVars = new HashSet<>();
|
||||||
|
for (Map.Entry<String, Model> modelEntry : swagger.getDefinitions().entrySet()) {
|
||||||
|
if (refArray[refArray.length - 1].equalsIgnoreCase(modelEntry.getKey())) {
|
||||||
|
for (Map.Entry<String, Property> propertyEntry : modelEntry.getValue().getProperties().entrySet()) {
|
||||||
|
bodyFeederParams.add(propertyEntry.getKey());
|
||||||
|
sessionBodyVars.add("\"${" + propertyEntry.getKey() + "}\"");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
operation.setVendorExtension("x-gatling-body-feeder", operation.getOperationId() + "BodyFeeder");
|
||||||
|
operation.setVendorExtension("x-gatling-body-feeder-params", StringUtils.join(sessionBodyVars, ","));
|
||||||
|
try {
|
||||||
|
FileUtils.writeStringToFile(new File(outputFolder + File.separator + dataFolder + File.separator + operation.getOperationId() + "-" + "BodyParams.csv"), StringUtils.join(bodyFeederParams, ","));
|
||||||
|
} catch (IOException ioe) {
|
||||||
|
LOGGER.error("Could not create feeder file for operationId" + operation.getOperationId(), ioe);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (model instanceof ArrayModel) {
|
||||||
|
operation.setVendorExtension("x-gatling-body-object", "StringBody(\"[]\")");
|
||||||
|
} else {
|
||||||
|
operation.setVendorExtension("x-gatling-body-object", "StringBody(\"{}\")");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
prepareGatlingData(operation, headerParameters, "header");
|
||||||
|
prepareGatlingData(operation, formParameters, "form");
|
||||||
|
prepareGatlingData(operation, queryParameters, "query");
|
||||||
|
prepareGatlingData(operation, pathParameters, "path");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates all the necessary swagger vendor extensions and feeder files for gatling
|
||||||
|
*
|
||||||
|
* @param operation Swagger Operation
|
||||||
|
* @param parameters Swagger Parameters
|
||||||
|
* @param parameterType Swagger Parameter Type
|
||||||
|
*/
|
||||||
|
private void prepareGatlingData(Operation operation, Set<Parameter> parameters, String parameterType) {
|
||||||
|
if (parameters.size() > 0) {
|
||||||
|
List<String> parameterNames = new ArrayList<>();
|
||||||
|
List<Object> vendorList = new ArrayList<>();
|
||||||
|
for (Parameter parameter : parameters) {
|
||||||
|
Map<String, Object> extensionMap = new HashMap<>();
|
||||||
|
extensionMap.put("gatlingParamName", parameter.getName());
|
||||||
|
extensionMap.put("gatlingParamValue", "${" + parameter.getName() + "}");
|
||||||
|
vendorList.add(extensionMap);
|
||||||
|
parameterNames.add(parameter.getName());
|
||||||
|
}
|
||||||
|
operation.setVendorExtension("x-gatling-" + parameterType.toLowerCase() + "-params", vendorList);
|
||||||
|
operation.setVendorExtension("x-gatling-" + parameterType.toLowerCase() + "-feeder", operation.getOperationId() + parameterType.toUpperCase() + "Feeder");
|
||||||
|
try {
|
||||||
|
FileUtils.writeStringToFile(new File(outputFolder + File.separator + dataFolder + File.separator + operation.getOperationId() + "-" + parameterType.toLowerCase() + "Params.csv"), StringUtils.join(parameterNames, ","));
|
||||||
|
} catch (IOException ioe) {
|
||||||
|
LOGGER.error("Could not create feeder file for operationId" + operation.getOperationId(), ioe);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Optional - type declaration. This is a String which is used by the templates to instantiate your
|
||||||
|
* types. There is typically special handling for different property types
|
||||||
|
*
|
||||||
|
* @return a string value used as the `dataType` field for model templates, `returnType` for api templates
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String getTypeDeclaration(Property p) {
|
||||||
|
if (p instanceof ArrayProperty) {
|
||||||
|
ArrayProperty ap = (ArrayProperty) p;
|
||||||
|
Property inner = ap.getItems();
|
||||||
|
return getSwaggerType(p) + "[" + getTypeDeclaration(inner) + "]";
|
||||||
|
} else if (p instanceof MapProperty) {
|
||||||
|
MapProperty mp = (MapProperty) p;
|
||||||
|
Property inner = mp.getAdditionalProperties();
|
||||||
|
return getSwaggerType(p) + "[String, " + getTypeDeclaration(inner) + "]";
|
||||||
|
}
|
||||||
|
return super.getTypeDeclaration(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Optional - swagger type conversion. This is used to map swagger types in a `Property` into
|
||||||
|
* either language specific types via `typeMapping` or into complex models if there is not a mapping.
|
||||||
|
*
|
||||||
|
* @return a string value of the type or complex model for this property
|
||||||
|
* @see io.swagger.models.properties.Property
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String getSwaggerType(Property p) {
|
||||||
|
String swaggerType = super.getSwaggerType(p);
|
||||||
|
String type = null;
|
||||||
|
if (typeMapping.containsKey(swaggerType)) {
|
||||||
|
type = typeMapping.get(swaggerType);
|
||||||
|
if (languageSpecificPrimitives.contains(type))
|
||||||
|
return toModelName(type);
|
||||||
|
} else
|
||||||
|
type = swaggerType;
|
||||||
|
return toModelName(type);
|
||||||
|
}
|
||||||
|
}
|
@ -19,6 +19,7 @@ io.swagger.codegen.languages.ErlangServerCodegen
|
|||||||
io.swagger.codegen.languages.FinchServerCodegen
|
io.swagger.codegen.languages.FinchServerCodegen
|
||||||
io.swagger.codegen.languages.FlashClientCodegen
|
io.swagger.codegen.languages.FlashClientCodegen
|
||||||
io.swagger.codegen.languages.FlaskConnexionCodegen
|
io.swagger.codegen.languages.FlaskConnexionCodegen
|
||||||
|
io.swagger.codegen.languages.ScalaGatlingCodegen
|
||||||
io.swagger.codegen.languages.GoClientCodegen
|
io.swagger.codegen.languages.GoClientCodegen
|
||||||
io.swagger.codegen.languages.GoServerCodegen
|
io.swagger.codegen.languages.GoServerCodegen
|
||||||
io.swagger.codegen.languages.GroovyClientCodegen
|
io.swagger.codegen.languages.GroovyClientCodegen
|
||||||
|
@ -0,0 +1,147 @@
|
|||||||
|
package {{package}}
|
||||||
|
|
||||||
|
import {{modelPackage}}._
|
||||||
|
import com.typesafe.config.ConfigFactory
|
||||||
|
|
||||||
|
import io.gatling.core.Predef._
|
||||||
|
import io.gatling.http.Predef._
|
||||||
|
import io.gatling.core.structure.PopulationBuilder
|
||||||
|
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
import scala.collection.mutable
|
||||||
|
|
||||||
|
class {{classname}}Simulation extends Simulation {
|
||||||
|
|
||||||
|
def getCurrentDirectory = new File("").getAbsolutePath
|
||||||
|
def userDataDirectory = getCurrentDirectory + "/src/gatling/resources/data"
|
||||||
|
|
||||||
|
// basic test setup
|
||||||
|
val configName = System.getProperty("testConfig", "baseline")
|
||||||
|
val config = ConfigFactory.load(configName).withFallback(ConfigFactory.load("default"))
|
||||||
|
val durationSeconds = config.getInt("performance.durationSeconds")
|
||||||
|
val rampUpSeconds = config.getInt("performance.rampUpSeconds")
|
||||||
|
val rampDownSeconds = config.getInt("performance.rampDownSeconds")
|
||||||
|
val authentication = config.getString("performance.authorizationHeader")
|
||||||
|
val acceptHeader = config.getString("performance.acceptType")
|
||||||
|
val contentTypeHeader = config.getString("performance.contentType")
|
||||||
|
val rateMultiplier = config.getDouble("performance.rateMultiplier")
|
||||||
|
val instanceMultiplier = config.getDouble("performance.instanceMultiplier")
|
||||||
|
|
||||||
|
// global assertion data
|
||||||
|
val globalResponseTimeMinLTE = config.getInt("performance.global.assertions.responseTime.min.lte")
|
||||||
|
val globalResponseTimeMinGTE = config.getInt("performance.global.assertions.responseTime.min.gte")
|
||||||
|
val globalResponseTimeMaxLTE = config.getInt("performance.global.assertions.responseTime.max.lte")
|
||||||
|
val globalResponseTimeMaxGTE = config.getInt("performance.global.assertions.responseTime.max.gte")
|
||||||
|
val globalResponseTimeMeanLTE = config.getInt("performance.global.assertions.responseTime.mean.lte")
|
||||||
|
val globalResponseTimeMeanGTE = config.getInt("performance.global.assertions.responseTime.mean.gte")
|
||||||
|
val globalResponseTimeFailedRequestsPercentLTE = config.getDouble("performance.global.assertions.failedRequests.percent.lte")
|
||||||
|
val globalResponseTimeFailedRequestsPercentGTE = config.getDouble("performance.global.assertions.failedRequests.percent.gte")
|
||||||
|
val globalResponseTimeSuccessfulRequestsPercentLTE = config.getDouble("performance.global.assertions.successfulRequests.percent.lte")
|
||||||
|
val globalResponseTimeSuccessfulRequestsPercentGTE = config.getDouble("performance.global.assertions.successfulRequests.percent.gte")
|
||||||
|
|
||||||
|
// Setup http protocol configuration
|
||||||
|
val httpConf = http
|
||||||
|
.baseURL("{{basePath}}")
|
||||||
|
.doNotTrackHeader("1")
|
||||||
|
.acceptLanguageHeader("en-US,en;q=0.5")
|
||||||
|
.acceptEncodingHeader("gzip, deflate")
|
||||||
|
.userAgentHeader("Mozilla/5.0 (Windows NT 5.1; rv:31.0) Gecko/20100101 Firefox/31.0")
|
||||||
|
.acceptHeader(acceptHeader)
|
||||||
|
.contentTypeHeader(contentTypeHeader)
|
||||||
|
|
||||||
|
// set authorization header if it has been modified from config
|
||||||
|
if(!authentication.equals("~MANUAL_ENTRY")){
|
||||||
|
httpConf.authorizationHeader(authentication)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setup all the operations per second for the test to ultimately be generated from configs
|
||||||
|
{{#operations}}
|
||||||
|
{{#operation}}
|
||||||
|
val {{operationId}}PerSecond = config.getDouble("performance.operationsPerSecond.{{operationId}}") * rateMultiplier * instanceMultiplier
|
||||||
|
{{/operation}}
|
||||||
|
{{/operations}}
|
||||||
|
|
||||||
|
val scenarioBuilders: mutable.MutableList[PopulationBuilder] = new mutable.MutableList[PopulationBuilder]()
|
||||||
|
|
||||||
|
// Set up CSV feeders
|
||||||
|
{{#operations}}
|
||||||
|
{{#operation}}
|
||||||
|
{{#vendorExtensions.x-gatling-query-feeder}}
|
||||||
|
val {{vendorExtensions.x-gatling-query-feeder}} = csv(userDataDirectory + File.separator + "{{operationId}}-queryParams.csv").random
|
||||||
|
{{/vendorExtensions.x-gatling-query-feeder}}
|
||||||
|
{{#vendorExtensions.x-gatling-header-feeder}}
|
||||||
|
val {{vendorExtensions.x-gatling-header-feeder}} = csv(userDataDirectory + File.separator + "{{operationId}}-headerParams.csv").random
|
||||||
|
{{/vendorExtensions.x-gatling-header-feeder}}
|
||||||
|
{{#vendorExtensions.x-gatling-form-feeder}}
|
||||||
|
val {{vendorExtensions.x-gatling-form-feeder}} = csv(userDataDirectory + File.separator + "{{operationId}}-formParams.csv").random
|
||||||
|
{{/vendorExtensions.x-gatling-form-feeder}}
|
||||||
|
{{#vendorExtensions.x-gatling-path-feeder}}
|
||||||
|
val {{vendorExtensions.x-gatling-path-feeder}} = csv(userDataDirectory + File.separator + "{{operationId}}-pathParams.csv").random
|
||||||
|
{{/vendorExtensions.x-gatling-path-feeder}}
|
||||||
|
{{#vendorExtensions.x-gatling-body-feeder}}
|
||||||
|
val {{vendorExtensions.x-gatling-body-feeder}} = csv(userDataDirectory + File.separator + "{{operationId}}-bodyParams.csv", escapeChar = '\\').random
|
||||||
|
{{/vendorExtensions.x-gatling-body-feeder}}
|
||||||
|
{{/operation}}
|
||||||
|
{{/operations}}
|
||||||
|
|
||||||
|
// Setup all scenarios
|
||||||
|
|
||||||
|
{{#operations}}
|
||||||
|
{{#operation}}
|
||||||
|
{{#description}}/* {{{description}}} */{{/description}}
|
||||||
|
val scn{{operationId}} = scenario("{{operationId}}Simulation")
|
||||||
|
{{#vendorExtensions.x-gatling-query-feeder}}
|
||||||
|
.feed({{vendorExtensions.x-gatling-query-feeder}})
|
||||||
|
{{/vendorExtensions.x-gatling-query-feeder}}
|
||||||
|
{{#vendorExtensions.x-gatling-header-feeder}}
|
||||||
|
.feed({{vendorExtensions.x-gatling-header-feeder}})
|
||||||
|
{{/vendorExtensions.x-gatling-header-feeder}}
|
||||||
|
{{#vendorExtensions.x-gatling-form-feeder}}
|
||||||
|
.feed({{vendorExtensions.x-gatling-form-feeder}})
|
||||||
|
{{/vendorExtensions.x-gatling-form-feeder}}
|
||||||
|
{{#vendorExtensions.x-gatling-body-feeder}}
|
||||||
|
.feed({{vendorExtensions.x-gatling-body-feeder}})
|
||||||
|
{{/vendorExtensions.x-gatling-body-feeder}}
|
||||||
|
{{#vendorExtensions.x-gatling-path-feeder}}
|
||||||
|
.feed({{vendorExtensions.x-gatling-path-feeder}})
|
||||||
|
{{/vendorExtensions.x-gatling-path-feeder}}
|
||||||
|
.exec(http("{{operationId}}")
|
||||||
|
.httpRequest("{{httpMethod}}","{{{vendorExtensions.x-gatling-path}}}")
|
||||||
|
{{#vendorExtensions.x-gatling-query-params}}
|
||||||
|
.queryParam("{{gatlingParamName}}","{{gatlingParamValue}}")
|
||||||
|
{{/vendorExtensions.x-gatling-query-params}}
|
||||||
|
{{#vendorExtensions.x-gatling-header-params}}
|
||||||
|
.header("{{gatlingParamName}}","{{gatlingParamValue}}")
|
||||||
|
{{/vendorExtensions.x-gatling-header-params}}
|
||||||
|
{{#vendorExtensions.x-gatling-form-params}}
|
||||||
|
.formParam("{{gatlingParamName}}","{{gatlingParamValue}}")
|
||||||
|
{{/vendorExtensions.x-gatling-form-params}}
|
||||||
|
{{#vendorExtensions.x-gatling-body-object}}
|
||||||
|
.body(StringBody({{{vendorExtensions.x-gatling-body-object}}}{{#vendorExtensions.x-gatling-body-feeder-params}}({{{vendorExtensions.x-gatling-body-feeder-params}}}){{/vendorExtensions.x-gatling-body-feeder-params}}))
|
||||||
|
{{/vendorExtensions.x-gatling-body-object}})
|
||||||
|
|
||||||
|
// Run scn{{operationId}} with warm up and reach a constant rate for entire duration
|
||||||
|
scenarioBuilders += scn{{operationId}}.inject(
|
||||||
|
rampUsersPerSec(1) to({{operationId}}PerSecond) during(rampUpSeconds),
|
||||||
|
constantUsersPerSec({{operationId}}PerSecond) during(durationSeconds),
|
||||||
|
rampUsersPerSec({{operationId}}PerSecond) to(1) during(rampDownSeconds)
|
||||||
|
)
|
||||||
|
|
||||||
|
{{/operation}}
|
||||||
|
{{/operations}}
|
||||||
|
setUp(
|
||||||
|
scenarioBuilders.toList
|
||||||
|
).protocols(httpConf).assertions(
|
||||||
|
global.responseTime.min.lte(globalResponseTimeMinLTE),
|
||||||
|
global.responseTime.min.gte(globalResponseTimeMinGTE),
|
||||||
|
global.responseTime.max.lte(globalResponseTimeMaxLTE),
|
||||||
|
global.responseTime.max.gte(globalResponseTimeMaxGTE),
|
||||||
|
global.responseTime.mean.lte(globalResponseTimeMeanLTE),
|
||||||
|
global.responseTime.mean.gte(globalResponseTimeMeanGTE),
|
||||||
|
global.failedRequests.percent.lte(globalResponseTimeFailedRequestsPercentLTE),
|
||||||
|
global.failedRequests.percent.gte(globalResponseTimeFailedRequestsPercentGTE),
|
||||||
|
global.successfulRequests.percent.lte(globalResponseTimeSuccessfulRequestsPercentLTE),
|
||||||
|
global.successfulRequests.percent.gte(globalResponseTimeSuccessfulRequestsPercentGTE)
|
||||||
|
)
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
plugins {
|
||||||
|
id 'com.github.lkishalmi.gatling' version '0.4.1'
|
||||||
|
}
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
apply plugin: "com.github.lkishalmi.gatling"
|
||||||
|
|
||||||
|
gatling {
|
||||||
|
toolVersion = '2.3.0'
|
||||||
|
jvmArgs = ['-server', '-XX:+UseThreadPriorities',
|
||||||
|
'-XX:ThreadPriorityPolicy=42',
|
||||||
|
'-Xms2048M', '-Xmx2048M', '-Xmn500M',
|
||||||
|
'-XX:+HeapDumpOnOutOfMemoryError',
|
||||||
|
'-XX:+AggressiveOpts',
|
||||||
|
'-XX:+OptimizeStringConcat',
|
||||||
|
'-XX:+UseFastAccessorMethods',
|
||||||
|
'-XX:+UseParNewGC',
|
||||||
|
'-XX:+UseConcMarkSweepGC',
|
||||||
|
'-XX:+CMSParallelRemarkEnabled',
|
||||||
|
'-Djava.net.preferIPv4Stack=true',
|
||||||
|
'-Djava.net.preferIPv6Addresses=false']
|
||||||
|
}
|
@ -0,0 +1,51 @@
|
|||||||
|
performance {
|
||||||
|
authorizationHeader = "~MANUAL_ENTRY~"
|
||||||
|
rampUpSeconds = 60
|
||||||
|
rampDownSeconds = 60
|
||||||
|
durationSeconds = 360
|
||||||
|
contentType = "application/json"
|
||||||
|
acceptType = "application/json"
|
||||||
|
rateMultiplier = 1
|
||||||
|
instanceMultiplier = 1
|
||||||
|
operationsPerSecond {
|
||||||
|
{{#apiInfo}}
|
||||||
|
{{#apis}}
|
||||||
|
{{#operations}}
|
||||||
|
{{#operation}}
|
||||||
|
{{operationId}} = 1
|
||||||
|
{{/operation}}
|
||||||
|
{{/operations}}
|
||||||
|
{{/apis}}
|
||||||
|
{{/apiInfo}}
|
||||||
|
}
|
||||||
|
global {
|
||||||
|
assertions {
|
||||||
|
responseTime {
|
||||||
|
min {
|
||||||
|
lte = 30000
|
||||||
|
gte = 0
|
||||||
|
}
|
||||||
|
max {
|
||||||
|
lte = 30000
|
||||||
|
gte = 0
|
||||||
|
}
|
||||||
|
mean {
|
||||||
|
lte = 30000
|
||||||
|
gte = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
failedRequests {
|
||||||
|
percent {
|
||||||
|
lte = 5
|
||||||
|
gte = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
successfulRequests {
|
||||||
|
percent {
|
||||||
|
lte = 100
|
||||||
|
gte = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,132 @@
|
|||||||
|
#########################
|
||||||
|
# Gatling Configuration #
|
||||||
|
#########################
|
||||||
|
|
||||||
|
# This file contains all the settings configurable for Gatling with their default values
|
||||||
|
|
||||||
|
gatling {
|
||||||
|
core {
|
||||||
|
outputDirectoryBaseName = "" # The prefix for each simulation result folder (then suffixed by the report generation timestamp)
|
||||||
|
runDescription = "" # The description for this simulation run, displayed in each report
|
||||||
|
encoding = "utf-8" # Encoding to use throughout Gatling for file and string manipulation
|
||||||
|
simulationClass = "" # The FQCN of the simulation to run (when used in conjunction with noReports, the simulation for which assertions will be validated)
|
||||||
|
mute = false # When set to true, don't ask for simulation name nor run description (currently only used by Gatling SBT plugin)
|
||||||
|
elFileBodiesCacheMaxCapacity = 200 # Cache size for request body EL templates, set to 0 to disable
|
||||||
|
rawFileBodiesCacheMaxCapacity = 200 # Cache size for request body Raw templates, set to 0 to disable
|
||||||
|
rawFileBodiesInMemoryMaxSize = 1000 # Below this limit, raw file bodies will be cached in memory
|
||||||
|
pebbleFileBodiesCacheMaxCapacity = 200 # Cache size for request body Peeble templates, set to 0 to disable
|
||||||
|
|
||||||
|
extract {
|
||||||
|
regex {
|
||||||
|
cacheMaxCapacity = 200 # Cache size for the compiled regexes, set to 0 to disable caching
|
||||||
|
}
|
||||||
|
xpath {
|
||||||
|
cacheMaxCapacity = 200 # Cache size for the compiled XPath queries, set to 0 to disable caching
|
||||||
|
}
|
||||||
|
jsonPath {
|
||||||
|
cacheMaxCapacity = 200 # Cache size for the compiled jsonPath queries, set to 0 to disable caching
|
||||||
|
preferJackson = false # When set to true, prefer Jackson over Boon for JSON-related operations
|
||||||
|
}
|
||||||
|
css {
|
||||||
|
cacheMaxCapacity = 200 # Cache size for the compiled CSS selectors queries, set to 0 to disable caching
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
directory {
|
||||||
|
data = user-files/data # Folder where user's data (e.g. files used by Feeders) is located
|
||||||
|
bodies = user-files/bodies # Folder where bodies are located
|
||||||
|
simulations = user-files/simulations # Folder where the bundle's simulations are located
|
||||||
|
reportsOnly = "" # If set, name of report folder to look for in order to generate its report
|
||||||
|
binaries = "" # If set, name of the folder where compiles classes are located: Defaults to GATLING_HOME/target.
|
||||||
|
results = results # Name of the folder where all reports folder are located
|
||||||
|
}
|
||||||
|
}
|
||||||
|
charting {
|
||||||
|
noReports = false # When set to true, don't generate HTML reports
|
||||||
|
maxPlotPerSeries = 1000 # Number of points per graph in Gatling reports
|
||||||
|
useGroupDurationMetric = false # Switch group timings from cumulated response time to group duration.
|
||||||
|
indicators {
|
||||||
|
lowerBound = 800 # Lower bound for the requests' response time to track in the reports and the console summary
|
||||||
|
higherBound = 1200 # Higher bound for the requests' response time to track in the reports and the console summary
|
||||||
|
percentile1 = 50 # Value for the 1st percentile to track in the reports, the console summary and Graphite
|
||||||
|
percentile2 = 75 # Value for the 2nd percentile to track in the reports, the console summary and Graphite
|
||||||
|
percentile3 = 95 # Value for the 3rd percentile to track in the reports, the console summary and Graphite
|
||||||
|
percentile4 = 99 # Value for the 4th percentile to track in the reports, the console summary and Graphite
|
||||||
|
}
|
||||||
|
}
|
||||||
|
http {
|
||||||
|
fetchedCssCacheMaxCapacity = 200 # Cache size for CSS parsed content, set to 0 to disable
|
||||||
|
fetchedHtmlCacheMaxCapacity = 200 # Cache size for HTML parsed content, set to 0 to disable
|
||||||
|
perUserCacheMaxCapacity = 200 # Per virtual user cache size, set to 0 to disable
|
||||||
|
warmUpUrl = "http://gatling.io" # The URL to use to warm-up the HTTP stack (blank means disabled)
|
||||||
|
enableGA = true # Very light Google Analytics, please support
|
||||||
|
ssl {
|
||||||
|
keyStore {
|
||||||
|
type = "" # Type of SSLContext's KeyManagers store
|
||||||
|
file = "" # Location of SSLContext's KeyManagers store
|
||||||
|
password = "" # Password for SSLContext's KeyManagers store
|
||||||
|
algorithm = "" # Algorithm used SSLContext's KeyManagers store
|
||||||
|
}
|
||||||
|
trustStore {
|
||||||
|
type = "" # Type of SSLContext's TrustManagers store
|
||||||
|
file = "" # Location of SSLContext's TrustManagers store
|
||||||
|
password = "" # Password for SSLContext's TrustManagers store
|
||||||
|
algorithm = "" # Algorithm used by SSLContext's TrustManagers store
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ahc {
|
||||||
|
keepAlive = true # Allow pooling HTTP connections (keep-alive header automatically added)
|
||||||
|
connectTimeout = 10000 # Timeout when establishing a connection
|
||||||
|
handshakeTimeout = 10000 # Timeout when performing TLS hashshake
|
||||||
|
pooledConnectionIdleTimeout = 60000 # Timeout when a connection stays unused in the pool
|
||||||
|
readTimeout = 60000 # Timeout when a used connection stays idle
|
||||||
|
maxRetry = 2 # Number of times that a request should be tried again
|
||||||
|
requestTimeout = 60000 # Timeout of the requests
|
||||||
|
disableHttpsEndpointIdentificationAlgorithm = true # When set to true, don't enable SSL algorithm on the SSLEngine
|
||||||
|
useInsecureTrustManager = true # Use an insecure TrustManager that trusts all server certificates
|
||||||
|
httpClientCodecMaxChunkSize = 8192 # Maximum length of the content or each chunk
|
||||||
|
httpClientCodecInitialBufferSize = 128 # Initial HttpClientCodec buffer size
|
||||||
|
sslEnabledProtocols = [TLSv1.2, TLSv1.1, TLSv1] # Array of enabled protocols for HTTPS, if empty use the JDK defaults
|
||||||
|
sslEnabledCipherSuites = [] # Array of enabled cipher suites for HTTPS, if empty use the AHC defaults
|
||||||
|
sslSessionCacheSize = 0 # SSLSession cache size, set to 0 to use JDK's default
|
||||||
|
sslSessionTimeout = 0 # SSLSession timeout in seconds, set to 0 to use JDK's default (24h)
|
||||||
|
useOpenSsl = false # if OpenSSL should be used instead of JSSE (requires tcnative jar)
|
||||||
|
useNativeTransport = false # if native transport should be used instead of Java NIO (requires netty-transport-native-epoll, currently Linux only)
|
||||||
|
tcpNoDelay = true
|
||||||
|
soReuseAddress = false
|
||||||
|
soLinger = -1
|
||||||
|
soSndBuf = -1
|
||||||
|
soRcvBuf = -1
|
||||||
|
allocator = "pooled" # switch to unpooled for unpooled ByteBufAllocator
|
||||||
|
maxThreadLocalCharBufferSize = 200000 # Netty's default is 16k
|
||||||
|
}
|
||||||
|
dns {
|
||||||
|
queryTimeout = 5000 # Timeout of each DNS query in millis
|
||||||
|
maxQueriesPerResolve = 6 # Maximum allowed number of DNS queries for a given name resolution
|
||||||
|
}
|
||||||
|
}
|
||||||
|
jms {
|
||||||
|
replyTimeoutScanPeriod = 1000 # scan period for timedout reply messages
|
||||||
|
}
|
||||||
|
data {
|
||||||
|
writers = [console, file] # The list of DataWriters to which Gatling write simulation data (currently supported : console, file, graphite, jdbc)
|
||||||
|
console {
|
||||||
|
light = false # When set to true, displays a light version without detailed request stats
|
||||||
|
}
|
||||||
|
file {
|
||||||
|
bufferSize = 8192 # FileDataWriter's internal data buffer size, in bytes
|
||||||
|
}
|
||||||
|
leak {
|
||||||
|
noActivityTimeout = 30 # Period, in seconds, for which Gatling may have no activity before considering a leak may be happening
|
||||||
|
}
|
||||||
|
graphite {
|
||||||
|
light = false # only send the all* stats
|
||||||
|
host = "localhost" # The host where the Carbon server is located
|
||||||
|
port = 2003 # The port to which the Carbon server listens to (2003 is default for plaintext, 2004 is default for pickle)
|
||||||
|
protocol = "tcp" # The protocol used to send data to Carbon (currently supported : "tcp", "udp")
|
||||||
|
rootPathPrefix = "gatling" # The common prefix of all metrics sent to Graphite
|
||||||
|
bufferSize = 8192 # GraphiteDataWriter's internal data buffer size, in bytes
|
||||||
|
writeInterval = 1 # GraphiteDataWriter's write interval, in seconds
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<configuration>
|
||||||
|
|
||||||
|
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
|
||||||
|
<encoder>
|
||||||
|
<pattern>%d{HH:mm:ss.SSS} [%-5level] %logger{15} - %msg%n%rEx</pattern>
|
||||||
|
</encoder>
|
||||||
|
<immediateFlush>false</immediateFlush>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<!-- Uncomment for logging ALL HTTP request and responses -->
|
||||||
|
<!-- <logger name="io.gatling.http.ahc" level="TRACE" /> -->
|
||||||
|
<!-- <logger name="io.gatling.http.response" level="TRACE" /> -->
|
||||||
|
<!-- Uncomment for logging ONLY FAILED HTTP request and responses -->
|
||||||
|
<!-- <logger name="io.gatling.http.ahc" level="DEBUG" /> -->
|
||||||
|
<!-- <logger name="io.gatling.http.response" level="DEBUG" /> -->
|
||||||
|
|
||||||
|
<root level="WARN">
|
||||||
|
<appender-ref ref="CONSOLE" />
|
||||||
|
</root>
|
||||||
|
|
||||||
|
</configuration>
|
@ -0,0 +1,26 @@
|
|||||||
|
{{>licenseInfo}}
|
||||||
|
package {{package}}
|
||||||
|
|
||||||
|
{{#imports}}import {{import}}
|
||||||
|
{{/imports}}
|
||||||
|
|
||||||
|
{{#models}}
|
||||||
|
{{#model}}
|
||||||
|
case class {{classname}} (
|
||||||
|
{{#vars}}
|
||||||
|
{{#description}}
|
||||||
|
/* {{{description}}} */
|
||||||
|
{{/description}}
|
||||||
|
_{{{name}}}: {{^required}}Option[{{/required}}{{datatype}}{{^required}}]{{/required}}{{#hasMore}},{{/hasMore}}
|
||||||
|
{{/vars}}
|
||||||
|
)
|
||||||
|
object {{classname}} {
|
||||||
|
def toStringBody({{#vars}}var_{{name}}: {{^required}}{{/required}}Object{{^required}}{{/required}}{{#hasMore}}, {{/hasMore}}{{/vars}}) =
|
||||||
|
s"""
|
||||||
|
| {
|
||||||
|
| {{#vars}}"{{{name}}}":$var_{{{name}}}{{#hasMore}},{{/hasMore}}{{/vars}}
|
||||||
|
| }
|
||||||
|
""".stripMargin
|
||||||
|
}
|
||||||
|
{{/model}}
|
||||||
|
{{/models}}
|
@ -0,0 +1,8 @@
|
|||||||
|
/*___Generated_by_IDEA___*/
|
||||||
|
|
||||||
|
package io.swagger.client;
|
||||||
|
|
||||||
|
/* This stub is only used by the IDE. It is NOT the BuildConfig class actually packed into the APK */
|
||||||
|
public final class BuildConfig {
|
||||||
|
public final static boolean DEBUG = Boolean.parseBoolean(null);
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
/*___Generated_by_IDEA___*/
|
||||||
|
|
||||||
|
package io.swagger.client;
|
||||||
|
|
||||||
|
/* This stub is only used by the IDE. It is NOT the Manifest class actually packed into the APK */
|
||||||
|
public final class Manifest {
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
/*___Generated_by_IDEA___*/
|
||||||
|
|
||||||
|
package io.swagger.client;
|
||||||
|
|
||||||
|
/* This stub is only used by the IDE. It is NOT the R class actually packed into the APK */
|
||||||
|
public final class R {
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
/*___Generated_by_IDEA___*/
|
||||||
|
|
||||||
|
package io.swagger.client;
|
||||||
|
|
||||||
|
/* This stub is only used by the IDE. It is NOT the BuildConfig class actually packed into the APK */
|
||||||
|
public final class BuildConfig {
|
||||||
|
public final static boolean DEBUG = Boolean.parseBoolean(null);
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
/*___Generated_by_IDEA___*/
|
||||||
|
|
||||||
|
package io.swagger.client;
|
||||||
|
|
||||||
|
/* This stub is only used by the IDE. It is NOT the Manifest class actually packed into the APK */
|
||||||
|
public final class Manifest {
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
/*___Generated_by_IDEA___*/
|
||||||
|
|
||||||
|
package io.swagger.client;
|
||||||
|
|
||||||
|
/* This stub is only used by the IDE. It is NOT the R class actually packed into the APK */
|
||||||
|
public final class R {
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
/*___Generated_by_IDEA___*/
|
||||||
|
|
||||||
|
package io.swagger.client;
|
||||||
|
|
||||||
|
/* This stub is only used by the IDE. It is NOT the BuildConfig class actually packed into the APK */
|
||||||
|
public final class BuildConfig {
|
||||||
|
public final static boolean DEBUG = Boolean.parseBoolean(null);
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
/*___Generated_by_IDEA___*/
|
||||||
|
|
||||||
|
package io.swagger.client;
|
||||||
|
|
||||||
|
/* This stub is only used by the IDE. It is NOT the Manifest class actually packed into the APK */
|
||||||
|
public final class Manifest {
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
/*___Generated_by_IDEA___*/
|
||||||
|
|
||||||
|
package io.swagger.client;
|
||||||
|
|
||||||
|
/* This stub is only used by the IDE. It is NOT the R class actually packed into the APK */
|
||||||
|
public final class R {
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
/*___Generated_by_IDEA___*/
|
||||||
|
|
||||||
|
package io.swagger.client;
|
||||||
|
|
||||||
|
/* This stub is only used by the IDE. It is NOT the BuildConfig class actually packed into the APK */
|
||||||
|
public final class BuildConfig {
|
||||||
|
public final static boolean DEBUG = Boolean.parseBoolean(null);
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
/*___Generated_by_IDEA___*/
|
||||||
|
|
||||||
|
package io.swagger.client;
|
||||||
|
|
||||||
|
/* This stub is only used by the IDE. It is NOT the Manifest class actually packed into the APK */
|
||||||
|
public final class Manifest {
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
/*___Generated_by_IDEA___*/
|
||||||
|
|
||||||
|
package io.swagger.client;
|
||||||
|
|
||||||
|
/* This stub is only used by the IDE. It is NOT the R class actually packed into the APK */
|
||||||
|
public final class R {
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
/*___Generated_by_IDEA___*/
|
||||||
|
|
||||||
|
package io.swagger.client;
|
||||||
|
|
||||||
|
/* This stub is only used by the IDE. It is NOT the BuildConfig class actually packed into the APK */
|
||||||
|
public final class BuildConfig {
|
||||||
|
public final static boolean DEBUG = Boolean.parseBoolean(null);
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
/*___Generated_by_IDEA___*/
|
||||||
|
|
||||||
|
package io.swagger.client;
|
||||||
|
|
||||||
|
/* This stub is only used by the IDE. It is NOT the Manifest class actually packed into the APK */
|
||||||
|
public final class Manifest {
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
/*___Generated_by_IDEA___*/
|
||||||
|
|
||||||
|
package io.swagger.client;
|
||||||
|
|
||||||
|
/* This stub is only used by the IDE. It is NOT the R class actually packed into the APK */
|
||||||
|
public final class R {
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
/*___Generated_by_IDEA___*/
|
||||||
|
|
||||||
|
package io.swagger.client;
|
||||||
|
|
||||||
|
/* This stub is only used by the IDE. It is NOT the BuildConfig class actually packed into the APK */
|
||||||
|
public final class BuildConfig {
|
||||||
|
public final static boolean DEBUG = Boolean.parseBoolean(null);
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
/*___Generated_by_IDEA___*/
|
||||||
|
|
||||||
|
package io.swagger.client;
|
||||||
|
|
||||||
|
/* This stub is only used by the IDE. It is NOT the Manifest class actually packed into the APK */
|
||||||
|
public final class Manifest {
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
/*___Generated_by_IDEA___*/
|
||||||
|
|
||||||
|
package io.swagger.client;
|
||||||
|
|
||||||
|
/* This stub is only used by the IDE. It is NOT the R class actually packed into the APK */
|
||||||
|
public final class R {
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
/*___Generated_by_IDEA___*/
|
||||||
|
|
||||||
|
package io.swagger.client;
|
||||||
|
|
||||||
|
/* This stub is only used by the IDE. It is NOT the BuildConfig class actually packed into the APK */
|
||||||
|
public final class BuildConfig {
|
||||||
|
public final static boolean DEBUG = Boolean.parseBoolean(null);
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
/*___Generated_by_IDEA___*/
|
||||||
|
|
||||||
|
package io.swagger.client;
|
||||||
|
|
||||||
|
/* This stub is only used by the IDE. It is NOT the Manifest class actually packed into the APK */
|
||||||
|
public final class Manifest {
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
/*___Generated_by_IDEA___*/
|
||||||
|
|
||||||
|
package io.swagger.client;
|
||||||
|
|
||||||
|
/* This stub is only used by the IDE. It is NOT the R class actually packed into the APK */
|
||||||
|
public final class R {
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
/*___Generated_by_IDEA___*/
|
||||||
|
|
||||||
|
package io.swagger.client;
|
||||||
|
|
||||||
|
/* This stub is only used by the IDE. It is NOT the BuildConfig class actually packed into the APK */
|
||||||
|
public final class BuildConfig {
|
||||||
|
public final static boolean DEBUG = Boolean.parseBoolean(null);
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
/*___Generated_by_IDEA___*/
|
||||||
|
|
||||||
|
package io.swagger.client;
|
||||||
|
|
||||||
|
/* This stub is only used by the IDE. It is NOT the Manifest class actually packed into the APK */
|
||||||
|
public final class Manifest {
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
/*___Generated_by_IDEA___*/
|
||||||
|
|
||||||
|
package io.swagger.client;
|
||||||
|
|
||||||
|
/* This stub is only used by the IDE. It is NOT the R class actually packed into the APK */
|
||||||
|
public final class R {
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
/*___Generated_by_IDEA___*/
|
||||||
|
|
||||||
|
package io.swagger.client;
|
||||||
|
|
||||||
|
/* This stub is only used by the IDE. It is NOT the BuildConfig class actually packed into the APK */
|
||||||
|
public final class BuildConfig {
|
||||||
|
public final static boolean DEBUG = Boolean.parseBoolean(null);
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
/*___Generated_by_IDEA___*/
|
||||||
|
|
||||||
|
package io.swagger.client;
|
||||||
|
|
||||||
|
/* This stub is only used by the IDE. It is NOT the Manifest class actually packed into the APK */
|
||||||
|
public final class Manifest {
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
/*___Generated_by_IDEA___*/
|
||||||
|
|
||||||
|
package io.swagger.client;
|
||||||
|
|
||||||
|
/* This stub is only used by the IDE. It is NOT the R class actually packed into the APK */
|
||||||
|
public final class R {
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
/*___Generated_by_IDEA___*/
|
||||||
|
|
||||||
|
package io.swagger.client;
|
||||||
|
|
||||||
|
/* This stub is only used by the IDE. It is NOT the BuildConfig class actually packed into the APK */
|
||||||
|
public final class BuildConfig {
|
||||||
|
public final static boolean DEBUG = Boolean.parseBoolean(null);
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
/*___Generated_by_IDEA___*/
|
||||||
|
|
||||||
|
package io.swagger.client;
|
||||||
|
|
||||||
|
/* This stub is only used by the IDE. It is NOT the Manifest class actually packed into the APK */
|
||||||
|
public final class Manifest {
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
/*___Generated_by_IDEA___*/
|
||||||
|
|
||||||
|
package io.swagger.client;
|
||||||
|
|
||||||
|
/* This stub is only used by the IDE. It is NOT the R class actually packed into the APK */
|
||||||
|
public final class R {
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
/*___Generated_by_IDEA___*/
|
||||||
|
|
||||||
|
package io.swagger.client;
|
||||||
|
|
||||||
|
/* This stub is only used by the IDE. It is NOT the BuildConfig class actually packed into the APK */
|
||||||
|
public final class BuildConfig {
|
||||||
|
public final static boolean DEBUG = Boolean.parseBoolean(null);
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
/*___Generated_by_IDEA___*/
|
||||||
|
|
||||||
|
package io.swagger.client;
|
||||||
|
|
||||||
|
/* This stub is only used by the IDE. It is NOT the Manifest class actually packed into the APK */
|
||||||
|
public final class Manifest {
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
/*___Generated_by_IDEA___*/
|
||||||
|
|
||||||
|
package io.swagger.client;
|
||||||
|
|
||||||
|
/* This stub is only used by the IDE. It is NOT the R class actually packed into the APK */
|
||||||
|
public final class R {
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
/*___Generated_by_IDEA___*/
|
||||||
|
|
||||||
|
package io.swagger.client;
|
||||||
|
|
||||||
|
/* This stub is only used by the IDE. It is NOT the BuildConfig class actually packed into the APK */
|
||||||
|
public final class BuildConfig {
|
||||||
|
public final static boolean DEBUG = Boolean.parseBoolean(null);
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
/*___Generated_by_IDEA___*/
|
||||||
|
|
||||||
|
package io.swagger.client;
|
||||||
|
|
||||||
|
/* This stub is only used by the IDE. It is NOT the Manifest class actually packed into the APK */
|
||||||
|
public final class Manifest {
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
/*___Generated_by_IDEA___*/
|
||||||
|
|
||||||
|
package io.swagger.client;
|
||||||
|
|
||||||
|
/* This stub is only used by the IDE. It is NOT the R class actually packed into the APK */
|
||||||
|
public final class R {
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
/*___Generated_by_IDEA___*/
|
||||||
|
|
||||||
|
package io.swagger.client;
|
||||||
|
|
||||||
|
/* This stub is only used by the IDE. It is NOT the BuildConfig class actually packed into the APK */
|
||||||
|
public final class BuildConfig {
|
||||||
|
public final static boolean DEBUG = Boolean.parseBoolean(null);
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
/*___Generated_by_IDEA___*/
|
||||||
|
|
||||||
|
package io.swagger.client;
|
||||||
|
|
||||||
|
/* This stub is only used by the IDE. It is NOT the Manifest class actually packed into the APK */
|
||||||
|
public final class Manifest {
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
/*___Generated_by_IDEA___*/
|
||||||
|
|
||||||
|
package io.swagger.client;
|
||||||
|
|
||||||
|
/* This stub is only used by the IDE. It is NOT the R class actually packed into the APK */
|
||||||
|
public final class R {
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
/*___Generated_by_IDEA___*/
|
||||||
|
|
||||||
|
package io.swagger.client;
|
||||||
|
|
||||||
|
/* This stub is only used by the IDE. It is NOT the BuildConfig class actually packed into the APK */
|
||||||
|
public final class BuildConfig {
|
||||||
|
public final static boolean DEBUG = Boolean.parseBoolean(null);
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
/*___Generated_by_IDEA___*/
|
||||||
|
|
||||||
|
package io.swagger.client;
|
||||||
|
|
||||||
|
/* This stub is only used by the IDE. It is NOT the Manifest class actually packed into the APK */
|
||||||
|
public final class Manifest {
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
/*___Generated_by_IDEA___*/
|
||||||
|
|
||||||
|
package io.swagger.client;
|
||||||
|
|
||||||
|
/* This stub is only used by the IDE. It is NOT the R class actually packed into the APK */
|
||||||
|
public final class R {
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
/*___Generated_by_IDEA___*/
|
||||||
|
|
||||||
|
package io.swagger.client;
|
||||||
|
|
||||||
|
/* This stub is only used by the IDE. It is NOT the BuildConfig class actually packed into the APK */
|
||||||
|
public final class BuildConfig {
|
||||||
|
public final static boolean DEBUG = Boolean.parseBoolean(null);
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
/*___Generated_by_IDEA___*/
|
||||||
|
|
||||||
|
package io.swagger.client;
|
||||||
|
|
||||||
|
/* This stub is only used by the IDE. It is NOT the Manifest class actually packed into the APK */
|
||||||
|
public final class Manifest {
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
/*___Generated_by_IDEA___*/
|
||||||
|
|
||||||
|
package io.swagger.client;
|
||||||
|
|
||||||
|
/* This stub is only used by the IDE. It is NOT the R class actually packed into the APK */
|
||||||
|
public final class R {
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
/*___Generated_by_IDEA___*/
|
||||||
|
|
||||||
|
package io.swagger.client;
|
||||||
|
|
||||||
|
/* This stub is only used by the IDE. It is NOT the BuildConfig class actually packed into the APK */
|
||||||
|
public final class BuildConfig {
|
||||||
|
public final static boolean DEBUG = Boolean.parseBoolean(null);
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
/*___Generated_by_IDEA___*/
|
||||||
|
|
||||||
|
package io.swagger.client;
|
||||||
|
|
||||||
|
/* This stub is only used by the IDE. It is NOT the Manifest class actually packed into the APK */
|
||||||
|
public final class Manifest {
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
/*___Generated_by_IDEA___*/
|
||||||
|
|
||||||
|
package io.swagger.client;
|
||||||
|
|
||||||
|
/* This stub is only used by the IDE. It is NOT the R class actually packed into the APK */
|
||||||
|
public final class R {
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
/*___Generated_by_IDEA___*/
|
||||||
|
|
||||||
|
package io.swagger.client;
|
||||||
|
|
||||||
|
/* This stub is only used by the IDE. It is NOT the BuildConfig class actually packed into the APK */
|
||||||
|
public final class BuildConfig {
|
||||||
|
public final static boolean DEBUG = Boolean.parseBoolean(null);
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
/*___Generated_by_IDEA___*/
|
||||||
|
|
||||||
|
package io.swagger.client;
|
||||||
|
|
||||||
|
/* This stub is only used by the IDE. It is NOT the Manifest class actually packed into the APK */
|
||||||
|
public final class Manifest {
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
/*___Generated_by_IDEA___*/
|
||||||
|
|
||||||
|
package io.swagger.client;
|
||||||
|
|
||||||
|
/* This stub is only used by the IDE. It is NOT the R class actually packed into the APK */
|
||||||
|
public final class R {
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
/*___Generated_by_IDEA___*/
|
||||||
|
|
||||||
|
package io.swagger.client;
|
||||||
|
|
||||||
|
/* This stub is only used by the IDE. It is NOT the BuildConfig class actually packed into the APK */
|
||||||
|
public final class BuildConfig {
|
||||||
|
public final static boolean DEBUG = Boolean.parseBoolean(null);
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
/*___Generated_by_IDEA___*/
|
||||||
|
|
||||||
|
package io.swagger.client;
|
||||||
|
|
||||||
|
/* This stub is only used by the IDE. It is NOT the Manifest class actually packed into the APK */
|
||||||
|
public final class Manifest {
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
/*___Generated_by_IDEA___*/
|
||||||
|
|
||||||
|
package io.swagger.client;
|
||||||
|
|
||||||
|
/* This stub is only used by the IDE. It is NOT the R class actually packed into the APK */
|
||||||
|
public final class R {
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
# Swagger Codegen Ignore
|
||||||
|
# Generated by swagger-codegen https://github.com/swagger-api/swagger-codegen
|
||||||
|
|
||||||
|
# Use this file to prevent files from being overwritten by the generator.
|
||||||
|
# The patterns follow closely to .gitignore or .dockerignore.
|
||||||
|
|
||||||
|
# As an example, the C# client generator defines ApiClient.cs.
|
||||||
|
# You can make changes and tell Swagger Codgen to ignore just this file by uncommenting the following line:
|
||||||
|
#ApiClient.cs
|
||||||
|
|
||||||
|
# You can match any string of characters against a directory, file or extension with a single asterisk (*):
|
||||||
|
#foo/*/qux
|
||||||
|
# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux
|
||||||
|
|
||||||
|
# You can recursively match patterns against a directory, file or extension with a double asterisk (**):
|
||||||
|
#foo/**/qux
|
||||||
|
# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux
|
||||||
|
|
||||||
|
# You can also negate patterns with an exclamation (!).
|
||||||
|
# For example, you can ignore all files in a docs folder with the file extension .md:
|
||||||
|
#docs/*.md
|
||||||
|
# Then explicitly reverse the ignore rule for a single file:
|
||||||
|
#!docs/README.md
|
@ -0,0 +1 @@
|
|||||||
|
2.3.0-SNAPSHOT
|
29
samples/client/petstore/scala-gatling/build.gradle
Normal file
29
samples/client/petstore/scala-gatling/build.gradle
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
plugins {
|
||||||
|
id 'com.github.lkishalmi.gatling' version '0.4.1'
|
||||||
|
}
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
apply plugin: "com.github.lkishalmi.gatling"
|
||||||
|
|
||||||
|
gatling {
|
||||||
|
toolVersion = '2.3.0'
|
||||||
|
jvmArgs = ['-server', '-XX:+UseThreadPriorities',
|
||||||
|
'-XX:ThreadPriorityPolicy=42',
|
||||||
|
'-Xms2048M', '-Xmx2048M', '-Xmn500M',
|
||||||
|
'-XX:+HeapDumpOnOutOfMemoryError',
|
||||||
|
'-XX:+AggressiveOpts',
|
||||||
|
'-XX:+OptimizeStringConcat',
|
||||||
|
'-XX:+UseFastAccessorMethods',
|
||||||
|
'-XX:+UseParNewGC',
|
||||||
|
'-XX:+UseConcMarkSweepGC',
|
||||||
|
'-XX:+CMSParallelRemarkEnabled',
|
||||||
|
'-Djava.net.preferIPv4Stack=true',
|
||||||
|
'-Djava.net.preferIPv6Addresses=false']
|
||||||
|
}
|
@ -0,0 +1,62 @@
|
|||||||
|
performance {
|
||||||
|
authorizationHeader = "~MANUAL_ENTRY~"
|
||||||
|
rampUpSeconds = 60
|
||||||
|
rampDownSeconds = 60
|
||||||
|
durationSeconds = 360
|
||||||
|
contentType = "application/json"
|
||||||
|
acceptType = "application/json"
|
||||||
|
rateMultiplier = 1
|
||||||
|
instanceMultiplier = 1
|
||||||
|
operationsPerSecond {
|
||||||
|
addPet = 1
|
||||||
|
deletePet = 1
|
||||||
|
findPetsByStatus = 1
|
||||||
|
findPetsByTags = 1
|
||||||
|
getPetById = 1
|
||||||
|
updatePet = 1
|
||||||
|
updatePetWithForm = 1
|
||||||
|
uploadFile = 1
|
||||||
|
deleteOrder = 1
|
||||||
|
getInventory = 1
|
||||||
|
getOrderById = 1
|
||||||
|
placeOrder = 1
|
||||||
|
createUser = 1
|
||||||
|
createUsersWithArrayInput = 1
|
||||||
|
createUsersWithListInput = 1
|
||||||
|
deleteUser = 1
|
||||||
|
getUserByName = 1
|
||||||
|
loginUser = 1
|
||||||
|
logoutUser = 1
|
||||||
|
updateUser = 1
|
||||||
|
}
|
||||||
|
global {
|
||||||
|
assertions {
|
||||||
|
responseTime {
|
||||||
|
min {
|
||||||
|
lte = 30000
|
||||||
|
gte = 0
|
||||||
|
}
|
||||||
|
max {
|
||||||
|
lte = 30000
|
||||||
|
gte = 0
|
||||||
|
}
|
||||||
|
mean {
|
||||||
|
lte = 30000
|
||||||
|
gte = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
failedRequests {
|
||||||
|
percent {
|
||||||
|
lte = 5
|
||||||
|
gte = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
successfulRequests {
|
||||||
|
percent {
|
||||||
|
lte = 100
|
||||||
|
gte = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,62 @@
|
|||||||
|
performance {
|
||||||
|
authorizationHeader = "~MANUAL_ENTRY~"
|
||||||
|
rampUpSeconds = 60
|
||||||
|
rampDownSeconds = 60
|
||||||
|
durationSeconds = 360
|
||||||
|
contentType = "application/json"
|
||||||
|
acceptType = "application/json"
|
||||||
|
rateMultiplier = 1
|
||||||
|
instanceMultiplier = 1
|
||||||
|
operationsPerSecond {
|
||||||
|
addPet = 1
|
||||||
|
deletePet = 1
|
||||||
|
findPetsByStatus = 1
|
||||||
|
findPetsByTags = 1
|
||||||
|
getPetById = 1
|
||||||
|
updatePet = 1
|
||||||
|
updatePetWithForm = 1
|
||||||
|
uploadFile = 1
|
||||||
|
deleteOrder = 1
|
||||||
|
getInventory = 1
|
||||||
|
getOrderById = 1
|
||||||
|
placeOrder = 1
|
||||||
|
createUser = 1
|
||||||
|
createUsersWithArrayInput = 1
|
||||||
|
createUsersWithListInput = 1
|
||||||
|
deleteUser = 1
|
||||||
|
getUserByName = 1
|
||||||
|
loginUser = 1
|
||||||
|
logoutUser = 1
|
||||||
|
updateUser = 1
|
||||||
|
}
|
||||||
|
global {
|
||||||
|
assertions {
|
||||||
|
responseTime {
|
||||||
|
min {
|
||||||
|
lte = 30000
|
||||||
|
gte = 0
|
||||||
|
}
|
||||||
|
max {
|
||||||
|
lte = 30000
|
||||||
|
gte = 0
|
||||||
|
}
|
||||||
|
mean {
|
||||||
|
lte = 30000
|
||||||
|
gte = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
failedRequests {
|
||||||
|
percent {
|
||||||
|
lte = 5
|
||||||
|
gte = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
successfulRequests {
|
||||||
|
percent {
|
||||||
|
lte = 100
|
||||||
|
gte = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,62 @@
|
|||||||
|
performance {
|
||||||
|
authorizationHeader = "~MANUAL_ENTRY~"
|
||||||
|
rampUpSeconds = 60
|
||||||
|
rampDownSeconds = 60
|
||||||
|
durationSeconds = 360
|
||||||
|
contentType = "application/json"
|
||||||
|
acceptType = "application/json"
|
||||||
|
rateMultiplier = 1
|
||||||
|
instanceMultiplier = 1
|
||||||
|
operationsPerSecond {
|
||||||
|
addPet = 1
|
||||||
|
deletePet = 1
|
||||||
|
findPetsByStatus = 1
|
||||||
|
findPetsByTags = 1
|
||||||
|
getPetById = 1
|
||||||
|
updatePet = 1
|
||||||
|
updatePetWithForm = 1
|
||||||
|
uploadFile = 1
|
||||||
|
deleteOrder = 1
|
||||||
|
getInventory = 1
|
||||||
|
getOrderById = 1
|
||||||
|
placeOrder = 1
|
||||||
|
createUser = 1
|
||||||
|
createUsersWithArrayInput = 1
|
||||||
|
createUsersWithListInput = 1
|
||||||
|
deleteUser = 1
|
||||||
|
getUserByName = 1
|
||||||
|
loginUser = 1
|
||||||
|
logoutUser = 1
|
||||||
|
updateUser = 1
|
||||||
|
}
|
||||||
|
global {
|
||||||
|
assertions {
|
||||||
|
responseTime {
|
||||||
|
min {
|
||||||
|
lte = 30000
|
||||||
|
gte = 0
|
||||||
|
}
|
||||||
|
max {
|
||||||
|
lte = 30000
|
||||||
|
gte = 0
|
||||||
|
}
|
||||||
|
mean {
|
||||||
|
lte = 30000
|
||||||
|
gte = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
failedRequests {
|
||||||
|
percent {
|
||||||
|
lte = 5
|
||||||
|
gte = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
successfulRequests {
|
||||||
|
percent {
|
||||||
|
lte = 100
|
||||||
|
gte = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,62 @@
|
|||||||
|
performance {
|
||||||
|
authorizationHeader = "~MANUAL_ENTRY~"
|
||||||
|
rampUpSeconds = 60
|
||||||
|
rampDownSeconds = 60
|
||||||
|
durationSeconds = 360
|
||||||
|
contentType = "application/json"
|
||||||
|
acceptType = "application/json"
|
||||||
|
rateMultiplier = 1
|
||||||
|
instanceMultiplier = 1
|
||||||
|
operationsPerSecond {
|
||||||
|
addPet = 1
|
||||||
|
deletePet = 1
|
||||||
|
findPetsByStatus = 1
|
||||||
|
findPetsByTags = 1
|
||||||
|
getPetById = 1
|
||||||
|
updatePet = 1
|
||||||
|
updatePetWithForm = 1
|
||||||
|
uploadFile = 1
|
||||||
|
deleteOrder = 1
|
||||||
|
getInventory = 1
|
||||||
|
getOrderById = 1
|
||||||
|
placeOrder = 1
|
||||||
|
createUser = 1
|
||||||
|
createUsersWithArrayInput = 1
|
||||||
|
createUsersWithListInput = 1
|
||||||
|
deleteUser = 1
|
||||||
|
getUserByName = 1
|
||||||
|
loginUser = 1
|
||||||
|
logoutUser = 1
|
||||||
|
updateUser = 1
|
||||||
|
}
|
||||||
|
global {
|
||||||
|
assertions {
|
||||||
|
responseTime {
|
||||||
|
min {
|
||||||
|
lte = 30000
|
||||||
|
gte = 0
|
||||||
|
}
|
||||||
|
max {
|
||||||
|
lte = 30000
|
||||||
|
gte = 0
|
||||||
|
}
|
||||||
|
mean {
|
||||||
|
lte = 30000
|
||||||
|
gte = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
failedRequests {
|
||||||
|
percent {
|
||||||
|
lte = 5
|
||||||
|
gte = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
successfulRequests {
|
||||||
|
percent {
|
||||||
|
lte = 100
|
||||||
|
gte = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<configuration>
|
||||||
|
|
||||||
|
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
|
||||||
|
<encoder>
|
||||||
|
<pattern>%d{HH:mm:ss.SSS} [%-5level] %logger{15} - %msg%n%rEx</pattern>
|
||||||
|
</encoder>
|
||||||
|
<immediateFlush>false</immediateFlush>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<!-- Uncomment for logging ALL HTTP request and responses -->
|
||||||
|
<!-- <logger name="io.gatling.http.ahc" level="TRACE" /> -->
|
||||||
|
<!-- <logger name="io.gatling.http.response" level="TRACE" /> -->
|
||||||
|
<!-- Uncomment for logging ONLY FAILED HTTP request and responses -->
|
||||||
|
<!-- <logger name="io.gatling.http.ahc" level="DEBUG" /> -->
|
||||||
|
<!-- <logger name="io.gatling.http.response" level="DEBUG" /> -->
|
||||||
|
|
||||||
|
<root level="WARN">
|
||||||
|
<appender-ref ref="CONSOLE" />
|
||||||
|
</root>
|
||||||
|
|
||||||
|
</configuration>
|
@ -0,0 +1,62 @@
|
|||||||
|
performance {
|
||||||
|
authorizationHeader = "~MANUAL_ENTRY~"
|
||||||
|
rampUpSeconds = 60
|
||||||
|
rampDownSeconds = 60
|
||||||
|
durationSeconds = 360
|
||||||
|
contentType = "application/json"
|
||||||
|
acceptType = "application/json"
|
||||||
|
rateMultiplier = 1
|
||||||
|
instanceMultiplier = 1
|
||||||
|
operationsPerSecond {
|
||||||
|
addPet = 1
|
||||||
|
deletePet = 1
|
||||||
|
findPetsByStatus = 1
|
||||||
|
findPetsByTags = 1
|
||||||
|
getPetById = 1
|
||||||
|
updatePet = 1
|
||||||
|
updatePetWithForm = 1
|
||||||
|
uploadFile = 1
|
||||||
|
deleteOrder = 1
|
||||||
|
getInventory = 1
|
||||||
|
getOrderById = 1
|
||||||
|
placeOrder = 1
|
||||||
|
createUser = 1
|
||||||
|
createUsersWithArrayInput = 1
|
||||||
|
createUsersWithListInput = 1
|
||||||
|
deleteUser = 1
|
||||||
|
getUserByName = 1
|
||||||
|
loginUser = 1
|
||||||
|
logoutUser = 1
|
||||||
|
updateUser = 1
|
||||||
|
}
|
||||||
|
global {
|
||||||
|
assertions {
|
||||||
|
responseTime {
|
||||||
|
min {
|
||||||
|
lte = 30000
|
||||||
|
gte = 0
|
||||||
|
}
|
||||||
|
max {
|
||||||
|
lte = 30000
|
||||||
|
gte = 0
|
||||||
|
}
|
||||||
|
mean {
|
||||||
|
lte = 30000
|
||||||
|
gte = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
failedRequests {
|
||||||
|
percent {
|
||||||
|
lte = 5
|
||||||
|
gte = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
successfulRequests {
|
||||||
|
percent {
|
||||||
|
lte = 100
|
||||||
|
gte = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,62 @@
|
|||||||
|
performance {
|
||||||
|
authorizationHeader = "~MANUAL_ENTRY~"
|
||||||
|
rampUpSeconds = 60
|
||||||
|
rampDownSeconds = 60
|
||||||
|
durationSeconds = 360
|
||||||
|
contentType = "application/json"
|
||||||
|
acceptType = "application/json"
|
||||||
|
rateMultiplier = 1
|
||||||
|
instanceMultiplier = 1
|
||||||
|
operationsPerSecond {
|
||||||
|
addPet = 1
|
||||||
|
deletePet = 1
|
||||||
|
findPetsByStatus = 1
|
||||||
|
findPetsByTags = 1
|
||||||
|
getPetById = 1
|
||||||
|
updatePet = 1
|
||||||
|
updatePetWithForm = 1
|
||||||
|
uploadFile = 1
|
||||||
|
deleteOrder = 1
|
||||||
|
getInventory = 1
|
||||||
|
getOrderById = 1
|
||||||
|
placeOrder = 1
|
||||||
|
createUser = 1
|
||||||
|
createUsersWithArrayInput = 1
|
||||||
|
createUsersWithListInput = 1
|
||||||
|
deleteUser = 1
|
||||||
|
getUserByName = 1
|
||||||
|
loginUser = 1
|
||||||
|
logoutUser = 1
|
||||||
|
updateUser = 1
|
||||||
|
}
|
||||||
|
global {
|
||||||
|
assertions {
|
||||||
|
responseTime {
|
||||||
|
min {
|
||||||
|
lte = 30000
|
||||||
|
gte = 0
|
||||||
|
}
|
||||||
|
max {
|
||||||
|
lte = 30000
|
||||||
|
gte = 0
|
||||||
|
}
|
||||||
|
mean {
|
||||||
|
lte = 30000
|
||||||
|
gte = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
failedRequests {
|
||||||
|
percent {
|
||||||
|
lte = 5
|
||||||
|
gte = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
successfulRequests {
|
||||||
|
percent {
|
||||||
|
lte = 100
|
||||||
|
gte = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1 @@
|
|||||||
|
photoUrls,name,id,category,tags,status
|
|
@ -0,0 +1 @@
|
|||||||
|
firstName,lastName,password,userStatus,phone,id,email,username
|
|
@ -0,0 +1 @@
|
|||||||
|
orderId
|
|
@ -0,0 +1 @@
|
|||||||
|
api_key
|
|
@ -0,0 +1 @@
|
|||||||
|
petId
|
|
@ -0,0 +1 @@
|
|||||||
|
username
|
|
@ -0,0 +1 @@
|
|||||||
|
status
|
|
@ -0,0 +1 @@
|
|||||||
|
tags
|
|
@ -0,0 +1 @@
|
|||||||
|
orderId
|
|
@ -0,0 +1 @@
|
|||||||
|
petId
|
|
@ -0,0 +1 @@
|
|||||||
|
username
|
|
@ -0,0 +1 @@
|
|||||||
|
username,password
|
|
@ -0,0 +1 @@
|
|||||||
|
petId,quantity,id,shipDate,complete,status
|
|
@ -0,0 +1 @@
|
|||||||
|
photoUrls,name,id,category,tags,status
|
|
@ -0,0 +1 @@
|
|||||||
|
name,status
|
|
@ -0,0 +1 @@
|
|||||||
|
petId
|
|
@ -0,0 +1 @@
|
|||||||
|
firstName,lastName,password,userStatus,phone,id,email,username
|
|
@ -0,0 +1 @@
|
|||||||
|
username
|
|
@ -0,0 +1 @@
|
|||||||
|
file,additionalMetadata
|
|
@ -0,0 +1 @@
|
|||||||
|
petId
|
|
@ -0,0 +1,223 @@
|
|||||||
|
package io.swagger.client.api
|
||||||
|
|
||||||
|
import io.swagger.client.model._
|
||||||
|
import com.typesafe.config.ConfigFactory
|
||||||
|
|
||||||
|
import io.gatling.core.Predef._
|
||||||
|
import io.gatling.http.Predef._
|
||||||
|
import io.gatling.core.structure.PopulationBuilder
|
||||||
|
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
import scala.collection.mutable
|
||||||
|
|
||||||
|
class PetApiSimulation extends Simulation {
|
||||||
|
|
||||||
|
def getCurrentDirectory = new File("").getAbsolutePath
|
||||||
|
def userDataDirectory = getCurrentDirectory + "/src/gatling/resources/data"
|
||||||
|
|
||||||
|
// basic test setup
|
||||||
|
val configName = System.getProperty("testConfig", "baseline")
|
||||||
|
val config = ConfigFactory.load(configName).withFallback(ConfigFactory.load("default"))
|
||||||
|
val durationSeconds = config.getInt("performance.durationSeconds")
|
||||||
|
val rampUpSeconds = config.getInt("performance.rampUpSeconds")
|
||||||
|
val rampDownSeconds = config.getInt("performance.rampDownSeconds")
|
||||||
|
val authentication = config.getString("performance.authorizationHeader")
|
||||||
|
val acceptHeader = config.getString("performance.acceptType")
|
||||||
|
val contentTypeHeader = config.getString("performance.contentType")
|
||||||
|
val rateMultiplier = config.getDouble("performance.rateMultiplier")
|
||||||
|
val instanceMultiplier = config.getDouble("performance.instanceMultiplier")
|
||||||
|
|
||||||
|
// global assertion data
|
||||||
|
val globalResponseTimeMinLTE = config.getInt("performance.global.assertions.responseTime.min.lte")
|
||||||
|
val globalResponseTimeMinGTE = config.getInt("performance.global.assertions.responseTime.min.gte")
|
||||||
|
val globalResponseTimeMaxLTE = config.getInt("performance.global.assertions.responseTime.max.lte")
|
||||||
|
val globalResponseTimeMaxGTE = config.getInt("performance.global.assertions.responseTime.max.gte")
|
||||||
|
val globalResponseTimeMeanLTE = config.getInt("performance.global.assertions.responseTime.mean.lte")
|
||||||
|
val globalResponseTimeMeanGTE = config.getInt("performance.global.assertions.responseTime.mean.gte")
|
||||||
|
val globalResponseTimeFailedRequestsPercentLTE = config.getDouble("performance.global.assertions.failedRequests.percent.lte")
|
||||||
|
val globalResponseTimeFailedRequestsPercentGTE = config.getDouble("performance.global.assertions.failedRequests.percent.gte")
|
||||||
|
val globalResponseTimeSuccessfulRequestsPercentLTE = config.getDouble("performance.global.assertions.successfulRequests.percent.lte")
|
||||||
|
val globalResponseTimeSuccessfulRequestsPercentGTE = config.getDouble("performance.global.assertions.successfulRequests.percent.gte")
|
||||||
|
|
||||||
|
// Setup http protocol configuration
|
||||||
|
val httpConf = http
|
||||||
|
.baseURL("http://petstore.swagger.io/v2")
|
||||||
|
.doNotTrackHeader("1")
|
||||||
|
.acceptLanguageHeader("en-US,en;q=0.5")
|
||||||
|
.acceptEncodingHeader("gzip, deflate")
|
||||||
|
.userAgentHeader("Mozilla/5.0 (Windows NT 5.1; rv:31.0) Gecko/20100101 Firefox/31.0")
|
||||||
|
.acceptHeader(acceptHeader)
|
||||||
|
.contentTypeHeader(contentTypeHeader)
|
||||||
|
|
||||||
|
// set authorization header if it has been modified from config
|
||||||
|
if(!authentication.equals("~MANUAL_ENTRY")){
|
||||||
|
httpConf.authorizationHeader(authentication)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setup all the operations per second for the test to ultimately be generated from configs
|
||||||
|
val addPetPerSecond = config.getDouble("performance.operationsPerSecond.addPet") * rateMultiplier * instanceMultiplier
|
||||||
|
val deletePetPerSecond = config.getDouble("performance.operationsPerSecond.deletePet") * rateMultiplier * instanceMultiplier
|
||||||
|
val findPetsByStatusPerSecond = config.getDouble("performance.operationsPerSecond.findPetsByStatus") * rateMultiplier * instanceMultiplier
|
||||||
|
val findPetsByTagsPerSecond = config.getDouble("performance.operationsPerSecond.findPetsByTags") * rateMultiplier * instanceMultiplier
|
||||||
|
val getPetByIdPerSecond = config.getDouble("performance.operationsPerSecond.getPetById") * rateMultiplier * instanceMultiplier
|
||||||
|
val updatePetPerSecond = config.getDouble("performance.operationsPerSecond.updatePet") * rateMultiplier * instanceMultiplier
|
||||||
|
val updatePetWithFormPerSecond = config.getDouble("performance.operationsPerSecond.updatePetWithForm") * rateMultiplier * instanceMultiplier
|
||||||
|
val uploadFilePerSecond = config.getDouble("performance.operationsPerSecond.uploadFile") * rateMultiplier * instanceMultiplier
|
||||||
|
|
||||||
|
val scenarioBuilders: mutable.MutableList[PopulationBuilder] = new mutable.MutableList[PopulationBuilder]()
|
||||||
|
|
||||||
|
// Set up CSV feeders
|
||||||
|
val addPetBodyFeeder = csv(userDataDirectory + File.separator + "addPet-bodyParams.csv", escapeChar = '\\').random
|
||||||
|
val deletePetHEADERFeeder = csv(userDataDirectory + File.separator + "deletePet-headerParams.csv").random
|
||||||
|
val deletePetPATHFeeder = csv(userDataDirectory + File.separator + "deletePet-pathParams.csv").random
|
||||||
|
val findPetsByStatusQUERYFeeder = csv(userDataDirectory + File.separator + "findPetsByStatus-queryParams.csv").random
|
||||||
|
val findPetsByTagsQUERYFeeder = csv(userDataDirectory + File.separator + "findPetsByTags-queryParams.csv").random
|
||||||
|
val getPetByIdPATHFeeder = csv(userDataDirectory + File.separator + "getPetById-pathParams.csv").random
|
||||||
|
val updatePetBodyFeeder = csv(userDataDirectory + File.separator + "updatePet-bodyParams.csv", escapeChar = '\\').random
|
||||||
|
val updatePetWithFormFORMFeeder = csv(userDataDirectory + File.separator + "updatePetWithForm-formParams.csv").random
|
||||||
|
val updatePetWithFormPATHFeeder = csv(userDataDirectory + File.separator + "updatePetWithForm-pathParams.csv").random
|
||||||
|
val uploadFileFORMFeeder = csv(userDataDirectory + File.separator + "uploadFile-formParams.csv").random
|
||||||
|
val uploadFilePATHFeeder = csv(userDataDirectory + File.separator + "uploadFile-pathParams.csv").random
|
||||||
|
|
||||||
|
// Setup all scenarios
|
||||||
|
|
||||||
|
|
||||||
|
val scnaddPet = scenario("addPetSimulation")
|
||||||
|
.feed(addPetBodyFeeder)
|
||||||
|
.exec(http("addPet")
|
||||||
|
.httpRequest("POST","/pet")
|
||||||
|
.body(StringBody(Pet.toStringBody("${id}","${category}","${name}","${tags}","${status}","${photoUrls}")))
|
||||||
|
)
|
||||||
|
|
||||||
|
// Run scnaddPet with warm up and reach a constant rate for entire duration
|
||||||
|
scenarioBuilders += scnaddPet.inject(
|
||||||
|
rampUsersPerSec(1) to(addPetPerSecond) during(rampUpSeconds),
|
||||||
|
constantUsersPerSec(addPetPerSecond) during(durationSeconds),
|
||||||
|
rampUsersPerSec(addPetPerSecond) to(1) during(rampDownSeconds)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
val scndeletePet = scenario("deletePetSimulation")
|
||||||
|
.feed(deletePetHEADERFeeder)
|
||||||
|
.feed(deletePetPATHFeeder)
|
||||||
|
.exec(http("deletePet")
|
||||||
|
.httpRequest("DELETE","/pet/${petId}")
|
||||||
|
.header("api_key","${api_key}")
|
||||||
|
)
|
||||||
|
|
||||||
|
// Run scndeletePet with warm up and reach a constant rate for entire duration
|
||||||
|
scenarioBuilders += scndeletePet.inject(
|
||||||
|
rampUsersPerSec(1) to(deletePetPerSecond) during(rampUpSeconds),
|
||||||
|
constantUsersPerSec(deletePetPerSecond) during(durationSeconds),
|
||||||
|
rampUsersPerSec(deletePetPerSecond) to(1) during(rampDownSeconds)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
val scnfindPetsByStatus = scenario("findPetsByStatusSimulation")
|
||||||
|
.feed(findPetsByStatusQUERYFeeder)
|
||||||
|
.exec(http("findPetsByStatus")
|
||||||
|
.httpRequest("GET","/pet/findByStatus")
|
||||||
|
.queryParam("status","${status}")
|
||||||
|
)
|
||||||
|
|
||||||
|
// Run scnfindPetsByStatus with warm up and reach a constant rate for entire duration
|
||||||
|
scenarioBuilders += scnfindPetsByStatus.inject(
|
||||||
|
rampUsersPerSec(1) to(findPetsByStatusPerSecond) during(rampUpSeconds),
|
||||||
|
constantUsersPerSec(findPetsByStatusPerSecond) during(durationSeconds),
|
||||||
|
rampUsersPerSec(findPetsByStatusPerSecond) to(1) during(rampDownSeconds)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
val scnfindPetsByTags = scenario("findPetsByTagsSimulation")
|
||||||
|
.feed(findPetsByTagsQUERYFeeder)
|
||||||
|
.exec(http("findPetsByTags")
|
||||||
|
.httpRequest("GET","/pet/findByTags")
|
||||||
|
.queryParam("tags","${tags}")
|
||||||
|
)
|
||||||
|
|
||||||
|
// Run scnfindPetsByTags with warm up and reach a constant rate for entire duration
|
||||||
|
scenarioBuilders += scnfindPetsByTags.inject(
|
||||||
|
rampUsersPerSec(1) to(findPetsByTagsPerSecond) during(rampUpSeconds),
|
||||||
|
constantUsersPerSec(findPetsByTagsPerSecond) during(durationSeconds),
|
||||||
|
rampUsersPerSec(findPetsByTagsPerSecond) to(1) during(rampDownSeconds)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
val scngetPetById = scenario("getPetByIdSimulation")
|
||||||
|
.feed(getPetByIdPATHFeeder)
|
||||||
|
.exec(http("getPetById")
|
||||||
|
.httpRequest("GET","/pet/${petId}")
|
||||||
|
)
|
||||||
|
|
||||||
|
// Run scngetPetById with warm up and reach a constant rate for entire duration
|
||||||
|
scenarioBuilders += scngetPetById.inject(
|
||||||
|
rampUsersPerSec(1) to(getPetByIdPerSecond) during(rampUpSeconds),
|
||||||
|
constantUsersPerSec(getPetByIdPerSecond) during(durationSeconds),
|
||||||
|
rampUsersPerSec(getPetByIdPerSecond) to(1) during(rampDownSeconds)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
val scnupdatePet = scenario("updatePetSimulation")
|
||||||
|
.feed(updatePetBodyFeeder)
|
||||||
|
.exec(http("updatePet")
|
||||||
|
.httpRequest("PUT","/pet")
|
||||||
|
.body(StringBody(Pet.toStringBody("${id}","${category}","${name}","${tags}","${status}","${photoUrls}")))
|
||||||
|
)
|
||||||
|
|
||||||
|
// Run scnupdatePet with warm up and reach a constant rate for entire duration
|
||||||
|
scenarioBuilders += scnupdatePet.inject(
|
||||||
|
rampUsersPerSec(1) to(updatePetPerSecond) during(rampUpSeconds),
|
||||||
|
constantUsersPerSec(updatePetPerSecond) during(durationSeconds),
|
||||||
|
rampUsersPerSec(updatePetPerSecond) to(1) during(rampDownSeconds)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
val scnupdatePetWithForm = scenario("updatePetWithFormSimulation")
|
||||||
|
.feed(updatePetWithFormFORMFeeder)
|
||||||
|
.feed(updatePetWithFormPATHFeeder)
|
||||||
|
.exec(http("updatePetWithForm")
|
||||||
|
.httpRequest("POST","/pet/${petId}")
|
||||||
|
.formParam("name","${name}")
|
||||||
|
.formParam("status","${status}")
|
||||||
|
)
|
||||||
|
|
||||||
|
// Run scnupdatePetWithForm with warm up and reach a constant rate for entire duration
|
||||||
|
scenarioBuilders += scnupdatePetWithForm.inject(
|
||||||
|
rampUsersPerSec(1) to(updatePetWithFormPerSecond) during(rampUpSeconds),
|
||||||
|
constantUsersPerSec(updatePetWithFormPerSecond) during(durationSeconds),
|
||||||
|
rampUsersPerSec(updatePetWithFormPerSecond) to(1) during(rampDownSeconds)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
val scnuploadFile = scenario("uploadFileSimulation")
|
||||||
|
.feed(uploadFileFORMFeeder)
|
||||||
|
.feed(uploadFilePATHFeeder)
|
||||||
|
.exec(http("uploadFile")
|
||||||
|
.httpRequest("POST","/pet/${petId}/uploadImage")
|
||||||
|
.formParam("file","${file}")
|
||||||
|
.formParam("additionalMetadata","${additionalMetadata}")
|
||||||
|
)
|
||||||
|
|
||||||
|
// Run scnuploadFile with warm up and reach a constant rate for entire duration
|
||||||
|
scenarioBuilders += scnuploadFile.inject(
|
||||||
|
rampUsersPerSec(1) to(uploadFilePerSecond) during(rampUpSeconds),
|
||||||
|
constantUsersPerSec(uploadFilePerSecond) during(durationSeconds),
|
||||||
|
rampUsersPerSec(uploadFilePerSecond) to(1) during(rampDownSeconds)
|
||||||
|
)
|
||||||
|
|
||||||
|
setUp(
|
||||||
|
scenarioBuilders.toList
|
||||||
|
).protocols(httpConf).assertions(
|
||||||
|
global.responseTime.min.lte(globalResponseTimeMinLTE),
|
||||||
|
global.responseTime.min.gte(globalResponseTimeMinGTE),
|
||||||
|
global.responseTime.max.lte(globalResponseTimeMaxLTE),
|
||||||
|
global.responseTime.max.gte(globalResponseTimeMaxGTE),
|
||||||
|
global.responseTime.mean.lte(globalResponseTimeMeanLTE),
|
||||||
|
global.responseTime.mean.gte(globalResponseTimeMeanGTE),
|
||||||
|
global.failedRequests.percent.lte(globalResponseTimeFailedRequestsPercentLTE),
|
||||||
|
global.failedRequests.percent.gte(globalResponseTimeFailedRequestsPercentGTE),
|
||||||
|
global.successfulRequests.percent.lte(globalResponseTimeSuccessfulRequestsPercentLTE),
|
||||||
|
global.successfulRequests.percent.gte(globalResponseTimeSuccessfulRequestsPercentGTE)
|
||||||
|
)
|
||||||
|
}
|
@ -0,0 +1,143 @@
|
|||||||
|
package io.swagger.client.api
|
||||||
|
|
||||||
|
import io.swagger.client.model._
|
||||||
|
import com.typesafe.config.ConfigFactory
|
||||||
|
|
||||||
|
import io.gatling.core.Predef._
|
||||||
|
import io.gatling.http.Predef._
|
||||||
|
import io.gatling.core.structure.PopulationBuilder
|
||||||
|
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
import scala.collection.mutable
|
||||||
|
|
||||||
|
class StoreApiSimulation extends Simulation {
|
||||||
|
|
||||||
|
def getCurrentDirectory = new File("").getAbsolutePath
|
||||||
|
def userDataDirectory = getCurrentDirectory + "/src/gatling/resources/data"
|
||||||
|
|
||||||
|
// basic test setup
|
||||||
|
val configName = System.getProperty("testConfig", "baseline")
|
||||||
|
val config = ConfigFactory.load(configName).withFallback(ConfigFactory.load("default"))
|
||||||
|
val durationSeconds = config.getInt("performance.durationSeconds")
|
||||||
|
val rampUpSeconds = config.getInt("performance.rampUpSeconds")
|
||||||
|
val rampDownSeconds = config.getInt("performance.rampDownSeconds")
|
||||||
|
val authentication = config.getString("performance.authorizationHeader")
|
||||||
|
val acceptHeader = config.getString("performance.acceptType")
|
||||||
|
val contentTypeHeader = config.getString("performance.contentType")
|
||||||
|
val rateMultiplier = config.getDouble("performance.rateMultiplier")
|
||||||
|
val instanceMultiplier = config.getDouble("performance.instanceMultiplier")
|
||||||
|
|
||||||
|
// global assertion data
|
||||||
|
val globalResponseTimeMinLTE = config.getInt("performance.global.assertions.responseTime.min.lte")
|
||||||
|
val globalResponseTimeMinGTE = config.getInt("performance.global.assertions.responseTime.min.gte")
|
||||||
|
val globalResponseTimeMaxLTE = config.getInt("performance.global.assertions.responseTime.max.lte")
|
||||||
|
val globalResponseTimeMaxGTE = config.getInt("performance.global.assertions.responseTime.max.gte")
|
||||||
|
val globalResponseTimeMeanLTE = config.getInt("performance.global.assertions.responseTime.mean.lte")
|
||||||
|
val globalResponseTimeMeanGTE = config.getInt("performance.global.assertions.responseTime.mean.gte")
|
||||||
|
val globalResponseTimeFailedRequestsPercentLTE = config.getDouble("performance.global.assertions.failedRequests.percent.lte")
|
||||||
|
val globalResponseTimeFailedRequestsPercentGTE = config.getDouble("performance.global.assertions.failedRequests.percent.gte")
|
||||||
|
val globalResponseTimeSuccessfulRequestsPercentLTE = config.getDouble("performance.global.assertions.successfulRequests.percent.lte")
|
||||||
|
val globalResponseTimeSuccessfulRequestsPercentGTE = config.getDouble("performance.global.assertions.successfulRequests.percent.gte")
|
||||||
|
|
||||||
|
// Setup http protocol configuration
|
||||||
|
val httpConf = http
|
||||||
|
.baseURL("http://petstore.swagger.io/v2")
|
||||||
|
.doNotTrackHeader("1")
|
||||||
|
.acceptLanguageHeader("en-US,en;q=0.5")
|
||||||
|
.acceptEncodingHeader("gzip, deflate")
|
||||||
|
.userAgentHeader("Mozilla/5.0 (Windows NT 5.1; rv:31.0) Gecko/20100101 Firefox/31.0")
|
||||||
|
.acceptHeader(acceptHeader)
|
||||||
|
.contentTypeHeader(contentTypeHeader)
|
||||||
|
|
||||||
|
// set authorization header if it has been modified from config
|
||||||
|
if(!authentication.equals("~MANUAL_ENTRY")){
|
||||||
|
httpConf.authorizationHeader(authentication)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setup all the operations per second for the test to ultimately be generated from configs
|
||||||
|
val deleteOrderPerSecond = config.getDouble("performance.operationsPerSecond.deleteOrder") * rateMultiplier * instanceMultiplier
|
||||||
|
val getInventoryPerSecond = config.getDouble("performance.operationsPerSecond.getInventory") * rateMultiplier * instanceMultiplier
|
||||||
|
val getOrderByIdPerSecond = config.getDouble("performance.operationsPerSecond.getOrderById") * rateMultiplier * instanceMultiplier
|
||||||
|
val placeOrderPerSecond = config.getDouble("performance.operationsPerSecond.placeOrder") * rateMultiplier * instanceMultiplier
|
||||||
|
|
||||||
|
val scenarioBuilders: mutable.MutableList[PopulationBuilder] = new mutable.MutableList[PopulationBuilder]()
|
||||||
|
|
||||||
|
// Set up CSV feeders
|
||||||
|
val deleteOrderPATHFeeder = csv(userDataDirectory + File.separator + "deleteOrder-pathParams.csv").random
|
||||||
|
val getOrderByIdPATHFeeder = csv(userDataDirectory + File.separator + "getOrderById-pathParams.csv").random
|
||||||
|
val placeOrderBodyFeeder = csv(userDataDirectory + File.separator + "placeOrder-bodyParams.csv", escapeChar = '\\').random
|
||||||
|
|
||||||
|
// Setup all scenarios
|
||||||
|
|
||||||
|
|
||||||
|
val scndeleteOrder = scenario("deleteOrderSimulation")
|
||||||
|
.feed(deleteOrderPATHFeeder)
|
||||||
|
.exec(http("deleteOrder")
|
||||||
|
.httpRequest("DELETE","/store/order/${orderId}")
|
||||||
|
)
|
||||||
|
|
||||||
|
// Run scndeleteOrder with warm up and reach a constant rate for entire duration
|
||||||
|
scenarioBuilders += scndeleteOrder.inject(
|
||||||
|
rampUsersPerSec(1) to(deleteOrderPerSecond) during(rampUpSeconds),
|
||||||
|
constantUsersPerSec(deleteOrderPerSecond) during(durationSeconds),
|
||||||
|
rampUsersPerSec(deleteOrderPerSecond) to(1) during(rampDownSeconds)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
val scngetInventory = scenario("getInventorySimulation")
|
||||||
|
.exec(http("getInventory")
|
||||||
|
.httpRequest("GET","/store/inventory")
|
||||||
|
)
|
||||||
|
|
||||||
|
// Run scngetInventory with warm up and reach a constant rate for entire duration
|
||||||
|
scenarioBuilders += scngetInventory.inject(
|
||||||
|
rampUsersPerSec(1) to(getInventoryPerSecond) during(rampUpSeconds),
|
||||||
|
constantUsersPerSec(getInventoryPerSecond) during(durationSeconds),
|
||||||
|
rampUsersPerSec(getInventoryPerSecond) to(1) during(rampDownSeconds)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
val scngetOrderById = scenario("getOrderByIdSimulation")
|
||||||
|
.feed(getOrderByIdPATHFeeder)
|
||||||
|
.exec(http("getOrderById")
|
||||||
|
.httpRequest("GET","/store/order/${orderId}")
|
||||||
|
)
|
||||||
|
|
||||||
|
// Run scngetOrderById with warm up and reach a constant rate for entire duration
|
||||||
|
scenarioBuilders += scngetOrderById.inject(
|
||||||
|
rampUsersPerSec(1) to(getOrderByIdPerSecond) during(rampUpSeconds),
|
||||||
|
constantUsersPerSec(getOrderByIdPerSecond) during(durationSeconds),
|
||||||
|
rampUsersPerSec(getOrderByIdPerSecond) to(1) during(rampDownSeconds)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
val scnplaceOrder = scenario("placeOrderSimulation")
|
||||||
|
.feed(placeOrderBodyFeeder)
|
||||||
|
.exec(http("placeOrder")
|
||||||
|
.httpRequest("POST","/store/order")
|
||||||
|
.body(StringBody(Order.toStringBody("${id}","${shipDate}","${complete}","${quantity}","${status}","${petId}")))
|
||||||
|
)
|
||||||
|
|
||||||
|
// Run scnplaceOrder with warm up and reach a constant rate for entire duration
|
||||||
|
scenarioBuilders += scnplaceOrder.inject(
|
||||||
|
rampUsersPerSec(1) to(placeOrderPerSecond) during(rampUpSeconds),
|
||||||
|
constantUsersPerSec(placeOrderPerSecond) during(durationSeconds),
|
||||||
|
rampUsersPerSec(placeOrderPerSecond) to(1) during(rampDownSeconds)
|
||||||
|
)
|
||||||
|
|
||||||
|
setUp(
|
||||||
|
scenarioBuilders.toList
|
||||||
|
).protocols(httpConf).assertions(
|
||||||
|
global.responseTime.min.lte(globalResponseTimeMinLTE),
|
||||||
|
global.responseTime.min.gte(globalResponseTimeMinGTE),
|
||||||
|
global.responseTime.max.lte(globalResponseTimeMaxLTE),
|
||||||
|
global.responseTime.max.gte(globalResponseTimeMaxGTE),
|
||||||
|
global.responseTime.mean.lte(globalResponseTimeMeanLTE),
|
||||||
|
global.responseTime.mean.gte(globalResponseTimeMeanGTE),
|
||||||
|
global.failedRequests.percent.lte(globalResponseTimeFailedRequestsPercentLTE),
|
||||||
|
global.failedRequests.percent.gte(globalResponseTimeFailedRequestsPercentGTE),
|
||||||
|
global.successfulRequests.percent.lte(globalResponseTimeSuccessfulRequestsPercentLTE),
|
||||||
|
global.successfulRequests.percent.gte(globalResponseTimeSuccessfulRequestsPercentGTE)
|
||||||
|
)
|
||||||
|
}
|
@ -0,0 +1,210 @@
|
|||||||
|
package io.swagger.client.api
|
||||||
|
|
||||||
|
import io.swagger.client.model._
|
||||||
|
import com.typesafe.config.ConfigFactory
|
||||||
|
|
||||||
|
import io.gatling.core.Predef._
|
||||||
|
import io.gatling.http.Predef._
|
||||||
|
import io.gatling.core.structure.PopulationBuilder
|
||||||
|
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
import scala.collection.mutable
|
||||||
|
|
||||||
|
class UserApiSimulation extends Simulation {
|
||||||
|
|
||||||
|
def getCurrentDirectory = new File("").getAbsolutePath
|
||||||
|
def userDataDirectory = getCurrentDirectory + "/src/gatling/resources/data"
|
||||||
|
|
||||||
|
// basic test setup
|
||||||
|
val configName = System.getProperty("testConfig", "baseline")
|
||||||
|
val config = ConfigFactory.load(configName).withFallback(ConfigFactory.load("default"))
|
||||||
|
val durationSeconds = config.getInt("performance.durationSeconds")
|
||||||
|
val rampUpSeconds = config.getInt("performance.rampUpSeconds")
|
||||||
|
val rampDownSeconds = config.getInt("performance.rampDownSeconds")
|
||||||
|
val authentication = config.getString("performance.authorizationHeader")
|
||||||
|
val acceptHeader = config.getString("performance.acceptType")
|
||||||
|
val contentTypeHeader = config.getString("performance.contentType")
|
||||||
|
val rateMultiplier = config.getDouble("performance.rateMultiplier")
|
||||||
|
val instanceMultiplier = config.getDouble("performance.instanceMultiplier")
|
||||||
|
|
||||||
|
// global assertion data
|
||||||
|
val globalResponseTimeMinLTE = config.getInt("performance.global.assertions.responseTime.min.lte")
|
||||||
|
val globalResponseTimeMinGTE = config.getInt("performance.global.assertions.responseTime.min.gte")
|
||||||
|
val globalResponseTimeMaxLTE = config.getInt("performance.global.assertions.responseTime.max.lte")
|
||||||
|
val globalResponseTimeMaxGTE = config.getInt("performance.global.assertions.responseTime.max.gte")
|
||||||
|
val globalResponseTimeMeanLTE = config.getInt("performance.global.assertions.responseTime.mean.lte")
|
||||||
|
val globalResponseTimeMeanGTE = config.getInt("performance.global.assertions.responseTime.mean.gte")
|
||||||
|
val globalResponseTimeFailedRequestsPercentLTE = config.getDouble("performance.global.assertions.failedRequests.percent.lte")
|
||||||
|
val globalResponseTimeFailedRequestsPercentGTE = config.getDouble("performance.global.assertions.failedRequests.percent.gte")
|
||||||
|
val globalResponseTimeSuccessfulRequestsPercentLTE = config.getDouble("performance.global.assertions.successfulRequests.percent.lte")
|
||||||
|
val globalResponseTimeSuccessfulRequestsPercentGTE = config.getDouble("performance.global.assertions.successfulRequests.percent.gte")
|
||||||
|
|
||||||
|
// Setup http protocol configuration
|
||||||
|
val httpConf = http
|
||||||
|
.baseURL("http://petstore.swagger.io/v2")
|
||||||
|
.doNotTrackHeader("1")
|
||||||
|
.acceptLanguageHeader("en-US,en;q=0.5")
|
||||||
|
.acceptEncodingHeader("gzip, deflate")
|
||||||
|
.userAgentHeader("Mozilla/5.0 (Windows NT 5.1; rv:31.0) Gecko/20100101 Firefox/31.0")
|
||||||
|
.acceptHeader(acceptHeader)
|
||||||
|
.contentTypeHeader(contentTypeHeader)
|
||||||
|
|
||||||
|
// set authorization header if it has been modified from config
|
||||||
|
if(!authentication.equals("~MANUAL_ENTRY")){
|
||||||
|
httpConf.authorizationHeader(authentication)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setup all the operations per second for the test to ultimately be generated from configs
|
||||||
|
val createUserPerSecond = config.getDouble("performance.operationsPerSecond.createUser") * rateMultiplier * instanceMultiplier
|
||||||
|
val createUsersWithArrayInputPerSecond = config.getDouble("performance.operationsPerSecond.createUsersWithArrayInput") * rateMultiplier * instanceMultiplier
|
||||||
|
val createUsersWithListInputPerSecond = config.getDouble("performance.operationsPerSecond.createUsersWithListInput") * rateMultiplier * instanceMultiplier
|
||||||
|
val deleteUserPerSecond = config.getDouble("performance.operationsPerSecond.deleteUser") * rateMultiplier * instanceMultiplier
|
||||||
|
val getUserByNamePerSecond = config.getDouble("performance.operationsPerSecond.getUserByName") * rateMultiplier * instanceMultiplier
|
||||||
|
val loginUserPerSecond = config.getDouble("performance.operationsPerSecond.loginUser") * rateMultiplier * instanceMultiplier
|
||||||
|
val logoutUserPerSecond = config.getDouble("performance.operationsPerSecond.logoutUser") * rateMultiplier * instanceMultiplier
|
||||||
|
val updateUserPerSecond = config.getDouble("performance.operationsPerSecond.updateUser") * rateMultiplier * instanceMultiplier
|
||||||
|
|
||||||
|
val scenarioBuilders: mutable.MutableList[PopulationBuilder] = new mutable.MutableList[PopulationBuilder]()
|
||||||
|
|
||||||
|
// Set up CSV feeders
|
||||||
|
val createUserBodyFeeder = csv(userDataDirectory + File.separator + "createUser-bodyParams.csv", escapeChar = '\\').random
|
||||||
|
val deleteUserPATHFeeder = csv(userDataDirectory + File.separator + "deleteUser-pathParams.csv").random
|
||||||
|
val getUserByNamePATHFeeder = csv(userDataDirectory + File.separator + "getUserByName-pathParams.csv").random
|
||||||
|
val loginUserQUERYFeeder = csv(userDataDirectory + File.separator + "loginUser-queryParams.csv").random
|
||||||
|
val updateUserPATHFeeder = csv(userDataDirectory + File.separator + "updateUser-pathParams.csv").random
|
||||||
|
val updateUserBodyFeeder = csv(userDataDirectory + File.separator + "updateUser-bodyParams.csv", escapeChar = '\\').random
|
||||||
|
|
||||||
|
// Setup all scenarios
|
||||||
|
|
||||||
|
|
||||||
|
val scncreateUser = scenario("createUserSimulation")
|
||||||
|
.feed(createUserBodyFeeder)
|
||||||
|
.exec(http("createUser")
|
||||||
|
.httpRequest("POST","/user")
|
||||||
|
.body(StringBody(User.toStringBody("${password}","${id}","${lastName}","${firstName}","${email}","${userStatus}","${phone}","${username}")))
|
||||||
|
)
|
||||||
|
|
||||||
|
// Run scncreateUser with warm up and reach a constant rate for entire duration
|
||||||
|
scenarioBuilders += scncreateUser.inject(
|
||||||
|
rampUsersPerSec(1) to(createUserPerSecond) during(rampUpSeconds),
|
||||||
|
constantUsersPerSec(createUserPerSecond) during(durationSeconds),
|
||||||
|
rampUsersPerSec(createUserPerSecond) to(1) during(rampDownSeconds)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
val scncreateUsersWithArrayInput = scenario("createUsersWithArrayInputSimulation")
|
||||||
|
.exec(http("createUsersWithArrayInput")
|
||||||
|
.httpRequest("POST","/user/createWithArray")
|
||||||
|
.body(StringBody(StringBody("[]")))
|
||||||
|
)
|
||||||
|
|
||||||
|
// Run scncreateUsersWithArrayInput with warm up and reach a constant rate for entire duration
|
||||||
|
scenarioBuilders += scncreateUsersWithArrayInput.inject(
|
||||||
|
rampUsersPerSec(1) to(createUsersWithArrayInputPerSecond) during(rampUpSeconds),
|
||||||
|
constantUsersPerSec(createUsersWithArrayInputPerSecond) during(durationSeconds),
|
||||||
|
rampUsersPerSec(createUsersWithArrayInputPerSecond) to(1) during(rampDownSeconds)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
val scncreateUsersWithListInput = scenario("createUsersWithListInputSimulation")
|
||||||
|
.exec(http("createUsersWithListInput")
|
||||||
|
.httpRequest("POST","/user/createWithList")
|
||||||
|
.body(StringBody(StringBody("[]")))
|
||||||
|
)
|
||||||
|
|
||||||
|
// Run scncreateUsersWithListInput with warm up and reach a constant rate for entire duration
|
||||||
|
scenarioBuilders += scncreateUsersWithListInput.inject(
|
||||||
|
rampUsersPerSec(1) to(createUsersWithListInputPerSecond) during(rampUpSeconds),
|
||||||
|
constantUsersPerSec(createUsersWithListInputPerSecond) during(durationSeconds),
|
||||||
|
rampUsersPerSec(createUsersWithListInputPerSecond) to(1) during(rampDownSeconds)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
val scndeleteUser = scenario("deleteUserSimulation")
|
||||||
|
.feed(deleteUserPATHFeeder)
|
||||||
|
.exec(http("deleteUser")
|
||||||
|
.httpRequest("DELETE","/user/${username}")
|
||||||
|
)
|
||||||
|
|
||||||
|
// Run scndeleteUser with warm up and reach a constant rate for entire duration
|
||||||
|
scenarioBuilders += scndeleteUser.inject(
|
||||||
|
rampUsersPerSec(1) to(deleteUserPerSecond) during(rampUpSeconds),
|
||||||
|
constantUsersPerSec(deleteUserPerSecond) during(durationSeconds),
|
||||||
|
rampUsersPerSec(deleteUserPerSecond) to(1) during(rampDownSeconds)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
val scngetUserByName = scenario("getUserByNameSimulation")
|
||||||
|
.feed(getUserByNamePATHFeeder)
|
||||||
|
.exec(http("getUserByName")
|
||||||
|
.httpRequest("GET","/user/${username}")
|
||||||
|
)
|
||||||
|
|
||||||
|
// Run scngetUserByName with warm up and reach a constant rate for entire duration
|
||||||
|
scenarioBuilders += scngetUserByName.inject(
|
||||||
|
rampUsersPerSec(1) to(getUserByNamePerSecond) during(rampUpSeconds),
|
||||||
|
constantUsersPerSec(getUserByNamePerSecond) during(durationSeconds),
|
||||||
|
rampUsersPerSec(getUserByNamePerSecond) to(1) during(rampDownSeconds)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
val scnloginUser = scenario("loginUserSimulation")
|
||||||
|
.feed(loginUserQUERYFeeder)
|
||||||
|
.exec(http("loginUser")
|
||||||
|
.httpRequest("GET","/user/login")
|
||||||
|
.queryParam("username","${username}")
|
||||||
|
.queryParam("password","${password}")
|
||||||
|
)
|
||||||
|
|
||||||
|
// Run scnloginUser with warm up and reach a constant rate for entire duration
|
||||||
|
scenarioBuilders += scnloginUser.inject(
|
||||||
|
rampUsersPerSec(1) to(loginUserPerSecond) during(rampUpSeconds),
|
||||||
|
constantUsersPerSec(loginUserPerSecond) during(durationSeconds),
|
||||||
|
rampUsersPerSec(loginUserPerSecond) to(1) during(rampDownSeconds)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
val scnlogoutUser = scenario("logoutUserSimulation")
|
||||||
|
.exec(http("logoutUser")
|
||||||
|
.httpRequest("GET","/user/logout")
|
||||||
|
)
|
||||||
|
|
||||||
|
// Run scnlogoutUser with warm up and reach a constant rate for entire duration
|
||||||
|
scenarioBuilders += scnlogoutUser.inject(
|
||||||
|
rampUsersPerSec(1) to(logoutUserPerSecond) during(rampUpSeconds),
|
||||||
|
constantUsersPerSec(logoutUserPerSecond) during(durationSeconds),
|
||||||
|
rampUsersPerSec(logoutUserPerSecond) to(1) during(rampDownSeconds)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
val scnupdateUser = scenario("updateUserSimulation")
|
||||||
|
.feed(updateUserBodyFeeder)
|
||||||
|
.feed(updateUserPATHFeeder)
|
||||||
|
.exec(http("updateUser")
|
||||||
|
.httpRequest("PUT","/user/${username}")
|
||||||
|
.body(StringBody(User.toStringBody("${password}","${id}","${lastName}","${firstName}","${email}","${userStatus}","${phone}","${username}")))
|
||||||
|
)
|
||||||
|
|
||||||
|
// Run scnupdateUser with warm up and reach a constant rate for entire duration
|
||||||
|
scenarioBuilders += scnupdateUser.inject(
|
||||||
|
rampUsersPerSec(1) to(updateUserPerSecond) during(rampUpSeconds),
|
||||||
|
constantUsersPerSec(updateUserPerSecond) during(durationSeconds),
|
||||||
|
rampUsersPerSec(updateUserPerSecond) to(1) during(rampDownSeconds)
|
||||||
|
)
|
||||||
|
|
||||||
|
setUp(
|
||||||
|
scenarioBuilders.toList
|
||||||
|
).protocols(httpConf).assertions(
|
||||||
|
global.responseTime.min.lte(globalResponseTimeMinLTE),
|
||||||
|
global.responseTime.min.gte(globalResponseTimeMinGTE),
|
||||||
|
global.responseTime.max.lte(globalResponseTimeMaxLTE),
|
||||||
|
global.responseTime.max.gte(globalResponseTimeMaxGTE),
|
||||||
|
global.responseTime.mean.lte(globalResponseTimeMeanLTE),
|
||||||
|
global.responseTime.mean.gte(globalResponseTimeMeanGTE),
|
||||||
|
global.failedRequests.percent.lte(globalResponseTimeFailedRequestsPercentLTE),
|
||||||
|
global.failedRequests.percent.gte(globalResponseTimeFailedRequestsPercentGTE),
|
||||||
|
global.successfulRequests.percent.lte(globalResponseTimeSuccessfulRequestsPercentLTE),
|
||||||
|
global.successfulRequests.percent.gte(globalResponseTimeSuccessfulRequestsPercentGTE)
|
||||||
|
)
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
|
||||||
|
package io.swagger.client.model
|
||||||
|
|
||||||
|
|
||||||
|
case class ApiResponse (
|
||||||
|
_code: Option[Integer],
|
||||||
|
_type: Option[String],
|
||||||
|
_message: Option[String]
|
||||||
|
)
|
||||||
|
object ApiResponse {
|
||||||
|
def toStringBody(var_code: Object, var_type: Object, var_message: Object) =
|
||||||
|
s"""
|
||||||
|
| {
|
||||||
|
| "code":$var_code,"type":$var_type,"message":$var_message
|
||||||
|
| }
|
||||||
|
""".stripMargin
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
|
||||||
|
package io.swagger.client.model
|
||||||
|
|
||||||
|
|
||||||
|
case class Category (
|
||||||
|
_id: Option[Long],
|
||||||
|
_name: Option[String]
|
||||||
|
)
|
||||||
|
object Category {
|
||||||
|
def toStringBody(var_id: Object, var_name: Object) =
|
||||||
|
s"""
|
||||||
|
| {
|
||||||
|
| "id":$var_id,"name":$var_name
|
||||||
|
| }
|
||||||
|
""".stripMargin
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
|
||||||
|
package io.swagger.client.model
|
||||||
|
|
||||||
|
import java.util.Date
|
||||||
|
|
||||||
|
case class Order (
|
||||||
|
_id: Option[Long],
|
||||||
|
_petId: Option[Long],
|
||||||
|
_quantity: Option[Integer],
|
||||||
|
_shipDate: Option[Date],
|
||||||
|
/* Order Status */
|
||||||
|
_status: Option[String],
|
||||||
|
_complete: Option[Boolean]
|
||||||
|
)
|
||||||
|
object Order {
|
||||||
|
def toStringBody(var_id: Object, var_petId: Object, var_quantity: Object, var_shipDate: Object, var_status: Object, var_complete: Object) =
|
||||||
|
s"""
|
||||||
|
| {
|
||||||
|
| "id":$var_id,"petId":$var_petId,"quantity":$var_quantity,"shipDate":$var_shipDate,"status":$var_status,"complete":$var_complete
|
||||||
|
| }
|
||||||
|
""".stripMargin
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user