Skip to content

Commit 0a9896b

Browse files
Add Tomcat support in the system test runner and tests to the spring-jakarta sample (#4635)
* Add Tomcat support in the system test runner and tests to the spring-jakarta sample * Create webapps directory and revert library changes only needed for the spring sample * Adapt test instead of endpoint in spring-jakarta sample * Format code * Add task dependency from run on war in spring-jakarta sample * Format code * Add missing argument in interactive mode and build before launching in the system-test-runner * Add spring-jakarta sample to CI system tests config file * Stop tomcat server on signal in system-test-runner * Stop Tomcat process in all cases --------- Co-authored-by: Sentry Github Bot <[email protected]>
1 parent 7c7a209 commit 0a9896b

File tree

10 files changed

+363
-76
lines changed

10 files changed

+363
-76
lines changed

.github/workflows/system-tests-backend.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ jobs:
6363
- sample: "sentry-samples-jul"
6464
agent: "false"
6565
agent-auto-init: "true"
66+
- sample: "sentry-samples-spring-jakarta"
67+
agent: "false"
68+
agent-auto-init: "true"
6669
steps:
6770
- uses: actions/checkout@v4
6871
with:

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ distributions/
2121
sentry-spring-boot-starter-jakarta/src/main/resources/META-INF/spring.factories
2222
sentry-samples/sentry-samples-spring-boot-jakarta/spy.log
2323
sentry-mock-server.txt
24+
tomcat-server.txt
2425
spring-server.txt
26+
*.pid
2527
spy.log
2628
.kotlin
29+
**/tomcat.8080/webapps/

gradle/libs.versions.toml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ retrofit = { module = "com.squareup.retrofit2:retrofit", version.ref = "retrofit
122122
retrofit-gson = { module = "com.squareup.retrofit2:converter-gson", version.ref = "retrofit" }
123123
sentry-native-ndk = { module = "io.sentry:sentry-native-ndk", version = "0.10.0" }
124124
servlet-api = { module = "javax.servlet:javax.servlet-api", version = "3.1.0" }
125-
servlet-jakarta-api = { module = "jakarta.servlet:jakarta.servlet-api", version = "5.0.0" }
125+
servlet-jakarta-api = { module = "jakarta.servlet:jakarta.servlet-api", version = "6.1.0" }
126126
slf4j-api = { module = "org.slf4j:slf4j-api", version.ref = "slf4j" }
127127
slf4j-jdk14 = { module = "org.slf4j:slf4j-jdk14", version.ref = "slf4j" }
128128
slf4j2-api = { module = "org.slf4j:slf4j-api", version = "2.0.5" }
@@ -152,6 +152,10 @@ springboot3-starter-jdbc = { module = "org.springframework.boot:spring-boot-star
152152
springboot3-starter-actuator = { module = "org.springframework.boot:spring-boot-starter-actuator", version.ref = "springboot3" }
153153
timber = { module = "com.jakewharton.timber:timber", version = "4.7.1" }
154154

155+
# tomcat libraries
156+
tomcat-catalina-jakarta = { module = "org.apache.tomcat:tomcat-catalina", version = "11.0.10" }
157+
tomcat-embed-jasper-jakarta = { module = "org.apache.tomcat.embed:tomcat-embed-jasper", version = "11.0.10" }
158+
155159
# test libraries
156160
androidx-compose-ui-test-junit4 = { module = "androidx.compose.ui:ui-test-junit4", version = "1.6.8" }
157161
androidx-test-core = { module = "androidx.test:core", version.ref = "androidxTestCore" }

sentry-samples/sentry-samples-spring-jakarta/build.gradle.kts

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
33
import org.springframework.boot.gradle.plugin.SpringBootPlugin
44

55
plugins {
6+
application
67
alias(libs.plugins.springboot3) apply false
78
alias(libs.plugins.spring.dependency.management)
89
kotlin("jvm")
@@ -11,6 +12,11 @@ plugins {
1112
alias(libs.plugins.gretty)
1213
}
1314

15+
application { mainClass.set("io.sentry.samples.spring.jakarta.Main") }
16+
17+
// Ensure WAR is up to date before run task
18+
tasks.named("run") { dependsOn(tasks.named("war")) }
19+
1420
group = "io.sentry.sample.spring-jakarta"
1521

1622
version = "0.0.1-SNAPSHOT"
@@ -37,16 +43,43 @@ dependencies {
3743
implementation(libs.logback.classic)
3844
implementation(libs.servlet.jakarta.api)
3945
implementation(libs.slf4j2.api)
46+
47+
implementation(libs.tomcat.catalina.jakarta)
48+
implementation(libs.tomcat.embed.jasper.jakarta)
49+
50+
testImplementation(projects.sentrySystemTestSupport)
51+
testImplementation(libs.kotlin.test.junit)
4052
testImplementation(libs.springboot.starter.test) {
4153
exclude(group = "org.junit.vintage", module = "junit-vintage-engine")
4254
}
4355
}
4456

45-
tasks.withType<Test>().configureEach { useJUnitPlatform() }
46-
4757
tasks.withType<KotlinCompile>().configureEach {
4858
kotlinOptions {
4959
freeCompilerArgs = listOf("-Xjsr305=strict")
5060
jvmTarget = JavaVersion.VERSION_17.toString()
5161
}
5262
}
63+
64+
configure<SourceSetContainer> { test { java.srcDir("src/test/java") } }
65+
66+
tasks.register<Test>("systemTest").configure {
67+
group = "verification"
68+
description = "Runs the System tests"
69+
70+
outputs.upToDateWhen { false }
71+
72+
maxParallelForks = 1
73+
74+
// Cap JVM args per test
75+
minHeapSize = "128m"
76+
maxHeapSize = "1g"
77+
78+
filter { includeTestsMatching("io.sentry.systemtest*") }
79+
}
80+
81+
tasks.named("test").configure {
82+
require(this is Test)
83+
84+
filter { excludeTestsMatching("io.sentry.systemtest.*") }
85+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package io.sentry.samples.spring.jakarta;
2+
3+
import java.io.File;
4+
import java.io.IOException;
5+
import org.apache.catalina.LifecycleException;
6+
import org.apache.catalina.startup.Tomcat;
7+
8+
public class Main {
9+
10+
public static void main(String[] args) throws LifecycleException, IOException {
11+
File webappsDirectory = new File("./tomcat.8080/webapps");
12+
if (!webappsDirectory.exists()) {
13+
boolean didCreateDirectories = webappsDirectory.mkdirs();
14+
if (!didCreateDirectories) {
15+
throw new RuntimeException(
16+
"Failed to create directory required by Tomcat: " + webappsDirectory.getAbsolutePath());
17+
}
18+
}
19+
20+
String pathToWar = "./build/libs";
21+
String warName = "sentry-samples-spring-jakarta-0.0.1-SNAPSHOT";
22+
File war = new File(pathToWar + "/" + warName + ".war");
23+
24+
Tomcat tomcat = new Tomcat();
25+
tomcat.setPort(8080);
26+
tomcat.getConnector();
27+
28+
tomcat.addWebapp("/" + warName, war.getCanonicalPath());
29+
tomcat.start();
30+
tomcat.getServer().await();
31+
}
32+
}

sentry-samples/sentry-samples-spring-jakarta/src/main/java/io/sentry/samples/spring/jakarta/web/Person.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
package io.sentry.samples.spring.jakarta.web;
22

3+
import com.fasterxml.jackson.annotation.JsonCreator;
4+
import com.fasterxml.jackson.annotation.JsonProperty;
5+
36
public class Person {
47
private final String firstName;
58
private final String lastName;
69

7-
public Person(String firstName, String lastName) {
10+
@JsonCreator
11+
public Person(
12+
@JsonProperty("firstName") String firstName, @JsonProperty("lastName") String lastName) {
813
this.firstName = firstName;
914
this.lastName = lastName;
1015
}

sentry-samples/sentry-samples-spring-jakarta/src/main/java/io/sentry/samples/spring/jakarta/web/PersonController.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ public PersonController(PersonService personService) {
2222
}
2323

2424
@GetMapping("{id}")
25-
Person person(@PathVariable Long id) {
25+
Person person(@PathVariable("id") Long id) {
2626
Sentry.logger().warn("warn Sentry logging");
2727
Sentry.logger().error("error Sentry logging");
2828
Sentry.logger().info("hello %s %s", "there", "world!");
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package io.sentry
2+
3+
import kotlin.test.Test
4+
import kotlin.test.assertTrue
5+
6+
class DummyTest {
7+
@Test
8+
fun `the only test`() {
9+
// only needed to have more than 0 tests and not fail the build
10+
assertTrue(true)
11+
}
12+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package io.sentry.systemtest
2+
3+
import io.sentry.systemtest.util.TestHelper
4+
import kotlin.test.Test
5+
import kotlin.test.assertEquals
6+
import org.junit.Before
7+
8+
class PersonSystemTest {
9+
lateinit var testHelper: TestHelper
10+
11+
@Before
12+
fun setup() {
13+
testHelper = TestHelper("http://localhost:8080/sentry-samples-spring-jakarta-0.0.1-SNAPSHOT")
14+
testHelper.reset()
15+
}
16+
17+
@Test
18+
fun `get person fails`() {
19+
val restClient = testHelper.restClient
20+
restClient.getPerson(11L)
21+
assertEquals(500, restClient.lastKnownStatusCode)
22+
23+
testHelper.ensureTransactionReceived { transaction, envelopeHeader ->
24+
testHelper.doesTransactionHaveOp(transaction, "http.server")
25+
}
26+
27+
Thread.sleep(10000)
28+
29+
testHelper.ensureLogsReceived { logs, envelopeHeader ->
30+
testHelper.doesContainLogWithBody(logs, "warn Sentry logging") &&
31+
testHelper.doesContainLogWithBody(logs, "error Sentry logging") &&
32+
testHelper.doesContainLogWithBody(logs, "hello there world!")
33+
}
34+
}
35+
36+
@Test
37+
fun `create person works`() {
38+
val restClient = testHelper.restClient
39+
val person = Person("firstA", "lastB")
40+
val returnedPerson = restClient.createPerson(person)
41+
assertEquals(200, restClient.lastKnownStatusCode)
42+
43+
assertEquals(person.firstName, returnedPerson!!.firstName)
44+
assertEquals(person.lastName, returnedPerson!!.lastName)
45+
}
46+
}

0 commit comments

Comments
 (0)