Skip to content

Commit

Permalink
Merge branch 'main' into remove-moq-instrumentation-aspnetcore-tests
Browse files Browse the repository at this point in the history
  • Loading branch information
ngruson committed Dec 5, 2023
2 parents f202cbf + f11801d commit d1e8510
Show file tree
Hide file tree
Showing 17 changed files with 382 additions and 176 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,8 @@
[assembly: InternalsVisibleTo("OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010051c1562a090fb0c9f391012a32198b5e5d9a60e9b80fa2d7b434c9e5ccb7259bd606e66f9660676afc6692b8cdc6793d190904551d2103b7b22fa636dcbb8208839785ba402ea08fc00c8f1500ccef28bbf599aa64ffb1e1d5dc1bf3420a3777badfe697856e9d52070a50c3ea5821c80bef17ca3acffa28f89dd413f096f898")]
[assembly: InternalsVisibleTo("Benchmarks, PublicKey=002400000480000094000000060200000024000052534131000400000100010051c1562a090fb0c9f391012a32198b5e5d9a60e9b80fa2d7b434c9e5ccb7259bd606e66f9660676afc6692b8cdc6793d190904551d2103b7b22fa636dcbb8208839785ba402ea08fc00c8f1500ccef28bbf599aa64ffb1e1d5dc1bf3420a3777badfe697856e9d52070a50c3ea5821c80bef17ca3acffa28f89dd413f096f898")]
[assembly: InternalsVisibleTo("MockOpenTelemetryCollector, PublicKey=002400000480000094000000060200000024000052534131000400000100010051c1562a090fb0c9f391012a32198b5e5d9a60e9b80fa2d7b434c9e5ccb7259bd606e66f9660676afc6692b8cdc6793d190904551d2103b7b22fa636dcbb8208839785ba402ea08fc00c8f1500ccef28bbf599aa64ffb1e1d5dc1bf3420a3777badfe697856e9d52070a50c3ea5821c80bef17ca3acffa28f89dd413f096f898")]

// Used by Moq.
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")]
#else
[assembly: InternalsVisibleTo("OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests")]
[assembly: InternalsVisibleTo("Benchmarks")]
[assembly: InternalsVisibleTo("MockOpenTelemetryCollector")]

// Used by Moq.
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]
#endif
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@
#if !NET6_0_OR_GREATER
using System.Net.Http;
#endif
using Moq;
using Moq.Protected;
using OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation;
using OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation.ExportClient;
using OpenTelemetry.Resources;
Expand Down Expand Up @@ -94,51 +92,20 @@ public void SendExportRequest_ExportTraceServiceRequest_SendsCorrectHttpRequest(
Headers = $"{header1.Name}={header1.Value}, {header2.Name} = {header2.Value}",
};

var httpHandlerMock = new Mock<HttpMessageHandler>();
var testHttpHandler = new TestHttpMessageHandler();

HttpRequestMessage httpRequest = null;
var httpRequestContent = Array.Empty<byte>();

httpHandlerMock.Protected()
#if NET6_0_OR_GREATER
.Setup<HttpResponseMessage>("Send", ItExpr.IsAny<HttpRequestMessage>(), ItExpr.IsAny<CancellationToken>())
.Returns((HttpRequestMessage request, CancellationToken token) =>
{
return new HttpResponseMessage();
})
.Callback<HttpRequestMessage, CancellationToken>(async (r, ct) =>
{
httpRequest = r;

// We have to capture content as it can't be accessed after request is disposed inside of SendExportRequest method
httpRequestContent = await r.Content.ReadAsByteArrayAsync(ct);
})
#else
.Setup<Task<HttpResponseMessage>>("SendAsync", ItExpr.IsAny<HttpRequestMessage>(), ItExpr.IsAny<CancellationToken>())
.ReturnsAsync((HttpRequestMessage request, CancellationToken token) =>
{
return new HttpResponseMessage();
})
.Callback<HttpRequestMessage, CancellationToken>(async (r, ct) =>
{
httpRequest = r;

// We have to capture content as it can't be accessed after request is disposed inside of SendExportRequest method
httpRequestContent = await r.Content.ReadAsByteArrayAsync();
})
#endif
.Verifiable();

var exportClient = new OtlpHttpTraceExportClient(options, new HttpClient(httpHandlerMock.Object));
var exportClient = new OtlpHttpTraceExportClient(options, new HttpClient(testHttpHandler));

