Replace LegacyMockZipkinCollector with MockSpansCollector (#1471)

This commit is contained in:
Robert Pająk 2022-10-20 14:20:37 +02:00 committed by GitHub
parent 0168588f1b
commit e8bcd8d01e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 96 additions and 163 deletions

View File

@ -47,10 +47,7 @@ public class StrongNamedValidation
internal static CallTargetState OnMethodBegin<TTarget>(TTarget instance) internal static CallTargetState OnMethodBegin<TTarget>(TTarget instance)
{ {
using var activity = ValidationActivitySource.StartActivity(nameof(StrongNamedValidation)); using var activity = ValidationActivitySource.StartActivity(nameof(StrongNamedValidation));
activity.AddTag("validation", nameof(StrongNamedValidation));
Console.WriteLine($"Validation: {nameof(StrongNamedValidation)}"); Console.WriteLine($"Validation: {nameof(StrongNamedValidation)}");
return CallTargetState.GetDefault(); return CallTargetState.GetDefault();
} }
} }

View File

@ -15,12 +15,9 @@
// </copyright> // </copyright>
#if NETFRAMEWORK #if NETFRAMEWORK
using System;
using System.IO; using System.IO;
using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using FluentAssertions; using FluentAssertions;
using FluentAssertions.Execution;
using IntegrationTests.Helpers; using IntegrationTests.Helpers;
using Xunit; using Xunit;
using Xunit.Abstractions; using Xunit.Abstractions;
@ -40,6 +37,9 @@ public class DomainNeutralTests : TestHelper
{ {
EnvironmentTools.IsWindowsAdministrator().Should().BeTrue(); EnvironmentTools.IsWindowsAdministrator().Should().BeTrue();
using var collector = await MockSpansCollector.Start(Output);
collector.Expect("TestApplication.StrongNamedValidation");
// Add the necessary assembly to the GAC so it can be loaded as domain-neutral. // Add the necessary assembly to the GAC so it can be loaded as domain-neutral.
var instrumentationAssembly = Path.Combine( var instrumentationAssembly = Path.Combine(
EnvironmentTools.GetSolutionDirectory(), EnvironmentTools.GetSolutionDirectory(),
@ -55,22 +55,10 @@ public class DomainNeutralTests : TestHelper
var assemblyPath = GetTestAssemblyPath(); var assemblyPath = GetTestAssemblyPath();
var integrationsFile = Path.Combine(assemblyPath, "StrongNamedTestsIntegrations.json"); var integrationsFile = Path.Combine(assemblyPath, "StrongNamedTestsIntegrations.json");
File.Exists(integrationsFile).Should().BeTrue(); File.Exists(integrationsFile).Should().BeTrue();
SetEnvironmentVariable("OTEL_DOTNET_AUTO_INTEGRATIONS_FILE", integrationsFile); SetEnvironmentVariable("OTEL_DOTNET_AUTO_INTEGRATIONS_FILE", integrationsFile);
RunTestApplication(otlpTraceCollectorPort: collector.Port);
using var agent = await LegacyMockZipkinCollector.Start(Output); collector.AssertExpectations();
RunTestApplication(agent.Port);
const int expectedSpansCount = 1;
var spans = await agent.WaitForSpansAsync(expectedSpansCount);
using (new AssertionScope())
{
spans.Count.Should().Be(expectedSpansCount);
spans.Count(s => s.Tags["validation"] == "StrongNamedValidation").Should().Be(1);
}
} }
} }
#endif #endif

View File

