Skip to content

Commit 0bfa4f4

Browse files
committed
Added GRPC test
1 parent a2a78f7 commit 0bfa4f4

File tree

2 files changed

+261
-0
lines changed

2 files changed

+261
-0
lines changed

exporters/common/src/test/java/io/opentelemetry/exporter/internal/grpc/GrpcExporterTest.java

Lines changed: 216 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,27 @@
55

66
package io.opentelemetry.exporter.internal.grpc;
77

8+
import static org.assertj.core.api.Assertions.assertThat;
89
import static org.assertj.core.api.Assertions.assertThatThrownBy;
10+
import static org.mockito.ArgumentMatchers.any;
11+
import static org.mockito.Mockito.doAnswer;
912

13+
import io.opentelemetry.api.common.Attributes;
1014
import io.opentelemetry.exporter.internal.ExporterMetrics;
15+
import java.io.IOException;
1116
import java.net.URI;
17+
import java.util.function.Consumer;
18+
import io.opentelemetry.exporter.internal.marshal.Marshaler;
19+
import io.opentelemetry.sdk.common.HealthMetricLevel;
20+
import io.opentelemetry.sdk.internal.ComponentId;
21+
import io.opentelemetry.sdk.internal.SemConvAttributes;
22+
import io.opentelemetry.sdk.metrics.SdkMeterProvider;
23+
import io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions;
24+
import io.opentelemetry.sdk.testing.exporter.InMemoryMetricReader;
1225
import org.junit.jupiter.api.Test;
26+
import org.junit.jupiter.params.ParameterizedTest;
27+
import org.junit.jupiter.params.provider.EnumSource;
28+
import org.mockito.Mockito;
1329

