mirror of
https://github.com/OpenAPITools/openapi-generator.git
synced 2025-06-03 15:30:59 +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.FlashClientCodegen
|
||||
io.swagger.codegen.languages.FlaskConnexionCodegen
|
||||
io.swagger.codegen.languages.ScalaGatlingCodegen
|
||||
io.swagger.codegen.languages.GoClientCodegen
|
||||
io.swagger.codegen.languages.GoServerCodegen
|
||||
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