var resourceBuilder = ResourceBuilder.CreateEmpty();
if (includeServiceNameInResource)
{
resourceBuilder.AddAttributes(
new List<KeyValuePair<string, object>>
{
new KeyValuePair<string, object>(ResourceSemanticConventions.AttributeServiceName, "service_name"),
new KeyValuePair<string, object>(ResourceSemanticConventions.AttributeServiceNamespace, "ns_1"),
new(ResourceSemanticConventions.AttributeServiceName, "service_name"),
new(ResourceSemanticConventions.AttributeServiceNamespace, "ns_1"),
});
}

Expand Down Expand Up @@ -166,7 +133,7 @@ public void SendExportRequest_ExportTraceServiceRequest_SendsCorrectHttpRequest(

processor.Shutdown();

var batch = new Batch<Activity>(exportedItems.ToArray(), exportedItems.Count);
var batch = new Batch<Activity>([.. exportedItems], exportedItems.Count);
RunTest(batch);

void RunTest(Batch<Activity> batch)
Expand All @@ -178,6 +145,8 @@ void RunTest(Batch<Activity> batch)
// Act
var result = exportClient.SendExportRequest(request);

var httpRequest = testHttpHandler.HttpRequestMessage;

// Assert
Assert.True(result);
Assert.NotNull(httpRequest);
Expand All @@ -192,11 +161,11 @@ void RunTest(Batch<Activity> batch)
Assert.Contains(httpRequest.Headers, entry => entry.Key == OtlpExporterOptions.StandardHeaders[i].Key && entry.Value.First() == OtlpExporterOptions.StandardHeaders[i].Value);
}

Assert.NotNull(httpRequest.Content);
Assert.NotNull(testHttpHandler.HttpRequestContent);
Assert.IsType<OtlpHttpTraceExportClient.ExportRequestContent>(httpRequest.Content);
Assert.Contains(httpRequest.Content.Headers, h => h.Key == "Content-Type" && h.Value.First() == OtlpHttpTraceExportClient.MediaContentType);

var exportTraceRequest = OtlpCollector.ExportTraceServiceRequest.Parser.ParseFrom(httpRequestContent);
var exportTraceRequest = OtlpCollector.ExportTraceServiceRequest.Parser.ParseFrom(testHttpHandler.HttpRequestContent);
Assert.NotNull(exportTraceRequest);
Assert.Single(exportTraceRequest.ResourceSpans);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
<PackageReference Include="Microsoft.Extensions.Hosting" />
<PackageReference Include="Microsoft.Extensions.Http" />
<PackageReference Include="Microsoft.NET.Test.Sdk" />
<PackageReference Include="Moq" />
<PackageReference Include="xunit" />
<PackageReference Include="xunit.runner.visualstudio" PrivateAssets="All">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,7 @@
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Moq;
using OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation;
using OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation.ExportClient;
using OpenTelemetry.Internal;
using OpenTelemetry.Logs;
using OpenTelemetry.Resources;
Expand Down Expand Up @@ -589,37 +587,34 @@ public void CheckToOtlpLogRecordRespectsAttributeLimits()
public void Export_WhenExportClientIsProvidedInCtor_UsesProvidedExportClient()
{
// Arrange.
var fakeExportClient = new Mock<IExportClient<OtlpCollector.ExportLogsServiceRequest>>();
var testExportClient = new TestExportClient<OtlpCollector.ExportLogsServiceRequest>();
var emptyLogRecords = Array.Empty<LogRecord>();
var emptyBatch = new Batch<LogRecord>(emptyLogRecords, emptyLogRecords.Length);
var sut = new OtlpLogExporter(
new OtlpExporterOptions(),
new SdkLimitOptions(),
new ExperimentalOptions(),
fakeExportClient.Object);
testExportClient);

// Act.
var result = sut.Export(emptyBatch);
sut.Export(emptyBatch);

// Assert.
fakeExportClient.Verify(x => x.SendExportRequest(It.IsAny<OtlpCollector.ExportLogsServiceRequest>(), default), Times.Once());
Assert.True(testExportClient.SendExportRequestCalled);
}

[Fact]
public void Export_WhenExportClientThrowsException_ReturnsExportResultFailure()
{
// Arrange.
var fakeExportClient = new Mock<IExportClient<OtlpCollector.ExportLogsServiceRequest>>();
var testExportClient = new TestExportClient<OtlpCollector.ExportLogsServiceRequest>(throwException: true);
var emptyLogRecords = Array.Empty<LogRecord>();
var emptyBatch = new Batch<LogRecord>(emptyLogRecords, emptyLogRecords.Length);
fakeExportClient
.Setup(_ => _.SendExportRequest(It.IsAny<OtlpCollector.ExportLogsServiceRequest>(), default))
.Throws(new Exception("Test Exception"));
var sut = new OtlpLogExporter(
new OtlpExporterOptions(),
new SdkLimitOptions(),
new ExperimentalOptions(),
fakeExportClient.Object);
testExportClient);