@ -14,11 +14,7 @@
// limitations under the License. // limitations under the License.
// </copyright> // </copyright>
using System;
using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using FluentAssertions;
using FluentAssertions.Execution;
using IntegrationTests.Helpers; using IntegrationTests.Helpers;
using Xunit; using Xunit;
using Xunit.Abstractions; using Xunit.Abstractions;
@ -36,22 +32,14 @@ public class GrpcNetClientTests : TestHelper
[Trait("Category", "EndToEnd")] [Trait("Category", "EndToEnd")]
public async Task SubmitsTraces() public async Task SubmitsTraces()
{ {
using var agent = await LegacyMockZipkinCollector.Start(Output); using var collector = await MockSpansCollector.Start(Output);
collector.Expect("OpenTelemetry.Instrumentation.GrpcNetClient");
// Grpc.Net.Client is using various version of http communication under the hood. // Grpc.Net.Client is using various version of http communication under the hood.
// Disabling HttpClient instrumentation to have consistent set of spans. // Enabling only GrpcNetClient instrumentation to have consistent set of spans.
SetEnvironmentVariable("OTEL_DOTNET_AUTO_TRACES_DISABLED_INSTRUMENTATIONS", "HttpClient"); SetEnvironmentVariable("OTEL_DOTNET_AUTO_TRACES_ENABLED_INSTRUMENTATIONS", "GrpcNetClient");
RunTestApplication(otlpTraceCollectorPort: collector.Port, enableClrProfiler: !IsCoreClr());
RunTestApplication(agent.Port, enableClrProfiler: !IsCoreClr()); collector.AssertExpectations();
const int expectedSpansCount = 1;
var spans = await agent.WaitForSpansAsync(expectedSpansCount);
using (new AssertionScope())
{
spans.Count.Should().Be(expectedSpansCount);
spans.Count(s => s.Tags["otel.library.name"] == "OpenTelemetry.Instrumentation.GrpcNetClient").Should().Be(1);
}
} }
} }

View File

