Replace LegacyMockZipkinCollector with MockSpansCollector (#1471)
This commit is contained in:
parent
0168588f1b
commit
e8bcd8d01e
|
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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;");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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]
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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()
|
||||||
|
|
Loading…
Reference in New Issue