spring-projects / spring-projects/spring-boot
AutoConfigureTestGrpcTransport does not participate in the test context's key and tries to start the same in-process server multiple times
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 81.5k
- Forks
- 42.7k
- Avg merge
- 2d 4h
- Merged PRs (30d)
- 65
Description
My working 1.0.3 setup:
<dependency>
<groupId>org.springframework.grpc</groupId>
<artifactId>spring-grpc-server-spring-boot-starter</artifactId>
<version>1.0.3</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.grpc</groupId>
<artifactId>spring-grpc-test</artifactId>
<version>${spring-grpc.version}</version>
<optional>true</optional>
</dependency>
Test class:
@ExtensionMethod({WebTestClientExtensions.class, GrpcClientExtensions.class})
@WebFluxTest
@AutoConfigureInProcessTransport
@ImportAutoConfiguration({
ReactiveWebSecurityAutoConfiguration.class,
GrpcServerAutoConfiguration.class,
GrpcServerFactoryAutoConfiguration.class
})
public class GrpcIntegrationTests extends AbstractGrpcIntegrationTests {
private static final String TEST_FIXTURES_FOLDER = "test-fixtures/grpc/";
@SpringBootConfiguration
@EnableAutoConfiguration
static class TestApplication extends AbstractGrpcTestApplication {}
GrpcIntegrationTests() {
super(TEST_FIXTURES_FOLDER);
}
@Nested
@ActiveProfiles("oauth2-disabled")
class GrpcOAuth2DisabledTests extends AbstractGrpcIntegrationTests {
GrpcOAuth2DisabledTests() {
super(TEST_FIXTURES_FOLDER);
}
Abstract class:
@ContextConfiguration(
initializers = AbstractGrpcIntegrationTests.GrpcApplicationContextInitializer.class)
@TestPropertySource(
properties = {})
public abstract class AbstractGrpcIntegrationTests extends AbstractApiReactiveIntegrationTests {
@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
@Autowired
protected ReactorGrpcTestServiceGrpc.ReactorGrpcTestServiceStub stub;
protected AbstractGrpcIntegrationTests(String testFixturesFolder) {
super(testFixturesFolder);
}
public static final class GrpcApplicationContextInitializer
implements ApplicationContextInitializer<ConfigurableApplicationContext> {
@Override
public void initialize(@NonNull ConfigurableApplicationContext applicationContext) {
TestPropertyValues.of("spring.grpc.server.inprocess.name=test-inprocess-" + UUID.randomUUID())
.applyTo(applicationContext);
}
}
protected abstract static class AbstractGrpcTestApplication extends AbstractTestApplication {
@Bean
public GrpcTestService grpcTestService() {
return new GrpcTestService();
}
@Bean
public ReactorGrpcTestServiceGrpc.ReactorGrpcTestServiceStub stub(
GrpcChannelFactory channels,
@Value("${spring.grpc.server.inprocess.name}") String name) {
return ReactorGrpcTestServiceGrpc.newReactorStub(channels.createChannel(name));
}
}
}
So the idea was that the @Nested tests would each create a test-inprocess- instead and wire up the stub.
Now I'm trying to get this to work with:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-grpc-server</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-grpc-server-test</artifactId>
<optional>true</optional>
</dependency>
new test class preamble:
@ExtensionMethod({WebTestClientExtensions.class, GrpcClientExtensions.class})
@WebFluxTest
@AutoConfigureTestGrpcTransport
@ImportAutoConfiguration({
ReactiveWebSecurityAutoConfiguration.class,
GrpcServerAutoConfiguration.class
})
The top level test class works fine, but @Nested classes fail with:
Caused by: java.io.IOException: name already registered: 3f6df1c8-474e-47ea-9995-acf6d64baff4
Seems like it is ignoring the spring.grpc.server.inprocess.name property and/or starting up duplicate instances.
I read the migration guide and didn't see anything around this.
Except maybe this blurb:
Test Specific Factory Classes
Tests now use a custom GrpcServerFactory to create in-process channels rather than using InProcessGrpcServerFactory. This helps keep InProcessGrpcServerFactory for user code and allow better detection of then a factory is for test purposes.
but not much information on it.
Trying to debug, it only gets into InProcessGrpcServerConfiguration if I use:
@AutoConfigureTestGrpcTransport(enableServerFactory = true)
Then it uses my custom names, but it still tries to create the inprocess server with the plain guid which I assume is the spring boot one.
EDIT: Seems to be an oversight with TestGrpcTransportAutoConfiguration not respecting the custom name. If I exclude it and then c&p TestGrpcChannelFactory into my code and create these 3 beans:
@Bean
ClientInterceptorsConfigurer grpcClientInterceptorsConfigurer(ApplicationContext applicationContext) {
return new ClientInterceptorsConfigurer(applicationContext);
}
@Bean
public SslBundles sslBundles() {
SslBundle sslBundle = SslBundle.of(SslStoreBundle.NONE);
return new DefaultSslBundleRegistry("grpc", sslBundle);
}
@Bean
@Order(Ordered.HIGHEST_PRECEDENCE)
TestGrpcChannelFactory testGrpcChannelFactory(ClientInterceptorsConfigurer interceptorsConfigurer, @Value("${spring.grpc.server.inprocess.name}") String name) {
return new TestGrpcChannelFactory(name, interceptorsConfigurer);
}
Then it works, so the problem seems to be that you're using private static final String address = InProcessServerBuilder.generateName(); and ignoring the property.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with TestGrpcTransportAutoConfiguration and TestGrpcChannelFactory, then trace how InProcessGrpcServerConfiguration handles spring.grpc.server.inprocess.name. Reproduce the failure with the shown nested test classes and distinct UUID-based names. Done means nested contexts start without duplicate in-process server registration and the configured names are respected.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- grpc, java, spring-boot
- Domain
- api, backend, testing
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100