forked from loafle/openapi-generator-original
[K6 Generator] various enhancements (request body example data extraction, support for generating scenario tests and load tests out of the box, and much more) (#11106)
* Further K6 OpenAPI generator enhancements * request body example data extraction * request grouping and ordering * response visibility * request data extraction for chaining requests Signed-off-by: Michael H. Siemaszko <mhs@into.software> * Further K6 OpenAPI generator enhancements - regenerated samples Signed-off-by: Michael H. Siemaszko <mhs@into.software> * Fix suggested changes by linter * Fix extra spaces in the template * Log exception * Rename function signature to camelCase * Address comments on Big-O * Move declaration of variable near the usage * Add config file for generating k6 script * Regenerate k6 script * Regenerate samples * Fix predicate * Fix missing import Co-authored-by: Michael H. Siemaszko <mhs@into.software>
This commit is contained in:
parent
94e3ae10fd
commit
fedc54af9a
6
bin/configs/k6.yaml
Normal file
6
bin/configs/k6.yaml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
generatorName: k6
|
||||||
|
outputDir: samples/client/petstore/k6
|
||||||
|
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore-with-fake-endpoints-models-for-testing.yaml
|
||||||
|
templateDir: modules/openapi-generator/src/main/resources/k6
|
||||||
|
additionalProperties:
|
||||||
|
appName: PetstoreClient
|
@ -297,6 +297,11 @@
|
|||||||
<artifactId>commons-lang3</artifactId>
|
<artifactId>commons-lang3</artifactId>
|
||||||
<version>${commons-lang.version}</version>
|
<version>${commons-lang.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-text</artifactId>
|
||||||
|
<version>${commons-text.version}</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>commons-cli</groupId>
|
<groupId>commons-cli</groupId>
|
||||||
<artifactId>commons-cli</artifactId>
|
<artifactId>commons-cli</artifactId>
|
||||||
|
@ -66,7 +66,11 @@ public class CodegenOperation {
|
|||||||
*
|
*
|
||||||
* @return true if parameter exists, false otherwise
|
* @return true if parameter exists, false otherwise
|
||||||
*/
|
*/
|
||||||
private static boolean nonempty(List<?> params) {
|
private static boolean nonEmpty(List<?> params) {
|
||||||
|
return params != null && params.size() > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean nonEmpty(Map<?, ?> params) {
|
||||||
return params != null && params.size() > 0;
|
return params != null && params.size() > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,7 +80,7 @@ public class CodegenOperation {
|
|||||||
* @return true if body parameter exists, false otherwise
|
* @return true if body parameter exists, false otherwise
|
||||||
*/
|
*/
|
||||||
public boolean getHasBodyParam() {
|
public boolean getHasBodyParam() {
|
||||||
return nonempty(bodyParams);
|
return nonEmpty(bodyParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -85,7 +89,7 @@ public class CodegenOperation {
|
|||||||
* @return true if query parameter exists, false otherwise
|
* @return true if query parameter exists, false otherwise
|
||||||
*/
|
*/
|
||||||
public boolean getHasQueryParams() {
|
public boolean getHasQueryParams() {
|
||||||
return nonempty(queryParams);
|
return nonEmpty(queryParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -103,7 +107,7 @@ public class CodegenOperation {
|
|||||||
* @return true if header parameter exists, false otherwise
|
* @return true if header parameter exists, false otherwise
|
||||||
*/
|
*/
|
||||||
public boolean getHasHeaderParams() {
|
public boolean getHasHeaderParams() {
|
||||||
return nonempty(headerParams);
|
return nonEmpty(headerParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -112,7 +116,7 @@ public class CodegenOperation {
|
|||||||
* @return true if path parameter exists, false otherwise
|
* @return true if path parameter exists, false otherwise
|
||||||
*/
|
*/
|
||||||
public boolean getHasPathParams() {
|
public boolean getHasPathParams() {
|
||||||
return nonempty(pathParams);
|
return nonEmpty(pathParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -121,7 +125,7 @@ public class CodegenOperation {
|
|||||||
* @return true if any form parameter exists, false otherwise
|
* @return true if any form parameter exists, false otherwise
|
||||||
*/
|
*/
|
||||||
public boolean getHasFormParams() {
|
public boolean getHasFormParams() {
|
||||||
return nonempty(formParams);
|
return nonEmpty(formParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -139,7 +143,7 @@ public class CodegenOperation {
|
|||||||
* @return true if any cookie parameter exists, false otherwise
|
* @return true if any cookie parameter exists, false otherwise
|
||||||
*/
|
*/
|
||||||
public boolean getHasCookieParams() {
|
public boolean getHasCookieParams() {
|
||||||
return nonempty(cookieParams);
|
return nonEmpty(cookieParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -148,7 +152,7 @@ public class CodegenOperation {
|
|||||||
* @return true if any optional parameter exists, false otherwise
|
* @return true if any optional parameter exists, false otherwise
|
||||||
*/
|
*/
|
||||||
public boolean getHasOptionalParams() {
|
public boolean getHasOptionalParams() {
|
||||||
return nonempty(optionalParams);
|
return nonEmpty(optionalParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -157,7 +161,7 @@ public class CodegenOperation {
|
|||||||
* @return true if any optional parameter exists, false otherwise
|
* @return true if any optional parameter exists, false otherwise
|
||||||
*/
|
*/
|
||||||
public boolean getHasRequiredParams() {
|
public boolean getHasRequiredParams() {
|
||||||
return nonempty(requiredParams);
|
return nonEmpty(requiredParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -166,7 +170,7 @@ public class CodegenOperation {
|
|||||||
* @return true if header response exists, false otherwise
|
* @return true if header response exists, false otherwise
|
||||||
*/
|
*/
|
||||||
public boolean getHasResponseHeaders() {
|
public boolean getHasResponseHeaders() {
|
||||||
return nonempty(responseHeaders);
|
return nonEmpty(responseHeaders);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -175,7 +179,7 @@ public class CodegenOperation {
|
|||||||
* @return true if examples parameter exists, false otherwise
|
* @return true if examples parameter exists, false otherwise
|
||||||
*/
|
*/
|
||||||
public boolean getHasExamples() {
|
public boolean getHasExamples() {
|
||||||
return nonempty(examples);
|
return nonEmpty(examples);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -187,6 +191,15 @@ public class CodegenOperation {
|
|||||||
return responses.stream().filter(response -> response.isDefault).findFirst().isPresent();
|
return responses.stream().filter(response -> response.isDefault).findFirst().isPresent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if there's at least one vendor extension
|
||||||
|
*
|
||||||
|
* @return true if vendor extensions exists, false otherwise
|
||||||
|
*/
|
||||||
|
public boolean getHasVendorExtensions() {
|
||||||
|
return nonEmpty(vendorExtensions);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if act as Restful index method
|
* Check if act as Restful index method
|
||||||
*
|
*
|
||||||
|
@ -28,22 +28,28 @@ import java.util.Arrays;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.OptionalInt;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.TreeMap;
|
||||||
import java.util.TreeSet;
|
import java.util.TreeSet;
|
||||||
|
import java.util.Map.Entry;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import org.apache.commons.lang3.StringEscapeUtils;
|
import org.apache.commons.text.StringEscapeUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.openapitools.codegen.CodegenConfig;
|
import org.openapitools.codegen.CodegenConfig;
|
||||||
import org.openapitools.codegen.CodegenConstants;
|
import org.openapitools.codegen.CodegenConstants;
|
||||||
import org.openapitools.codegen.CodegenModel;
|
import org.openapitools.codegen.CodegenModel;
|
||||||
|
import org.openapitools.codegen.CodegenOperation;
|
||||||
import org.openapitools.codegen.CodegenParameter;
|
import org.openapitools.codegen.CodegenParameter;
|
||||||
import org.openapitools.codegen.CodegenProperty;
|
import org.openapitools.codegen.CodegenProperty;
|
||||||
import org.openapitools.codegen.CodegenResponse;
|
import org.openapitools.codegen.CodegenResponse;
|
||||||
@ -56,10 +62,13 @@ import org.openapitools.codegen.utils.ModelUtils;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.samskivert.mustache.Mustache;
|
import com.samskivert.mustache.Mustache;
|
||||||
import com.samskivert.mustache.Mustache.Lambda;
|
import com.samskivert.mustache.Mustache.Lambda;
|
||||||
import com.samskivert.mustache.Template;
|
import com.samskivert.mustache.Template;
|
||||||
|
|
||||||
|
import io.swagger.v3.core.util.Json;
|
||||||
import io.swagger.v3.oas.models.OpenAPI;
|
import io.swagger.v3.oas.models.OpenAPI;
|
||||||
import io.swagger.v3.oas.models.Operation;
|
import io.swagger.v3.oas.models.Operation;
|
||||||
import io.swagger.v3.oas.models.PathItem;
|
import io.swagger.v3.oas.models.PathItem;
|
||||||
@ -73,6 +82,24 @@ import io.swagger.v3.oas.models.servers.Server;
|
|||||||
|
|
||||||
public class K6ClientCodegen extends DefaultCodegen implements CodegenConfig {
|
public class K6ClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||||
|
|
||||||
|
// K6 vendor extension - operation grouping - group operations and define their
|
||||||
|
// ordering, to allow for e.g. scenario testing
|
||||||
|
private static final String X_OPERATION_GROUPING = "x-k6-openapi-operation-grouping";
|
||||||
|
|
||||||
|
// K6 vendor extension - operation response - for now, allows to hide given
|
||||||
|
// operation response, so that in case of multiple 2xx responses, generated
|
||||||
|
// script checks only against e.g. code 200 responses
|
||||||
|
private static final String X_OPERATION_RESPONSE = "x-k6-openapi-operation-response";
|
||||||
|
private static final String X_OPERATION_RESPONSE_HIDE = "hide";
|
||||||
|
|
||||||
|
// K6 vendor extension - extract data from operation - allows to specify path to
|
||||||
|
// value in body of response which should be extracted and assigned to variable
|
||||||
|
// for later use by other operations
|
||||||
|
private static final String X_OPERATION_DATAEXTRACT = "x-k6-openapi-operation-dataextract";
|
||||||
|
private static final String X_OPERATION_DATAEXTRACT_OPERATION_ID = "operationId"; // denotes ID of operation whose response body contains value to be extracted
|
||||||
|
private static final String X_OPERATION_DATAEXTRACT_VALUE_PATH = "valuePath"; // denotes path to value in body of response which should be extracted
|
||||||
|
private static final String X_OPERATION_DATAEXTRACT_PARAMETER_NAME = "parameterName"; // denotes name of parameter to which extracted value should be assigned
|
||||||
|
|
||||||
public K6ClientCodegen() {
|
public K6ClientCodegen() {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
@ -86,6 +113,7 @@ public class K6ClientCodegen extends DefaultCodegen implements CodegenConfig {
|
|||||||
String key;
|
String key;
|
||||||
Object value;
|
Object value;
|
||||||
boolean hasExample;
|
boolean hasExample;
|
||||||
|
boolean initialize;
|
||||||
|
|
||||||
public Parameter(String key, Object value) {
|
public Parameter(String key, Object value) {
|
||||||
this.key = key;
|
this.key = key;
|
||||||
@ -98,6 +126,11 @@ public class K6ClientCodegen extends DefaultCodegen implements CodegenConfig {
|
|||||||
this.hasExample = hasExample;
|
this.hasExample = hasExample;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Parameter(String key, boolean initialize) {
|
||||||
|
this.key = key;
|
||||||
|
this.initialize = initialize;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return key.hashCode();
|
return key.hashCode();
|
||||||
@ -110,7 +143,32 @@ public class K6ClientCodegen extends DefaultCodegen implements CodegenConfig {
|
|||||||
if (obj == null || getClass() != obj.getClass())
|
if (obj == null || getClass() != obj.getClass())
|
||||||
return false;
|
return false;
|
||||||
Parameter p = (Parameter) obj;
|
Parameter p = (Parameter) obj;
|
||||||
return key.equals(p.key) && value.equals(p.value) && hasExample == p.hasExample;
|
return key.equals(p.key) && value.equals(p.value) && hasExample == p.hasExample
|
||||||
|
&& initialize == p.initialize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stores information specified in `X_OPERATION_GROUPING` K6 vendor extension
|
||||||
|
static class OperationGrouping {
|
||||||
|
String groupName;
|
||||||
|
int order;
|
||||||
|
|
||||||
|
public OperationGrouping(String groupName, int order) {
|
||||||
|
this.groupName = groupName;
|
||||||
|
this.order = order;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stores information specified in `X_OPERATION_DATAEXTRACT` K6 vendor extension
|
||||||
|
static class DataExtractSubstituteParameter {
|
||||||
|
String operationId;
|
||||||
|
String valuePath;
|
||||||
|
String paramName;
|
||||||
|
|
||||||
|
public DataExtractSubstituteParameter(String operationId, String valuePath, String paramName) {
|
||||||
|
this.operationId = operationId;
|
||||||
|
this.valuePath = valuePath;
|
||||||
|
this.paramName = paramName;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,10 +196,10 @@ public class K6ClientCodegen extends DefaultCodegen implements CodegenConfig {
|
|||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
Set<String> exampleValues = ((Map<String, Example>) rawValue).values().stream()
|
Set<String> exampleValues = ((Map<String, Example>) rawValue).values().stream()
|
||||||
.map(x -> quoteExample(
|
.map(x -> quoteExample(
|
||||||
StringEscapeUtils.escapeEcmaScript(
|
StringEscapeUtils.escapeEcmaScript(
|
||||||
String.valueOf(x.getValue()))))
|
String.valueOf(x.getValue()))))
|
||||||
.collect(Collectors.toCollection(() -> new TreeSet<>()));
|
.collect(Collectors.toCollection(TreeSet::new));
|
||||||
|
|
||||||
if (!exampleValues.isEmpty()) {
|
if (!exampleValues.isEmpty()) {
|
||||||
|
|
||||||
@ -160,11 +218,20 @@ public class K6ClientCodegen extends DefaultCodegen implements CodegenConfig {
|
|||||||
quoteExample(
|
quoteExample(
|
||||||
StringEscapeUtils.escapeEcmaScript(
|
StringEscapeUtils.escapeEcmaScript(
|
||||||
String.valueOf(
|
String.valueOf(
|
||||||
((K6ClientCodegen.Parameter) fragment.context()).value))),
|
((K6ClientCodegen.Parameter) fragment.context()).value))),
|
||||||
";",
|
";",
|
||||||
" // extracted from 'example' field defined at the parameter level of OpenAPI spec"));
|
" // extracted from 'example' field defined at the parameter level of OpenAPI spec"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// param needs to be initialized for subsequent data extraction - see `X_OPERATION_DATAEXTRACT` K6 vendor extension
|
||||||
|
} else if (fragment.context() instanceof K6ClientCodegen.Parameter
|
||||||
|
&& ((K6ClientCodegen.Parameter) fragment.context()).initialize) {
|
||||||
|
|
||||||
|
writer.write(String.join("",
|
||||||
|
"null",
|
||||||
|
";",
|
||||||
|
" // parameter initialized for subsequent data extraction"));
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
writer.write(noExampleParamValue);
|
writer.write(noExampleParamValue);
|
||||||
}
|
}
|
||||||
@ -231,25 +298,33 @@ public class K6ClientCodegen extends DefaultCodegen implements CodegenConfig {
|
|||||||
|
|
||||||
static class HTTPRequest {
|
static class HTTPRequest {
|
||||||
String method;
|
String method;
|
||||||
|
boolean isDelete;
|
||||||
String path;
|
String path;
|
||||||
@Nullable
|
@Nullable
|
||||||
List<Parameter> query;
|
List<Parameter> query;
|
||||||
@Nullable
|
@Nullable
|
||||||
HTTPBody body;
|
HTTPBody body;
|
||||||
|
boolean hasBodyExample;
|
||||||
@Nullable
|
@Nullable
|
||||||
HTTPParameters params;
|
HTTPParameters params;
|
||||||
@Nullable
|
@Nullable
|
||||||
List<k6Check> k6Checks;
|
List<k6Check> k6Checks;
|
||||||
|
@Nullable
|
||||||
|
DataExtractSubstituteParameter dataExtract;
|
||||||
|
|
||||||
public HTTPRequest(String method, String path, @Nullable List<Parameter> query, @Nullable HTTPBody body,
|
public HTTPRequest(String method, String path, @Nullable List<Parameter> query, @Nullable HTTPBody body,
|
||||||
@Nullable HTTPParameters params, @Nullable List<k6Check> k6Checks) {
|
boolean hasBodyExample, @Nullable HTTPParameters params, @Nullable List<k6Check> k6Checks,
|
||||||
|
DataExtractSubstituteParameter dataExtract) {
|
||||||
// NOTE: https://k6.io/docs/javascript-api/k6-http/del-url-body-params
|
// NOTE: https://k6.io/docs/javascript-api/k6-http/del-url-body-params
|
||||||
this.method = method.equals("delete") ? "del" : method;
|
this.method = method.equals("delete") ? "del" : method;
|
||||||
|
this.isDelete = method.equals("delete");
|
||||||
this.path = path;
|
this.path = path;
|
||||||
this.query = query;
|
this.query = query;
|
||||||
this.body = body;
|
this.body = body;
|
||||||
|
this.hasBodyExample = hasBodyExample;
|
||||||
this.params = params;
|
this.params = params;
|
||||||
this.k6Checks = k6Checks;
|
this.k6Checks = k6Checks;
|
||||||
|
this.dataExtract = dataExtract;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -257,11 +332,26 @@ public class K6ClientCodegen extends DefaultCodegen implements CodegenConfig {
|
|||||||
String groupName;
|
String groupName;
|
||||||
Set<Parameter> variables; // query and path parameters
|
Set<Parameter> variables; // query and path parameters
|
||||||
List<HTTPRequest> requests;
|
List<HTTPRequest> requests;
|
||||||
|
private final Map<Integer, HTTPRequest> requestsMap;
|
||||||
|
|
||||||
public HTTPRequestGroup(String groupName, Set<Parameter> variables, List<HTTPRequest> requests) {
|
public HTTPRequestGroup(String groupName, Set<Parameter> variables, Map<Integer, HTTPRequest> requestsMap) {
|
||||||
this.groupName = groupName;
|
this.groupName = groupName;
|
||||||
this.variables = variables;
|
this.variables = variables;
|
||||||
this.requests = requests;
|
this.requestsMap = requestsMap;
|
||||||
|
this.requests = sortRequests(requestsMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addRequests(Map<Integer, HTTPRequest> moreRequests) {
|
||||||
|
this.requestsMap.putAll(moreRequests);
|
||||||
|
this.requests = sortRequests(this.requestsMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addVariables(Set<Parameter> moreVariables) {
|
||||||
|
this.variables.addAll(moreVariables);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<HTTPRequest> sortRequests(Map<Integer, HTTPRequest> requestsMap) {
|
||||||
|
return new ArrayList<>(new TreeMap<>(requestsMap).values());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -398,14 +488,21 @@ public class K6ClientCodegen extends DefaultCodegen implements CodegenConfig {
|
|||||||
}
|
}
|
||||||
additionalProperties.put(BASE_URL, baseURL);
|
additionalProperties.put(BASE_URL, baseURL);
|
||||||
|
|
||||||
List<HTTPRequestGroup> requestGroups = new ArrayList<>();
|
// if data is to be extracted from any of the operations' responses, this has to
|
||||||
|
// be known prior to executing processing of OpenAPI spec further down
|
||||||
|
Map<String, DataExtractSubstituteParameter> dataExtractSubstituteParams = getDataExtractSubstituteParameters(
|
||||||
|
openAPI);
|
||||||
|
|
||||||
|
Map<String, HTTPRequestGroup> requestGroups = new HashMap<>();
|
||||||
Set<Parameter> extraParameters = new HashSet<>();
|
Set<Parameter> extraParameters = new HashSet<>();
|
||||||
Map<String, Set<Parameter>> pathVariables = new HashMap<>();
|
Map<String, Set<Parameter>> pathVariables = new HashMap<>();
|
||||||
|
|
||||||
for (String path : openAPI.getPaths().keySet()) {
|
for (String path : openAPI.getPaths().keySet()) {
|
||||||
List<HTTPRequest> requests = new ArrayList<>();
|
Map<Integer, HTTPRequest> requests = new HashMap<>();
|
||||||
Set<Parameter> variables = new HashSet<>();
|
Set<Parameter> variables = new HashSet<>();
|
||||||
|
|
||||||
|
String groupName = path;
|
||||||
|
|
||||||
for (Map.Entry<PathItem.HttpMethod, Operation> methodOperation : openAPI.getPaths().get(path).
|
for (Map.Entry<PathItem.HttpMethod, Operation> methodOperation : openAPI.getPaths().get(path).
|
||||||
readOperationsMap().entrySet()) {
|
readOperationsMap().entrySet()) {
|
||||||
List<Parameter> httpParams = new ArrayList<>();
|
List<Parameter> httpParams = new ArrayList<>();
|
||||||
@ -416,11 +513,32 @@ public class K6ClientCodegen extends DefaultCodegen implements CodegenConfig {
|
|||||||
|
|
||||||
final Operation operation = methodOperation.getValue();
|
final Operation operation = methodOperation.getValue();
|
||||||
final PathItem.HttpMethod method = methodOperation.getKey();
|
final PathItem.HttpMethod method = methodOperation.getKey();
|
||||||
|
OptionalInt operationGroupingOrder = OptionalInt.empty();
|
||||||
|
|
||||||
|
String operationId = operation.getOperationId();
|
||||||
|
|
||||||
|
boolean hasRequestBodyExample = false;
|
||||||
|
|
||||||
|
// optionally group and order operations - see `X_OPERATION_GROUPING` K6 vendor
|
||||||
|
// extension
|
||||||
|
final CodegenOperation cgOperation = super.fromOperation(path, method.name(), operation, null);
|
||||||
|
Optional<OperationGrouping> operationGrouping = extractOperationGrouping(cgOperation);
|
||||||
|
if (operationGrouping.isPresent()) {
|
||||||
|
groupName = operationGrouping.get().groupName;
|
||||||
|
operationGroupingOrder = OptionalInt.of(operationGrouping.get().order);
|
||||||
|
}
|
||||||
|
|
||||||
for (Map.Entry<String, ApiResponse> resp : operation.getResponses().entrySet()) {
|
for (Map.Entry<String, ApiResponse> resp : operation.getResponses().entrySet()) {
|
||||||
String statusData = resp.getKey().equals("default") ? "200" : resp.getKey();
|
String statusData = resp.getKey().equals("default") ? "200" : resp.getKey();
|
||||||
|
|
||||||
|
// optionally hide given response - see `X_OPERATION_RESPONSE` K6 vendor
|
||||||
|
// extension
|
||||||
|
// i.e. in case of multiple 2xx responses, generated script checks only against
|
||||||
|
// e.g. code 200 responses
|
||||||
|
boolean hideOperationResponse = shouldHideOperationResponse(resp.getValue());
|
||||||
|
|
||||||
int status = Integer.parseInt(statusData);
|
int status = Integer.parseInt(statusData);
|
||||||
if (status >= 200 && status < 300) {
|
if (!hideOperationResponse && (status >= 200 && status < 300)) {
|
||||||
k6Checks.add(new k6Check(status, resp.getValue().getDescription()));
|
k6Checks.add(new k6Check(status, resp.getValue().getDescription()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -428,7 +546,7 @@ public class K6ClientCodegen extends DefaultCodegen implements CodegenConfig {
|
|||||||
if (hasBodyParameter(openAPI, operation) || hasFormParameter(openAPI, operation)) {
|
if (hasBodyParameter(openAPI, operation) || hasFormParameter(openAPI, operation)) {
|
||||||
String defaultContentType = hasFormParameter(openAPI, operation) ? "application/x-www-form-urlencoded" : "application/json";
|
String defaultContentType = hasFormParameter(openAPI, operation) ? "application/x-www-form-urlencoded" : "application/json";
|
||||||
List<String> consumes = new ArrayList<>(getConsumesInfo(openAPI, operation));
|
List<String> consumes = new ArrayList<>(getConsumesInfo(openAPI, operation));
|
||||||
String contentTypeValue = consumes == null || consumes.isEmpty() ? defaultContentType : consumes.get(0);
|
String contentTypeValue = consumes.isEmpty() ? defaultContentType : consumes.get(0);
|
||||||
if (contentTypeValue.equals("*/*"))
|
if (contentTypeValue.equals("*/*"))
|
||||||
contentTypeValue = "application/json";
|
contentTypeValue = "application/json";
|
||||||
Parameter contentType = new Parameter("Content-Type", getDoubleQuotedString(contentTypeValue));
|
Parameter contentType = new Parameter("Content-Type", getDoubleQuotedString(contentTypeValue));
|
||||||
@ -436,6 +554,12 @@ public class K6ClientCodegen extends DefaultCodegen implements CodegenConfig {
|
|||||||
|
|
||||||
RequestBody requestBody = ModelUtils.getReferencedRequestBody(openAPI, operation.getRequestBody());
|
RequestBody requestBody = ModelUtils.getReferencedRequestBody(openAPI, operation.getRequestBody());
|
||||||
|
|
||||||
|
// extract request body example, if present
|
||||||
|
hasRequestBodyExample = hasRequestBodyExample(requestBody, contentTypeValue);
|
||||||
|
if (hasRequestBodyExample) {
|
||||||
|
extractRequestBodyExample(requestBody, contentTypeValue, bodyOrFormParams);
|
||||||
|
}
|
||||||
|
|
||||||
for (Map.Entry<String, ApiResponse> responseEntry : operation.getResponses().entrySet()) {
|
for (Map.Entry<String, ApiResponse> responseEntry : operation.getResponses().entrySet()) {
|
||||||
CodegenResponse r = fromResponse(responseEntry.getKey(), responseEntry.getValue());
|
CodegenResponse r = fromResponse(responseEntry.getKey(), responseEntry.getValue());
|
||||||
if (r.baseType != null &&
|
if (r.baseType != null &&
|
||||||
@ -445,30 +569,34 @@ public class K6ClientCodegen extends DefaultCodegen implements CodegenConfig {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
List<CodegenParameter> formParameters = fromRequestBodyToFormParameters(requestBody, imports);
|
// if we have at least one request body example, we do not need to construct these dummies
|
||||||
for (CodegenParameter parameter : formParameters) {
|
if (!hasRequestBodyExample) {
|
||||||
String reference = "";
|
List<CodegenParameter> formParameters = fromRequestBodyToFormParameters(requestBody, imports);
|
||||||
if (parameter.isModel) {
|
for (CodegenParameter parameter : formParameters) {
|
||||||
Schema nestedSchema = ModelUtils.getSchema(openAPI, parameter.baseType);
|
String reference = "";
|
||||||
CodegenModel model = fromModel(parameter.paramName, nestedSchema);
|
if (parameter.isModel) {
|
||||||
reference = generateNestedModelTemplate(model);
|
Schema nestedSchema = ModelUtils.getSchema(openAPI, parameter.baseType);
|
||||||
if (parameter.dataType.equals("List")) {
|
CodegenModel model = fromModel(parameter.paramName, nestedSchema);
|
||||||
reference = "[" + reference + "]";
|
reference = generateNestedModelTemplate(model);
|
||||||
|
if (parameter.dataType.equals("List")) {
|
||||||
|
reference = "[" + reference + "]";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
Parameter k6Parameter;
|
Parameter k6Parameter;
|
||||||
if (parameter.dataType.equals("File")) {
|
if (parameter.dataType.equals("File")) {
|
||||||
k6Parameter = new Parameter(parameter.paramName,
|
k6Parameter = new Parameter(parameter.paramName,
|
||||||
"http.file(open(\"/path/to/file.bin\", \"b\"), \"test.bin\")");
|
"http.file(open(\"/path/to/file.bin\", \"b\"), \"test.bin\")");
|
||||||
} else {
|
} else {
|
||||||
k6Parameter = new Parameter(parameter.paramName, !reference.isEmpty() ? reference
|
k6Parameter = new Parameter(parameter.paramName, !reference.isEmpty() ? reference
|
||||||
: getDoubleQuotedString(parameter.dataType.toLowerCase(Locale.ROOT)));
|
: getDoubleQuotedString(parameter.dataType.toLowerCase(Locale.ROOT)));
|
||||||
}
|
}
|
||||||
|
|
||||||
bodyOrFormParams.add(k6Parameter);
|
bodyOrFormParams.add(k6Parameter);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String accepts = getAccept(openAPI, operation);
|
String accepts = getAccept(openAPI, operation);
|
||||||
String responseType = getDoubleQuotedString(accepts);
|
String responseType = getDoubleQuotedString(accepts);
|
||||||
|
|
||||||
@ -507,32 +635,46 @@ public class K6ClientCodegen extends DefaultCodegen implements CodegenConfig {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (NullPointerException e) {
|
} catch (NullPointerException e) {
|
||||||
|
LOGGER.error(e.getMessage(), e);
|
||||||
}
|
}
|
||||||
|
|
||||||
pathVariables.put(path, variables);
|
pathVariables.put(groupName, variables);
|
||||||
|
|
||||||
final HTTPParameters params = new HTTPParameters(null, null, httpParams, null, null, null, null, null,
|
final HTTPParameters params = new HTTPParameters(null, null, httpParams, null, null, null, null, null,
|
||||||
responseType.length() > 0 ? responseType : null);
|
responseType.length() > 0 ? responseType : null);
|
||||||
|
|
||||||
assert params.headers != null;
|
assert params.headers != null;
|
||||||
requests.add(new HTTPRequest(method.toString().toLowerCase(Locale.ROOT), path,
|
|
||||||
|
// check if data needs to be extracted from response of this operation
|
||||||
|
Optional<DataExtractSubstituteParameter> dataExtract = getDataExtractSubstituteParameter(
|
||||||
|
dataExtractSubstituteParams, operationId);
|
||||||
|
|
||||||
|
// calculate order for this current request
|
||||||
|
Integer requestOrder = calculateRequestOrder(operationGroupingOrder, requests.size());
|
||||||
|
|
||||||
|
requests.put(requestOrder, new HTTPRequest(method.toString().toLowerCase(Locale.ROOT), path,
|
||||||
queryParams.size() > 0 ? queryParams : null,
|
queryParams.size() > 0 ? queryParams : null,
|
||||||
bodyOrFormParams.size() > 0 ? new HTTPBody(bodyOrFormParams) : null,
|
bodyOrFormParams.size() > 0 ? new HTTPBody(bodyOrFormParams) : null, hasRequestBodyExample,
|
||||||
params.headers.size() > 0 ? params : null, k6Checks.size() > 0 ? k6Checks : null));
|
params.headers.size() > 0 ? params : null, k6Checks.size() > 0 ? k6Checks : null,
|
||||||
|
dataExtract.orElse(null)));
|
||||||
}
|
}
|
||||||
requestGroups.add(new HTTPRequestGroup(path, pathVariables.get(path), requests));
|
|
||||||
|
addOrUpdateRequestGroup(requestGroups, groupName, pathVariables.get(groupName), requests);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (HTTPRequestGroup requestGroup : requestGroups) {
|
for (HTTPRequestGroup requestGroup : requestGroups.values()) {
|
||||||
for (HTTPRequest request : requestGroup.requests) {
|
for (HTTPRequest request : requestGroup.requests) {
|
||||||
if (request.path.contains("/{")) {
|
if (request.path.contains("/{")) {
|
||||||
request.path = request.path.replace("/{", "/${");
|
request.path = request.path.replace("/{", "/${");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// any variables not defined yet but used for subsequent data extraction must be
|
||||||
|
// initialized
|
||||||
|
initializeDataExtractSubstituteParameters(dataExtractSubstituteParams, requestGroup);
|
||||||
}
|
}
|
||||||
|
|
||||||
additionalProperties.put("requestGroups", requestGroups);
|
additionalProperties.put("requestGroups", requestGroups.values());
|
||||||
additionalProperties.put("extra", extraParameters);
|
additionalProperties.put("extra", extraParameters);
|
||||||
|
|
||||||
for (String[] supportingTemplateFile : JAVASCRIPT_SUPPORTING_FILES) {
|
for (String[] supportingTemplateFile : JAVASCRIPT_SUPPORTING_FILES) {
|
||||||
@ -749,4 +891,268 @@ public class K6ClientCodegen extends DefaultCodegen implements CodegenConfig {
|
|||||||
protected ImmutableMap.Builder<String, Lambda> addMustacheLambdas() {
|
protected ImmutableMap.Builder<String, Lambda> addMustacheLambdas() {
|
||||||
return super.addMustacheLambdas().put("handleParamValue", new ParameterValueLambda());
|
return super.addMustacheLambdas().put("handleParamValue", new ParameterValueLambda());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We're iterating over paths but grouping requests across paths, therefore
|
||||||
|
* these need to be aggregated.
|
||||||
|
*
|
||||||
|
* @param requestGroups
|
||||||
|
* @param groupName
|
||||||
|
* @param variables
|
||||||
|
* @param requests
|
||||||
|
*/
|
||||||
|
private void addOrUpdateRequestGroup(Map<String, HTTPRequestGroup> requestGroups, String groupName,
|
||||||
|
Set<Parameter> variables, Map<Integer, HTTPRequest> requests) {
|
||||||
|
if (requestGroups.containsKey(groupName)) {
|
||||||
|
HTTPRequestGroup existingHTTPRequestGroup = requestGroups.get(groupName);
|
||||||
|
existingHTTPRequestGroup.addRequests(requests);
|
||||||
|
existingHTTPRequestGroup.addVariables(variables);
|
||||||
|
} else {
|
||||||
|
requestGroups.put(groupName, new HTTPRequestGroup(groupName, variables, requests));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If `X_OPERATION_DATAEXTRACT` K6 vendor extension is present, extract info
|
||||||
|
* from it.
|
||||||
|
*
|
||||||
|
* @param openAPI
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private Map<String, DataExtractSubstituteParameter> getDataExtractSubstituteParameters(OpenAPI openAPI) {
|
||||||
|
Map<String, DataExtractSubstituteParameter> dataExtractSubstituteParams = new HashMap<>();
|
||||||
|
|
||||||
|
for (String path : openAPI.getPaths().keySet()) {
|
||||||
|
for (Map.Entry<PathItem.HttpMethod, Operation> methodOperation : openAPI.getPaths().get(path)
|
||||||
|
.readOperationsMap().entrySet()) {
|
||||||
|
|
||||||
|
final PathItem.HttpMethod method = methodOperation.getKey();
|
||||||
|
final Operation operation = methodOperation.getValue();
|
||||||
|
final CodegenOperation cgOperation = super.fromOperation(path, method.name(), operation, null);
|
||||||
|
|
||||||
|
if (cgOperation.getHasVendorExtensions()
|
||||||
|
&& cgOperation.vendorExtensions.containsKey(X_OPERATION_DATAEXTRACT)
|
||||||
|
&& cgOperation.vendorExtensions.get(X_OPERATION_DATAEXTRACT) instanceof java.util.Map) {
|
||||||
|
|
||||||
|
Optional<DataExtractSubstituteParameter> dataExtractSubstituteParameter = getDataExtractSubstituteParameter(
|
||||||
|
(Map<?, ?>) cgOperation.vendorExtensions.get(X_OPERATION_DATAEXTRACT));
|
||||||
|
|
||||||
|
// TODO: add support for extracting data for multiple params
|
||||||
|
dataExtractSubstituteParameter.ifPresent(extractSubstituteParameter -> dataExtractSubstituteParams.put(extractSubstituteParameter.operationId,
|
||||||
|
extractSubstituteParameter));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return dataExtractSubstituteParams;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Optionally, retrieve information specified in the `X_OPERATION_DATAEXTRACT`
|
||||||
|
* K6 vendor extension
|
||||||
|
*
|
||||||
|
* @param xOperationDataExtractProperties
|
||||||
|
* @return optional as only returned if all required info is present
|
||||||
|
*/
|
||||||
|
private Optional<DataExtractSubstituteParameter> getDataExtractSubstituteParameter(
|
||||||
|
Map<?, ?> xOperationDataExtractProperties) {
|
||||||
|
|
||||||
|
Optional<String> operationId = Optional.empty();
|
||||||
|
Optional<String> valuePath = Optional.empty();
|
||||||
|
Optional<String> parameterName = Optional.empty();
|
||||||
|
|
||||||
|
for (Map.Entry<?, ?> xOperationDataExtractPropertiesEntry : xOperationDataExtractProperties.entrySet()) {
|
||||||
|
|
||||||
|
switch (String.valueOf(xOperationDataExtractPropertiesEntry.getKey())) {
|
||||||
|
case X_OPERATION_DATAEXTRACT_OPERATION_ID:
|
||||||
|
operationId = Optional.of(String.valueOf(xOperationDataExtractPropertiesEntry.getValue()));
|
||||||
|
continue;
|
||||||
|
|
||||||
|
case X_OPERATION_DATAEXTRACT_VALUE_PATH:
|
||||||
|
valuePath = Optional.of(String.valueOf(xOperationDataExtractPropertiesEntry.getValue()));
|
||||||
|
continue;
|
||||||
|
|
||||||
|
case X_OPERATION_DATAEXTRACT_PARAMETER_NAME:
|
||||||
|
parameterName = Optional.of(String.valueOf(xOperationDataExtractPropertiesEntry.getValue()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (operationId.isPresent() && valuePath.isPresent() && parameterName.isPresent()) {
|
||||||
|
return Optional
|
||||||
|
.of(new DataExtractSubstituteParameter(operationId.get(), valuePath.get(), parameterName.get()));
|
||||||
|
|
||||||
|
} else {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Optionally, retrieve data extraction properties for given operation
|
||||||
|
*
|
||||||
|
* @param dataExtractSubstituteParams
|
||||||
|
* @param operationId
|
||||||
|
* @return optional as only returned if present for given operation
|
||||||
|
*/
|
||||||
|
private Optional<DataExtractSubstituteParameter> getDataExtractSubstituteParameter(
|
||||||
|
Map<String, DataExtractSubstituteParameter> dataExtractSubstituteParams, String operationId) {
|
||||||
|
|
||||||
|
return (!dataExtractSubstituteParams.isEmpty() && dataExtractSubstituteParams.containsKey(operationId))
|
||||||
|
? Optional.of(dataExtractSubstituteParams.get(operationId))
|
||||||
|
: Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Optionally, retrieve information specified in the `X_OPERATION_GROUPING` K6
|
||||||
|
* vendor extension
|
||||||
|
*
|
||||||
|
* @param cgOperation
|
||||||
|
* @return optional as only returned if required info is present
|
||||||
|
*/
|
||||||
|
private Optional<OperationGrouping> extractOperationGrouping(CodegenOperation cgOperation) {
|
||||||
|
Optional<OperationGrouping> operationGrouping = Optional.empty();
|
||||||
|
|
||||||
|
if (cgOperation.getHasVendorExtensions() && cgOperation.vendorExtensions.containsKey(X_OPERATION_GROUPING)
|
||||||
|
&& cgOperation.vendorExtensions.get(X_OPERATION_GROUPING) instanceof java.util.Map) {
|
||||||
|
|
||||||
|
Map.Entry<?, ?> operationGroupingEntry = ((Map<?, ?>) cgOperation.vendorExtensions
|
||||||
|
.get(X_OPERATION_GROUPING)).entrySet().stream().findFirst().get();
|
||||||
|
|
||||||
|
return Optional.of(new OperationGrouping(String.valueOf(operationGroupingEntry.getKey()),
|
||||||
|
Integer.parseInt(String.valueOf(operationGroupingEntry.getValue()))));
|
||||||
|
}
|
||||||
|
|
||||||
|
return operationGrouping;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If `X_OPERATION_RESPONSE` K6 vendor extension is present, check if given
|
||||||
|
* operation response should be hidden.
|
||||||
|
*
|
||||||
|
* @param resp
|
||||||
|
* @return true if should be hidden, false otherwise
|
||||||
|
*/
|
||||||
|
private boolean shouldHideOperationResponse(ApiResponse resp) {
|
||||||
|
boolean hideOperationResponse = false;
|
||||||
|
|
||||||
|
if (Objects.nonNull(resp.getExtensions()) && !resp.getExtensions().isEmpty()
|
||||||
|
&& resp.getExtensions().containsKey(X_OPERATION_RESPONSE)) {
|
||||||
|
|
||||||
|
Map<?, ?> respExtensions = (Map<?, ?>) resp.getExtensions().get(X_OPERATION_RESPONSE);
|
||||||
|
Entry<?, ?> entry = respExtensions.entrySet().stream().findFirst().orElse(null);
|
||||||
|
|
||||||
|
if (entry.getKey().equals(X_OPERATION_RESPONSE_HIDE)) {
|
||||||
|
return Boolean.parseBoolean(String.valueOf(entry.getValue()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if example is present for given request body and content type.
|
||||||
|
*
|
||||||
|
* @param requestBody
|
||||||
|
* @param contentTypeValue
|
||||||
|
* @return true if present, false otherwise
|
||||||
|
*/
|
||||||
|
private boolean hasRequestBodyExample(RequestBody requestBody, String contentTypeValue) {
|
||||||
|
return (Objects.nonNull(requestBody.getContent()) && requestBody.getContent().containsKey(contentTypeValue)
|
||||||
|
&& Objects.nonNull(requestBody.getContent().get(contentTypeValue).getExamples())
|
||||||
|
&& !requestBody.getContent().get(contentTypeValue).getExamples().isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract example for given request body.
|
||||||
|
*
|
||||||
|
* @param requestBody
|
||||||
|
* @param contentTypeValue
|
||||||
|
* @param bodyOrFormParams
|
||||||
|
*/
|
||||||
|
private void extractRequestBodyExample(RequestBody requestBody, String contentTypeValue,
|
||||||
|
List<Parameter> bodyOrFormParams) {
|
||||||
|
|
||||||
|
Optional<Map.Entry<String, Example>> requestBodyExampleEntry = requestBody.getContent().get(contentTypeValue)
|
||||||
|
.getExamples().entrySet().stream().findFirst();
|
||||||
|
|
||||||
|
if (requestBodyExampleEntry.isPresent()) {
|
||||||
|
|
||||||
|
Example requestBodyExample = requestBodyExampleEntry.get().getValue();
|
||||||
|
|
||||||
|
try {
|
||||||
|
JsonNode requestBodyExampleValueJsonNode = Json.mapper()
|
||||||
|
.readTree(String.valueOf(requestBodyExample.getValue()));
|
||||||
|
|
||||||
|
Iterator<Map.Entry<String, JsonNode>> fields = requestBodyExampleValueJsonNode.fields();
|
||||||
|
while (fields.hasNext()) {
|
||||||
|
Map.Entry<String, JsonNode> fieldsEntry = fields.next();
|
||||||
|
|
||||||
|
JsonNode exampleValueAsJsonNode = fieldsEntry.getValue();
|
||||||
|
|
||||||
|
Parameter k6Parameter = new Parameter(fieldsEntry.getKey(),
|
||||||
|
exampleValueAsJsonNode.isNumber() ? exampleValueAsJsonNode.asText()
|
||||||
|
: exampleValueAsJsonNode.toString());
|
||||||
|
|
||||||
|
bodyOrFormParams.add(k6Parameter);
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (JsonProcessingException e) {
|
||||||
|
LOGGER.error(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate order for this current request
|
||||||
|
*
|
||||||
|
* @param operationGroupingOrder
|
||||||
|
* @param requestsSize
|
||||||
|
* @return request order
|
||||||
|
*/
|
||||||
|
private Integer calculateRequestOrder(OptionalInt operationGroupingOrder, int requestsSize) {
|
||||||
|
int requestOrder;
|
||||||
|
|
||||||
|
if (operationGroupingOrder.isPresent()) {
|
||||||
|
requestOrder = operationGroupingOrder.getAsInt() - 1;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
switch (requestsSize) {
|
||||||
|
case 0:
|
||||||
|
case 1:
|
||||||
|
requestOrder = requestsSize;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
requestOrder = (requestsSize - 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return requestOrder;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
/**
|
||||||
|
* Any variables not defined yet but used for subsequent data extraction must be
|
||||||
|
* initialized
|
||||||
|
*
|
||||||
|
* @param dataExtractSubstituteParams
|
||||||
|
* @param requestGroup
|
||||||
|
*/
|
||||||
|
private void initializeDataExtractSubstituteParameters(
|
||||||
|
Map<String, DataExtractSubstituteParameter> dataExtractSubstituteParams, HTTPRequestGroup requestGroup) {
|
||||||
|
|
||||||
|
if (!dataExtractSubstituteParams.isEmpty()) {
|
||||||
|
Set<String> existingVariablesNames = requestGroup.variables.stream().map(v -> v.key)
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
|
||||||
|
Set<DataExtractSubstituteParameter> initializeVariables = dataExtractSubstituteParams.values().stream()
|
||||||
|
.filter(p -> !existingVariablesNames.contains(toVarName(p.paramName))).collect(Collectors.toSet());
|
||||||
|
|
||||||
|
for (DataExtractSubstituteParameter initializeVariable : initializeVariables) {
|
||||||
|
requestGroup.variables.add(new Parameter(toVarName(initializeVariable.paramName), true));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -19,48 +19,50 @@ export default function() {
|
|||||||
let {{{key}}} = {{#lambda.handleParamValue}}{{value}}{{/lambda.handleParamValue}}
|
let {{{key}}} = {{#lambda.handleParamValue}}{{value}}{{/lambda.handleParamValue}}
|
||||||
{{/variables}}
|
{{/variables}}
|
||||||
{{#requests}}
|
{{#requests}}
|
||||||
{{#-first}}
|
|
||||||
let url = BASE_URL + `{{{path}}}{{=<% %>=}}<%#query%><%#-first%>?<%/-first%><%& key%>=<%& value%><%^-last%>&<%/-last%><%/query%><%={{ }}=%>`;
|
|
||||||
// Request No. {{-index}}
|
|
||||||
{{#body}}
|
|
||||||
// TODO: edit the parameters of the request body.
|
|
||||||
let body = {{#body}}{{=<% %>=}}{<%#parameters%>"<%& key%>": <%& value%><%^-last%>, <%/-last%><%/parameters%>}<%={{ }}=%>{{/body}};
|
|
||||||
{{/body}}
|
|
||||||
{{#params}}
|
|
||||||
let params = {{#params}}{{=<% %>=}}{headers: {<%# headers%>"<%& key%>": <%& value%><%^-last%>, <%/-last%><%/headers%><%#responseType%>, "Accept": <%& responseType%><%/responseType%>}<%# auth%>, auth: "<%& auth%>"<%/auth%>}<%={{ }}=%>{{/params}};
|
|
||||||
{{/params}}
|
|
||||||
let request = http.{{method}}(url{{#body}}, body{{/body}}{{#params}}, params{{/params}});
|
|
||||||
{{#k6Checks}}
|
|
||||||
{{=<% %>=}}
|
|
||||||
check(request, {
|
|
||||||
"<%& description%>": (r) => r.status === <%& status%>
|
|
||||||
});
|
|
||||||
<%={{ }}=%>
|
|
||||||
{{/k6Checks}}
|
|
||||||
{{/-first}}
|
|
||||||
{{^-first}}
|
|
||||||
// Request No. {{-index}}
|
|
||||||
{{#body}}
|
|
||||||
// TODO: edit the parameters of the request body.
|
|
||||||
body = {{#body}}{{=<% %>=}}{<%#parameters%>"<%& key%>": <%& value%><%^-last%>, <%/-last%><%/parameters%>}<%={{ }}=%>{{/body}};
|
|
||||||
{{/body}}
|
|
||||||
{{#params}}
|
|
||||||
params = {{#params}}{{=<% %>=}}{headers: {<%# headers%>"<%& key%>": <%& value%><%^-last%>, <%/-last%><%/headers%>}<%# auth%>, auth: "<%& auth%>"<%/auth%>}<%={{ }}=%>{{/params}};
|
|
||||||
{{/params}}
|
|
||||||
request = http.{{method}}(url{{#body}}, body{{/body}}{{#params}}, params{{/params}});
|
|
||||||
{{#k6Checks}}
|
|
||||||
{{=<% %>=}}
|
|
||||||
check(request, {
|
|
||||||
"<%& description%>": (r) => r.status === <%& status%>
|
|
||||||
});
|
|
||||||
<%={{ }}=%>
|
|
||||||
{{/k6Checks}}
|
|
||||||
{{/-first}}
|
|
||||||
sleep(SLEEP_DURATION);
|
|
||||||
{{^-last}}
|
|
||||||
|
|
||||||
{{/-last}}
|
// Request No. {{-index}}
|
||||||
|
{
|
||||||
|
let url = BASE_URL + `{{{path}}}{{=<% %>=}}<%#query%><%#-first%>?<%/-first%><%& key%>=<%& value%><%^-last%>&<%/-last%><%/query%><%={{ }}=%>`;
|
||||||
|
{{#body}}
|
||||||
|
{{^hasBodyExample}}
|
||||||
|
// TODO: edit the parameters of the request body.
|
||||||
|
{{/hasBodyExample}}
|
||||||
|
let body = {{#body}}{{=<% %>=}}{<%#parameters%>"<%& key%>": <%& value%><%^-last%>, <%/-last%><%/parameters%>}<%={{ }}=%>{{/body}};
|
||||||
|
{{/body}}
|
||||||
|
{{#params}}
|
||||||
|
let params = {{#params}}{{=<% %>=}}{headers: {<%# headers%>"<%& key%>": <%& value%><%^-last%>, <%/-last%><%/headers%><%#responseType%>, "Accept": <%& responseType%><%/responseType%>}<%# auth%>, auth: "<%& auth%>"<%/auth%>}<%={{ }}=%>{{/params}};
|
||||||
|
{{/params}}
|
||||||
|
{{#isDelete}}
|
||||||
|
{{#params}}
|
||||||
|
// this is a DELETE method request - if params are also set, empty body must be passed
|
||||||
|
let request = http.{{method}}(url, {} {{#params}}, params{{/params}});
|
||||||
|
{{/params}}
|
||||||
|
{{^params}}
|
||||||
|
let request = http.{{method}}(url);
|
||||||
|
{{/params}}
|
||||||
|
{{/isDelete}}
|
||||||
|
{{^isDelete}}
|
||||||
|
let request = http.{{method}}(url{{#body}}, JSON.stringify(body){{/body}}{{#params}}, params{{/params}});
|
||||||
|
{{/isDelete}}
|
||||||
|
|
||||||
|
{{#k6Checks}}
|
||||||
|
{{=<% %>=}}
|
||||||
|
check(request, {
|
||||||
|
"<%& description%>": (r) => r.status === <%& status%>
|
||||||
|
});
|
||||||
|
<%={{ }}=%>
|
||||||
|
{{/k6Checks}}
|
||||||
|
{{#dataExtract}}
|
||||||
|
|
||||||
|
{{{paramName}}} = JSON.parse(request.body).{{{valuePath}}}; // extract data for subsequent use
|
||||||
|
{{/dataExtract}}
|
||||||
|
{{^-last}}
|
||||||
|
|
||||||
|
sleep(SLEEP_DURATION);
|
||||||
|
{{/-last}}
|
||||||
|
}
|
||||||
{{/requests}}
|
{{/requests}}
|
||||||
});
|
});
|
||||||
|
|
||||||
{{/requestGroups}}
|
{{/requestGroups}}
|
||||||
}
|
}
|
||||||
|
1
pom.xml
1
pom.xml
@ -1545,6 +1545,7 @@
|
|||||||
<commons-cli.version>1.4</commons-cli.version>
|
<commons-cli.version>1.4</commons-cli.version>
|
||||||
<commons-io.version>2.11.0</commons-io.version>
|
<commons-io.version>2.11.0</commons-io.version>
|
||||||
<commons-lang.version>3.12.0</commons-lang.version>
|
<commons-lang.version>3.12.0</commons-lang.version>
|
||||||
|
<commons-text.version>1.9</commons-text.version>
|
||||||
<diffutils.version>1.3.0</diffutils.version>
|
<diffutils.version>1.3.0</diffutils.version>
|
||||||
<generex.version>1.0.2</generex.version>
|
<generex.version>1.0.2</generex.version>
|
||||||
<git-commit-id-plugin.version>4.9.10</git-commit-id-plugin.version>
|
<git-commit-id-plugin.version>4.9.10</git-commit-id-plugin.version>
|
||||||
|
2
samples/client/petstore/k6/.openapi-generator/FILES
Normal file
2
samples/client/petstore/k6/.openapi-generator/FILES
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
README.md
|
||||||
|
script.js
|
@ -1 +1 @@
|
|||||||
5.3.0-SNAPSHOT
|
5.3.1-SNAPSHOT
|
@ -1,204 +1,576 @@
|
|||||||
/*
|
/*
|
||||||
* OpenAPI Petstore
|
* OpenAPI Petstore
|
||||||
* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
|
* This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\
|
||||||
*
|
*
|
||||||
* OpenAPI spec version: 1.0.0
|
* OpenAPI spec version: 1.0.0
|
||||||
*
|
*
|
||||||
* NOTE: This class is auto generated by OpenAPI Generator.
|
* NOTE: This class is auto generated by OpenAPI Generator.
|
||||||
* https://github.com/OpenAPITools/openapi-generator
|
* https://github.com/OpenAPITools/openapi-generator
|
||||||
*
|
*
|
||||||
* OpenAPI generator version: 5.3.0-SNAPSHOT
|
* OpenAPI generator version: 5.3.1-SNAPSHOT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
import http from "k6/http";
|
import http from "k6/http";
|
||||||
import { group, check, sleep } from "k6";
|
import { group, check, sleep } from "k6";
|
||||||
|
|
||||||
const BASE_URL = "http://petstore.swagger.io/v2";
|
const BASE_URL = "https://127.0.0.1/no_varaible";
|
||||||
// Sleep duration between successive requests.
|
// Sleep duration between successive requests.
|
||||||
// You might want to edit the value of this variable or remove calls to the sleep function on the script.
|
// You might want to edit the value of this variable or remove calls to the sleep function on the script.
|
||||||
const SLEEP_DURATION = 0.1;
|
const SLEEP_DURATION = 0.1;
|
||||||
// Global variables should be initialized.
|
// Global variables should be initialized.
|
||||||
|
let booleanGroup = "TODO_EDIT_THE_BOOLEAN_GROUP";
|
||||||
|
let header1 = "TODO_EDIT_THE_HEADER_1";
|
||||||
let apiKey = "TODO_EDIT_THE_API_KEY";
|
let apiKey = "TODO_EDIT_THE_API_KEY";
|
||||||
|
let requiredBooleanGroup = "TODO_EDIT_THE_REQUIRED_BOOLEAN_GROUP";
|
||||||
|
let enumHeaderStringArray = "TODO_EDIT_THE_ENUM_HEADER_STRING_ARRAY";
|
||||||
|
let enumHeaderString = "TODO_EDIT_THE_ENUM_HEADER_STRING";
|
||||||
|
|
||||||
export default function() {
|
export default function() {
|
||||||
|
group("/fake", () => {
|
||||||
|
let enumQueryInteger = 'TODO_EDIT_THE_ENUM_QUERY_INTEGER'; // specify value as there is no example value for this parameter in OpenAPI spec
|
||||||
|
let enumQueryString = 'TODO_EDIT_THE_ENUM_QUERY_STRING'; // specify value as there is no example value for this parameter in OpenAPI spec
|
||||||
|
let enumQueryStringArray = 'TODO_EDIT_THE_ENUM_QUERY_STRING_ARRAY'; // specify value as there is no example value for this parameter in OpenAPI spec
|
||||||
|
let enumQueryDouble = 'TODO_EDIT_THE_ENUM_QUERY_DOUBLE'; // specify value as there is no example value for this parameter in OpenAPI spec
|
||||||
|
|
||||||
|
// Request No. 1
|
||||||
|
{
|
||||||
|
let url = BASE_URL + `/fake?enum_query_string_array=${enum_query_string_array}&enum_query_string=${enum_query_string}&enum_query_integer=${enum_query_integer}&enum_query_double=${enum_query_double}`;
|
||||||
|
// TODO: edit the parameters of the request body.
|
||||||
|
let body = {"enumFormStringArray": "list", "enumFormString": "string"};
|
||||||
|
let params = {headers: {"Content-Type": "application/x-www-form-urlencoded", "enum_header_string_array": `${enumHeaderStringArray}`, "enum_header_string": `${enumHeaderString}`, "Accept": "application/json"}};
|
||||||
|
let request = http.get(url, JSON.stringify(body), params);
|
||||||
|
|
||||||
|
|
||||||
|
sleep(SLEEP_DURATION);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Request No. 2
|
||||||
|
{
|
||||||
|
let url = BASE_URL + `/fake`;
|
||||||
|
// TODO: edit the parameters of the request body.
|
||||||
|
let body = {"client": "string"};
|
||||||
|
let params = {headers: {"Content-Type": "application/json", "Accept": "application/json"}};
|
||||||
|
let request = http.patch(url, JSON.stringify(body), params);
|
||||||
|
|
||||||
|
check(request, {
|
||||||
|
"successful operation": (r) => r.status === 200
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
group("/fake/outer/boolean", () => {
|
||||||
|
|
||||||
|
// Request No. 1
|
||||||
|
{
|
||||||
|
let url = BASE_URL + `/fake/outer/boolean`;
|
||||||
|
let params = {headers: {"Content-Type": "application/json", "Accept": "*/*"}};
|
||||||
|
let request = http.post(url, params);
|
||||||
|
|
||||||
|
check(request, {
|
||||||
|
"Output boolean": (r) => r.status === 200
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
group("/another-fake/dummy", () => {
|
||||||
|
|
||||||
|
// Request No. 1
|
||||||
|
{
|
||||||
|
let url = BASE_URL + `/another-fake/dummy`;
|
||||||
|
// TODO: edit the parameters of the request body.
|
||||||
|
let body = {"client": "string"};
|
||||||
|
let params = {headers: {"Content-Type": "application/json", "Accept": "application/json"}};
|
||||||
|
let request = http.patch(url, JSON.stringify(body), params);
|
||||||
|
|
||||||
|
check(request, {
|
||||||
|
"successful operation": (r) => r.status === 200
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
group("/pet", () => {
|
group("/pet", () => {
|
||||||
let url = BASE_URL + `/pet`;
|
|
||||||
// Request No. 1
|
// Request No. 1
|
||||||
// TODO: edit the parameters of the request body.
|
{
|
||||||
let body = {"id": "long", "category": {"id": "long", "name": "string"}, "name": "string", "photoUrls": "list", "tags": [{"id": "long", "name": "string"}], "status": "string"};
|
let url = BASE_URL + `/pet`;
|
||||||
let params = {headers: {"Content-Type": "application/json", "Accept": "application/json"}};
|
// TODO: edit the parameters of the request body.
|
||||||
let request = http.put(url, body, params);
|
let body = {"id": "long", "category": {"id": "long", "name": "string"}, "name": "string", "photoUrls": "set", "tags": "list", "status": "string"};
|
||||||
sleep(SLEEP_DURATION);
|
let params = {headers: {"Content-Type": "application/json", "Accept": "application/json"}};
|
||||||
|
let request = http.put(url, JSON.stringify(body), params);
|
||||||
|
|
||||||
|
check(request, {
|
||||||
|
"Successful operation": (r) => r.status === 200
|
||||||
|
});
|
||||||
|
|
||||||
|
sleep(SLEEP_DURATION);
|
||||||
|
}
|
||||||
|
|
||||||
// Request No. 2
|
// Request No. 2
|
||||||
// TODO: edit the parameters of the request body.
|
{
|
||||||
body = {"id": "long", "category": {"id": "long", "name": "string"}, "name": "string", "photoUrls": "list", "tags": [{"id": "long", "name": "string"}], "status": "string"};
|
let url = BASE_URL + `/pet`;
|
||||||
params = {headers: {"Content-Type": "application/json"}};
|
// TODO: edit the parameters of the request body.
|
||||||
request = http.post(url, body, params);
|
let body = {"id": "long", "category": {"id": "long", "name": "string"}, "name": "string", "photoUrls": "set", "tags": "list", "status": "string"};
|
||||||
sleep(SLEEP_DURATION);
|
let params = {headers: {"Content-Type": "application/json", "Accept": "application/json"}};
|
||||||
|
let request = http.post(url, JSON.stringify(body), params);
|
||||||
|
|
||||||
|
check(request, {
|
||||||
|
"Successful operation": (r) => r.status === 200
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
group("/pet/findByStatus", () => {
|
|
||||||
let status = 'TODO_EDIT_THE_STATUS'; // specify value as there is no example value for this parameter in OpenAPI spec
|
group("/user/{username}", () => {
|
||||||
let url = BASE_URL + `/pet/findByStatus?status=${status}`;
|
let username = 'TODO_EDIT_THE_USERNAME'; // specify value as there is no example value for this parameter in OpenAPI spec
|
||||||
|
|
||||||
// Request No. 1
|
// Request No. 1
|
||||||
let request = http.get(url);
|
{
|
||||||
check(request, {
|
let url = BASE_URL + `/user/${username}`;
|
||||||
"successful operation": (r) => r.status === 200
|
let request = http.get(url);
|
||||||
});
|
|
||||||
sleep(SLEEP_DURATION);
|
check(request, {
|
||||||
});
|
"successful operation": (r) => r.status === 200
|
||||||
group("/pet/findByTags", () => {
|
});
|
||||||
let tags = 'TODO_EDIT_THE_TAGS'; // specify value as there is no example value for this parameter in OpenAPI spec
|
|
||||||
let url = BASE_URL + `/pet/findByTags?tags=${tags}`;
|
sleep(SLEEP_DURATION);
|
||||||
// Request No. 1
|
}
|
||||||
let request = http.get(url);
|
|
||||||
check(request, {
|
|
||||||
"successful operation": (r) => r.status === 200
|
|
||||||
});
|
|
||||||
sleep(SLEEP_DURATION);
|
|
||||||
});
|
|
||||||
group("/pet/{petId}", () => {
|
|
||||||
let petId = 'TODO_EDIT_THE_PETID'; // specify value as there is no example value for this parameter in OpenAPI spec
|
|
||||||
let url = BASE_URL + `/pet/${petId}`;
|
|
||||||
// Request No. 1
|
|
||||||
let request = http.get(url);
|
|
||||||
check(request, {
|
|
||||||
"successful operation": (r) => r.status === 200
|
|
||||||
});
|
|
||||||
sleep(SLEEP_DURATION);
|
|
||||||
|
|
||||||
// Request No. 2
|
// Request No. 2
|
||||||
// TODO: edit the parameters of the request body.
|
{
|
||||||
body = {"name": "string", "status": "string"};
|
let url = BASE_URL + `/user/${username}`;
|
||||||
params = {headers: {"Content-Type": "application/x-www-form-urlencoded"}};
|
let request = http.del(url);
|
||||||
request = http.post(url, body, params);
|
|
||||||
sleep(SLEEP_DURATION);
|
|
||||||
|
|
||||||
// Request No. 3
|
}
|
||||||
params = {headers: {"api_key": `${apiKey}`}};
|
|
||||||
request = http.del(url, params);
|
|
||||||
sleep(SLEEP_DURATION);
|
|
||||||
});
|
});
|
||||||
group("/pet/{petId}/uploadImage", () => {
|
|
||||||
let petId = 'TODO_EDIT_THE_PETID'; // specify value as there is no example value for this parameter in OpenAPI spec
|
|
||||||
let url = BASE_URL + `/pet/${petId}/uploadImage`;
|
|
||||||
// Request No. 1
|
|
||||||
// TODO: edit the parameters of the request body.
|
|
||||||
let body = {"additionalMetadata": "string", "file": http.file(open("/path/to/file.bin", "b"), "test.bin")};
|
|
||||||
let params = {headers: {"Content-Type": "multipart/form-data", "Accept": "application/json"}};
|
|
||||||
let request = http.post(url, body, params);
|
|
||||||
check(request, {
|
|
||||||
"successful operation": (r) => r.status === 200
|
|
||||||
});
|
|
||||||
sleep(SLEEP_DURATION);
|
|
||||||
});
|
|
||||||
group("/store/inventory", () => {
|
|
||||||
let url = BASE_URL + `/store/inventory`;
|
|
||||||
// Request No. 1
|
|
||||||
let request = http.get(url);
|
|
||||||
check(request, {
|
|
||||||
"successful operation": (r) => r.status === 200
|
|
||||||
});
|
|
||||||
sleep(SLEEP_DURATION);
|
|
||||||
});
|
|
||||||
group("/store/order", () => {
|
|
||||||
let url = BASE_URL + `/store/order`;
|
|
||||||
// Request No. 1
|
|
||||||
// TODO: edit the parameters of the request body.
|
|
||||||
let body = {"id": "long", "petId": "long", "quantity": "integer", "shipDate": "date", "status": "string", "complete": "boolean"};
|
|
||||||
let params = {headers: {"Content-Type": "application/json", "Accept": "application/json"}};
|
|
||||||
let request = http.post(url, body, params);
|
|
||||||
check(request, {
|
|
||||||
"successful operation": (r) => r.status === 200
|
|
||||||
});
|
|
||||||
sleep(SLEEP_DURATION);
|
|
||||||
});
|
|
||||||
group("/store/order/{orderId}", () => {
|
|
||||||
let orderId = 'TODO_EDIT_THE_ORDERID'; // specify value as there is no example value for this parameter in OpenAPI spec
|
|
||||||
let url = BASE_URL + `/store/order/${orderId}`;
|
|
||||||
// Request No. 1
|
|
||||||
let request = http.get(url);
|
|
||||||
check(request, {
|
|
||||||
"successful operation": (r) => r.status === 200
|
|
||||||
});
|
|
||||||
sleep(SLEEP_DURATION);
|
|
||||||
|
|
||||||
// Request No. 2
|
group("/fake/body-with-binary", () => {
|
||||||
request = http.del(url);
|
|
||||||
sleep(SLEEP_DURATION);
|
|
||||||
});
|
|
||||||
group("/user", () => {
|
|
||||||
let url = BASE_URL + `/user`;
|
|
||||||
// Request No. 1
|
// Request No. 1
|
||||||
// TODO: edit the parameters of the request body.
|
{
|
||||||
let body = {"id": "long", "username": "string", "firstName": "string", "lastName": "string", "email": "string", "password": "string", "phone": "string", "userStatus": "integer"};
|
let url = BASE_URL + `/fake/body-with-binary`;
|
||||||
let params = {headers: {"Content-Type": "application/json", "Accept": "application/json"}};
|
let params = {headers: {"Content-Type": "image/png", "Accept": "application/json"}};
|
||||||
let request = http.post(url, body, params);
|
let request = http.put(url, params);
|
||||||
check(request, {
|
|
||||||
"successful operation": (r) => r.status === 200
|
check(request, {
|
||||||
});
|
"Success": (r) => r.status === 200
|
||||||
sleep(SLEEP_DURATION);
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
group("/user/createWithArray", () => {
|
|
||||||
let url = BASE_URL + `/user/createWithArray`;
|
group("/fake_classname_test", () => {
|
||||||
|
|
||||||
// Request No. 1
|
// Request No. 1
|
||||||
let params = {headers: {"Content-Type": "application/json", "Accept": "application/json"}};
|
{
|
||||||
let request = http.post(url, params);
|
let url = BASE_URL + `/fake_classname_test`;
|
||||||
check(request, {
|
// TODO: edit the parameters of the request body.
|
||||||
"successful operation": (r) => r.status === 200
|
let body = {"client": "string"};
|
||||||
});
|
let params = {headers: {"Content-Type": "application/json", "Accept": "application/json"}};
|
||||||
sleep(SLEEP_DURATION);
|
let request = http.patch(url, JSON.stringify(body), params);
|
||||||
|
|
||||||
|
check(request, {
|
||||||
|
"successful operation": (r) => r.status === 200
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
group("/user/createWithList", () => {
|
group("/user/createWithList", () => {
|
||||||
let url = BASE_URL + `/user/createWithList`;
|
|
||||||
// Request No. 1
|
// Request No. 1
|
||||||
let params = {headers: {"Content-Type": "application/json", "Accept": "application/json"}};
|
{
|
||||||
let request = http.post(url, params);
|
let url = BASE_URL + `/user/createWithList`;
|
||||||
check(request, {
|
let params = {headers: {"Content-Type": "application/json", "Accept": "application/json"}};
|
||||||
"successful operation": (r) => r.status === 200
|
let request = http.post(url, params);
|
||||||
});
|
|
||||||
sleep(SLEEP_DURATION);
|
check(request, {
|
||||||
|
"successful operation": (r) => r.status === 200
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
group("/fake/inline-additionalProperties", () => {
|
||||||
|
|
||||||
|
// Request No. 1
|
||||||
|
{
|
||||||
|
let url = BASE_URL + `/fake/inline-additionalProperties`;
|
||||||
|
let params = {headers: {"Content-Type": "application/json", "Accept": "application/json"}};
|
||||||
|
let request = http.post(url, params);
|
||||||
|
|
||||||
|
check(request, {
|
||||||
|
"successful operation": (r) => r.status === 200
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
group("/store/inventory", () => {
|
||||||
|
|
||||||
|
// Request No. 1
|
||||||
|
{
|
||||||
|
let url = BASE_URL + `/store/inventory`;
|
||||||
|
let request = http.get(url);
|
||||||
|
|
||||||
|
check(request, {
|
||||||
|
"successful operation": (r) => r.status === 200
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
group("/user/login", () => {
|
group("/user/login", () => {
|
||||||
let password = 'TODO_EDIT_THE_PASSWORD'; // specify value as there is no example value for this parameter in OpenAPI spec
|
let password = 'TODO_EDIT_THE_PASSWORD'; // specify value as there is no example value for this parameter in OpenAPI spec
|
||||||
let username = 'TODO_EDIT_THE_USERNAME'; // specify value as there is no example value for this parameter in OpenAPI spec
|
let username = 'TODO_EDIT_THE_USERNAME'; // specify value as there is no example value for this parameter in OpenAPI spec
|
||||||
let url = BASE_URL + `/user/login?username=${username}&password=${password}`;
|
|
||||||
// Request No. 1
|
// Request No. 1
|
||||||
let request = http.get(url);
|
{
|
||||||
check(request, {
|
let url = BASE_URL + `/user/login?username=${username}&password=${password}`;
|
||||||
"successful operation": (r) => r.status === 200
|
let request = http.get(url);
|
||||||
});
|
|
||||||
sleep(SLEEP_DURATION);
|
check(request, {
|
||||||
|
"successful operation": (r) => r.status === 200
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
group("/user/logout", () => {
|
|
||||||
let url = BASE_URL + `/user/logout`;
|
group("/fake/outer/composite", () => {
|
||||||
|
|
||||||
// Request No. 1
|
// Request No. 1
|
||||||
let request = http.get(url);
|
{
|
||||||
check(request, {
|
let url = BASE_URL + `/fake/outer/composite`;
|
||||||
"successful operation": (r) => r.status === 200
|
// TODO: edit the parameters of the request body.
|
||||||
});
|
let body = {"myNumber": "bigdecimal", "myString": "string", "myBoolean": "boolean"};
|
||||||
sleep(SLEEP_DURATION);
|
let params = {headers: {"Content-Type": "application/json", "Accept": "*/*"}};
|
||||||
|
let request = http.post(url, JSON.stringify(body), params);
|
||||||
|
|
||||||
|
check(request, {
|
||||||
|
"Output composite": (r) => r.status === 200
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
group("/user/{username}", () => {
|
|
||||||
let username = 'TODO_EDIT_THE_USERNAME'; // specify value as there is no example value for this parameter in OpenAPI spec
|
group("/fake/jsonFormData", () => {
|
||||||
let url = BASE_URL + `/user/${username}`;
|
|
||||||
// Request No. 1
|
// Request No. 1
|
||||||
let request = http.get(url);
|
{
|
||||||
check(request, {
|
let url = BASE_URL + `/fake/jsonFormData`;
|
||||||
"successful operation": (r) => r.status === 200
|
// TODO: edit the parameters of the request body.
|
||||||
});
|
let body = {"param": "string", "param2": "string"};
|
||||||
sleep(SLEEP_DURATION);
|
let params = {headers: {"Content-Type": "application/x-www-form-urlencoded", "Accept": "application/json"}};
|
||||||
|
let request = http.get(url, JSON.stringify(body), params);
|
||||||
|
|
||||||
|
check(request, {
|
||||||
|
"successful operation": (r) => r.status === 200
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
group("/fake/{petId}/uploadImageWithRequiredFile", () => {
|
||||||
|
let petId = 'TODO_EDIT_THE_PETID'; // specify value as there is no example value for this parameter in OpenAPI spec
|
||||||
|
|
||||||
|
// Request No. 1
|
||||||
|
{
|
||||||
|
let url = BASE_URL + `/fake/${petId}/uploadImageWithRequiredFile`;
|
||||||
|
// TODO: edit the parameters of the request body.
|
||||||
|
let body = {"additionalMetadata": "string", "requiredFile": http.file(open("/path/to/file.bin", "b"), "test.bin")};
|
||||||
|
let params = {headers: {"Content-Type": "multipart/form-data", "Accept": "application/json"}};
|
||||||
|
let request = http.post(url, JSON.stringify(body), params);
|
||||||
|
|
||||||
|
check(request, {
|
||||||
|
"successful operation": (r) => r.status === 200
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
group("/pet/{petId}", () => {
|
||||||
|
let petId = 'TODO_EDIT_THE_PETID'; // specify value as there is no example value for this parameter in OpenAPI spec
|
||||||
|
|
||||||
|
// Request No. 1
|
||||||
|
{
|
||||||
|
let url = BASE_URL + `/pet/${petId}`;
|
||||||
|
let request = http.get(url);
|
||||||
|
|
||||||
|
check(request, {
|
||||||
|
"successful operation": (r) => r.status === 200
|
||||||
|
});
|
||||||
|
|
||||||
|
sleep(SLEEP_DURATION);
|
||||||
|
}
|
||||||
|
|
||||||
// Request No. 2
|
// Request No. 2
|
||||||
// TODO: edit the parameters of the request body.
|
{
|
||||||
body = {"id": "long", "username": "string", "firstName": "string", "lastName": "string", "email": "string", "password": "string", "phone": "string", "userStatus": "integer"};
|
let url = BASE_URL + `/pet/${petId}`;
|
||||||
params = {headers: {"Content-Type": "application/json"}};
|
let params = {headers: {"api_key": `${apiKey}`, "Accept": "application/json"}};
|
||||||
request = http.put(url, body, params);
|
// this is a DELETE method request - if params are also set, empty body must be passed
|
||||||
sleep(SLEEP_DURATION);
|
let request = http.del(url, {} , params);
|
||||||
|
|
||||||
// Request No. 3
|
check(request, {
|
||||||
request = http.del(url);
|
"Successful operation": (r) => r.status === 200
|
||||||
sleep(SLEEP_DURATION);
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
group("/foo", () => {
|
||||||
|
|
||||||
|
// Request No. 1
|
||||||
|
{
|
||||||
|
let url = BASE_URL + `/foo`;
|
||||||
|
let request = http.get(url);
|
||||||
|
|
||||||
|
check(request, {
|
||||||
|
"response": (r) => r.status === 200
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
group("/fake/outer/string", () => {
|
||||||
|
|
||||||
|
// Request No. 1
|
||||||
|
{
|
||||||
|
let url = BASE_URL + `/fake/outer/string`;
|
||||||
|
let params = {headers: {"Content-Type": "application/json", "Accept": "*/*"}};
|
||||||
|
let request = http.post(url, params);
|
||||||
|
|
||||||
|
check(request, {
|
||||||
|
"Output string": (r) => r.status === 200
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
group("/fake/test-query-parameters", () => {
|
||||||
|
let allowEmpty = 'TODO_EDIT_THE_ALLOWEMPTY'; // specify value as there is no example value for this parameter in OpenAPI spec
|
||||||
|
let ioutil = 'TODO_EDIT_THE_IOUTIL'; // specify value as there is no example value for this parameter in OpenAPI spec
|
||||||
|
let context = 'TODO_EDIT_THE_CONTEXT'; // specify value as there is no example value for this parameter in OpenAPI spec
|
||||||
|
let http = 'TODO_EDIT_THE_HTTP'; // specify value as there is no example value for this parameter in OpenAPI spec
|
||||||
|
let pipe = 'TODO_EDIT_THE_PIPE'; // specify value as there is no example value for this parameter in OpenAPI spec
|
||||||
|
let language = 'TODO_EDIT_THE_LANGUAGE'; // specify value as there is no example value for this parameter in OpenAPI spec
|
||||||
|
let url = 'TODO_EDIT_THE_URL'; // specify value as there is no example value for this parameter in OpenAPI spec
|
||||||
|
|
||||||
|
// Request No. 1
|
||||||
|
{
|
||||||
|
let url = BASE_URL + `/fake/test-query-parameters?pipe=${pipe}&ioutil=${ioutil}&http=${http}&url=${url}&context=${context}&language=${language}&allowEmpty=${allowEmpty}`;
|
||||||
|
let request = http.put(url);
|
||||||
|
|
||||||
|
check(request, {
|
||||||
|
"Success": (r) => r.status === 200
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
group("/store/order/{order_id}", () => {
|
||||||
|
let orderId = 'TODO_EDIT_THE_ORDER_ID'; // specify value as there is no example value for this parameter in OpenAPI spec
|
||||||
|
|
||||||
|
// Request No. 1
|
||||||
|
{
|
||||||
|
let url = BASE_URL + `/store/order/${order_id}`;
|
||||||
|
let request = http.get(url);
|
||||||
|
|
||||||
|
check(request, {
|
||||||
|
"successful operation": (r) => r.status === 200
|
||||||
|
});
|
||||||
|
|
||||||
|
sleep(SLEEP_DURATION);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Request No. 2
|
||||||
|
{
|
||||||
|
let url = BASE_URL + `/store/order/${order_id}`;
|
||||||
|
let request = http.del(url);
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
group("/pet/findByStatus", () => {
|
||||||
|
let status = 'TODO_EDIT_THE_STATUS'; // specify value as there is no example value for this parameter in OpenAPI spec
|
||||||
|
|
||||||
|
// Request No. 1
|
||||||
|
{
|
||||||
|
let url = BASE_URL + `/pet/findByStatus?status=${status}`;
|
||||||
|
let request = http.get(url);
|
||||||
|
|
||||||
|
check(request, {
|
||||||
|
"successful operation": (r) => r.status === 200
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
group("/fake/body-with-query-params", () => {
|
||||||
|
let query = 'TODO_EDIT_THE_QUERY'; // specify value as there is no example value for this parameter in OpenAPI spec
|
||||||
|
|
||||||
|
// Request No. 1
|
||||||
|
{
|
||||||
|
let url = BASE_URL + `/fake/body-with-query-params?query=${query}`;
|
||||||
|
// TODO: edit the parameters of the request body.
|
||||||
|
let body = {"id": "long", "username": "string", "firstName": "string", "lastName": "string", "email": "string", "password": "string", "phone": "string", "userStatus": "integer"};
|
||||||
|
let params = {headers: {"Content-Type": "application/json", "Accept": "application/json"}};
|
||||||
|
let request = http.put(url, JSON.stringify(body), params);
|
||||||
|
|
||||||
|
check(request, {
|
||||||
|
"Success": (r) => r.status === 200
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
group("/pet/{petId}/uploadImage", () => {
|
||||||
|
let petId = 'TODO_EDIT_THE_PETID'; // specify value as there is no example value for this parameter in OpenAPI spec
|
||||||
|
|
||||||
|
// Request No. 1
|
||||||
|
{
|
||||||
|
let url = BASE_URL + `/pet/${petId}/uploadImage`;
|
||||||
|
// TODO: edit the parameters of the request body.
|
||||||
|
let body = {"additionalMetadata": "string", "file": http.file(open("/path/to/file.bin", "b"), "test.bin")};
|
||||||
|
let params = {headers: {"Content-Type": "multipart/form-data", "Accept": "application/json"}};
|
||||||
|
let request = http.post(url, JSON.stringify(body), params);
|
||||||
|
|
||||||
|
check(request, {
|
||||||
|
"successful operation": (r) => r.status === 200
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
group("/fake/http-signature-test", () => {
|
||||||
|
let query1 = 'TODO_EDIT_THE_QUERY_1'; // specify value as there is no example value for this parameter in OpenAPI spec
|
||||||
|
|
||||||
|
// Request No. 1
|
||||||
|
{
|
||||||
|
let url = BASE_URL + `/fake/http-signature-test?query_1=${query_1}`;
|
||||||
|
// TODO: edit the parameters of the request body.
|
||||||
|
let body = {"id": "long", "category": {"id": "long", "name": "string"}, "name": "string", "photoUrls": "set", "tags": "list", "status": "string"};
|
||||||
|
let params = {headers: {"Content-Type": "application/json", "header_1": `${header1}`, "Accept": "application/json"}};
|
||||||
|
let request = http.get(url, JSON.stringify(body), params);
|
||||||
|
|
||||||
|
check(request, {
|
||||||
|
"The instance started successfully": (r) => r.status === 200
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
group("/user", () => {
|
||||||
|
|
||||||
|
// Request No. 1
|
||||||
|
{
|
||||||
|
let url = BASE_URL + `/user`;
|
||||||
|
// TODO: edit the parameters of the request body.
|
||||||
|
let body = {"id": "long", "username": "string", "firstName": "string", "lastName": "string", "email": "string", "password": "string", "phone": "string", "userStatus": "integer"};
|
||||||
|
let params = {headers: {"Content-Type": "application/json", "Accept": "application/json"}};
|
||||||
|
let request = http.post(url, JSON.stringify(body), params);
|
||||||
|
|
||||||
|
check(request, {
|
||||||
|
"successful operation": (r) => r.status === 200
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
group("/fake/property/enum-int", () => {
|
||||||
|
|
||||||
|
// Request No. 1
|
||||||
|
{
|
||||||
|
let url = BASE_URL + `/fake/property/enum-int`;
|
||||||
|
// TODO: edit the parameters of the request body.
|
||||||
|
let body = {"value": "outerenuminteger"};
|
||||||
|
let params = {headers: {"Content-Type": "application/json", "Accept": "*/*"}};
|
||||||
|
let request = http.post(url, JSON.stringify(body), params);
|
||||||
|
|
||||||
|
check(request, {
|
||||||
|
"Output enum (int)": (r) => r.status === 200
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
group("/user/createWithArray", () => {
|
||||||
|
|
||||||
|
// Request No. 1
|
||||||
|
{
|
||||||
|
let url = BASE_URL + `/user/createWithArray`;
|
||||||
|
let params = {headers: {"Content-Type": "application/json", "Accept": "application/json"}};
|
||||||
|
let request = http.post(url, params);
|
||||||
|
|
||||||
|
check(request, {
|
||||||
|
"successful operation": (r) => r.status === 200
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
group("/fake/body-with-file-schema", () => {
|
||||||
|
|
||||||
|
// Request No. 1
|
||||||
|
{
|
||||||
|
let url = BASE_URL + `/fake/body-with-file-schema`;
|
||||||
|
// TODO: edit the parameters of the request body.
|
||||||
|
let body = {"file": http.file(open("/path/to/file.bin", "b"), "test.bin"), "files": "list"};
|
||||||
|
let params = {headers: {"Content-Type": "application/json", "Accept": "application/json"}};
|
||||||
|
let request = http.put(url, JSON.stringify(body), params);
|
||||||
|
|
||||||
|
check(request, {
|
||||||
|
"Success": (r) => r.status === 200
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
group("/pet/findByTags", () => {
|
||||||
|
let tags = 'TODO_EDIT_THE_TAGS'; // specify value as there is no example value for this parameter in OpenAPI spec
|
||||||
|
|
||||||
|
// Request No. 1
|
||||||
|
{
|
||||||
|
let url = BASE_URL + `/pet/findByTags?tags=${tags}`;
|
||||||
|
let request = http.get(url);
|
||||||
|
|
||||||
|
check(request, {
|
||||||
|
"successful operation": (r) => r.status === 200
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
group("/store/order", () => {
|
||||||
|
|
||||||
|
// Request No. 1
|
||||||
|
{
|
||||||
|
let url = BASE_URL + `/store/order`;
|
||||||
|
// TODO: edit the parameters of the request body.
|
||||||
|
let body = {"id": "long", "petId": "long", "quantity": "integer", "shipDate": "date", "status": "string", "complete": "boolean"};
|
||||||
|
let params = {headers: {"Content-Type": "application/json", "Accept": "application/json"}};
|
||||||
|
let request = http.post(url, JSON.stringify(body), params);
|
||||||
|
|
||||||
|
check(request, {
|
||||||
|
"successful operation": (r) => r.status === 200
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
group("/user/logout", () => {
|
||||||
|
|
||||||
|
// Request No. 1
|
||||||
|
{
|
||||||
|
let url = BASE_URL + `/user/logout`;
|
||||||
|
let request = http.get(url);
|
||||||
|
|
||||||
|
check(request, {
|
||||||
|
"successful operation": (r) => r.status === 200
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
group("/fake/health", () => {
|
||||||
|
|
||||||
|
// Request No. 1
|
||||||
|
{
|
||||||
|
let url = BASE_URL + `/fake/health`;
|
||||||
|
let request = http.get(url);
|
||||||
|
|
||||||
|
check(request, {
|
||||||
|
"The instance started successfully": (r) => r.status === 200
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
group("/fake/outer/number", () => {
|
||||||
|
|
||||||
|
// Request No. 1
|
||||||
|
{
|
||||||
|
let url = BASE_URL + `/fake/outer/number`;
|
||||||
|
let params = {headers: {"Content-Type": "application/json", "Accept": "*/*"}};
|
||||||
|
let request = http.post(url, params);
|
||||||
|
|
||||||
|
check(request, {
|
||||||
|
"Output number": (r) => r.status === 200
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user