Skip to content

Commit 296653e

Browse files
committed
#7: Support for in-process transport for testing
Signed-off-by: andreilisa <andreilisa2001@gmail.com>
1 parent 1397632 commit 296653e

File tree

4 files changed

+184
-1
lines changed

4 files changed

+184
-1
lines changed
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
/*
2+
* Copyright 2024-2024 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.grpc.sample;
18+
19+
import io.grpc.ManagedChannel;
20+
import org.junit.jupiter.api.AfterEach;
21+
import org.junit.jupiter.api.BeforeEach;
22+
import org.junit.jupiter.api.Nested;
23+
import org.junit.jupiter.api.Test;
24+
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
25+
import org.springframework.boot.test.context.SpringBootTest;
26+
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
27+
import org.springframework.grpc.test.InProcessApplicationContextInitializer;
28+
29+
import static org.assertj.core.api.Assertions.assertThat;
30+
import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy;
31+
32+
/*
33+
* @author Andrei Lisa
34+
*/
35+
36+
@SpringBootTest
37+
class InProcessApplicationContextInitializerTests {
38+
39+
private AnnotationConfigApplicationContext context;
40+
41+
@BeforeEach
42+
public void setUp() {
43+
System.clearProperty("spring.grpc.inprocess");
44+
context = new AnnotationConfigApplicationContext();
45+
}
46+
47+
@AfterEach
48+
public void cleanUp() {
49+
InProcessApplicationContextInitializer.shutdown();
50+
context.close();
51+
}
52+
53+
@Nested
54+
class WhenDefaultEnabled {
55+
56+
@Test
57+
void shouldInitializeInProcessServer() {
58+
new InProcessApplicationContextInitializer().initialize(context);
59+
context.refresh();
60+
61+
ManagedChannel channel = context.getBean("grpcInProcessChannel", ManagedChannel.class);
62+
assertThat(channel).isNotNull().isInstanceOf(ManagedChannel.class);
63+
}
64+
65+
}
66+
67+
@Nested
68+
class WhenDisabledByProperty {
69+
70+
@Test
71+
void shouldNotInitializeInProcessServer() {
72+
System.setProperty("spring.grpc.inprocess", "false");
73+
new InProcessApplicationContextInitializer().initialize(context);
74+
context.refresh();
75+
assertThatThrownBy(() -> {
76+
context.getBean("grpcInProcessChannel", ManagedChannel.class);
77+
}).isInstanceOf(NoSuchBeanDefinitionException.class);
78+
}
79+
80+
}
81+
82+
@Nested
83+
class WhenShutdownIsCalled {
84+
85+
@Test
86+
void shouldShutdownInProcessServer() {
87+
new InProcessApplicationContextInitializer().initialize(context);
88+
context.refresh();
89+
90+
ManagedChannel channel = context.getBean("grpcInProcessChannel", ManagedChannel.class);
91+
assertThat(channel).isNotNull();
92+
93+
InProcessApplicationContextInitializer.shutdown();
94+
95+
assertThat(channel).isNotNull();
96+
assertThat(channel.isShutdown()).isTrue();
97+
}
98+
99+
}
100+
101+
}

spring-grpc-test/pom.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,5 +35,9 @@
3535
<groupId>io.grpc</groupId>
3636
<artifactId>grpc-testing</artifactId>
3737
</dependency>
38+
<dependency>
39+
<groupId>io.grpc</groupId>
40+
<artifactId>grpc-inprocess</artifactId>
41+
</dependency>
3842
</dependencies>
3943
</project>
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/*
2+
* Copyright 2024-2024 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.grpc.test;
18+
19+
import io.grpc.ManagedChannel;
20+
import io.grpc.Server;
21+
import io.grpc.inprocess.InProcessChannelBuilder;
22+
import io.grpc.inprocess.InProcessServerBuilder;
23+
import org.springframework.context.ApplicationContextInitializer;
24+
import org.springframework.context.ConfigurableApplicationContext;
25+
26+
/*
27+
* @author Andrei Lisa
28+
*/
29+
public class InProcessApplicationContextInitializer
30+
implements ApplicationContextInitializer<ConfigurableApplicationContext> {
31+
32+
private static final String PROPERTY_SOURCE_NAME = "spring.grpc.inprocess";
33+
34+
private static final String CHANNEL_NAME = "grpcInProcessChannel";
35+
36+
private static Server grpcServer;
37+
38+
private static ManagedChannel grpcChannel;
39+
40+
@Override
41+
public void initialize(ConfigurableApplicationContext applicationContext) {
42+
String inProcessEnabled = System.getProperty(PROPERTY_SOURCE_NAME, "true");
43+
44+
if ("true".equalsIgnoreCase(inProcessEnabled) && isJarOnClasspath()) {
45+
try {
46+
String serverName = InProcessServerBuilder.generateName();
47+
48+
grpcServer = InProcessServerBuilder.forName(serverName).directExecutor().build().start();
49+
50+
grpcChannel = InProcessChannelBuilder.forName(serverName).directExecutor().build();
51+
applicationContext.getBeanFactory().registerSingleton(CHANNEL_NAME, grpcChannel);
52+
53+
}
54+
catch (Exception e) {
55+
throw new RuntimeException("Failed to initialize in-process gRPC server", e);
56+
}
57+
}
58+
}
59+
60+
private boolean isJarOnClasspath() {
61+
try {
62+
Class.forName("io.grpc.inprocess.InProcessChannelBuilder");
63+
return true;
64+
}
65+
catch (ClassNotFoundException e) {
66+
return false;
67+
}
68+
}
69+
70+
public static void shutdown() {
71+
if (grpcChannel != null)
72+
grpcChannel.shutdownNow();
73+
if (grpcServer != null)
74+
grpcServer.shutdownNow();
75+
}
76+
77+
}
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
# Application Context Initializers
22
org.springframework.context.ApplicationContextInitializer=\
3-
org.springframework.grpc.test.ServerPortInfoApplicationContextInitializer
3+
org.springframework.grpc.test.ServerPortInfoApplicationContextInitializer,\
4+
org.springframework.grpc.test.InProcessApplicationContextInitializer

0 commit comments

Comments
 (0)