Skip to content

Commit d904f4c

Browse files
committed
test(spring-boot): Stop the Boot 2 agent app when it fails to start
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent 77e2e56 commit d904f4c

2 files changed

Lines changed: 27 additions & 10 deletions

File tree

‎sentry-spring-boot/src/integrationTestOtelAgent/kotlin/io/sentry/spring/boot/otelagentintegrationtest/AgentApp.kt‎

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,16 @@ class AgentApp(args: List<String> = emptyList()) : Closeable {
4141
)
4242

4343
// The agent instruments classes as they load, which on a busy CI runner has taken over a minute.
44-
val restTemplate =
45-
TestRestTemplate(
46-
RestTemplateBuilder().rootUri("http://localhost:${app.awaitPort(timeoutSeconds = 180)}")
47-
)
44+
private val port =
45+
try {
46+
app.awaitPort(timeoutSeconds = 180)
47+
} catch (e: IllegalStateException) {
48+
// The caller never gets this instance, so it can't stop the app.
49+
close()
50+
throw e
51+
}
52+
53+
val restTemplate = TestRestTemplate(RestTemplateBuilder().rootUri("http://localhost:$port"))
4854

4955
override fun close() {
5056
app.close()
@@ -56,10 +62,20 @@ class AgentApp(args: List<String> = emptyList()) : Closeable {
5662

5763
/**
5864
* The app most test classes share. It takes seconds to start, so each test JVM starts it once
59-
* and stops it when the JVM exits.
65+
* and stops it when the JVM exits. If it doesn't start, the remaining tests fail with the same
66+
* error rather than each waiting for a new app to time out.
6067
*/
61-
val shared: AgentApp by lazy {
62-
AgentApp().also { app -> Runtime.getRuntime().addShutdownHook(Thread { app.close() }) }
68+
val shared: AgentApp
69+
get() = sharedApp.getOrThrow()
70+
71+
private val sharedApp: Result<AgentApp> by lazy {
72+
try {
73+
Result.success(
74+
AgentApp().also { app -> Runtime.getRuntime().addShutdownHook(Thread { app.close() }) }
75+
)
76+
} catch (e: IllegalStateException) {
77+
Result.failure(e)
78+
}
6379
}
6480
}
6581
}

‎sentry-spring-boot/src/integrationTestOtelAgent/kotlin/io/sentry/spring/boot/otelagentintegrationtest/KafkaOtelCoexistenceIntegrationTest.kt‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import org.springframework.kafka.test.EmbeddedKafkaBroker
1717
*/
1818
class KafkaOtelCoexistenceIntegrationTest : IntegrationTest() {
1919
override val app: AgentApp
20-
get() = kafkaApp
20+
get() = kafkaApp!!
2121

2222
@Test
2323
fun `OpenTelemetry traces both sides of a message instead of Sentry's Kafka integration`() {
@@ -56,7 +56,8 @@ class KafkaOtelCoexistenceIntegrationTest : IntegrationTest() {
5656
companion object {
5757
// With the fixture's KAFKA_TOPIC, so no Docker is needed.
5858
private val kafka = EmbeddedKafkaBroker(1, true, 1, "sentry-topic")
59-
private lateinit var kafkaApp: AgentApp
59+
// Unset if the app didn't start, in which case stopApp still has to stop the broker.
60+
private var kafkaApp: AgentApp? = null
6061

6162
@JvmStatic
6263
@BeforeClass
@@ -74,7 +75,7 @@ class KafkaOtelCoexistenceIntegrationTest : IntegrationTest() {
7475
@JvmStatic
7576
@AfterClass
7677
fun stopApp() {
77-
kafkaApp.close()
78+
kafkaApp?.close()
7879
kafka.destroy()
7980
}
8081
}

0 commit comments

Comments
 (0)