Skip to content

Commit 47cc9f2

Browse files
author
Alexander Furer
committed
closes #242
1 parent 6a21761 commit 47cc9f2

18 files changed

+541
-227
lines changed

grpc-spring-boot-starter-demo/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ dependencies {
8282
testCompile 'org.springframework.boot:spring-boot-starter-test'
8383
testCompile 'com.github.stefanbirkner:system-rules:1.18.0'
8484
testCompile('org.springframework.cloud:spring-cloud-starter-consul-discovery')
85-
testCompile 'com.pszymczyk.consul:embedded-consul:2.1.4'
85+
testCompile 'com.pszymczyk.consul:embedded-consul:2.2.1'
8686
testCompile 'org.awaitility:awaitility:4.0.3'
8787
testCompile "org.springframework.cloud:spring-cloud-config-server"
8888
testCompile "org.springframework.cloud:spring-cloud-config-client"

grpc-spring-boot-starter-demo/src/test/java/org/lognet/springboot/grpc/ConsulRegistrationTest.java

Lines changed: 0 additions & 104 deletions
This file was deleted.

grpc-spring-boot-starter-demo/src/test/java/org/lognet/springboot/grpc/DemoAppTest.java

Lines changed: 5 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,11 @@
77
import io.grpc.examples.CalculatorOuterClass;
88
import io.grpc.examples.GreeterGrpc;
99
import io.grpc.examples.GreeterOuterClass;
10-
import io.grpc.health.v1.HealthCheckRequest;
11-
import io.grpc.health.v1.HealthCheckResponse;
12-
import io.grpc.health.v1.HealthGrpc;
1310
import io.grpc.reflection.v1alpha.ServerReflectionGrpc;
1411
import io.grpc.reflection.v1alpha.ServerReflectionRequest;
1512
import io.grpc.reflection.v1alpha.ServerReflectionResponse;
1613
import io.grpc.reflection.v1alpha.ServiceResponse;
1714
import io.grpc.stub.StreamObserver;
18-
import io.micrometer.core.instrument.Timer;
1915
import io.micrometer.prometheus.PrometheusConfig;
2016
import org.awaitility.Awaitility;
2117
import org.hamcrest.Matchers;
@@ -27,20 +23,17 @@
2723
import org.mockito.Mockito;
2824
import org.springframework.beans.factory.annotation.Autowired;
2925
import org.springframework.beans.factory.annotation.Qualifier;
30-
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
3126
import org.springframework.boot.test.context.SpringBootTest;
3227
import org.springframework.boot.test.system.OutputCaptureRule;
3328
import org.springframework.boot.test.web.client.TestRestTemplate;
3429
import org.springframework.http.HttpStatus;
3530
import org.springframework.http.ResponseEntity;
3631
import org.springframework.test.context.ActiveProfiles;
3732
import org.springframework.test.context.junit4.SpringRunner;
38-
import org.springframework.test.web.servlet.MockMvc;
3933

4034
import java.time.Duration;
4135
import java.util.ArrayList;
4236
import java.util.List;
43-
import java.util.Objects;
4437
import java.util.Optional;
4538
import java.util.Spliterator;
4639
import java.util.Spliterators;
@@ -54,14 +47,11 @@
5447
import static org.hamcrest.CoreMatchers.containsString;
5548
import static org.hamcrest.CoreMatchers.not;
5649
import static org.hamcrest.MatcherAssert.assertThat;
57-
import static org.hamcrest.Matchers.greaterThan;
58-
import static org.hamcrest.Matchers.notNullValue;
59-
import static org.junit.Assert.*;
50+
import static org.junit.Assert.assertEquals;
51+
import static org.junit.Assert.assertFalse;
52+
import static org.junit.Assert.assertNotNull;
53+
import static org.junit.Assert.assertNull;
6054
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
61-
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
62-
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
63-
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
64-
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
6555

6656
/**
6757
* Created by alexf on 28-Jan-16.
@@ -164,14 +154,7 @@ public void onCompleted() {
164154
}
165155

166156

167-
@Test
168-
public void testHealthCheck() throws ExecutionException, InterruptedException {
169-
final HealthCheckRequest healthCheckRequest = HealthCheckRequest.newBuilder().setService(GreeterGrpc.getServiceDescriptor().getName()).build();
170-
final HealthGrpc.HealthFutureStub healthFutureStub = HealthGrpc.newFutureStub(channel);
171-
final HealthCheckResponse.ServingStatus servingStatus = healthFutureStub.check(healthCheckRequest).get().getStatus();
172-
assertNotNull(servingStatus);
173-
assertEquals(servingStatus, HealthCheckResponse.ServingStatus.SERVING);
174-
}
157+
175158

176159
@Override
177160
protected void afterGreeting() throws Exception {
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package org.lognet.springboot.grpc.consul;
2+
3+
import com.ecwid.consul.v1.health.model.Check;
4+
import com.ecwid.consul.v1.health.model.HealthService;
5+
import org.hamcrest.Matchers;
6+
import org.junit.runner.RunWith;
7+
import org.lognet.springboot.grpc.demo.DemoApp;
8+
import org.springframework.boot.test.context.SpringBootTest;
9+
import org.springframework.test.context.junit4.SpringRunner;
10+
11+
import java.util.List;
12+
13+
import static org.hamcrest.MatcherAssert.assertThat;
14+
15+
16+
@SpringBootTest(classes = DemoApp.class)
17+
@RunWith(SpringRunner.class)
18+
public class ConsulDefaultRegistrationTest extends ConsulRegistrationBaseTest{
19+
20+
21+
22+
23+
@Override
24+
void doTest( List<HealthService> healthServices) {
25+
26+
27+
assertThat(healthServices,Matchers.hasSize(1));
28+
29+
final long healthyGrpcServicesChecksCount = healthServices
30+
.stream()
31+
.flatMap(h -> h.getChecks().stream())
32+
.filter(c -> Check.CheckStatus.PASSING.equals(c.getStatus()) && c.getCheckId().contains(serviceId))
33+
.count();
34+
assertThat(healthyGrpcServicesChecksCount,Matchers.is(1L));
35+
}
36+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package org.lognet.springboot.grpc.consul;
2+
3+
import com.ecwid.consul.v1.health.model.Check;
4+
import com.ecwid.consul.v1.health.model.HealthService;
5+
import org.hamcrest.Matchers;
6+
import org.junit.runner.RunWith;
7+
import org.lognet.springboot.grpc.demo.DemoApp;
8+
import org.springframework.boot.test.context.SpringBootTest;
9+
import org.springframework.test.context.event.RecordApplicationEvents;
10+
import org.springframework.test.context.junit4.SpringRunner;
11+
12+
import java.util.List;
13+
14+
import static org.hamcrest.MatcherAssert.assertThat;
15+
16+
17+
@SpringBootTest(classes = DemoApp.class,properties = "grpc.consul.registration-mode=SINGLE_SERVER_WITH_CHECK_PER_SERVICE")
18+
@RunWith(SpringRunner.class)
19+
@RecordApplicationEvents
20+
public class ConsulPerServiceHealthCheckTest extends ConsulRegistrationBaseTest{
21+
22+
23+
24+
25+
@Override
26+
void doTest( List<HealthService> healthServices) {
27+
assertThat(healthServices,Matchers.hasSize(1));
28+
final long healthyGrpcServicesChecksCount = healthServices
29+
.stream()
30+
.flatMap(h -> h.getChecks().stream())
31+
.filter(c -> Check.CheckStatus.PASSING.equals(c.getStatus()) && c.getCheckId().contains(serviceId))
32+
.count();
33+
assertThat(healthyGrpcServicesChecksCount,Matchers.is((long)getServicesDefinitions().size()));
34+
}
35+
}
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
package org.lognet.springboot.grpc.consul;
2+
3+
4+
import com.ecwid.consul.v1.ConsulClient;
5+
import com.ecwid.consul.v1.QueryParams;
6+
import com.ecwid.consul.v1.health.HealthServicesRequest;
7+
import com.ecwid.consul.v1.health.model.HealthService;
8+
import com.pszymczyk.consul.ConsulProcess;
9+
import com.pszymczyk.consul.ConsulStarterBuilder;
10+
import io.grpc.BindableService;
11+
import io.grpc.ManagedChannel;
12+
import io.grpc.ManagedChannelBuilder;
13+
import io.grpc.ServerServiceDefinition;
14+
import io.grpc.examples.GreeterGrpc;
15+
import io.grpc.examples.GreeterOuterClass;
16+
import io.grpc.health.v1.HealthGrpc;
17+
import org.awaitility.Awaitility;
18+
import org.hamcrest.Matchers;
19+
import org.junit.After;
20+
import org.junit.AfterClass;
21+
import org.junit.Before;
22+
import org.junit.BeforeClass;
23+
import org.junit.Test;
24+
import org.lognet.springboot.grpc.autoconfigure.GRpcServerProperties;
25+
import org.lognet.springboot.grpc.autoconfigure.consul.ServiceRegistrationMode;
26+
import org.springframework.beans.factory.annotation.Autowired;
27+
import org.springframework.cloud.client.ServiceInstance;
28+
import org.springframework.cloud.client.discovery.DiscoveryClient;
29+
import org.springframework.context.ConfigurableApplicationContext;
30+
import org.springframework.test.context.ActiveProfiles;
31+
import org.springframework.util.SocketUtils;
32+
33+
import java.time.Duration;
34+
import java.util.List;
35+
import java.util.Optional;
36+
import java.util.concurrent.TimeUnit;
37+
import java.util.stream.Collectors;
38+
39+
import static org.hamcrest.MatcherAssert.assertThat;
40+
41+
42+
@ActiveProfiles("consul-test")
43+
public abstract class ConsulRegistrationBaseTest {
44+
private static ConsulProcess consul;
45+
46+
@BeforeClass
47+
public static void startConsul() {
48+
int port = SocketUtils.findAvailableTcpPort();
49+
50+
51+
consul = ConsulStarterBuilder.consulStarter().withHttpPort(port).build().start();
52+
System.setProperty("spring.cloud.consul.port", String.valueOf(port));
53+
54+
}
55+
56+
@AfterClass
57+
public static void clear() {
58+
System.clearProperty("spring.cloud.consul.port");
59+
Optional.ofNullable(consul).ifPresent(ConsulProcess::close);
60+
61+
}
62+
63+
64+
@Autowired
65+
protected DiscoveryClient discoveryClient;
66+
67+
@Autowired
68+
protected ConfigurableApplicationContext applicationContext;
69+
70+
protected final String serviceId = "grpc-grpc-demo";
71+
72+
protected ConsulClient consulClient;
73+
private ManagedChannel channel;
74+
75+
@Before
76+
public void setUp() throws Exception {
77+
78+
79+
consulClient = new ConsulClient("localhost", Integer.parseInt(System.getProperty("spring.cloud.consul.port")));
80+
81+
82+
List<ServiceInstance> instances = discoveryClient.getInstances(serviceId);
83+
assertThat(instances, Matchers.not(Matchers.empty()));
84+
85+
ServiceInstance serviceInstance = instances.get(0);
86+
87+
channel = ManagedChannelBuilder.forAddress(serviceInstance.getHost(), serviceInstance.getPort())
88+
.usePlaintext()
89+
.build();
90+
91+
final GreeterGrpc.GreeterFutureStub greeterFutureStub = GreeterGrpc.newFutureStub(channel);
92+
final GreeterOuterClass.HelloRequest helloRequest = GreeterOuterClass.HelloRequest.newBuilder().setName("Bob").build();
93+
final String reply = greeterFutureStub.sayHello(helloRequest).get().getMessage();
94+
assertThat("Reply should not be null", reply, Matchers.notNullValue(String.class));
95+
}
96+
97+
@After
98+
public void tearDown() throws Exception {
99+
channel.shutdownNow();
100+
channel.awaitTermination(1, TimeUnit.SECONDS);
101+
applicationContext.stop();
102+
}
103+
104+
@Test
105+
public void contextLoads() {
106+
107+
108+
int expectedRegistrations = applicationContext.getBean(GRpcServerProperties.class)
109+
.getConsul()
110+
.getRegistrationMode().equals(ServiceRegistrationMode.STANDALONE_SERVICES) ?
111+
getServicesDefinitions().size() : 1;
112+
113+
final List<HealthService> healthServices = Awaitility.await()
114+
.atMost(Duration.ofSeconds(20))
115+
.pollInterval(Duration.ofSeconds(3))
116+
.until(() -> consulClient.getHealthServices(serviceId, HealthServicesRequest.newBuilder()
117+
.setPassing(true)
118+
.setQueryParams(QueryParams.DEFAULT)
119+
.build())
120+
.getValue()
121+
122+
, Matchers.hasSize(Matchers.greaterThanOrEqualTo(expectedRegistrations)));
123+
124+
doTest(healthServices);
125+
126+
127+
}
128+
129+
abstract void doTest(List<HealthService> healthServices);
130+
131+
protected List<ServerServiceDefinition> getServicesDefinitions() {
132+
return applicationContext.getBeansOfType(BindableService.class)
133+
.values()
134+
.stream()
135+
.map(BindableService::bindService)
136+
.filter(s -> !s.getServiceDescriptor().equals(HealthGrpc.getServiceDescriptor()))
137+
.collect(Collectors.toList());
138+
}
139+
}

0 commit comments

Comments
 (0)