Skip to content

Commit 9d3ecdb

Browse files
romtsnclaude
authored andcommitted
test: Fix follow-ups from the sample tests stack review
Fix issues the review of the sample tests stack found in the new in-module end-to-end tests: - MockSentryServer keeps the error when it can't read a body and rethrows it while waiting, so a serialization bug no longer looks like a missing envelope. - ChildJvmApp only takes a port that two reads agree on. A partly written port such as "54" of "54321" parsed and pointed the test at the wrong port. - The agentless test starts a span through the OpenTelemetry API and checks that it reaches Sentry. Before, it passed with the OpenTelemetry wiring broken. - The Person tests use id 11 and match their transaction by URL, so envelopes from the tracing tests' /person/1 calls can't satisfy them. - The Boot 2 Kafka test shares the suite's context and broker, as on Boot 3 and 4. Its second context re-ran Sentry.init and made later tests depend on the run order. Boot 2.4 to 2.6 were the reason for the split and are gone. - Tests fail clearly when a system property the Gradle task sets is missing, rather than running with -javaagent:null. - Remove the Boot 2 version gating from the samples, the runner's files from .gitignore, and the unused jackson-kotlin entry. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent e48e7ab commit 9d3ecdb

28 files changed

Lines changed: 202 additions & 214 deletions

File tree

‎.claude/skills/test/SKILL.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ Extract the module name and optional test class filter from the argument.
3232
| Signal | Test Type |
3333
|--------|-----------|
3434
| Path contains `/src/integrationTest*/` or `/src/agentFixture/` | Integration test suite |
35+
| Module name only, and the user asks for integration or end-to-end tests | Integration test suite: each `src/integrationTest*/` directory of the module |
3536
| Path contains `sentry-samples/`, or module name starts with `sentry-samples-` | None: samples have no tests |
3637
| Everything else | Unit test |
3738

‎.gitignore‎

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,6 @@ distributions/
2222
*.vscode/
2323
sentry-spring-boot-starter-jakarta/src/main/resources/META-INF/spring.factories
2424
sentry-samples/sentry-samples-spring-boot-jakarta/spy.log
25-
sentry-mock-server.txt
26-
tomcat-server.txt
27-
spring-server.txt
2825
*.pid
2926
spy.log
3027
.kotlin

‎gradle/libs.versions.toml‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,6 @@ graphql-java22 = { module = "com.graphql-java:graphql-java", version = "22.1" }
144144
graphql-java24 = { module = "com.graphql-java:graphql-java", version = "24.0" }
145145
jackson-bom = { module = "com.fasterxml.jackson:jackson-bom", version.ref = "jackson" }
146146
jackson-databind = { module = "com.fasterxml.jackson.core:jackson-databind", version.ref = "jackson" }
147-
jackson-kotlin = { module = "com.fasterxml.jackson.module:jackson-module-kotlin", version.ref = "jackson" }
148147
jetbrains-annotations = { module = "org.jetbrains:annotations", version = "23.0.0" }
149148
kotlin-bom = { module = "org.jetbrains.kotlin:kotlin-bom", version.ref = "kotlin" }
150149
kotlin-test-junit = { module = "org.jetbrains.kotlin:kotlin-test-junit", version.ref = "kotlin" }