@ -146,6 +146,15 @@ public class MockSpansCollector : IDisposable
} }
} }
public void AssertEmpty(TimeSpan? timeout = null)
{
timeout ??= DefaultWaitTimeout;
if (_spans.TryTake(out var resourceSpan, timeout.Value))
{
Assert.Fail($"Expected nothing, but got: {resourceSpan}");
}
}
private static void FailExpectations( private static void FailExpectations(
List<Expectation> missingExpectations, List<Expectation> missingExpectations,
List<Collected> expectationsMet, List<Collected> expectationsMet,

View File

@ -14,10 +14,7 @@
// limitations under the License. // limitations under the License.
// </copyright> // </copyright>
using System;
using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using FluentAssertions;
using IntegrationTests.Helpers; using IntegrationTests.Helpers;
using Xunit; using Xunit;
using Xunit.Abstractions; using Xunit.Abstractions;
@ -27,14 +24,12 @@ namespace IntegrationTests;
[Collection(PostgresCollection.Name)] [Collection(PostgresCollection.Name)]
public class NpqsqlTests : TestHelper public class NpqsqlTests : TestHelper
{ {
private const string ServiceName = "TestApplication.Npgsql";
private readonly PostgresFixture _postgres; private readonly PostgresFixture _postgres;
public NpqsqlTests(ITestOutputHelper output, PostgresFixture postgres) public NpqsqlTests(ITestOutputHelper output, PostgresFixture postgres)
: base("Npgsql", output) : base("Npgsql", output)
{ {
_postgres = postgres; _postgres = postgres;
SetEnvironmentVariable("OTEL_SERVICE_NAME", ServiceName);
} }
[Fact] [Fact]
@ -42,12 +37,11 @@ public class NpqsqlTests : TestHelper
[Trait("Containers", "Linux")] [Trait("Containers", "Linux")]
public async Task SubmitsTraces() public async Task SubmitsTraces()
{ {
using var agent = await LegacyMockZipkinCollector.Start(Output); using var collector = await MockSpansCollector.Start(Output);
collector.Expect("Npgsql");
RunTestApplication(agent.Port, arguments: $"--postgres {_postgres.Port}", enableClrProfiler: !IsCoreClr()); RunTestApplication(otlpTraceCollectorPort: collector.Port, arguments: $"--postgres {_postgres.Port}", enableClrProfiler: !IsCoreClr());
var spans = await agent.WaitForSpansAsync(1);
spans.Count.Should().Be(1); collector.AssertExpectations();
spans.First().Tags["db.statement"].Should().Be("SELECT 123;");
} }
} }

View File

@ -15,7 +15,6 @@
// </copyright> // </copyright>
using System.Threading.Tasks; using System.Threading.Tasks;
using FluentAssertions;
using IntegrationTests.Helpers; using IntegrationTests.Helpers;
using Xunit; using Xunit;
using Xunit.Abstractions; using Xunit.Abstractions;
@ -33,13 +32,13 @@ public class PluginsTests : TestHelper
[Trait("Category", "EndToEnd")] [Trait("Category", "EndToEnd")]
public async Task SubmitsTraces() public async Task SubmitsTraces()
{ {
using var collector = await MockSpansCollector.Start(Output);
collector.Expect("MyCompany.MyProduct.MyLibrary");
SetEnvironmentVariable("OTEL_DOTNET_AUTO_PLUGINS", "TestApplication.Plugins.Plugin, TestApplication.Plugins, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"); SetEnvironmentVariable("OTEL_DOTNET_AUTO_PLUGINS", "TestApplication.Plugins.Plugin, TestApplication.Plugins, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null");
RunTestApplication(otlpTraceCollectorPort: collector.Port);
using var collector = await LegacyMockZipkinCollector.Start(Output); collector.AssertExpectations();
RunTestApplication(collector.Port);
var spans = await collector.WaitForSpansAsync(1);
spans.Should().Contain(x => x.Name == "SayHello");
} }
[Fact] [Fact]

View File

@ -14,11 +14,7 @@
// limitations under the License. // limitations under the License.
// </copyright> // </copyright>
using System;
using System.Collections.Generic;
using System.Collections.Immutable; using System.Collections.Immutable;
using System.Diagnostics;
using System.Linq;
using System.Net; using System.Net;
using System.Net.Http; using System.Net.Http;
using System.Reflection; using System.Reflection;
@ -26,13 +22,14 @@ using System.Threading.Tasks;
using FluentAssertions; using FluentAssertions;
using FluentAssertions.Extensions; using FluentAssertions.Extensions;
using IntegrationTests.Helpers; using IntegrationTests.Helpers;
using IntegrationTests.Helpers.Mocks;
using IntegrationTests.Helpers.Models;
using Xunit; using Xunit;
using Xunit.Abstractions; using Xunit.Abstractions;
#if NETFRAMEWORK #if NETFRAMEWORK
using IntegrationTests.Helpers.Compatibility; using IntegrationTests.Helpers.Compatibility;
#else
using System;
using System.Collections.Generic;
#endif #endif
namespace IntegrationTests; namespace IntegrationTests;
@ -52,22 +49,18 @@ public class SmokeTests : TestHelper
[Trait("Category", "EndToEnd")] [Trait("Category", "EndToEnd")]
public async Task SubmitsTraces() public async Task SubmitsTraces()
{ {
var spans = await RunTestApplicationAsync(); await VerifyTestApplicationInstrumented();
AssertAllSpansReceived(spans);
} }
[Fact] [Fact]
[Trait("Category", "EndToEnd")] [Trait("Category", "EndToEnd")]
public async Task WhenStartupHookIsNotEnabled() public async Task WhenStartupHookIsNotEnabled()
{ {
var spans = await RunTestApplicationAsync(enableStartupHook: false);
#if NETFRAMEWORK #if NETFRAMEWORK
AssertAllSpansReceived(spans); await VerifyTestApplicationInstrumented(enableStartupHook: false);
#else #else
// on .NET Core it is required to set DOTNET_STARTUP_HOOKS // on .NET Core it is required to set DOTNET_STARTUP_HOOKS
AssertNoSpansReceived(spans); await VerifyTestApplicationNotInstrumented(enableStartupHook: false);
#endif #endif
} }
@ -75,13 +68,11 @@ public class SmokeTests : TestHelper
[Trait("Category", "EndToEnd")] [Trait("Category", "EndToEnd")]
public async Task WhenClrProfilerIsNotEnabled() public async Task WhenClrProfilerIsNotEnabled()
{ {
var spans = await RunTestApplicationAsync(enableClrProfiler: false);
#if NETFRAMEWORK #if NETFRAMEWORK
// on .NET Framework it is required to set the CLR .NET Profiler // on .NET Framework it is required to set the CLR .NET Profiler
AssertNoSpansReceived(spans); await VerifyTestApplicationNotInstrumented(enableClrProfiler: false);
#else #else
AssertAllSpansReceived(spans); await VerifyTestApplicationInstrumented(enableClrProfiler: false);
#endif #endif
} }
@ -91,9 +82,7 @@ public class SmokeTests : TestHelper
{ {
SetEnvironmentVariable("OTEL_DOTNET_AUTO_EXCLUDE_PROCESSES", "dotnet,dotnet.exe"); SetEnvironmentVariable("OTEL_DOTNET_AUTO_EXCLUDE_PROCESSES", "dotnet,dotnet.exe");
var spans = await RunTestApplicationAsync(); await VerifyTestApplicationInstrumented();
AssertAllSpansReceived(spans);
} }
[Fact] [Fact]
@ -102,9 +91,7 @@ public class SmokeTests : TestHelper
{ {
SetEnvironmentVariable("OTEL_DOTNET_AUTO_EXCLUDE_PROCESSES", $"dotnet,dotnet.exe,{EnvironmentHelper.FullTestApplicationName},{EnvironmentHelper.FullTestApplicationName}.exe"); SetEnvironmentVariable("OTEL_DOTNET_AUTO_EXCLUDE_PROCESSES", $"dotnet,dotnet.exe,{EnvironmentHelper.FullTestApplicationName},{EnvironmentHelper.FullTestApplicationName}.exe");
var spans = await RunTestApplicationAsync(); await VerifyTestApplicationNotInstrumented();
AssertNoSpansReceived(spans);
} }
[Fact] [Fact]
@ -113,14 +100,12 @@ public class SmokeTests : TestHelper
{ {
SetEnvironmentVariable("OTEL_DOTNET_AUTO_INCLUDE_PROCESSES", "dotnet,dotnet.exe"); SetEnvironmentVariable("OTEL_DOTNET_AUTO_INCLUDE_PROCESSES", "dotnet,dotnet.exe");
var spans = await RunTestApplicationAsync();
#if NETFRAMEWORK #if NETFRAMEWORK
AssertNoSpansReceived(spans); await VerifyTestApplicationNotInstrumented();
#else #else
// FIXME: OTEL_DOTNET_AUTO_INCLUDE_PROCESSES does not work on .NET Core. // FIXME: OTEL_DOTNET_AUTO_INCLUDE_PROCESSES does not work on .NET Core.
// https://github.com/open-telemetry/opentelemetry-dotnet-instrumentation/issues/895 // https://github.com/open-telemetry/opentelemetry-dotnet-instrumentation/issues/895
AssertAllSpansReceived(spans); await VerifyTestApplicationInstrumented();
#endif #endif
} }
@ -130,9 +115,7 @@ public class SmokeTests : TestHelper
{ {
SetEnvironmentVariable("OTEL_DOTNET_AUTO_INCLUDE_PROCESSES", $"{EnvironmentHelper.FullTestApplicationName},{EnvironmentHelper.FullTestApplicationName}.exe"); SetEnvironmentVariable("OTEL_DOTNET_AUTO_INCLUDE_PROCESSES", $"{EnvironmentHelper.FullTestApplicationName},{EnvironmentHelper.FullTestApplicationName}.exe");
var spans = await RunTestApplicationAsync(); await VerifyTestApplicationInstrumented();
AssertAllSpansReceived(spans);
} }
[Fact] [Fact]
@ -291,41 +274,29 @@ public class SmokeTests : TestHelper
} }
#endif #endif
private static void AssertNoSpansReceived(IImmutableList<IMockSpan> spans) private async Task VerifyTestApplicationInstrumented(bool enableStartupHook = true, bool enableClrProfiler = true)
{ {
Assert.True(spans.Count == 0, $"Expecting no spans, received {spans.Count}"); using var collector = await MockSpansCollector.Start(Output);
} collector.Expect("MyCompany.MyProduct.MyLibrary");
private static void AssertAllSpansReceived(IImmutableList<IMockSpan> spans)
{
var expectedSpanCount = 2;
Assert.True(spans.Count() == expectedSpanCount, $"Expecting {expectedSpanCount} spans, received {spans.Count()}");
if (expectedSpanCount > 0)
{
Assert.Single(spans.Select(s => s.Service).Distinct());
var expectations = new List<SpanExpectation>();
expectations.Add(new SpanExpectation(ServiceName, "1.0.0", "SayHello", "MyCompany.MyProduct.MyLibrary", ActivityKind.Internal));
#if NETFRAMEWORK #if NETFRAMEWORK
expectations.Add(new SpanExpectation(ServiceName, "1.0.0.0", "HTTP GET", "OpenTelemetry.HttpWebRequest", ActivityKind.Client)); collector.Expect("OpenTelemetry.HttpWebRequest");
#else #else
expectations.Add(new SpanExpectation(ServiceName, "1.0.0.0", "HTTP GET", "OpenTelemetry.Instrumentation.Http", ActivityKind.Client)); collector.Expect("OpenTelemetry.Instrumentation.Http");
#endif #endif
SpanTestHelpers.AssertExpectationsMet(expectations, spans); SetEnvironmentVariable("OTEL_DOTNET_AUTO_TRACES_ADDITIONAL_SOURCES", "MyCompany.MyProduct.MyLibrary");
} RunTestApplication(otlpTraceCollectorPort: collector.Port, enableStartupHook: enableStartupHook, enableClrProfiler: enableClrProfiler);
collector.AssertExpectations();
} }
private async Task<IImmutableList<IMockSpan>> RunTestApplicationAsync(bool enableStartupHook = true, bool enableClrProfiler = true) private async Task VerifyTestApplicationNotInstrumented(bool enableStartupHook = true, bool enableClrProfiler = true)
{ {
using var collector = await MockSpansCollector.Start(Output);
SetEnvironmentVariable("OTEL_DOTNET_AUTO_TRACES_ADDITIONAL_SOURCES", "MyCompany.MyProduct.MyLibrary"); SetEnvironmentVariable("OTEL_DOTNET_AUTO_TRACES_ADDITIONAL_SOURCES", "MyCompany.MyProduct.MyLibrary");
RunTestApplication(otlpTraceCollectorPort: collector.Port, enableStartupHook: enableStartupHook, enableClrProfiler: enableClrProfiler);
using var agent = await LegacyMockZipkinCollector.Start(Output); collector.AssertEmpty(5.Seconds());
RunTestApplication(agent.Port, enableStartupHook: enableStartupHook, enableClrProfiler: enableClrProfiler);
// The process emitting the spans already finished by this time, there is no need to wait more,
// just get the spans received so far.
return await agent.WaitForSpansAsync(count: 2, timeout: TimeSpan.Zero);
} }
} }

