Skip to content

Commit

Permalink
Removed Moq dependency from Exporter.OpenTelemetryProtocol.Tests (#5118)
Browse files Browse the repository at this point in the history
  • Loading branch information
ngruson authored Dec 5, 2023
1 parent d617171 commit 5ca1124
Show file tree
Hide file tree
Showing 7 changed files with 113 additions and 69 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));
}
}

0 comments on commit 5ca1124

Please sign in to comment.