Skip to content

Commit 085892c

Browse files
committed
example with 10 distinct faults
1 parent 2b11fb1 commit 085892c

File tree

6 files changed

+389
-0
lines changed

6 files changed

+389
-0
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,4 @@
2121

2222
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
2323
hs_err_pid*
24+
/.idea/

pom.xml

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
2+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
3+
<modelVersion>4.0.0</modelVersion>
4+
5+
<groupId>org.evomaster</groupId>
6+
<artifactId>rest-faults</artifactId>
7+
8+
<version>1.0.0</version>
9+
10+
<inceptionYear>2023</inceptionYear>
11+
<name>rest-faults</name>
12+
<description>REST API example with different faults</description>
13+
<packaging>jar</packaging>
14+
15+
<properties>
16+
<java.version>1.8</java.version>
17+
<springboot.version>2.7.7</springboot.version>
18+
<springdoc.version>1.6.9</springdoc.version>
19+
</properties>
20+
21+
22+
<dependencies>
23+
<dependency>
24+
<groupId>org.springframework.boot</groupId>
25+
<artifactId>spring-boot</artifactId>
26+
<version>${springboot.version}</version>
27+
</dependency>
28+
<dependency>
29+
<groupId>org.springframework.boot</groupId>
30+
<artifactId>spring-boot-starter-web</artifactId>
31+
<version>${springboot.version}</version>
32+
</dependency>
33+
<dependency>
34+
<groupId>org.springdoc</groupId>
35+
<artifactId>springdoc-openapi-ui</artifactId>
36+
<version>${springdoc.version}</version>
37+
</dependency>
38+
</dependencies>
39+
40+
<build>
41+
<plugins>
42+
<plugin>
43+
<groupId>org.apache.maven.plugins</groupId>
44+
<artifactId>maven-compiler-plugin</artifactId>
45+
<version>3.5.1</version>
46+
<configuration>
47+
<source>${java.version}</source>
48+
<target>${java.version}</target>
49+
<encoding>${project.build.sourceEncoding}</encoding>
50+
</configuration>
51+
</plugin>
52+
<plugin>
53+
<!-- Need to create self-executable uber/fat jars for Spring-->
54+
<groupId>org.springframework.boot</groupId>
55+
<artifactId>spring-boot-maven-plugin</artifactId>
56+
<version>${springboot.version}</version>
57+
<executions>
58+
<execution>
59+
<goals>
60+
<goal>repackage</goal>
61+
</goals>
62+
</execution>
63+
</executions>
64+
</plugin>
65+
</plugins>
66+
</build>
67+
68+
</project>
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
package com.example.api;
2+
3+
4+
import org.springframework.http.MediaType;
5+
import org.springframework.http.ResponseEntity;
6+
import org.springframework.web.bind.annotation.*;
7+
8+
import java.net.URI;
9+
10+
@RestController("/api")
11+
public class Endpoints {
12+
13+
private int z = 0;
14+
15+
private FooDto k = new FooDto();
16+
17+
@GetMapping("/x")
18+
public String getX(){
19+
//#1 thrown exception
20+
throw new RuntimeException("Simulated thrown exception");
21+
}
22+
23+
24+
@GetMapping(value = "/y", produces = MediaType.APPLICATION_JSON_VALUE)
25+
public ResponseEntity<FooDto> getY(){
26+
27+
FooDto dto = new FooDto();
28+
dto.i = 42;
29+
dto.s = "FOO";
30+
dto.b = null; //#2 required in schema
31+
32+
//#3 schema gives different status code
33+
return ResponseEntity.status(201).body(dto);
34+
}
35+
36+
@PostMapping(value = "/y", consumes = MediaType.APPLICATION_JSON_VALUE)
37+
public ResponseEntity postY(
38+
@RequestBody FooDto dto
39+
){
40+
//not checking any constraint
41+
//#3,#4,#5: 3 different constraints on data
42+
43+
//#6: location header leading to 404
44+
return ResponseEntity.created(URI.create("/api/doesNotExist")).build();
45+
}
46+
47+
@DeleteMapping("/y")
48+
public void deleteY(){
49+
//do nothing
50+
//#7 GET would still return data
51+
}
52+
53+
@PutMapping(value = "/k", consumes = MediaType.APPLICATION_JSON_VALUE)
54+
public void putK(
55+
@RequestBody FooDto dto
56+
){
57+
//k = dto; //this would had been correct
58+
//#9: partial update
59+
if(dto.b != null){
60+
k.b = dto.b;
61+
}
62+
if(dto.s != null){
63+
k.s = dto.s;
64+
}
65+
if(dto.i != null){
66+
k.i = dto.i;
67+
}
68+
}
69+
70+
@GetMapping(value = "/k", produces = MediaType.APPLICATION_JSON_VALUE)
71+
public ResponseEntity<FooDto> getK(){
72+
73+
return ResponseEntity.status(200).body(k);
74+
}
75+
76+
77+
@GetMapping("/z")
78+
public int getZ(){
79+
return z;
80+
}
81+
82+
@PutMapping("/z")
83+
public void putZ(
84+
@RequestBody int delta
85+
){
86+
//#10 not idempotent
87+
z += delta;
88+
}
89+
90+
91+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package com.example.api;
2+
3+
public class FooDto {
4+
5+
public Integer i;
6+
7+
public Boolean b;
8+
9+
public String s;
10+
11+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package com.example.api;
2+
3+
4+
import org.springframework.boot.SpringApplication;
5+
import org.springframework.boot.autoconfigure.SpringBootApplication;
6+
7+
@SpringBootApplication
8+
public class Main {
9+
10+
public static void main(String[] args) {
11+
SpringApplication.run(Main.class, args);
12+
}
13+
}

src/main/resources/schema.json

Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
{
2+
"openapi": "3.0.1",
3+
"info": {
4+
"title": "OpenAPI definition",
5+
"version": "v0"
6+
},
7+
"servers": [
8+
{
9+
"url": "http://localhost:8080",
10+
"description": "Generated server url"
11+
}
12+
],
13+
"paths": {
14+
"/z": {
15+
"get": {
16+
"tags": [
17+
"endpoints"
18+
],
19+
"operationId": "getZ",
20+
"responses": {
21+
"200": {
22+
"description": "OK",
23+
"content": {
24+
"*/*": {
25+
"schema": {
26+
"type": "integer",
27+
"format": "int32"
28+
}
29+
}
30+
}
31+
}
32+
}
33+
},
34+
"put": {
35+
"tags": [
36+
"endpoints"
37+
],
38+
"operationId": "putZ",
39+
"requestBody": {
40+
"content": {
41+
"application/json": {
42+
"schema": {
43+
"type": "integer",
44+
"format": "int32"
45+
}
46+
}
47+
},
48+
"required": true
49+
},
50+
"responses": {
51+
"200": {
52+
"description": "OK"
53+
}
54+
}
55+
}
56+
},
57+
"/k": {
58+
"get": {
59+
"tags": [
60+
"endpoints"
61+
],
62+
"operationId": "getK",
63+
"responses": {
64+
"200": {
65+
"description": "OK",
66+
"content": {
67+
"application/json": {
68+
"schema": {
69+
"$ref": "#/components/schemas/FooDto"
70+
}
71+
}
72+
}
73+
}
74+
}
75+
},
76+
"put": {
77+
"tags": [
78+
"endpoints"
79+
],
80+
"operationId": "putK",
81+
"requestBody": {
82+
"content": {
83+
"application/json": {
84+
"schema": {
85+
"$ref": "#/components/schemas/FooDto"
86+
}
87+
}
88+
},
89+
"required": true
90+
},
91+
"responses": {
92+
"200": {
93+
"description": "OK"
94+
}
95+
}
96+
}
97+
},
98+
"/y": {
99+
"get": {
100+
"tags": [
101+
"endpoints"
102+
],
103+
"operationId": "getY",
104+
"responses": {
105+
"200": {
106+
"description": "OK",
107+
"content": {
108+
"application/json": {
109+
"schema": {
110+
"$ref": "#/components/schemas/FooDto"
111+
}
112+
}
113+
}
114+
}
115+
}
116+
},
117+
"post": {
118+
"tags": [
119+
"endpoints"
120+
],
121+
"operationId": "postY",
122+
"requestBody": {
123+
"content": {
124+
"application/json": {
125+
"schema": {
126+
"$ref": "#/components/schemas/FooDto"
127+
}
128+
}
129+
},
130+
"required": true
131+
},
132+
"responses": {
133+
"200": {
134+
"description": "OK",
135+
"content": {
136+
"*/*": {
137+
"schema": {
138+
"type": "string"
139+
}
140+
}
141+
}
142+
}
143+
}
144+
},
145+
"delete": {
146+
"tags": [
147+
"endpoints"
148+
],
149+
"operationId": "deleteY",
150+
"responses": {
151+
"200": {
152+
"description": "OK"
153+
}
154+
}
155+
}
156+
},
157+
"/x": {
158+
"get": {
159+
"tags": [
160+
"endpoints"
161+
],
162+
"operationId": "getX",
163+
"responses": {
164+
"200": {
165+
"description": "OK",
166+
"content": {
167+
"*/*": {
168+
"schema": {
169+
"type": "string"
170+
}
171+
}
172+
}
173+
}
174+
}
175+
}
176+
}
177+
},
178+
"components": {
179+
"schemas": {
180+
"FooDto": {
181+
"type": "object",
182+
"properties": {
183+
"i": {
184+
"type": "integer",
185+
"format": "int32",
186+
"maximum": 100
187+
},
188+
"b": {
189+
"type": "boolean"
190+
},
191+
"s": {
192+
"type": "string",
193+
"enum": [
194+
"FOO",
195+
"BAR"
196+
]
197+
}
198+
},
199+
"required": [
200+
"b"
201+
]
202+
}
203+
}
204+
}
205+
}

0 commit comments

Comments
 (0)