Skip to content

Commit 6e17128

Browse files
committed
perf test
1 parent b403d0f commit 6e17128

File tree

8 files changed

+335
-0
lines changed

8 files changed

+335
-0
lines changed

springdoc-openapi-starter-webmvc-api/pom.xml

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,51 @@
3939
<artifactId>money-api</artifactId>
4040
<scope>test</scope>
4141
</dependency>
42+
<dependency>
43+
<groupId>org.apache.groovy</groupId>
44+
<artifactId>groovy</artifactId>
45+
<scope>test</scope>
46+
</dependency>
4247
</dependencies>
4348
<build>
4449
<plugins>
50+
<plugin>
51+
<groupId>org.codehaus.mojo</groupId>
52+
<artifactId>build-helper-maven-plugin</artifactId>
53+
<executions>
54+
<execution>
55+
<id>add-generated-test-sources</id>
56+
<phase>generate-test-sources</phase>
57+
<goals>
58+
<goal>add-test-source</goal>
59+
</goals>
60+
<configuration>
61+
<sources>
62+
<source>target/generated-test-sources</source>
63+
</sources>
64+
</configuration>
65+
</execution>
66+
</executions>
67+
</plugin>
68+
<plugin>
69+
<groupId>org.codehaus.gmavenplus</groupId>
70+
<artifactId>gmavenplus-plugin</artifactId>
71+
<version>${gmavenplus-plugin.version}</version>
72+
<executions>
73+
<execution>
74+
<id>generate-dtos</id>
75+
<phase>generate-test-sources</phase>
76+
<goals>
77+
<goal>execute</goal>
78+
</goals>
79+
<configuration>
80+
<scripts>
81+
<script>${basedir}/src/test/groovy/v31/app248/generate.groovy</script>
82+
</scripts>
83+
</configuration>
84+
</execution>
85+
</executions>
86+
</plugin>
4587
<plugin>
4688
<groupId>org.apache.maven.plugins</groupId>
4789
<artifactId>maven-jar-plugin</artifactId>
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
package v31.app248
2+
3+
import java.nio.file.Files
4+
import java.nio.file.Path
5+
import java.nio.file.Paths
6+
7+
BASE_PACKAGE = 'test.org.springdoc.api.v31.app248'
8+
9+
def parse(String qualifiedClassName) {
10+
parts = qualifiedClassName.split('\\.')
11+
packages = parts[0..-2]
12+
className = parts[-1]
13+
return [className, packages]
14+
}
15+
16+
def package_name(List<String> packages) {
17+
return String.join('.', [BASE_PACKAGE] + packages)
18+
}
19+
20+
def directory(List<String> packages) {
21+
packages = BASE_PACKAGE.split('\\.') + packages
22+
return Paths.get(project.build.directory, "generated-test-sources", *packages)
23+
}
24+
25+
Path filePath(String className, List<String> packages) {
26+
return directory(packages).resolve(className + ".java")
27+
}
28+
29+
def generateDTO(String className, properties) {
30+
(className, packages) = parse(className)
31+
def package_ = package_name(packages)
32+
def path = filePath(className, packages)
33+
Files.createDirectories(path.parent)
34+
Files.newBufferedWriter(path).withWriter { w ->
35+
w << "package ${package_};\n\n"
36+
w << "public class ${className} {\n\n"
37+
properties.each { type, name ->
38+
w << "\tprivate $type $name;\n\n"
39+
}
40+
w << "\tpublic $className() {}\n\n"
41+
properties.each { type, name ->
42+
def capitalized = name.capitalize()
43+
w << "\tpublic $type get$capitalized() {\n"
44+
w << "\t\treturn this.$name;\n"
45+
w << "\t}\n\n"
46+
w << "\tpublic void set$capitalized($type $name) {\n"
47+
w << "\t\tthis.$name = $name;\n"
48+
w << "\t}\n\n"
49+
}
50+
w << "}\n\n"
51+
}
52+
}
53+
54+
def generateController(String className, String requestPath) {
55+
def imports = [
56+
'java.util.List',
57+
'org.springframework.http.ResponseEntity',
58+
'org.springframework.web.bind.annotation.GetMapping',
59+
'org.springframework.web.bind.annotation.PostMapping',
60+
'org.springframework.web.bind.annotation.RequestMapping',
61+
'org.springframework.web.bind.annotation.RestController',
62+
'test.org.springdoc.api.v31.app248.dto.PersonDTO'
63+
]
64+
65+
(className, packages) = parse(className)
66+
def package_ = package_name(packages)
67+
def path = filePath(className, packages)
68+
Files.createDirectories(path.parent)
69+
Files.newBufferedWriter(path).withWriter { w ->
70+
w << "package ${package_};\n\n"
71+
imports.each { imp -> w << "import $imp;\n\n" }
72+
w << "\n@RestController\n"
73+
w << "@RequestMapping(\"$requestPath\")\n"
74+
w << "public class ${className} {\n\n"
75+
w << "\t@PostMapping\n"
76+
w << "\tpublic ResponseEntity<PersonDTO> createPerson(PersonDTO createDto) {\n"
77+
w << "\t\treturn null;\n"
78+
w << "\t}\n\n"
79+
w << "\t@GetMapping\n"
80+
w << "\tpublic ResponseEntity<List<PersonDTO>> listPerson() {\n"
81+
w << "\t\treturn null;\n"
82+
w << "\t}\n\n"
83+
w << "\t@GetMapping(\"{id}\")\n"
84+
w << "\tpublic ResponseEntity<PersonDTO> getPerson(Long id) {\n"
85+
w << "\t\treturn null;\n"
86+
w << "\t}\n\n"
87+
w << "}\n"
88+
}
89+
}
90+
91+
def main() {
92+
generateDTO('dto.PersonDTO', [
93+
['Long', 'id'],
94+
['String', 'name'],
95+
['Address', 'address'],
96+
['PersonDetails1', 'details']
97+
])
98+
99+
def numControllers = 200
100+
def numDtos = 512
101+
(1..numDtos).each { i ->
102+
def className = "dto.PersonDetails$i"
103+
def props = [['String', 'value']]
104+
if (2 * i <= numDtos) {
105+
props << ["PersonDetails${2 * i}", 'details1']
106+
}
107+
if (2 * i + 1 <= numDtos) {
108+
props << ["PersonDetails${2 * i + 1}", 'details2']
109+
}
110+
generateDTO(className, props)
111+
}
112+
113+
(1..numControllers).each { i ->
114+
generateController("controller.Hello${i}Controller", "test${i}")
115+
}
116+
117+
Paths.get(project.build.directory, "generated-test-sources")
118+
.toFile()
119+
.eachFileRecurse {file ->
120+
println(file)
121+
}
122+
}
123+
124+
main()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package test.org.springdoc.api.v31.app248;
2+
3+
4+
import java.time.Duration;
5+
6+
import org.junit.jupiter.api.Test;
7+
import org.springdoc.core.utils.Constants;
8+
import org.springframework.boot.autoconfigure.SpringBootApplication;
9+
import org.springframework.boot.test.context.SpringBootTest;
10+
import test.org.springdoc.api.AbstractCommonTest;
11+
import static org.hamcrest.Matchers.is;
12+
import static org.junit.jupiter.api.Assertions.*;
13+
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
14+
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
15+
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
16+
17+
@SpringBootTest(properties = {
18+
"logging.level.io.swagger=DEBUG"
19+
})
20+
public class SpringDocApp248Test extends AbstractCommonTest {
21+
22+
public static String className;
23+
24+
@Test
25+
void performanceTest() {
26+
className = getClass().getSimpleName();
27+
assertTimeout(Duration.ofSeconds(2), () -> {
28+
mockMvc.perform(get(Constants.DEFAULT_API_DOCS_URL)).andExpect(status().isOk())
29+
.andExpect(jsonPath("$.openapi", is("3.1.0"))).andReturn();
30+
});
31+
}
32+
33+
@SpringBootApplication
34+
static class SpringDocTestApp {
35+
36+
}
37+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package test.org.springdoc.api.v31.app248.dto;
2+
3+
/**
4+
* @author bnasslahsen
5+
*/
6+
7+
public class Address {
8+
private AddressLine line1;
9+
10+
private AddressLine line2;
11+
12+
private AddressCity city;
13+
14+
private AddressState state;
15+
16+
private AddressCountry country;
17+
18+
public Address() {}
19+
20+
public AddressLine getLine1() {
21+
return line1;
22+
}
23+
24+
public void setLine1(AddressLine line1) {
25+
this.line1 = line1;
26+
}
27+
28+
public AddressLine getLine2() {
29+
return line2;
30+
}
31+
32+
public void setLine2(AddressLine line2) {
33+
this.line2 = line2;
34+
}
35+
36+
public AddressCity getCity() {
37+
return city;
38+
}
39+
40+
public void setCity(AddressCity city) {
41+
this.city = city;
42+
}
43+
44+
public AddressState getState() {
45+
return state;
46+
}
47+
48+
public void setState(AddressState state) {
49+
this.state = state;
50+
}
51+
52+
public AddressCountry getCountry() {
53+
return country;
54+
}
55+
56+
public void setCountry(AddressCountry country) {
57+
this.country = country;
58+
}
59+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package test.org.springdoc.api.v31.app248.dto;
2+
3+
import com.fasterxml.jackson.annotation.JsonCreator;
4+
import com.fasterxml.jackson.annotation.JsonValue;
5+
6+
public class AddressCity {
7+
private final String value;
8+
9+
@JsonCreator
10+
public AddressCity(String value) {
11+
this.value = value;
12+
}
13+
14+
@JsonValue
15+
public String getValue() {
16+
return value;
17+
}
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package test.org.springdoc.api.v31.app248.dto;
2+
3+
import com.fasterxml.jackson.annotation.JsonCreator;
4+
import com.fasterxml.jackson.annotation.JsonValue;
5+
6+
public class AddressCountry {
7+
private final String value;
8+
9+
@JsonCreator
10+
public AddressCountry(String value) {
11+
this.value = value;
12+
}
13+
14+
@JsonValue
15+
public String getValue() {
16+
return value;
17+
}
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package test.org.springdoc.api.v31.app248.dto;
2+
3+
import com.fasterxml.jackson.annotation.JsonCreator;
4+
import com.fasterxml.jackson.annotation.JsonProperty;
5+
import com.fasterxml.jackson.annotation.JsonValue;
6+
7+
public class AddressLine {
8+
private final String value;
9+
10+
@JsonCreator
11+
public AddressLine(@JsonProperty("value") String value) {
12+
this.value = value;
13+
}
14+
15+
@JsonValue
16+
public String getValue() {
17+
return value;
18+
}
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package test.org.springdoc.api.v31.app248.dto;
2+
3+
import com.fasterxml.jackson.annotation.JsonCreator;
4+
import com.fasterxml.jackson.annotation.JsonValue;
5+
6+
public class AddressState {
7+
private final String value;
8+
9+
@JsonCreator
10+
public AddressState(String value) {
11+
this.value = value;
12+
}
13+
14+
@JsonValue
15+
public String getValue() {
16+
return value;
17+
}
18+
}

0 commit comments

Comments
 (0)