1430
class GrpcExporterTest {
1531

@@ -31,4 +47,204 @@ void build_NoGrpcSenderProvider() {
3147
"No GrpcSenderProvider found on classpath. Please add dependency on "
3248
+ "opentelemetry-exporter-sender-okhttp or opentelemetry-exporter-sender-grpc-upstream");
3349
}
50+
51+
@ParameterizedTest
52+
@EnumSource
53+
@SuppressWarnings("unchecked")
54+
void testHealthMetrics(ExporterMetrics.Signal signal) {
55+
String signalMetricPrefix;
56+
String expectedUnit;
57+
switch (signal) {
58+
case SPAN:
59+
signalMetricPrefix = "otel.sdk.exporter.span.";
60+
expectedUnit = "{span}";
61+
break;
62+
case LOG:
63+
signalMetricPrefix = "otel.sdk.exporter.log.";
64+
expectedUnit = "{log_record}";
65+
break;
66+
case METRIC:
67+
signalMetricPrefix = "otel.sdk.exporter.metric.";
68+
expectedUnit = "{data_point}";
69+
break;
70+
default:
71+
throw new IllegalStateException();
72+
}
73+
74+
InMemoryMetricReader inMemoryMetrics = InMemoryMetricReader.create();
75+
try (SdkMeterProvider meterProvider =
76+
SdkMeterProvider.builder().registerMetricReader(inMemoryMetrics).build()) {
77+
78+
ComponentId id = ComponentId.generateLazy("test_exporter");
79+
80+
Attributes expectedAttributes =
81+
Attributes.builder()
82+
.put(SemConvAttributes.OTEL_COMPONENT_TYPE, "test_exporter")
83+
.put(SemConvAttributes.OTEL_COMPONENT_NAME, id.getComponentName())
84+
.build();
85+
86+
GrpcSender<Marshaler> mockSender = Mockito.mock(GrpcSender.class);
87+
Marshaler mockMarshaller = Mockito.mock(Marshaler.class);
88+
89+
GrpcExporter<Marshaler> exporter =
90+
new GrpcExporter<Marshaler>(
91+
"legacy_exporter",
92+
signal,
93+
mockSender,
94+
HealthMetricLevel.ON,
95+
id,
96+
() -> meterProvider
97+
);
98+
99+
doAnswer(
100+
invoc -> {
101+
Consumer<GrpcResponse> onResponse = invoc.getArgument(1);
102+
103+
assertThat(inMemoryMetrics.collectAllMetrics())
104+
.hasSize(1)
105+
.anySatisfy(
106+
metric ->
107+
OpenTelemetryAssertions.assertThat(metric)
108+
.hasName(signalMetricPrefix + "inflight")
109+
.hasUnit(expectedUnit)
110+
.hasLongSumSatisfying(
111+
ma ->
112+
ma.isNotMonotonic()
113+
.hasPointsSatisfying(
114+
pa ->
115+
pa.hasAttributes(expectedAttributes)
116+
.hasValue(42))));
117+
118+
onResponse.accept(GrpcResponse.create(0, null));
119+
return null;
120+
})
121+
.when(mockSender)
122+
.send(any(), any(), any());
123+
124+
exporter.export(mockMarshaller, 42);
125+
126+
doAnswer(
127+
invoc -> {
128+
Consumer<GrpcResponse> onResponse = invoc.getArgument(1);
129+
onResponse.accept(GrpcResponse.create(GrpcExporterUtil.GRPC_STATUS_UNAVAILABLE, null));
130+
return null;
131+
})
132+
.when(mockSender)
133+
.send(any(),any(), any());
134+
exporter.export(mockMarshaller, 15);
135+
136+
doAnswer(
137+
invoc -> {
138+
Consumer<Throwable> onError = invoc.getArgument(2);
139+
onError.accept(new IOException("Computer says no"));
140+
return null;
141+
})
142+
.when(mockSender)
143+
.send(any(), any(), any());
144+
exporter.export(mockMarshaller, 7);
145+
146+
assertThat(inMemoryMetrics.collectAllMetrics())
147+
.hasSize(3)
148+
.anySatisfy(
149+
metric ->
150+
OpenTelemetryAssertions.assertThat(metric)
151+
.hasName(signalMetricPrefix + "inflight")
152+
.hasUnit(expectedUnit)
153+
.hasLongSumSatisfying(
154+
ma ->
155+
ma.hasPointsSatisfying(
156+
pa -> pa.hasAttributes(expectedAttributes).hasValue(0))))
157+
.anySatisfy(
158+
metric ->
159+
OpenTelemetryAssertions.assertThat(metric)
160+
.hasName(signalMetricPrefix + "exported")
161+
.hasUnit(expectedUnit)
162+
.hasLongSumSatisfying(
163+
ma ->
164+
ma.hasPointsSatisfying(
165+
pa -> pa.hasAttributes(expectedAttributes).hasValue(42),
166+
pa ->
167+
pa.hasAttributes(
168+
expectedAttributes.toBuilder()
169+
.put(SemConvAttributes.ERROR_TYPE, ""+GrpcExporterUtil.GRPC_STATUS_UNAVAILABLE)
170+
.build())
171+
.hasValue(15),
172+
pa ->
173+
pa.hasAttributes(
174+
expectedAttributes.toBuilder()
175+
.put(
176+
SemConvAttributes.ERROR_TYPE,
177+
"java.io.IOException")
178+
.build())
179+
.hasValue(7))))
180+
.anySatisfy(
181+
metric ->
182+
OpenTelemetryAssertions.assertThat(metric)
183+
.hasName("otel.sdk.exporter.operation.duration")
184+
.hasUnit("s")
185+
.hasHistogramSatisfying(
186+
ma ->
187+
ma.hasPointsSatisfying(
188+
pa -> pa.hasAttributes(expectedAttributes).hasBucketCounts(1),
189+
pa ->
190+
pa.hasAttributes(
191+
expectedAttributes.toBuilder()
192+
.put(SemConvAttributes.ERROR_TYPE, ""+GrpcExporterUtil.GRPC_STATUS_UNAVAILABLE)
193+
.build())
194+
.hasBucketCounts(1),
195+
pa ->
196+
pa.hasAttributes(
197+
expectedAttributes.toBuilder()
198+
.put(
199+
SemConvAttributes.ERROR_TYPE,
200+
"java.io.IOException")
201+
.build())
202+
.hasBucketCounts(1))));
203+
}
204+
}
205+
206+
@Test
207+
@SuppressWarnings("unchecked")
208+
void testHealthMetricsDisabled() {
209+
InMemoryMetricReader inMemoryMetrics = InMemoryMetricReader.create();
210+
try (SdkMeterProvider meterProvider =
211+
SdkMeterProvider.builder().registerMetricReader(inMemoryMetrics).build()) {
212+
213+
ComponentId id = ComponentId.generateLazy("test_exporter");
214+
GrpcSender<Marshaler> mockSender = Mockito.mock(GrpcSender.class);
215+
Marshaler mockMarshaller = Mockito.mock(Marshaler.class);
216+
217+
GrpcExporter<Marshaler> exporter =
218+
new GrpcExporter<Marshaler>(
219+
"legacy_exporter",
220+
ExporterMetrics.Signal.SPAN,
221+
mockSender,
222+
HealthMetricLevel.OFF,
223+
id,
224+
() -> meterProvider
225+
);
226+
227+
doAnswer(
228+
invoc -> {
229+
Consumer<GrpcResponse> onResponse = invoc.getArgument(1);
230+
onResponse.accept(GrpcResponse.create(0, null));
231+
return null;
232+
})
233+
.when(mockSender)
234+
.send(any(), any(), any());
235+
exporter.export(mockMarshaller, 42);
236+
237+
doAnswer(
238+
invoc -> {
239+
Consumer<GrpcResponse> onResponse = invoc.getArgument(1);
240+
onResponse.accept(GrpcResponse.create(GrpcExporterUtil.GRPC_STATUS_UNAVAILABLE, null));
241+
return null;
242+
})
243+
.when(mockSender)
244+
.send(any(), any(), any());
245+
exporter.export(mockMarshaller, 42);
246+
247+
assertThat(inMemoryMetrics.collectAllMetrics()).isEmpty();
248+
}
249+
}
34250
}

