diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index 3c001cc5c0a..3da3a26d2d7 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -43,3 +43,14 @@ jobs: - uses: actions/checkout@v2 - name: Run W3C Trace Context docker-compose.integration run: docker-compose --file=test/OpenTelemetry.Instrumentation.W3cTraceContext.Tests/docker-compose.yml --file=build/docker-compose.${{ matrix.version }}.yml --project-directory=. up --exit-code-from=tests --build + + otlp-exporter-test: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + version: [netcoreapp2.1,netcoreapp3.1] + steps: + - uses: actions/checkout@v2 + - name: Run OTLP Exporter docker-compose.integration + run: docker-compose --file=test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/docker-compose.yml --file=build/docker-compose.${{ matrix.version }}.yml --project-directory=. up --exit-code-from=tests --build diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OpenTelemetry.Exporter.OpenTelemetryProtocol.csproj b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OpenTelemetry.Exporter.OpenTelemetryProtocol.csproj index 34067c518fa..e29b6855e7a 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OpenTelemetry.Exporter.OpenTelemetryProtocol.csproj +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OpenTelemetry.Exporter.OpenTelemetryProtocol.csproj @@ -1,6 +1,26 @@  - net452;net46;netstandard2.0;netstandard2.1 + net452;net46;netstandard2.0 + + + $(TargetFrameworks);netstandard2.1 + netstandard2.1 + OpenTelemetry protocol exporter for OpenTelemetry .NET $(PackageTags);OTLP diff --git a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/Dockerfile b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/Dockerfile new file mode 100644 index 00000000000..154130b97c1 --- /dev/null +++ b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/Dockerfile @@ -0,0 +1,17 @@ +# Create a container for running the OpenTelemetry Collector integration tests. +# This should be run from the root of the repo: +# docker build --file test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/Dockerfile + +ARG SDK_VERSION=3.1 +FROM mcr.microsoft.com/dotnet/core/sdk:${SDK_VERSION} AS build +ARG PUBLISH_CONFIGURATION=Release +ARG PUBLISH_FRAMEWORK=netcoreapp3.1 +WORKDIR /repo +COPY . ./ +WORKDIR "/repo/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests" +RUN dotnet publish "OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests.csproj" -c "${PUBLISH_CONFIGURATION}" -f "${PUBLISH_FRAMEWORK}" -o /drop -p:IntegrationBuild=true -p:TARGET_FRAMEWORK=${PUBLISH_FRAMEWORK} + +FROM mcr.microsoft.com/dotnet/core/sdk:${SDK_VERSION} AS final +WORKDIR /test +COPY --from=build /drop . +ENTRYPOINT ["dotnet", "vstest", "OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests.dll"] diff --git a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/IntegrationTests.cs b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/IntegrationTests.cs new file mode 100644 index 00000000000..1d001eeefe7 --- /dev/null +++ b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/IntegrationTests.cs @@ -0,0 +1,70 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Diagnostics; +using OpenTelemetry.Tests; +using OpenTelemetry.Trace; +using Xunit; + +namespace OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests +{ + public class IntegrationTests + { + private const string CollectorEndpointEnvVarName = "OTEL_EXPORTER_OTLP_ENDPOINT"; + private static readonly string CollectorEndpoint = SkipUnlessEnvVarFoundFactAttribute.GetEnvironmentVariable(CollectorEndpointEnvVarName); + + [Trait("CategoryName", "CollectorIntegrationTests")] + [SkipUnlessEnvVarFoundFact(CollectorEndpointEnvVarName)] + public void ExportResultIsSuccess() + { +#if NETCOREAPP3_1 + // Adding the OtlpExporter creates a GrpcChannel. + // This switch must be set before creating a GrpcChannel/HttpClient when calling an insecure gRPC service. + // See: https://docs.microsoft.com/aspnet/core/grpc/troubleshoot#call-insecure-grpc-services-with-net-core-client + AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true); +#endif + + var exporterOptions = new OtlpExporterOptions + { +#if NETCOREAPP3_1 || NET5_0 + Endpoint = new System.Uri($"http://{CollectorEndpoint}"), +#else + Endpoint = CollectorEndpoint, +#endif + }; + + var otlpExporter = new OtlpExporter(exporterOptions); + var delegatingExporter = new DelegatingTestExporter(otlpExporter); + var exportActivityProcessor = new SimpleActivityExportProcessor(delegatingExporter); + + var activitySourceName = "otlp.collector.test"; + + var builder = Sdk.CreateTracerProviderBuilder() + .AddSource(activitySourceName) + .AddProcessor(exportActivityProcessor); + + using var tracerProvider = builder.Build(); + + var source = new ActivitySource(activitySourceName); + var activity = source.StartActivity("Test Activity"); + activity?.Stop(); + + Assert.Single(delegatingExporter.ExportResults); + Assert.Equal(ExportResult.Success, delegatingExporter.ExportResults[0]); + } + } +} diff --git a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests.csproj b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests.csproj index b8219cfd7a5..699181ad13a 100644 --- a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests.csproj +++ b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests.csproj @@ -1,8 +1,9 @@  - netcoreapp2.1;netcoreapp3.1;net5.0 - $(TargetFrameworks);net452;net46 + netcoreapp2.1;netcoreapp3.1;net5.0 + $(TargetFrameworks);net452;net46 + $(TARGET_FRAMEWORK) false @@ -22,7 +23,9 @@ + + diff --git a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/config.yaml b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/config.yaml new file mode 100644 index 00000000000..544292318ff --- /dev/null +++ b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/config.yaml @@ -0,0 +1,20 @@ +# This is a configuration file for the OpenTelemetry Collector intended to be +# used in conjunction with the OTLP Exporter integration tests. +# +# For more information about the OpenTelemetry Collector see: +# https://github.com/open-telemetry/opentelemetry-collector +# +receivers: + otlp: + protocols: + grpc: + +exporters: + logging: + loglevel: debug + +service: + pipelines: + traces: + receivers: [otlp] + exporters: [logging] diff --git a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/docker-compose.yml b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/docker-compose.yml new file mode 100644 index 00000000000..5e7aee9b690 --- /dev/null +++ b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/docker-compose.yml @@ -0,0 +1,24 @@ +# Starts an OpenTelemetry Collector and then runs the OTLP exporter integration tests. +# This should be run from the root of the repo: +# docker-compose --file=test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/docker-compose.yml --project-directory=. up --exit-code-from=tests --build + +version: '3.7' + +services: + otel-collector: + image: otel/opentelemetry-collector + volumes: + - ./test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests:/cfg + command: --config=/cfg/config.yaml + ports: + - "55680:55680" + + tests: + build: + context: . + dockerfile: ./test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/Dockerfile + command: --TestCaseFilter:CategoryName=CollectorIntegrationTests + environment: + - OTEL_EXPORTER_OTLP_ENDPOINT=otel-collector:55680 + depends_on: + - otel-collector diff --git a/test/OpenTelemetry.Tests/Shared/DelegatingTestExporter.cs b/test/OpenTelemetry.Tests/Shared/DelegatingTestExporter.cs new file mode 100644 index 00000000000..a589668369a --- /dev/null +++ b/test/OpenTelemetry.Tests/Shared/DelegatingTestExporter.cs @@ -0,0 +1,40 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Collections.Generic; + +namespace OpenTelemetry.Tests +{ + public class DelegatingTestExporter : BaseExporter + where T : class + { + public List ExportResults = new List(); + + private readonly BaseExporter exporter; + + public DelegatingTestExporter(BaseExporter exporter) + { + this.exporter = exporter; + } + + public override ExportResult Export(in Batch batch) + { + var result = this.exporter.Export(batch); + this.ExportResults.Add(result); + return result; + } + } +} diff --git a/test/OpenTelemetry.Tests/Shared/SkipUnlessEnvVarFoundFactAttribute.cs b/test/OpenTelemetry.Tests/Shared/SkipUnlessEnvVarFoundFactAttribute.cs new file mode 100644 index 00000000000..512bd6188c3 --- /dev/null +++ b/test/OpenTelemetry.Tests/Shared/SkipUnlessEnvVarFoundFactAttribute.cs @@ -0,0 +1,44 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using Xunit; + +namespace OpenTelemetry.Tests +{ + internal class SkipUnlessEnvVarFoundFactAttribute : FactAttribute + { + public SkipUnlessEnvVarFoundFactAttribute(string environmentVariable) + { + if (string.IsNullOrEmpty(GetEnvironmentVariable(environmentVariable))) + { + this.Skip = $"Skipped because {environmentVariable} environment variable was not configured."; + } + } + + public static string GetEnvironmentVariable(string environmentVariableName) + { + string environmentVariableValue = Environment.GetEnvironmentVariable(environmentVariableName, EnvironmentVariableTarget.Process); + + if (string.IsNullOrEmpty(environmentVariableValue)) + { + environmentVariableValue = Environment.GetEnvironmentVariable(environmentVariableName, EnvironmentVariableTarget.Machine); + } + + return environmentVariableValue; + } + } +}