Skip to content

Commit 449c56d

Browse files
runningcodeclaude
andauthored
test(spring-boot): [Sample Tests 10] Move the Boot 3 Kafka test into the module (#6296)
* test(spring-boot): Move the Boot 3 Kafka test into the module Ports the jakarta sample's KafkaQueueSystemTest to the integrationTest suite with an embedded KRaft broker, so no Docker is needed. The five sample tests become two that keep every assertion: the publishing request's queue.publish span, and a queue.process transaction that continues the producer's trace. Both check the messaging attributes. The broker is declared with @embeddedkafka on the shared base class so it belongs to the one application context: it starts before the app's listener connects and stops after it. The jakarta sample has no system tests left, so it comes off the system-test runner, the backend workflow and the Spring Boot 3 matrix, which keeps running the module's integration suites. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * test(spring-boot): Fix the wrapping of the embedded broker comment Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
1 parent 798c4c5 commit 449c56d

12 files changed

Lines changed: 93 additions & 197 deletions

File tree

‎.github/workflows/spring-boot-3-matrix.yml‎

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,6 @@ jobs:
7171
- name: Build sample artifacts
7272
run: |
7373
./gradlew \
74-
:sentry-samples:sentry-samples-spring-boot-jakarta:bootJar \
75-
:sentry-samples:sentry-samples-spring-boot-jakarta:testClasses \
7674
:sentry-samples:sentry-samples-spring-boot-webflux-jakarta:bootJar \
7775
:sentry-samples:sentry-samples-spring-boot-webflux-jakarta:testClasses \
7876
:sentry-samples:sentry-samples-spring-boot-jakarta-opentelemetry:bootJar \
@@ -89,13 +87,6 @@ jobs:
8987
:sentry-spring-boot-jakarta:integrationTest \
9088
:sentry-spring-boot-jakarta:integrationTestOtelAgent
9189
92-
- name: Test sentry-samples-spring-boot-jakarta
93-
run: |
94-
python3 test/system-test-runner.py test \
95-
--module "sentry-samples-spring-boot-jakarta" \
96-
--agent false \
97-
--auto-init "true"
98-
9990
- name: Test sentry-samples-spring-boot-webflux-jakarta
10091
run: |
10192
python3 test/system-test-runner.py test \

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

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,10 @@ jobs:
2424
strategy:
2525
fail-fast: false
2626
matrix:
27-
sample: [ "sentry-samples-spring-boot-jakarta" ]
27+
sample: [ "sentry-samples-spring-boot" ]
2828
agent: [ "false" ]
2929
agent-auto-init: [ "true" ]
3030
include:
31-
- sample: "sentry-samples-spring-boot"
32-
agent: "false"
33-
agent-auto-init: "true"
3431
- sample: "sentry-samples-spring-boot-opentelemetry-noagent"
3532
agent: "false"
3633
agent-auto-init: "true"

‎gradle/libs.versions.toml‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ spotless = "8.8.0"
4848
springboot2 = "2.7.18"
4949
springboot3 = "3.5.0"
5050
springboot4 = "4.1.0"
51+
springKafka3 = "3.3.5"
5152
sqldelight = "2.3.2"
5253

5354
# Android
@@ -219,7 +220,8 @@ springboot3-starter-jdbc = { module = "org.springframework.boot:spring-boot-star
219220
springboot3-starter-actuator = { module = "org.springframework.boot:spring-boot-starter-actuator", version.ref = "springboot3" }
220221
springboot3-starter-cache = { module = "org.springframework.boot:spring-boot-starter-cache", version.ref = "springboot3" }
221222
spring-kafka2 = { module = "org.springframework.kafka:spring-kafka", version = "2.8.11" }
222-
spring-kafka3 = { module = "org.springframework.kafka:spring-kafka", version = "3.3.5" }
223+
spring-kafka3 = { module = "org.springframework.kafka:spring-kafka", version.ref = "springKafka3" }
224+
spring-kafka3-test = { module = "org.springframework.kafka:spring-kafka-test", version.ref = "springKafka3" }
223225
spring-kafka4 = { module = "org.springframework.kafka:spring-kafka" }
224226
kafka-clients = { module = "org.apache.kafka:kafka-clients", version = "3.8.1" }
225227
springboot4-otel = { module = "io.opentelemetry.instrumentation:opentelemetry-spring-boot-starter", version.ref = "otelInstrumentation" }

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

Lines changed: 0 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ plugins {
66
alias(libs.plugins.spring.dependency.management)
77
alias(libs.plugins.kotlin.jvm)
88
alias(libs.plugins.kotlin.spring)
9-
id("io.sentry.systemtest")
109
}
1110

1211
group = "io.sentry.sample.spring-boot-jakarta"
@@ -67,34 +66,4 @@ dependencies {
6766
// database query tracing
6867
implementation(projects.sentryJdbc)
6968
runtimeOnly(libs.hsqldb)
70-
71-
testImplementation(kotlin(Config.kotlinStdLib))
72-
testImplementation(projects.sentry)
73-
testImplementation(projects.sentrySystemTestSupport)
74-
testImplementation(libs.kotlin.test.junit)
75-
testImplementation(libs.slf4j2.api)
76-
testImplementation(libs.springboot3.starter.test) {
77-
exclude(group = "org.junit.vintage", module = "junit-vintage-engine")
78-
}
79-
testImplementation("ch.qos.logback:logback-classic:1.5.16")
80-
testImplementation("ch.qos.logback:logback-core:1.5.16")
81-
}
82-
83-
tasks.register<Test>("systemTest").configure {
84-
group = "verification"
85-
description = "Runs the System tests"
86-
87-
val test = project.extensions.getByType<SourceSetContainer>()["test"]
88-
testClassesDirs = test.output.classesDirs
89-
classpath = test.runtimeClasspath
90-
91-
maxParallelForks = 1
92-
93-
filter { includeTestsMatching("io.sentry.systemtest*") }
94-
}
95-
96-
tasks.named("test").configure {
97-
require(this is Test)
98-
99-
filter { excludeTestsMatching("io.sentry.systemtest.*") }
10069
}

‎sentry-samples/sentry-samples-spring-boot-jakarta/src/test/kotlin/io/sentry/DummyTest.kt‎

Lines changed: 0 additions & 12 deletions
This file was deleted.

‎sentry-samples/sentry-samples-spring-boot-jakarta/src/test/kotlin/io/sentry/systemtest/KafkaQueueSystemTest.kt‎

Lines changed: 0 additions & 117 deletions
This file was deleted.

‎sentry-samples/sentry-samples-spring-boot-jakarta/src/test/resources/logback.xml‎

Lines changed: 0 additions & 17 deletions
This file was deleted.

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@ testing {
180180
implementation(projects.sentryAsyncProfiler)
181181
implementation(projects.sentryGraphql22)
182182
implementation(projects.sentryJdbc)
183+
implementation(projects.sentryKafka)
183184
implementation(projects.sentryLogback)
184185
implementation(projects.sentryOkhttp)
185186
implementation(projects.sentryOpenfeature)
@@ -200,6 +201,8 @@ testing {
200201
implementation(libs.springboot3.starter.test)
201202
implementation(libs.springboot3.starter.web)
202203
implementation(libs.springboot3.starter.webflux)
204+
implementation(libs.spring.kafka3)
205+
implementation(libs.spring.kafka3.test)
203206
runtimeOnly(libs.hsqldb)
204207
}
205208
}

‎sentry-spring-boot-jakarta/src/integrationTest/kotlin/io/sentry/spring/boot/jakarta/integrationtest/IntegrationTest.kt‎

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,22 @@ import org.springframework.boot.test.context.SpringBootTest
77
import org.springframework.boot.test.web.client.TestRestTemplate
88
import org.springframework.boot.test.web.server.LocalServerPort
99
import org.springframework.boot.web.client.RestTemplateBuilder
10+
import org.springframework.kafka.test.context.EmbeddedKafka
1011
import org.springframework.test.context.DynamicPropertyRegistry
1112
import org.springframework.test.context.DynamicPropertySource
1213
import org.springframework.test.context.junit4.SpringRunner
1314

1415
/**
1516
* Drives [IntegrationTestApplication] over HTTP and asserts what reaches [server].
1617
*
17-
* Subclasses share one application context and one server, so the app starts once per suite.
18-
* Envelopes that arrive late can outlive [server]'s reset, so tests match on values only they
19-
* produce.
18+
* Subclasses share one application context, one server and one Kafka broker, so each starts once
19+
* per suite. Envelopes that arrive late can outlive [server]'s reset, so tests match on values only
20+
* they produce.
2021
*/
2122
@RunWith(SpringRunner::class)
23+
// An in-JVM KRaft broker, so no Docker is needed. As part of the context, it starts before the
24+
// app's Kafka listener connects and stops after it.
25+
@EmbeddedKafka(topics = [KAFKA_TOPIC], bootstrapServersProperty = "spring.kafka.bootstrap-servers")
2226
@SpringBootTest(
2327
classes = [IntegrationTestApplication::class],
2428
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
@@ -27,12 +31,14 @@ import org.springframework.test.context.junit4.SpringRunner
2731
"sentry.traces-sample-rate=1.0",
2832
"sentry.clients.ok-http-enabled=true",
2933
"sentry.enable-cache-tracing=true",
34+
"sentry.enable-queue-tracing=true",
3035
"sentry.logs.enabled=true",
3136
"sentry.profile-session-sample-rate=1.0",
3237
"sentry.profile-lifecycle=TRACE",
3338
"sentry.profiling-traces-dir-path=\${java.io.tmpdir}/sentry-integration-test/profiling-traces",
3439
"spring.datasource.url=jdbc:p6spy:hsqldb:mem:testdb",
3540
"spring.datasource.driver-class-name=com.p6spy.engine.spy.P6SpyDriver",
41+
"spring.kafka.consumer.auto-offset-reset=earliest",
3642
],
3743
)
3844
abstract class IntegrationTest {
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package io.sentry.spring.boot.jakarta.integrationtest
2+
3+
import org.springframework.kafka.annotation.KafkaListener
4+
import org.springframework.kafka.core.KafkaTemplate
5+
import org.springframework.stereotype.Component
6+
import org.springframework.web.bind.annotation.GetMapping
7+
import org.springframework.web.bind.annotation.RequestMapping
8+
import org.springframework.web.bind.annotation.RequestParam
9+
import org.springframework.web.bind.annotation.RestController
10+
11+
const val KAFKA_TOPIC = "sentry-topic"
12+
13+
@RestController
14+
@RequestMapping("/kafka")
15+
open class KafkaController(private val kafkaTemplate: KafkaTemplate<String, String>) {
16+
@GetMapping("/produce")
17+
open fun produce(@RequestParam message: String): String {
18+
kafkaTemplate.send(KAFKA_TOPIC, message)
19+
return "Message sent: $message"
20+
}
21+
}
22+
23+
@Component
24+
open class KafkaConsumer {
25+
/** Does nothing with the message; Sentry traces the listener invocation. */
26+
@KafkaListener(topics = [KAFKA_TOPIC], groupId = "sentry-integration-test")
27+
open fun listen(message: String) {}
28+
}

0 commit comments

Comments
 (0)