Skip to content

Commit b3db6af

Browse files
committed
Merge the audit fixes from the branches below
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> # Conflicts: # sentry-spring-boot-4/src/integrationTest/kotlin/io/sentry/spring/boot4/integrationtest/IntegrationTest.kt
2 parents ce29763 + 254e3ef commit b3db6af

6 files changed

Lines changed: 56 additions & 19 deletions

File tree

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

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import com.google.common.truth.Truth.assertThat
44
import io.sentry.SentryEnvelope
55
import io.sentry.protocol.SentryId
66
import io.sentry.test.transaction
7+
import kotlin.random.Random
78
import kotlin.test.Test
89
import org.springframework.http.HttpEntity
910
import org.springframework.http.HttpHeaders
@@ -27,26 +28,26 @@ class DistributedTracingIntegrationTest : IntegrationTest() {
2728
)
2829
assertThat(status).isEqualTo(500)
2930

30-
awaitTransaction("GET /tracing/{id}", traceId)
31+
val incoming = awaitTransaction("GET /tracing/{id}", traceId).transaction()!!
32+
assertThat(incoming.request?.url).endsWith("/tracing/1")
3133
awaitTransaction("GET /person/{id}", traceId)
3234
}
3335

3436
@Test
3537
fun `unsampled trace sends no transactions`() {
3638
val traceId = SentryId()
39+
// An id only this request uses, because a mishandled header could start a trace of its own.
40+
val id = Random.nextLong(2, Long.MAX_VALUE)
3741
val status =
3842
get(
39-
"/tracing/1",
43+
"/tracing/$id",
4044
sentryTrace = "$traceId-424cffc8f94feeee-0",
4145
baggage =
4246
"sentry-public_key=502f25099c204a2fbf4cb16edc5975d1,sentry-sample_rand=0.456789,sentry-sample_rate=0.5,sentry-sampled=false,sentry-trace_id=$traceId,sentry-transaction=HTTP%20GET",
4347
)
4448
assertThat(status).isEqualTo(500)
4549

46-
server.assertNoEnvelope {
47-
isTransaction(it, "GET /tracing/{id}", traceId) ||
48-
isTransaction(it, "GET /person/{id}", traceId)
49-
}
50+
server.assertNoEnvelope { isForRequest(it, id) }
5051
}
5152

5253
@Test
@@ -63,6 +64,8 @@ class DistributedTracingIntegrationTest : IntegrationTest() {
6364

6465
val incoming = awaitTransaction("GET /tracing/{id}", traceId).header.traceContext!!
6566
val outgoing = awaitTransaction("GET /person/{id}", traceId).header.traceContext!!
67+
assertThat(incoming.traceId).isEqualTo(traceId)
68+
assertThat(outgoing.traceId).isEqualTo(traceId)
6669
assertThat(incoming.sampleRand).isNotNull()
6770
assertThat(outgoing.sampleRand).isEqualTo(incoming.sampleRand)
6871
}
@@ -81,6 +84,8 @@ class DistributedTracingIntegrationTest : IntegrationTest() {
8184

8285
val incoming = awaitTransaction("GET /tracing/{id}", traceId).header.traceContext!!
8386
val outgoing = awaitTransaction("GET /person/{id}", traceId).header.traceContext!!
87+
assertThat(incoming.traceId).isEqualTo(traceId)
88+
assertThat(outgoing.traceId).isEqualTo(traceId)
8489
assertThat(incoming.sampleRate).isNotEqualTo("0.5")
8590
assertThat(outgoing.sampleRate).isEqualTo(incoming.sampleRate)
8691
}
@@ -130,6 +135,12 @@ class DistributedTracingIntegrationTest : IntegrationTest() {
130135
isTransaction(it, name, traceId)
131136
}
132137

