Skip to content

Commit

Permalink
Extract gRPC exporter test into shared base class. (#3903)
Browse files Browse the repository at this point in the history
* Extract gRPC exporter test into shared base class.

* Split out config test
  • Loading branch information
anuraaga authored Nov 19, 2021
1 parent 1c1d264 commit b9b8105
Show file tree
Hide file tree
Showing 17 changed files with 803 additions and 1,170 deletions.
2 changes: 1 addition & 1 deletion dependencyManagement/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ val DEPENDENCY_BOMS = listOf(
"com.fasterxml.jackson:jackson-bom:2.13.0",
"com.google.guava:guava-bom:31.0.1-jre",
"com.google.protobuf:protobuf-bom:3.18.1",
"com.linecorp.armeria:armeria-bom:1.11.0",
"com.linecorp.armeria:armeria-bom:1.13.2",
"io.grpc:grpc-bom:1.41.0",
"io.zipkin.brave:brave-bom:5.13.3",
"io.zipkin.reporter2:zipkin-reporter-bom:2.16.3",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ public final class OkHttpGrpcExporter<T extends Marshaler> implements GrpcExport
private static final String GRPC_STATUS = "grpc-status";
private static final String GRPC_MESSAGE = "grpc-message";

private static final String GRPC_STATUS_UNIMPLEMENTED = "12";
private static final String GRPC_STATUS_UNAVAILABLE = "14";

private final ThrottlingLogger logger =
new ThrottlingLogger(Logger.getLogger(OkHttpGrpcExporter.class.getName()));

Expand Down Expand Up @@ -146,14 +149,36 @@ public void onResponse(Call call, Response response) {
? "gRPC status code " + status
: "HTTP status code " + response.code();
String errorMessage = grpcMessage(response);
logger.log(
Level.WARNING,
"Failed to export "
+ type
+ "s. Server responded with "
+ codeMessage
+ ". Error message: "
+ errorMessage);

if (GRPC_STATUS_UNIMPLEMENTED.equals(status)) {
logger.log(
Level.SEVERE,
"Failed to export "
+ type
+ "s. Server responded with UNIMPLEMENTED. "
+ "This usually means that your collector is not configured with an otlp "
+ "receiver in the \"pipelines\" section of the configuration. "
+ "Full error message: "
+ errorMessage);
} else if (GRPC_STATUS_UNAVAILABLE.equals(status)) {
logger.log(
Level.SEVERE,
"Failed to export "
+ type
+ "s. Server is UNAVAILABLE. "
+ "Make sure your collector is running and reachable from this network. "
+ "Full error message:"
+ errorMessage);
} else {
logger.log(
Level.WARNING,
"Failed to export "
+ type
+ "s. Server responded with "
+ codeMessage
+ ". Error message: "
+ errorMessage);
}
result.fail();
}
});
Expand Down
15 changes: 1 addition & 14 deletions exporters/otlp/logs/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,9 @@ dependencies {

compileOnly("io.grpc:grpc-stub")

testImplementation(project(":exporters:otlp:testing-internal"))
testImplementation(project(":sdk:testing"))

testImplementation("com.google.protobuf:protobuf-java")
testImplementation("io.grpc:grpc-protobuf")
testImplementation("io.grpc:grpc-testing")
testImplementation("io.opentelemetry.proto:opentelemetry-proto")
testImplementation("org.slf4j:slf4j-simple")

add("testGrpcNettyImplementation", "com.linecorp.armeria:armeria-grpc")
add("testGrpcNettyImplementation", "com.linecorp.armeria:armeria-junit5")
add("testGrpcNettyRuntimeOnly", "io.grpc:grpc-netty")
Expand All @@ -57,11 +52,3 @@ tasks {
dependsOn("testGrpcNetty", "testGrpcNettyShaded", "testGrpcOkhttp", "testOkHttpOnly")
}
}