View File

@ -14,11 +14,7 @@
// limitations under the License. // limitations under the License.
// </copyright> // </copyright>
using System;
using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using FluentAssertions;
using FluentAssertions.Execution;
using IntegrationTests.Helpers; using IntegrationTests.Helpers;
using Xunit; using Xunit;
using Xunit.Abstractions; using Xunit.Abstractions;
@ -28,14 +24,12 @@ namespace IntegrationTests;
[Collection(SqlServerCollection.Name)] [Collection(SqlServerCollection.Name)]
public class SqlClientTests : TestHelper public class SqlClientTests : TestHelper
{ {
private const string ServiceName = "TestApplication.SqlClient";
private readonly SqlServerFixture _sqlServerFixture; private readonly SqlServerFixture _sqlServerFixture;
public SqlClientTests(ITestOutputHelper output, SqlServerFixture sqlServerFixture) public SqlClientTests(ITestOutputHelper output, SqlServerFixture sqlServerFixture)
: base("SqlClient", output) : base("SqlClient", output)
{ {
_sqlServerFixture = sqlServerFixture; _sqlServerFixture = sqlServerFixture;
SetEnvironmentVariable("OTEL_SERVICE_NAME", ServiceName);
} }
[Fact] [Fact]
@ -43,21 +37,11 @@ public class SqlClientTests : TestHelper
[Trait("Containers", "Linux")] [Trait("Containers", "Linux")]
public async Task SubmitTraces() public async Task SubmitTraces()
{ {
using var agent = await LegacyMockZipkinCollector.Start(Output); using var collector = await MockSpansCollector.Start(Output);
collector.Expect("OpenTelemetry.SqlClient");
const int expectedSpanCount = 8; RunTestApplication(otlpTraceCollectorPort: collector.Port, arguments: $"{_sqlServerFixture.Password} {_sqlServerFixture.Port}", enableClrProfiler: !IsCoreClr());
RunTestApplication(agent.Port, arguments: $"{_sqlServerFixture.Password} {_sqlServerFixture.Port}", enableClrProfiler: !IsCoreClr()); collector.AssertExpectations();
var spans = await agent.WaitForSpansAsync(expectedSpanCount);
using (new AssertionScope())
{
spans.Count.Should().Be(expectedSpanCount);
foreach (var span in spans)
{
span.Tags.Should().Contain(new KeyValuePair<string, string>("otel.library.name", "OpenTelemetry.SqlClient"));
}
}
} }
} }