// Act.
var result = sut.Export(emptyBatch);
Expand All @@ -632,17 +627,14 @@ public void Export_WhenExportClientThrowsException_ReturnsExportResultFailure()
public void Export_WhenExportIsSuccessful_ReturnsExportResultSuccess()
{
// Arrange.
var fakeExportClient = new Mock<IExportClient<OtlpCollector.ExportLogsServiceRequest>>();
var testExportClient = new TestExportClient<OtlpCollector.ExportLogsServiceRequest>();
var emptyLogRecords = Array.Empty<LogRecord>();
var emptyBatch = new Batch<LogRecord>(emptyLogRecords, emptyLogRecords.Length);
fakeExportClient
.Setup(_ => _.SendExportRequest(It.IsAny<OtlpCollector.ExportLogsServiceRequest>(), default))
.Returns(true);
var sut = new OtlpLogExporter(
new OtlpExporterOptions(),
new SdkLimitOptions(),
new ExperimentalOptions(),
fakeExportClient.Object);
testExportClient);

// Act.
var result = sut.Export(emptyBatch);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,7 @@
using System.Diagnostics;
using Google.Protobuf.Collections;
using Microsoft.Extensions.DependencyInjection;
using Moq;
using OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation;
using OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation.ExportClient;
using OpenTelemetry.Metrics;
using OpenTelemetry.Resources;
using OpenTelemetry.Tests;
Expand Down Expand Up @@ -642,13 +640,13 @@ public void UseOpenTelemetryProtocolActivityExporterWithCustomActivityProcessor(
[Fact]
public void Shutdown_ClientShutdownIsCalled()
{
var exportClientMock = new Mock<IExportClient<OtlpCollector.ExportTraceServiceRequest>>();
var exportClientMock = new TestExportClient<OtlpCollector.ExportTraceServiceRequest>();

var exporter = new OtlpTraceExporter(new OtlpExporterOptions(), DefaultSdkLimitOptions, exportClientMock.Object);
var exporter = new OtlpTraceExporter(new OtlpExporterOptions(), DefaultSdkLimitOptions, exportClientMock);

var result = exporter.Shutdown();
exporter.Shutdown();

exportClientMock.Verify(m => m.Shutdown(It.IsAny<int>()), Times.Once());
Assert.True(exportClientMock.ShutdownCalled);
}

[Fact]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// <copyright file="TestExportClient.cs" company="OpenTelemetry Authors">
// 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.
// </copyright>

using OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation.ExportClient;

namespace OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests;

internal class TestExportClient<T>(bool throwException = false) : IExportClient<T>
{
public bool SendExportRequestCalled { get; private set; }

public bool ShutdownCalled { get; private set; }

public bool ThrowException { get; set; } = throwException;

public bool SendExportRequest(T request, CancellationToken cancellationToken = default)
{
if (this.ThrowException)
{
throw new Exception("Exception thrown from SendExportRequest");
}

this.SendExportRequestCalled = true;
return true;
}

public bool Shutdown(int timeoutMilliseconds)
{
this.ShutdownCalled = true;
return true;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// <copyright file="TestHttpMessageHandler.cs" company="OpenTelemetry Authors">
// 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.
// </copyright>

#if !NET6_0_OR_GREATER
using System.Net.Http;
#endif

namespace OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests;

internal class TestHttpMessageHandler : HttpMessageHandler
{
public HttpRequestMessage HttpRequestMessage { get; private set; }

public byte[] HttpRequestContent { get; private set; }

public virtual HttpResponseMessage InternalSend(HttpRequestMessage request, CancellationToken cancellationToken)
{
this.HttpRequestMessage = request;
this.HttpRequestContent = request.Content.ReadAsByteArrayAsync().Result;
return new HttpResponseMessage();
}

#if NET6_0_OR_GREATER
protected override HttpResponseMessage Send(HttpRequestMessage request, CancellationToken cancellationToken)
{
return this.InternalSend(request, cancellationToken);
}
#endif

protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
return Task.FromResult(this.InternalSend(request, cancellationToken));
}
}
Loading

0 comments on commit d1e8510

Please sign in to comment.