configurations {
named("testOkHttpOnlyRuntimeClasspath") {
dependencies {
exclude("io.grpc")
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.exporter.otlp.logs;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatCode;
import static org.assertj.core.api.Assertions.assertThatThrownBy;

import io.opentelemetry.exporter.otlp.internal.grpc.OkHttpGrpcExporterBuilder;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.concurrent.TimeUnit;
import org.junit.jupiter.api.Test;

class ConfigTest {

@Test
@SuppressWarnings("PreferJavaTimeOverload")
void validConfig() {
assertThatCode(() -> OtlpGrpcLogExporter.builder().setTimeout(0, TimeUnit.MILLISECONDS))
.doesNotThrowAnyException();
assertThatCode(() -> OtlpGrpcLogExporter.builder().setTimeout(Duration.ofMillis(0)))
.doesNotThrowAnyException();
assertThatCode(() -> OtlpGrpcLogExporter.builder().setTimeout(10, TimeUnit.MILLISECONDS))
.doesNotThrowAnyException();
assertThatCode(() -> OtlpGrpcLogExporter.builder().setTimeout(Duration.ofMillis(10)))
.doesNotThrowAnyException();

assertThatCode(() -> OtlpGrpcLogExporter.builder().setEndpoint("http://localhost:4317"))
.doesNotThrowAnyException();
assertThatCode(() -> OtlpGrpcLogExporter.builder().setEndpoint("http://localhost"))
.doesNotThrowAnyException();
assertThatCode(() -> OtlpGrpcLogExporter.builder().setEndpoint("https://localhost"))
.doesNotThrowAnyException();
assertThatCode(() -> OtlpGrpcLogExporter.builder().setEndpoint("http://foo:bar@localhost"))
.doesNotThrowAnyException();

assertThatCode(() -> OtlpGrpcLogExporter.builder().setCompression("gzip"))
.doesNotThrowAnyException();
assertThatCode(() -> OtlpGrpcLogExporter.builder().setCompression("none"))
.doesNotThrowAnyException();

assertThatCode(
() -> OtlpGrpcLogExporter.builder().addHeader("foo", "bar").addHeader("baz", "qux"))
.doesNotThrowAnyException();

assertThatCode(
() ->
OtlpGrpcLogExporter.builder()
.setTrustedCertificates("foobar".getBytes(StandardCharsets.UTF_8)))
.doesNotThrowAnyException();
}

@Test
@SuppressWarnings("PreferJavaTimeOverload")
void invalidConfig() {
assertThatThrownBy(() -> OtlpGrpcLogExporter.builder().setTimeout(-1, TimeUnit.MILLISECONDS))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("timeout must be non-negative");
assertThatThrownBy(() -> OtlpGrpcLogExporter.builder().setTimeout(1, null))
.isInstanceOf(NullPointerException.class)
.hasMessage("unit");
assertThatThrownBy(() -> OtlpGrpcLogExporter.builder().setTimeout(null))
.isInstanceOf(NullPointerException.class)
.hasMessage("timeout");

assertThatThrownBy(() -> OtlpGrpcLogExporter.builder().setEndpoint(null))
.isInstanceOf(NullPointerException.class)
.hasMessage("endpoint");
assertThatThrownBy(() -> OtlpGrpcLogExporter.builder().setEndpoint("😺://localhost"))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("Invalid endpoint, must be a URL: 😺://localhost");
assertThatThrownBy(() -> OtlpGrpcLogExporter.builder().setEndpoint("localhost"))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("Invalid endpoint, must start with http:// or https://: localhost");
assertThatThrownBy(() -> OtlpGrpcLogExporter.builder().setEndpoint("gopher://localhost"))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("Invalid endpoint, must start with http:// or https://: gopher://localhost");

assertThatThrownBy(() -> OtlpGrpcLogExporter.builder().setCompression(null))
.isInstanceOf(NullPointerException.class)
.hasMessage("compressionMethod");
assertThatThrownBy(() -> OtlpGrpcLogExporter.builder().setCompression("foo"))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage(
"Unsupported compression method. Supported compression methods include: gzip, none.");
}

@Test
void usingOkHttp() {
assertThat(OtlpGrpcLogExporter.builder().delegate)
.isInstanceOf(OkHttpGrpcExporterBuilder.class);
}
}
Loading

0 comments on commit b9b8105

Please sign in to comment.