View File

@ -14,12 +14,9 @@
// limitations under the License. // limitations under the License.
// </copyright> // </copyright>
using System;
using System.IO; using System.IO;
using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using FluentAssertions; using FluentAssertions;
using FluentAssertions.Execution;
using IntegrationTests.Helpers; using IntegrationTests.Helpers;
using Xunit; using Xunit;
using Xunit.Abstractions; using Xunit.Abstractions;
@ -36,24 +33,15 @@ public class StrongNamedTests : TestHelper
[Fact] [Fact]
public async Task SubmitsTraces() public async Task SubmitsTraces()
{ {
using var collector = await MockSpansCollector.Start(Output);
collector.Expect("TestApplication.StrongNamedValidation");
var assemblyPath = GetTestAssemblyPath(); var assemblyPath = GetTestAssemblyPath();
var integrationsFile = Path.Combine(assemblyPath, "StrongNamedTestsIntegrations.json"); var integrationsFile = Path.Combine(assemblyPath, "StrongNamedTestsIntegrations.json");
File.Exists(integrationsFile).Should().BeTrue(); File.Exists(integrationsFile).Should().BeTrue();
SetEnvironmentVariable("OTEL_DOTNET_AUTO_INTEGRATIONS_FILE", integrationsFile); SetEnvironmentVariable("OTEL_DOTNET_AUTO_INTEGRATIONS_FILE", integrationsFile);
RunTestApplication(otlpTraceCollectorPort: collector.Port);
using var agent = await LegacyMockZipkinCollector.Start(Output); collector.AssertExpectations();
RunTestApplication(agent.Port);
const int expectedSpansCount = 1;
var spans = await agent.WaitForSpansAsync(expectedSpansCount);
using (new AssertionScope())
{
spans.Count.Should().Be(expectedSpansCount);
spans.Count(s => s.Tags["validation"] == "StrongNamedValidation").Should().Be(1);
}
} }
} }