138+
/** Whether [envelope] is a transaction for `/tracing/[id]` or the `/person/[id]` it calls. */
139+
private fun isForRequest(envelope: SentryEnvelope, id: Long): Boolean {
140+
val url = envelope.transaction()?.request?.url ?: return false
141+
return url.endsWith("/tracing/$id") || url.endsWith("/person/$id")
142+
}
143+
133144
private fun isTransaction(envelope: SentryEnvelope, name: String, traceId: SentryId): Boolean {
134145
val transaction = envelope.transaction() ?: return false
135146
return transaction.transaction == name && transaction.contexts.trace?.traceId == traceId

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ class GraphqlIntegrationTest : IntegrationTest() {
6767
val tasks = response["data"]["tasks"]
6868
assertThat(tasks.size()).isEqualTo(5)
6969
assertThat(tasks[0]["id"].asString()).isEqualTo("T1")
70+
assertThat(tasks[0]["assigneeId"].asString()).isEqualTo("A3")
71+
assertThat(tasks[0]["creatorId"].asString()).isEqualTo("C3")
7072
assertThat(tasks[0]["assignee"]["id"].asString()).isEqualTo("A3")
7173
assertThat(tasks[0]["creator"]["id"].asString()).isEqualTo("C3")
7274

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

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@ package io.sentry.spring.boot4.integrationtest
33
import io.sentry.test.MockSentryServer
44
import org.junit.Before
55
import org.junit.runner.RunWith
6-
import org.springframework.beans.factory.annotation.Autowired
6+
import org.springframework.boot.restclient.RestTemplateBuilder
77
import org.springframework.boot.resttestclient.TestRestTemplate
8-
import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate
98
import org.springframework.boot.test.context.SpringBootTest
9+
import org.springframework.boot.test.web.server.LocalServerPort
1010
import org.springframework.kafka.test.context.EmbeddedKafka
1111
import org.springframework.test.context.DynamicPropertyRegistry
1212
import org.springframework.test.context.DynamicPropertySource
@@ -20,8 +20,6 @@ import org.springframework.test.context.junit4.SpringRunner
2020
* they produce.
2121
*/
2222
@RunWith(SpringRunner::class)
23-
// Spring Boot 4 only provides TestRestTemplate when asked to.
24-
@AutoConfigureTestRestTemplate
2523
// An in-JVM KRaft broker, so no Docker is needed. As part of the context, it starts before the
2624
// app's Kafka listener connects and stops after it.
2725
@EmbeddedKafka(topics = [KAFKA_TOPIC], bootstrapServersProperty = "spring.kafka.bootstrap-servers")
@@ -44,7 +42,13 @@ import org.springframework.test.context.junit4.SpringRunner
4442
],
4543
)
4644
abstract class IntegrationTest {
47-
@Autowired lateinit var restTemplate: TestRestTemplate
45+
@LocalServerPort private var port = 0
46+
47+
// The context's TestRestTemplate comes from the RestTemplateBuilder that Sentry customizes, so
48+
// it would add trace headers of its own to the requests tests send. Tests use a plain one.
49+
val restTemplate: TestRestTemplate by lazy {
50+
TestRestTemplate(RestTemplateBuilder().rootUri("http://localhost:$port"))
51+
}
4852

4953
@Before
5054
fun resetServer() {

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

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import com.google.common.truth.Truth.assertThat
44
import io.sentry.SentryEnvelope
55
import io.sentry.protocol.SentryId
66
import io.sentry.test.transaction
7+
import kotlin.random.Random
78
import kotlin.test.Test
89
import org.springframework.http.HttpEntity
910
import org.springframework.http.HttpHeaders
@@ -27,26 +28,26 @@ class DistributedTracingIntegrationTest : IntegrationTest() {
2728
)
2829
assertThat(status).isEqualTo(500)
2930

30-
awaitTransaction("GET /tracing/{id}", traceId)
31+
val incoming = awaitTransaction("GET /tracing/{id}", traceId).transaction()!!
32+
assertThat(incoming.request?.url).endsWith("/tracing/1")
3133
awaitTransaction("GET /person/{id}", traceId)
3234
}
3335

3436
@Test
3537
fun `unsampled trace sends no transactions`() {
3638
val traceId = SentryId()
39+
// An id only this request uses, because a mishandled header could start a trace of its own.
40+
val id = Random.nextLong(2, Long.MAX_VALUE)
3741
val status =
3842
get(
39-
"/tracing/1",
43+
"/tracing/$id",
4044
sentryTrace = "$traceId-424cffc8f94feeee-0",
4145
baggage =
4246
"sentry-public_key=502f25099c204a2fbf4cb16edc5975d1,sentry-sample_rand=0.456789,sentry-sample_rate=0.5,sentry-sampled=false,sentry-trace_id=$traceId,sentry-transaction=HTTP%20GET",
4347
)
4448
assertThat(status).isEqualTo(500)
4549

46-
server.assertNoEnvelope {
47-
isTransaction(it, "GET /tracing/{id}", traceId) ||
48-
isTransaction(it, "GET /person/{id}", traceId)
49-
}
50+
server.assertNoEnvelope { isForRequest(it, id) }
5051
}
5152

5253
@Test
@@ -63,6 +64,8 @@ class DistributedTracingIntegrationTest : IntegrationTest() {
6364

6465
val incoming = awaitTransaction("GET /tracing/{id}", traceId).header.traceContext!!
6566
val outgoing = awaitTransaction("GET /person/{id}", traceId).header.traceContext!!
67+
assertThat(incoming.traceId).isEqualTo(traceId)
68+
assertThat(outgoing.traceId).isEqualTo(traceId)
6669
assertThat(incoming.sampleRand).isNotNull()
6770
assertThat(outgoing.sampleRand).isEqualTo(incoming.sampleRand)
6871
}
@@ -81,6 +84,8 @@ class DistributedTracingIntegrationTest : IntegrationTest() {
8184

8285
val incoming = awaitTransaction("GET /tracing/{id}", traceId).header.traceContext!!
8386
val outgoing = awaitTransaction("GET /person/{id}", traceId).header.traceContext!!
87+
assertThat(incoming.traceId).isEqualTo(traceId)
88+
assertThat(outgoing.traceId).isEqualTo(traceId)
8489
assertThat(incoming.sampleRate).isNotEqualTo("0.5")
8590
assertThat(outgoing.sampleRate).isEqualTo(incoming.sampleRate)
8691
}
@@ -130,6 +135,12 @@ class DistributedTracingIntegrationTest : IntegrationTest() {
130135
isTransaction(it, name, traceId)
131136
}
132137

138+
/** Whether [envelope] is a transaction for `/tracing/[id]` or the `/person/[id]` it calls. */
139+
private fun isForRequest(envelope: SentryEnvelope, id: Long): Boolean {
140+
val url = envelope.transaction()?.request?.url ?: return false
141+
return url.endsWith("/tracing/$id") || url.endsWith("/person/$id")
142+
}
143+
133144
private fun isTransaction(envelope: SentryEnvelope, name: String, traceId: SentryId): Boolean {
134145
val transaction = envelope.transaction() ?: return false
135146
return transaction.transaction == name && transaction.contexts.trace?.traceId == traceId

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ class GraphqlIntegrationTest : IntegrationTest() {
6767
val tasks = response["data"]["tasks"]
6868
assertThat(tasks.size()).isEqualTo(5)
6969
assertThat(tasks[0]["id"].asText()).isEqualTo("T1")
70+
assertThat(tasks[0]["assigneeId"].asText()).isEqualTo("A3")
71+
assertThat(tasks[0]["creatorId"].asText()).isEqualTo("C3")
7072
assertThat(tasks[0]["assignee"]["id"].asText()).isEqualTo("A3")
7173
assertThat(tasks[0]["creator"]["id"].asText()).isEqualTo("C3")
7274

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

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@ package io.sentry.spring.boot.jakarta.integrationtest
33
import io.sentry.test.MockSentryServer
44
import org.junit.Before
55
import org.junit.runner.RunWith
6-
import org.springframework.beans.factory.annotation.Autowired
76
import org.springframework.boot.test.context.SpringBootTest
87
import org.springframework.boot.test.web.client.TestRestTemplate
8+
import org.springframework.boot.test.web.server.LocalServerPort
9+
import org.springframework.boot.web.client.RestTemplateBuilder
910
import org.springframework.kafka.test.context.EmbeddedKafka
1011
import org.springframework.test.context.DynamicPropertyRegistry
1112
import org.springframework.test.context.DynamicPropertySource
@@ -41,7 +42,13 @@ import org.springframework.test.context.junit4.SpringRunner
4142
],
4243
)
4344
abstract class IntegrationTest {
44-
@Autowired lateinit var restTemplate: TestRestTemplate
45+
@LocalServerPort private var port = 0
46+
47+
// The context's TestRestTemplate comes from the RestTemplateBuilder that Sentry customizes, so
48+
// it would add trace headers of its own to the requests tests send. Tests use a plain one.
49+
val restTemplate: TestRestTemplate by lazy {
50+
TestRestTemplate(RestTemplateBuilder().rootUri("http://localhost:$port"))
51+
}
4552

4653
@Before
4754
fun resetServer() {

0 commit comments

Comments
 (0)