Please hint me how to get Sleuth Baggage working in integration test. It works as expected when test pass mock HTTP request but does not work when test calls service directly. My application is (Spring Boot 2.5.4, Spring Cloud 2020.0.3):
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
@Bean
BaggageField myBaggageField() {
return BaggageField.create("my-field-name");
}
@RestController
static class MyController {
@AutowiredMyService myService;
@GetMapping
String callService() {
return myService.updateAndGet();
}
}
@Service
static class MyService {
@Autowired BaggageField baggageField;
public String updateAndGet() {
baggageField.updateValue("value");
return baggageField.getValue();
}
}
}
application.yml:
spring.sleuth.baggage.remote-fields: my-field-name
test:
@SpringBootTest
@AutoConfigureMockMvc
class MyApplicationTests {
@Autowired
MyService myService;
@Autowired
MockMvc mockMvc;
@Test
void testBaggageByService() {
assertThat(myService.updateAndGet()).isEqualTo("value"); // FAILS
}
@Test
void testBaggageByController() throws Exception {
mockMvc.perform(get("/")).andExpect(content().string("value")); // PASS
}
}
Please read the docs about flush and update option in Brave - https://docs.spring.io/spring-cloud-sleuth/docs/current/reference/html/project-features.html#features-baggage
Set this up and try again
// configuration
@Bean
BaggageField countryCodeField() {
return BaggageField.create("my-field-name");
}
@Bean
ScopeDecorator mdcScopeDecorator() {
return MDCScopeDecorator.newBuilder()
.clear()
.add(SingleCorrelationField.newBuilder(countryCodeField())
.flushOnUpdate()
.build())
.build();
}
EDIT:
In your comment you state:
Well, Sleuth instrumentation is a Servlet Filter, but additionaly there are many other instrumentations, for example for message listener, for quartz scheduler etc. I simply guess there should be also instrumentation for integration test as well
There is no such integration and I don't see any point in having one. You have to start a span yourself, manually in your test and put it in scope. You can find an example here https://github.com/spring-cloud/spring-cloud-sleuth/blob/v3.0.3/tests/common/src/main/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/CircuitBreakerIntegrationTests.java#L55-L71
@Autowired
Tracer tracer;
@Autowired
CircuitBreakerFactory factory;
@Test
public void should_pass_tracing_information_when_using_circuit_breaker() {
// given
Tracer tracer = this.tracer;
ScopedSpan scopedSpan = null;
try {
scopedSpan = tracer.startScopedSpan("start");
// when
Span span = this.factory.create("name").run(tracer::currentSpan);
BDDAssertions.then(span).isNotNull();
BDDAssertions.then(scopedSpan.context().traceId()).isEqualTo(span.context().traceId());
}
finally {
scopedSpan.end();
}
}