exporters/common/src/test/java/io/opentelemetry/exporter/internal/http/HttpExporterTest.java

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,4 +194,49 @@ void testHealthMetrics(ExporterMetrics.Signal signal) {
194194
.hasBucketCounts(1))));
195195
}
196196
}
197+
198+
@Test
199+
void testHealthMetricsDisabled() {
200+
InMemoryMetricReader inMemoryMetrics = InMemoryMetricReader.create();
201+
try (SdkMeterProvider meterProvider =
202+
SdkMeterProvider.builder().registerMetricReader(inMemoryMetrics).build()) {
203+
204+
ComponentId id = ComponentId.generateLazy("test_exporter");
205+
HttpSender mockSender = Mockito.mock(HttpSender.class);
206+
Marshaler mockMarshaller = Mockito.mock(Marshaler.class);
207+
208+
HttpExporter<Marshaler> exporter =
209+
new HttpExporter<Marshaler>(
210+
"legacy_exporter",
211+
ExporterMetrics.Signal.METRIC,
212+
id,
213+
mockSender,
214+
() -> meterProvider,
215+
HealthMetricLevel.OFF,
216+
false);
217+
218+
doAnswer(
219+
invoc -> {
220+
Consumer<HttpSender.Response> onResponse = invoc.getArgument(2);
221+
onResponse.accept(new FakeHttpResponse(200, "Ok"));
222+
return null;
223+
})
224+
.when(mockSender)
225+
.send(any(), anyInt(), any(), any());
226+
exporter.export(mockMarshaller, 42);
227+
228+
doAnswer(
229+
invoc -> {
230+
Consumer<HttpSender.Response> onResponse = invoc.getArgument(2);
231+
onResponse.accept(new FakeHttpResponse(404, "not Found"));
232+
return null;
233+
})
234+
.when(mockSender)
235+
.send(any(), anyInt(), any(), any());
236+
exporter.export(mockMarshaller, 42);
237+
238+
239+
assertThat(inMemoryMetrics.collectAllMetrics()).isEmpty();
240+
}
241+
}
197242
}

0 commit comments

Comments
 (0)