‎sentry-opentelemetry/sentry-opentelemetry-agent/src/test/kotlin/io/sentry/opentelemetry/agent/AgentSmokeTest.kt‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import com.google.common.truth.Truth.assertThat
44
import io.sentry.opentelemetry.agent.fixture.HelloServer
55
import io.sentry.test.ChildJvmApp
66
import io.sentry.test.MockSentryServer
7+
import io.sentry.test.requiredTestProperty
78
import io.sentry.test.transaction
89
import java.io.File
910
import java.net.URL
@@ -32,7 +33,7 @@ class AgentSmokeTest {
3233
mainClass = HelloServer::class.java.name,
3334
classpath =
3435
File(HelloServer::class.java.protectionDomain.codeSource.location.toURI()).path,
35-
jvmArgs = listOf("-javaagent:${System.getProperty("sentry.test.agentJar")}"),
36+
jvmArgs = listOf("-javaagent:${requiredTestProperty("sentry.test.agentJar")}"),
3637
env =
3738
mapOf(
3839
"SENTRY_DSN" to server.dsn,

‎sentry-opentelemetry/sentry-opentelemetry-agentless/src/test/kotlin/io/sentry/opentelemetry/agentless/AgentlessEndToEndTest.kt‎

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ class AgentlessEndToEndTest {
4141
}
4242

4343
@Test
44-
fun `Sentry set up by OpenTelemetry reports events, a profiled transaction and metrics`() {
44+
fun `Sentry set up by OpenTelemetry reports events, a profiled transaction, OpenTelemetry spans and metrics`() {
4545
// The customizer's Sentry.init reads these as external configuration.
4646
System.setProperty("sentry.dsn", server.dsn)
4747
System.setProperty("sentry.traces-sample-rate", "1.0")
@@ -107,6 +107,11 @@ class AgentlessEndToEndTest {
107107
Thread.sleep(100)
108108
span.finish()
109109
transaction.finish()
110+
// A span started through the OpenTelemetry API only reaches Sentry if the customizer wired
111+
// Sentry's span processor into the SDK.
112+
val otelSpan =
113+
GlobalOpenTelemetry.getTracer("agentless-test").spanBuilder("otel span").startSpan()
114+
otelSpan.end()
110115
Sentry.flush(5000)
111116
// Sentry exports OpenTelemetry spans in batches every 5 seconds.
112117
openTelemetry.sdkTracerProvider.forceFlush().join(5, TimeUnit.SECONDS)
@@ -138,6 +143,10 @@ class AgentlessEndToEndTest {
138143
val sent =
139144
server.awaitEnvelope { it.transaction()?.transaction == "transaction name" }.transaction()!!
140145
assertThat(sent.spans.map { it.op }).contains("child")
146+
val otelTransaction =
147+
server.awaitEnvelope { it.transaction()?.transaction == "otel span" }.transaction()!!
148+
assertThat(otelTransaction.contexts.trace!!.traceId.toString())
149+
.isEqualTo(otelSpan.spanContext.traceId)
141150
val profilerId = sent.contexts.profile?.profilerId
142151
assertThat(profilerId).isNotNull()
143152
server.awaitEnvelope(timeoutMillis = 30_000) { it.profileChunk()?.profilerId == profilerId }

‎sentry-samples/sentry-samples-spring-boot-opentelemetry-noagent/build.gradle.kts‎

Lines changed: 4 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -25,18 +25,6 @@ group = "io.sentry.sample.spring-boot"
2525

2626
version = "0.0.1-SNAPSHOT"
2727

28-
fun springBoot2SupportsOptionalIntegrations(): Boolean {
29-
val version = libs.versions.springboot2.get().removeSuffix(".RELEASE")
30-
val parts = version.split(".").map { it.toIntOrNull() ?: 0 }
31-
val major = parts.getOrElse(0) { 0 }
32-
val minor = parts.getOrElse(1) { 0 }
33-
return major > 2 || (major == 2 && minor >= 7)
34-
}
35-
36-
val includeGraphql =
37-
!project.hasProperty("excludeGraphql") && springBoot2SupportsOptionalIntegrations()
38-
val includeKafka = !project.hasProperty("excludeKafka") && springBoot2SupportsOptionalIntegrations()
39-
4028
tasks.withType<KotlinCompile>().configureEach {
4129
kotlin {
4230
compilerOptions.freeCompilerArgs = listOf("-Xjsr305=strict")
@@ -49,9 +37,7 @@ dependencies {
4937
implementation(libs.springboot.starter)
5038
implementation(libs.springboot.starter.actuator)
5139
implementation(libs.springboot.starter.aop)
52-
if (includeGraphql) {
53-
implementation(libs.springboot.starter.graphql)
54-
}
40+
implementation(libs.springboot.starter.graphql)
5541
implementation(libs.springboot.starter.jdbc)
5642
implementation(libs.springboot.starter.quartz)
5743
implementation(libs.springboot.starter.security)
@@ -63,17 +49,13 @@ dependencies {
6349
implementation(kotlin(Config.kotlinStdLib, KotlinCompilerVersion.VERSION))
6450
implementation(projects.sentrySpringBootStarter)
6551
implementation(projects.sentryLogback)
66-
if (includeGraphql) {
67-
implementation(projects.sentryGraphql)
68-
}
52+
implementation(projects.sentryGraphql)
6953
implementation(projects.sentryQuartz)
7054
implementation(projects.sentryOpentelemetry.sentryOpentelemetryAgentlessSpring)
7155
implementation(projects.sentryAsyncProfiler)
7256

73-
if (includeKafka) {
74-
implementation(libs.spring.kafka2)
75-
implementation(projects.sentryKafka)
76-
}
57+
implementation(libs.spring.kafka2)
58+
implementation(projects.sentryKafka)
7759

7860
// database query tracing
7961
implementation(projects.sentryJdbc)
@@ -101,16 +83,3 @@ tasks.jar {
10183
}
10284

10385
tasks.startScripts { dependsOn(tasks.shadowJar) }
104-
105-
configure<SourceSetContainer> {
106-
main {
107-
if (!includeGraphql) {
108-
java.exclude("**/graphql/**")
109-
resources.exclude("graphql/**")
110-
}
111-
if (!includeKafka) {
112-
java.exclude("**/queues/kafka/**")
113-
resources.exclude("application-kafka.properties")
114-
}
115-
}
116-
}

‎sentry-samples/sentry-samples-spring-boot-opentelemetry/build.gradle.kts‎

Lines changed: 4 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -25,18 +25,6 @@ group = "io.sentry.sample.spring-boot"
2525

2626
version = "0.0.1-SNAPSHOT"
2727

28-
fun springBoot2SupportsOptionalIntegrations(): Boolean {
29-
val version = libs.versions.springboot2.get().removeSuffix(".RELEASE")
30-
val parts = version.split(".").map { it.toIntOrNull() ?: 0 }
31-
val major = parts.getOrElse(0) { 0 }
32-
val minor = parts.getOrElse(1) { 0 }
33-
return major > 2 || (major == 2 && minor >= 7)
34-
}
35-
36-
val includeGraphql =
37-
!project.hasProperty("excludeGraphql") && springBoot2SupportsOptionalIntegrations()
38-
val includeKafka = !project.hasProperty("excludeKafka") && springBoot2SupportsOptionalIntegrations()
39-
4028
tasks.withType<KotlinCompile>().configureEach {
4129
kotlin {
4230
compilerOptions.freeCompilerArgs = listOf("-Xjsr305=strict")
@@ -48,9 +36,7 @@ dependencies {
4836
implementation(libs.springboot.starter)
4937
implementation(libs.springboot.starter.actuator)
5038
implementation(libs.springboot.starter.aop)
51-
if (includeGraphql) {
52-
implementation(libs.springboot.starter.graphql)
53-
}
39+
implementation(libs.springboot.starter.graphql)
5440
implementation(libs.springboot.starter.jdbc)
5541
implementation(libs.springboot.starter.quartz)
5642
implementation(libs.springboot.starter.security)
@@ -62,17 +48,13 @@ dependencies {
6248
implementation(kotlin(Config.kotlinStdLib, KotlinCompilerVersion.VERSION))
6349
implementation(projects.sentrySpringBootStarter)
6450
implementation(projects.sentryLogback)
65-
if (includeGraphql) {
66-
implementation(projects.sentryGraphql)
67-
}
51+
implementation(projects.sentryGraphql)
6852
implementation(projects.sentryQuartz)
6953
implementation(projects.sentryAsyncProfiler)
7054
implementation(libs.otel)
7155

72-
if (includeKafka) {
73-
implementation(libs.spring.kafka2)
74-
implementation(projects.sentryKafka)
75-
}
56+
implementation(libs.spring.kafka2)
57+
implementation(projects.sentryKafka)
7658

7759
// database query tracing
7860
implementation(projects.sentryJdbc)
@@ -101,19 +83,6 @@ tasks.jar {
10183

10284
tasks.startScripts { dependsOn(tasks.shadowJar) }
10385

104-
configure<SourceSetContainer> {
105-
main {
106-
if (!includeGraphql) {
107-
java.exclude("**/graphql/**")
108-
resources.exclude("graphql/**")
109-
}
110-
if (!includeKafka) {
111-
java.exclude("**/queues/kafka/**")
112-
resources.exclude("application-kafka.properties")
113-
}
114-
}
115-
}
116-
11786
tasks.register<JavaExec>("bootRunWithAgent").configure {
11887
group = "application"
11988

‎sentry-samples/sentry-samples-spring-boot-webflux/build.gradle.kts‎

Lines changed: 2 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -25,30 +25,16 @@ group = "io.sentry.sample.spring-boot"
2525

2626
version = "0.0.1-SNAPSHOT"
2727

28-
fun springBoot2SupportsGraphql(): Boolean {
29-
val version = libs.versions.springboot2.get().removeSuffix(".RELEASE")
30-
val parts = version.split(".").map { it.toIntOrNull() ?: 0 }
31-
val major = parts.getOrElse(0) { 0 }
32-
val minor = parts.getOrElse(1) { 0 }
33-
return major > 2 || (major == 2 && minor >= 7)
34-
}
35-
36-
val includeGraphql = !project.hasProperty("excludeGraphql") && springBoot2SupportsGraphql()
37-
3828
dependencies {
3929
implementation(platform(libs.springboot2.bom))
4030
implementation(libs.springboot.starter.actuator)
41-
if (includeGraphql) {
42-
implementation(libs.springboot.starter.graphql)
43-
}
31+
implementation(libs.springboot.starter.graphql)
4432
implementation(libs.springboot.starter.webflux)
4533
implementation(Config.Libs.kotlinReflect)
4634
implementation(kotlin(Config.kotlinStdLib, KotlinCompilerVersion.VERSION))
4735
implementation(projects.sentrySpringBootStarter)
4836
implementation(projects.sentryLogback)
49-
if (includeGraphql) {
50-
implementation(projects.sentryGraphql)
51-
}
37+
implementation(projects.sentryGraphql)
5238
implementation(projects.sentryAsyncProfiler)
5339
}
5440

@@ -74,15 +60,6 @@ tasks.jar {
7460

7561
tasks.startScripts { dependsOn(tasks.shadowJar) }
7662

77-
configure<SourceSetContainer> {
78-
main {
79-
if (!includeGraphql) {
80-
java.exclude("**/graphql/**")
81-
resources.exclude("graphql/**")
82-
}
83-
}
84-
}
85-
8663
tasks.withType<KotlinCompile>().configureEach {
8764
kotlin {
8865
compilerOptions.freeCompilerArgs = listOf("-Xjsr305=strict")

‎sentry-samples/sentry-samples-spring-boot/build.gradle.kts‎

Lines changed: 4 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -25,18 +25,6 @@ group = "io.sentry.sample.spring-boot"
2525

2626
version = "0.0.1-SNAPSHOT"
2727

28-
fun springBoot2SupportsOptionalIntegrations(): Boolean {
29-
val version = libs.versions.springboot2.get().removeSuffix(".RELEASE")
30-
val parts = version.split(".").map { it.toIntOrNull() ?: 0 }
31-
val major = parts.getOrElse(0) { 0 }
32-
val minor = parts.getOrElse(1) { 0 }
33-
return major > 2 || (major == 2 && minor >= 7)
34-
}
35-
36-
val includeGraphql =
37-
!project.hasProperty("excludeGraphql") && springBoot2SupportsOptionalIntegrations()
38-
val includeKafka = !project.hasProperty("excludeKafka") && springBoot2SupportsOptionalIntegrations()
39-
4028
tasks.withType<KotlinCompile>().configureEach {
4129
kotlin {
4230
compilerOptions.freeCompilerArgs = listOf("-Xjsr305=strict")
@@ -48,9 +36,7 @@ dependencies {
4836
implementation(libs.springboot.starter)
4937
implementation(libs.springboot.starter.actuator)
5038
implementation(libs.springboot.starter.aop)
51-
if (includeGraphql) {
52-
implementation(libs.springboot.starter.graphql)
53-
}
39+
implementation(libs.springboot.starter.graphql)
5440
implementation(libs.springboot.starter.jdbc)
5541
implementation(libs.springboot.starter.quartz)
5642
implementation(libs.springboot.starter.security)
@@ -60,18 +46,14 @@ dependencies {
6046
implementation(libs.springboot.starter.websocket)
6147
implementation(libs.caffeine)
6248

63-
if (includeKafka) {
64-
implementation(libs.spring.kafka2)
65-
implementation(projects.sentryKafka)
66-
}
49+
implementation(libs.spring.kafka2)
50+
implementation(projects.sentryKafka)
6751
implementation(Config.Libs.aspectj)
6852
implementation(Config.Libs.kotlinReflect)
6953
implementation(kotlin(Config.kotlinStdLib, KotlinCompilerVersion.VERSION))
7054
implementation(projects.sentrySpringBootStarter)
7155
implementation(projects.sentryLogback)
72-
if (includeGraphql) {
73-
implementation(projects.sentryGraphql)
74-
}
56+
implementation(projects.sentryGraphql)
7557
implementation(projects.sentryQuartz)
7658
implementation(projects.sentryAsyncProfiler)
7759

@@ -108,16 +90,3 @@ tasks.jar {
10890
}
10991

11092
tasks.startScripts { dependsOn(tasks.shadowJar) }
111-
112-
configure<SourceSetContainer> {
113-
main {
114-
if (!includeGraphql) {
115-
java.exclude("**/graphql/**")
116-
resources.exclude("graphql/**")
117-
}
118-
if (!includeKafka) {
119-
java.exclude("**/queues/kafka/**")
120-
resources.exclude("application-kafka.properties")
121-
}
122-
}
123-
}

‎sentry-spring-boot-4/src/integrationTest/kotlin/io/sentry/spring/boot4/integrationtest/PersonIntegrationTest.kt‎

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,24 +19,32 @@ class PersonIntegrationTest : IntegrationTest() {
1919

2020
@Test
2121
fun `failed request reports errors, the transaction and logs`() {
22-
val response = restTemplate.getForEntity("/person/1", String::class.java)
22+
val response = restTemplate.getForEntity("/person/11", String::class.java)
2323
assertThat(response.statusCode.value()).isEqualTo(500)
2424
Sentry.flush(5000)
2525

2626
val logged =
27-
server.awaitEnvelope { it.event()?.message?.formatted == "Trying person with id=1" }.event()!!
27+
server
28+
.awaitEnvelope { it.event()?.message?.formatted == "Trying person with id=11" }
29+
.event()!!
2830
assertThat(logged.hasFlag("my-feature-flag", true)).isTrue()
2931

3032
val thrown =
3133
server
3234
.awaitEnvelope {
33-
it.event()?.exceptions?.any { e -> e.value == "Something went wrong [id=1]" } == true
35+
it.event()?.exceptions?.any { e -> e.value == "Something went wrong [id=11]" } == true
3436
}
3537
.event()!!
3638
assertThat(thrown.hasFlag("my-feature-flag", true)).isTrue()
3739

3840
val transaction =
39-
server.awaitEnvelope { it.transaction()?.transaction == "GET /person/{id}" }.transaction()!!
41+
server
42+
.awaitEnvelope {
43+
it.transaction()?.let { t ->
44+
t.transaction == "GET /person/{id}" && t.request?.url?.endsWith("/person/11") == true
45+
} == true
46+
}
47+
.transaction()!!
4048
assertThat(
4149
transaction.hasOp(
4250
"http.server",

0 commit comments

Comments
 (0)