View File

@ -46,7 +46,7 @@ internal class WcfServerTestHelper : TestHelper
var testSettings = new TestSettings var testSettings = new TestSettings
{ {
TracesSettings = new TracesSettings { Port = traceAgentPort } OtlpTracesSettings = new OtlpTracesSettings { Port = traceAgentPort }
}; };
// clear all relevant environment variables to start with a clean slate // clear all relevant environment variables to start with a clean slate
@ -102,6 +102,24 @@ internal class WcfServerTestHelper : TestHelper
environmentVariables["OTEL_EXPORTER_ZIPKIN_ENDPOINT"] = $"http://localhost:{testSettings.TracesSettings.Port}/api/v2/spans"; environmentVariables["OTEL_EXPORTER_ZIPKIN_ENDPOINT"] = $"http://localhost:{testSettings.TracesSettings.Port}/api/v2/spans";
} }
if (testSettings.OtlpTracesSettings != null)
{
environmentVariables["OTEL_TRACES_EXPORTER"] = testSettings.OtlpTracesSettings.Exporter;
environmentVariables["OTEL_EXPORTER_OTLP_ENDPOINT"] = $"http://localhost:{testSettings.OtlpTracesSettings.Port}";
}
if (testSettings.MetricsSettings != null)
{
environmentVariables["OTEL_METRICS_EXPORTER"] = testSettings.MetricsSettings.Exporter;
environmentVariables["OTEL_EXPORTER_OTLP_ENDPOINT"] = $"http://localhost:{testSettings.MetricsSettings.Port}";
}
if (testSettings.LogSettings != null)
{
environmentVariables["OTEL_LOGS_EXPORTER"] = testSettings.LogSettings.Exporter;
environmentVariables["OTEL_EXPORTER_OTLP_ENDPOINT"] = $"http://localhost:{testSettings.LogSettings.Port}";
}
environmentVariables["OTEL_DOTNET_AUTO_TRACES_ADDITIONAL_SOURCES"] = "TestApplication.*"; environmentVariables["OTEL_DOTNET_AUTO_TRACES_ADDITIONAL_SOURCES"] = "TestApplication.*";
foreach (var key in EnvironmentHelper.CustomEnvironmentVariables.Keys) foreach (var key in EnvironmentHelper.CustomEnvironmentVariables.Keys)

