Skip to content

Commit ac9ebcd

Browse files
authored
Add distributed tracing tests to more modules (#4237)
* Also use port when checking if a request is made to Sentry DSN * changelog * Add a param to control whether the test script should rebuild before running the tested server * Add system tests for distributed tracing * reuse util classes for system tests * add schema * Add distributed tracing tests to more modules * use mono.just for post body
1 parent 251127d commit ac9ebcd

File tree

14 files changed

+1700
-0
lines changed

14 files changed

+1700
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package io.sentry.samples.spring.boot.jakarta;
2+
3+
import java.nio.charset.Charset;
4+
import org.slf4j.Logger;
5+
import org.slf4j.LoggerFactory;
6+
import org.springframework.http.HttpHeaders;
7+
import org.springframework.web.bind.annotation.GetMapping;
8+
import org.springframework.web.bind.annotation.PathVariable;
9+
import org.springframework.web.bind.annotation.PostMapping;
10+
import org.springframework.web.bind.annotation.RequestBody;
11+
import org.springframework.web.bind.annotation.RequestMapping;
12+
import org.springframework.web.bind.annotation.RestController;
13+
import org.springframework.web.client.RestClient;
14+
15+
@RestController
16+
@RequestMapping("/tracing/")
17+
public class DistributedTracingController {
18+
private static final Logger LOGGER = LoggerFactory.getLogger(DistributedTracingController.class);
19+
private final RestClient restClient;
20+
21+
public DistributedTracingController(RestClient restClient) {
22+
this.restClient = restClient;
23+
}
24+
25+
@GetMapping("{id}")
26+
Person person(@PathVariable Long id) {
27+
return restClient
28+
.get()
29+
.uri("http://localhost:8080/person/{id}", id)
30+
.header(
31+
HttpHeaders.AUTHORIZATION,
32+
"Basic " + HttpHeaders.encodeBasicAuth("user", "password", Charset.defaultCharset()))
33+
.retrieve()
34+
.body(Person.class);
35+
}
36+
37+
@PostMapping
38+
Person create(@RequestBody Person person) {
39+
return restClient
40+
.post()
41+
.uri("http://localhost:8080/person/")
42+
.body(person)
43+
.header(
44+
HttpHeaders.AUTHORIZATION,
45+
"Basic " + HttpHeaders.encodeBasicAuth("user", "password", Charset.defaultCharset()))
46+
.retrieve()
47+
.body(Person.class);
48+
}
49+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
package io.sentry.systemtest
2+
3+
import io.sentry.protocol.SentryId
4+
import io.sentry.systemtest.util.TestHelper
5+
import org.junit.Before
6+
import kotlin.test.Test
7+
import kotlin.test.assertEquals
8+
import kotlin.test.assertNotEquals
9+
10+
class DistributedTracingSystemTest {
11+
12+
lateinit var testHelper: TestHelper
13+
14+
@Before
15+
fun setup() {
16+
testHelper = TestHelper("http://localhost:8080")
17+
testHelper.reset()
18+
}
19+
20+
@Test
21+
fun `get person distributed tracing`() {
22+
val traceId = SentryId()
23+
val restClient = testHelper.restClient
24+
restClient.getPersonDistributedTracing(
25+
1L,
26+
mapOf(
27+
"sentry-trace" to "$traceId-424cffc8f94feeee-1",
28+
"baggage" to "sentry-public_key=502f25099c204a2fbf4cb16edc5975d1,sentry-sample_rand=0.456789,sentry-sample_rate=0.5,sentry-sampled=true,sentry-trace_id=$traceId,sentry-transaction=HTTP%20GET"
29+
)
30+
)
31+
assertEquals(500, restClient.lastKnownStatusCode)
32+
33+
testHelper.ensureTransactionReceived { transaction, envelopeHeader ->
34+
transaction.transaction == "GET /tracing/{id}" &&
35+
testHelper.doesTransactionHaveTraceId(transaction, traceId.toString())
36+
}
37+
38+
testHelper.ensureTransactionReceived { transaction, envelopeHeader ->
39+
transaction.transaction == "GET /person/{id}" &&
40+
testHelper.doesTransactionHaveTraceId(transaction, traceId.toString())
41+
}
42+
}
43+
44+
@Test
45+
fun `get person distributed tracing with sampled false`() {
46+
val traceId = SentryId()
47+
val restClient = testHelper.restClient
48+
restClient.getPersonDistributedTracing(
49+
1L,
50+
mapOf(
51+
"sentry-trace" to "$traceId-424cffc8f94feeee-0",
52+
"baggage" to "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"
53+
)
54+
)
55+
assertEquals(500, restClient.lastKnownStatusCode)
56+
57+
testHelper.ensureNoTransactionReceived { transaction, envelopeHeader ->
58+
transaction.transaction == "GET /tracing/{id}"
59+
}
60+
61+
testHelper.ensureNoTransactionReceived { transaction, envelopeHeader ->
62+
transaction.transaction == "GET /person/{id}"
63+
}
64+
}
65+
66+
@Test
67+
fun `get person distributed tracing without sample_rand`() {
68+
val traceId = SentryId()
69+
val restClient = testHelper.restClient
70+
restClient.getPersonDistributedTracing(
71+
1L,
72+
mapOf(
73+
"sentry-trace" to "$traceId-424cffc8f94feeee-1",
74+
"baggage" to "sentry-public_key=502f25099c204a2fbf4cb16edc5975d1,sentry-sample_rate=0.5,sentry-sampled=true,sentry-trace_id=$traceId,sentry-transaction=HTTP%20GET"
75+
)
76+
)
77+
assertEquals(500, restClient.lastKnownStatusCode)
78+
79+
var sampleRand1: String? = null
80+
var sampleRand2: String? = null
81+
82+
testHelper.ensureTransactionReceived { transaction, envelopeHeader ->
83+
84+
val matches = transaction.transaction == "GET /tracing/{id}" &&
85+
envelopeHeader.traceContext!!.traceId == traceId &&
86+
testHelper.doesTransactionHaveTraceId(transaction, traceId.toString())
87+
88+
if (matches) {
89+
testHelper.logObject(envelopeHeader)
90+
testHelper.logObject(transaction)
91+
sampleRand1 = envelopeHeader.traceContext?.sampleRand
92+
}
93+
94+
matches
95+
}
96+
97+
testHelper.ensureTransactionReceived { transaction, envelopeHeader ->
98+
val matches = transaction.transaction == "GET /person/{id}" &&
99+
envelopeHeader.traceContext!!.traceId == traceId &&
100+
testHelper.doesTransactionHaveTraceId(transaction, traceId.toString())
101+
102+
if (matches) {
103+
testHelper.logObject(envelopeHeader)
104+
testHelper.logObject(transaction)
105+
sampleRand2 = envelopeHeader.traceContext?.sampleRand
106+
}
107+
108+
matches
109+
}
110+
111+
assertEquals(sampleRand1, sampleRand2)
112+
}
113+
114+
@Test
115+
fun `get person distributed tracing updates sample_rate on deferred decision`() {
116+
val traceId = SentryId()
117+
val restClient = testHelper.restClient
118+
restClient.getPersonDistributedTracing(
119+
1L,
120+
mapOf(
121+
"sentry-trace" to "$traceId-424cffc8f94feeee",
122+
"baggage" to "sentry-public_key=502f25099c204a2fbf4cb16edc5975d1,sentry-sample_rate=0.5,sentry-trace_id=$traceId,sentry-transaction=HTTP%20GET"
123+
)
124+
)
125+
assertEquals(500, restClient.lastKnownStatusCode)
126+
127+
var sampleRate1: String? = null
128+
var sampleRate2: String? = null
129+
130+
testHelper.ensureTransactionReceived { transaction, envelopeHeader ->
131+
132+
val matches = transaction.transaction == "GET /tracing/{id}" &&
133+
envelopeHeader.traceContext!!.traceId == traceId &&
134+
testHelper.doesTransactionHaveTraceId(transaction, traceId.toString())
135+
136+
if (matches) {
137+
testHelper.logObject(envelopeHeader)
138+
testHelper.logObject(transaction)
139+
sampleRate1 = envelopeHeader.traceContext?.sampleRate
140+
}
141+
142+
matches
143+
}
144+
145+
testHelper.ensureTransactionReceived { transaction, envelopeHeader ->
146+
val matches = transaction.transaction == "GET /person/{id}" &&
147+
envelopeHeader.traceContext!!.traceId == traceId &&
148+
testHelper.doesTransactionHaveTraceId(transaction, traceId.toString())
149+
150+
if (matches) {
151+
testHelper.logObject(envelopeHeader)
152+
testHelper.logObject(transaction)
153+
sampleRate2 = envelopeHeader.traceContext?.sampleRate
154+
}
155+
156+
matches
157+
}
158+
159+
assertEquals(sampleRate1, sampleRate2)
160+
assertNotEquals(sampleRate1, "0.5")
161+
}
162+
163+
@Test
164+
fun `create person distributed tracing`() {
165+
val traceId = SentryId()
166+
val restClient = testHelper.restClient
167+
val person = Person("firstA", "lastB")
168+
val returnedPerson = restClient.createPersonDistributedTracing(
169+
person,
170+
mapOf(
171+
"sentry-trace" to "$traceId-424cffc8f94feeee-1",
172+
"baggage" to "sentry-public_key=502f25099c204a2fbf4cb16edc5975d1,sentry-sample_rand=0.456789,sentry-sample_rate=0.5,sentry-sampled=true,sentry-trace_id=$traceId,sentry-transaction=HTTP%20GET"
173+
)
174+
)
175+
assertEquals(200, restClient.lastKnownStatusCode)
176+
177+
assertEquals(person.firstName, returnedPerson!!.firstName)
178+
assertEquals(person.lastName, returnedPerson!!.lastName)
179+
180+
testHelper.ensureTransactionReceived { transaction, envelopeHeader ->
181+
transaction.transaction == "POST /tracing/" &&
182+
testHelper.doesTransactionHaveTraceId(transaction, traceId.toString())
183+
}
184+
185+
testHelper.ensureTransactionReceived { transaction, envelopeHeader ->
186+
transaction.transaction == "POST /person/" &&
187+
testHelper.doesTransactionHaveTraceId(transaction, traceId.toString())
188+
}
189+
}
190+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package io.sentry.samples.spring.boot.jakarta;
2+
3+
import java.nio.charset.Charset;
4+
import org.slf4j.Logger;
5+
import org.slf4j.LoggerFactory;
6+
import org.springframework.http.HttpHeaders;
7+
import org.springframework.web.bind.annotation.GetMapping;
8+
import org.springframework.web.bind.annotation.PathVariable;
9+
import org.springframework.web.bind.annotation.PostMapping;
10+
import org.springframework.web.bind.annotation.RequestBody;
11+
import org.springframework.web.bind.annotation.RequestMapping;
12+
import org.springframework.web.bind.annotation.RestController;
13+
import org.springframework.web.client.RestClient;
14+
15+
@RestController
16+
@RequestMapping("/tracing/")
17+
public class DistributedTracingController {
18+
private static final Logger LOGGER = LoggerFactory.getLogger(DistributedTracingController.class);
19+
private final RestClient restClient;
20+
21+
public DistributedTracingController(RestClient restClient) {
22+
this.restClient = restClient;
23+
}
24+
25+
@GetMapping("{id}")
26+
Person person(@PathVariable Long id) {
27+
return restClient
28+
.get()
29+
.uri("http://localhost:8080/person/{id}", id)
30+
.header(
31+
HttpHeaders.AUTHORIZATION,
32+
"Basic " + HttpHeaders.encodeBasicAuth("user", "password", Charset.defaultCharset()))
33+
.retrieve()
34+
.body(Person.class);
35+
}
36+
37+
@PostMapping
38+
Person create(@RequestBody Person person) {
39+
return restClient
40+
.post()
41+
.uri("http://localhost:8080/person/")
42+
.body(person)
43+
.header(
44+
HttpHeaders.AUTHORIZATION,
45+
"Basic " + HttpHeaders.encodeBasicAuth("user", "password", Charset.defaultCharset()))
46+
.retrieve()
47+
.body(Person.class);
48+
}
49+
}

0 commit comments

Comments
 (0)