View File

@ -18,10 +18,10 @@ using System;
using System.Net.Sockets; using System.Net.Sockets;
using System.Threading.Tasks; using System.Threading.Tasks;
using FluentAssertions; using FluentAssertions;
using FluentAssertions.Execution;
using IntegrationTests.Helpers; using IntegrationTests.Helpers;
using Xunit; using Xunit;
using Xunit.Abstractions; using Xunit.Abstractions;
using static OpenTelemetry.Proto.Trace.V1.Span.Types;
namespace IntegrationTests; namespace IntegrationTests;
public abstract class WcfTestsBase : TestHelper, IDisposable public abstract class WcfTestsBase : TestHelper, IDisposable
@ -38,25 +38,22 @@ public abstract class WcfTestsBase : TestHelper, IDisposable
[Trait("Category", "EndToEnd")] [Trait("Category", "EndToEnd")]
public async Task SubmitsTraces() public async Task SubmitsTraces()
{ {
using var agent = await LegacyMockZipkinCollector.Start(Output); EnvironmentTools.IsWindowsAdministrator().Should().BeTrue(); // WCF Server needs admin
using var collector = await MockSpansCollector.Start(Output);
// the test app makes 2 calls (therefore we exepct 4 spans)
collector.Expect("OpenTelemetry.Instrumentation.Wcf", span => span.Kind == SpanKind.Server, "Server 1");
collector.Expect("OpenTelemetry.Instrumentation.Wcf", span => span.Kind == SpanKind.Client, "Client 1");
collector.Expect("OpenTelemetry.Instrumentation.Wcf", span => span.Kind == SpanKind.Server, "Server 2");
collector.Expect("OpenTelemetry.Instrumentation.Wcf", span => span.Kind == SpanKind.Client, "Client 2");
var serverHelper = new WcfServerTestHelper(Output); var serverHelper = new WcfServerTestHelper(Output);
_serverProcess = serverHelper.RunWcfServer(agent.Port); _serverProcess = serverHelper.RunWcfServer(collector.Port);
await WaitForServer(); await WaitForServer();
RunTestApplication(agent.Port); RunTestApplication(otlpTraceCollectorPort: collector.Port);
// wait so the spans from server are delivered collector.AssertExpectations();
await Task.Delay(2000);
var spans = await agent.WaitForSpansAsync(4);
using var scope = new AssertionScope();
spans.Count.Should().Be(4);
foreach (var span in spans)
{
span.Tags["otel.library.name"].Should().Be("OpenTelemetry.Instrumentation.Wcf");
}
} }
public void Dispose() public void Dispose()