Add support for SqlClient metrics (#3875)

This commit is contained in:
Piotr Kiełkowicz 2024-12-10 06:44:25 +01:00 committed by GitHub
parent 6c299d7a18
commit 3fc3553458
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 269 additions and 50 deletions

View File

@ -12,6 +12,7 @@ This component adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.h
- Support for .NET9. - Support for .NET9.
- Support for [RabbitMQ.Client](https://www.nuget.org/packages/RabbitMQ.Client/) - Support for [RabbitMQ.Client](https://www.nuget.org/packages/RabbitMQ.Client/)
traces instrumentation for versions `7.0.0`+. traces instrumentation for versions `7.0.0`+.
- Support for SqlClient metrics.
### Changed ### Changed

View File

@ -181,18 +181,25 @@ due to lack of stable semantic convention.
Metrics are stable, but particular instrumentation are in Experimental status Metrics are stable, but particular instrumentation are in Experimental status
due to lack of stable semantic convention. due to lack of stable semantic convention.
| ID | Instrumented library | Documentation | Supported versions | Instrumentation type | Status | | ID | Instrumented library | Documentation | Supported versions | Instrumentation type | Status |
|---------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------|----------------------|-----------------------------------------------------------------------------------------------------------------------------------| |---------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------|----------------------|-----------------------------------------------------------------------------------------------------------------------------------|
| `ASPNET` | ASP.NET Framework \[1\] **Not supported on .NET** | [ASP.NET metrics](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/Instrumentation.AspNet-1.9.0-beta.1/src/OpenTelemetry.Instrumentation.AspNet/README.md#list-of-metrics-produced) | * | source & bytecode | [Experimental](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/versioning-and-stability.md) | | `ASPNET` | ASP.NET Framework \[1\] **Not supported on .NET** | [ASP.NET metrics](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/Instrumentation.AspNet-1.9.0-beta.1/src/OpenTelemetry.Instrumentation.AspNet/README.md#list-of-metrics-produced) | * | source & bytecode | [Experimental](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/versioning-and-stability.md) |
| `ASPNETCORE` | ASP.NET Core **Not supported on .NET Framework** | [ASP.NET Core metrics](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/Instrumentation.AspNetCore-1.10.0/src/OpenTelemetry.Instrumentation.AspNetCore/README.md#list-of-metrics-produced) | * | source | [Experimental](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/versioning-and-stability.md) | | `ASPNETCORE` | ASP.NET Core **Not supported on .NET Framework** | [ASP.NET Core metrics](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/Instrumentation.AspNetCore-1.10.0/src/OpenTelemetry.Instrumentation.AspNetCore/README.md#list-of-metrics-produced) | * | source | [Experimental](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/versioning-and-stability.md) |
| `HTTPCLIENT` | [System.Net.Http.HttpClient](https://docs.microsoft.com/dotnet/api/system.net.http.httpclient) and [System.Net.HttpWebRequest](https://docs.microsoft.com/dotnet/api/system.net.httpwebrequest) | [HttpClient metrics](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/Instrumentation.Http-1.10.0/src/OpenTelemetry.Instrumentation.Http/README.md#list-of-metrics-produced) | * | source | [Experimental](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/versioning-and-stability.md) | | `HTTPCLIENT` | [System.Net.Http.HttpClient](https://docs.microsoft.com/dotnet/api/system.net.http.httpclient) and [System.Net.HttpWebRequest](https://docs.microsoft.com/dotnet/api/system.net.httpwebrequest) | [HttpClient metrics](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/Instrumentation.Http-1.10.0/src/OpenTelemetry.Instrumentation.Http/README.md#list-of-metrics-produced) | * | source | [Experimental](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/versioning-and-stability.md) |
| `NETRUNTIME` | [OpenTelemetry.Instrumentation.Runtime](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Runtime) | [Runtime metrics](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/Instrumentation.Runtime-1.10.0/src/OpenTelemetry.Instrumentation.Runtime/README.md#metrics) | * | source | [Experimental](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/versioning-and-stability.md) | | `NETRUNTIME` | [OpenTelemetry.Instrumentation.Runtime](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Runtime) | [Runtime metrics](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/Instrumentation.Runtime-1.10.0/src/OpenTelemetry.Instrumentation.Runtime/README.md#metrics) | * | source | [Experimental](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/versioning-and-stability.md) |
| `PROCESS` | [OpenTelemetry.Instrumentation.Process](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Process) | [Process metrics](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/Instrumentation.Process-1.10.0-beta.1/src/OpenTelemetry.Instrumentation.Process/README.md#metrics) | * | source | [Experimental](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/versioning-and-stability.md) | | `NSERVICEBUS` | [NServiceBus](https://www.nuget.org/packages/NServiceBus) | [NServiceBus metrics](https://docs.particular.net/samples/open-telemetry/prometheus-grafana/#reporting-metric-values) | ≥8.0.0 & < 10.0.0 | source & bytecode | [Experimental](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/versioning-and-stability.md) |
| `NSERVICEBUS` | [NServiceBus](https://www.nuget.org/packages/NServiceBus) | [NServiceBus metrics](https://docs.particular.net/samples/open-telemetry/prometheus-grafana/#reporting-metric-values) | ≥8.0.0 & < 10.0.0 | source & bytecode | [Experimental](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/versioning-and-stability.md) | | `PROCESS` | [OpenTelemetry.Instrumentation.Process](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Process) | [Process metrics](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/Instrumentation.Process-1.10.0-beta.1/src/OpenTelemetry.Instrumentation.Process/README.md#metrics) | * | source | [Experimental](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/versioning-and-stability.md) |
| `SQLCLIENT` | [Microsoft.Data.SqlClient](https://www.nuget.org/packages/Microsoft.Data.SqlClient), [System.Data.SqlClient](https://www.nuget.org/packages/System.Data.SqlClient) \[2\] and `System.Data` (shipped with .NET Framework) | [SqlClient metrics](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/releases/tag/Instrumentation.SqlClient-1.10.0-beta.1) | * \[3\] | source | [Experimental](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/versioning-and-stability.md) |
\[1\]: The ASP.NET metrics are generated only if the `AspNet` trace instrumentation \[1\]: The ASP.NET metrics are generated only if the `AspNet` trace instrumentation
is also enabled. is also enabled.
\[2\]: `System.Data.SqlClient` is [deprecated](https://www.nuget.org/packages/System.Data.SqlClient/4.9.0#readme-body-tab).
\[3\]: `Microsoft.Data.SqlClient` v3.* is not supported on .NET Framework,
due to [issue](https://github.com/open-telemetry/opentelemetry-dotnet/issues/4243).
`System.Data.SqlClient` is supported from version 4.8.5.
### Logs instrumentations ### Logs instrumentations
**Status**: [Experimental](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/versioning-and-stability.md). **Status**: [Experimental](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/versioning-and-stability.md).

View File

@ -43,7 +43,7 @@ internal static class DelayedInitialization
[MethodImpl(MethodImplOptions.NoInlining)] [MethodImpl(MethodImplOptions.NoInlining)]
public static void AddSqlClient(LazyInstrumentationLoader lazyInstrumentationLoader, PluginManager pluginManager, TracerSettings tracerSettings) public static void AddSqlClient(LazyInstrumentationLoader lazyInstrumentationLoader, PluginManager pluginManager, TracerSettings tracerSettings)
{ {
new SqlClientInitializer(lazyInstrumentationLoader, pluginManager, tracerSettings); new SqlClientTracerInitializer(lazyInstrumentationLoader, pluginManager, tracerSettings);
} }
#if NET #if NET
@ -89,5 +89,11 @@ internal static class DelayedInitialization
{ {
new HttpClientMetricsInitializer(lazyInstrumentationLoader); new HttpClientMetricsInitializer(lazyInstrumentationLoader);
} }
[MethodImpl(MethodImplOptions.NoInlining)]
public static void AddSqlClient(LazyInstrumentationLoader lazyInstrumentationLoader, PluginManager pluginManager)
{
new SqlClientMetricsInitializer(lazyInstrumentationLoader, pluginManager);
}
} }
} }

View File

@ -44,6 +44,7 @@ internal static class EnvironmentConfigurationMetricHelper
.AddMeter("Microsoft.AspNetCore.Diagnostics") .AddMeter("Microsoft.AspNetCore.Diagnostics")
.AddMeter("Microsoft.AspNetCore.RateLimiting"), .AddMeter("Microsoft.AspNetCore.RateLimiting"),
#endif #endif
MetricInstrumentation.SqlClient => Wrappers.AddSqlClientInstrumentation(builder, lazyInstrumentationLoader, pluginManager),
_ => null, _ => null,
}; };
} }
@ -115,6 +116,13 @@ internal static class EnvironmentConfigurationMetricHelper
return builder.AddProcessInstrumentation(); return builder.AddProcessInstrumentation();
} }
[MethodImpl(MethodImplOptions.NoInlining)]
public static MeterProviderBuilder AddSqlClientInstrumentation(MeterProviderBuilder builder, LazyInstrumentationLoader lazyInstrumentationLoader, PluginManager pluginManager)
{
DelayedInitialization.Metrics.AddSqlClient(lazyInstrumentationLoader, pluginManager);
return builder.AddMeter("OpenTelemetry.Instrumentation.SqlClient");
}
// Exporters // Exporters
[MethodImpl(MethodImplOptions.NoInlining)] [MethodImpl(MethodImplOptions.NoInlining)]

View File

@ -39,6 +39,11 @@ internal enum MetricInstrumentation
/// <summary> /// <summary>
/// ASP.NET Core instrumentation. /// ASP.NET Core instrumentation.
/// </summary> /// </summary>
AspNetCore = 6 AspNetCore = 6,
#endif #endif
/// <summary>
/// SqlClient instrumentation.
/// </summary>
SqlClient = 7
} }

View File

@ -296,6 +296,9 @@ internal static class Instrumentation
break; break;
case MetricInstrumentation.NServiceBus: case MetricInstrumentation.NServiceBus:
break; break;
case MetricInstrumentation.SqlClient:
DelayedInitialization.Metrics.AddSqlClient(lazyInstrumentationLoader, pluginManager);
break;
default: default:
Logger.Warning($"Configured metric instrumentation type is not supported: {instrumentation}"); Logger.Warning($"Configured metric instrumentation type is not supported: {instrumentation}");
if (FailFastSettings.Value.FailFast) if (FailFastSettings.Value.FailFast)

View File

@ -1,23 +1,12 @@
// Copyright The OpenTelemetry Authors // Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
using System.Reflection;
using OpenTelemetry.AutoInstrumentation.Configurations;
using OpenTelemetry.AutoInstrumentation.Plugins;
namespace OpenTelemetry.AutoInstrumentation.Loading.Initializers; namespace OpenTelemetry.AutoInstrumentation.Loading.Initializers;
internal class SqlClientInitializer internal abstract class SqlClientInitializer
{ {
private readonly PluginManager _pluginManager; protected SqlClientInitializer(LazyInstrumentationLoader lazyInstrumentationLoader)
private readonly TracerSettings _tracerSettings;
private int _initialized;
public SqlClientInitializer(LazyInstrumentationLoader lazyInstrumentationLoader, PluginManager pluginManager, TracerSettings tracerSettings)
{ {
_pluginManager = pluginManager;
_tracerSettings = tracerSettings;
lazyInstrumentationLoader.Add(new GenericInitializer("System.Data.SqlClient", InitializeOnFirstCall)); lazyInstrumentationLoader.Add(new GenericInitializer("System.Data.SqlClient", InitializeOnFirstCall));
lazyInstrumentationLoader.Add(new GenericInitializer("Microsoft.Data.SqlClient", InitializeOnFirstCall)); lazyInstrumentationLoader.Add(new GenericInitializer("Microsoft.Data.SqlClient", InitializeOnFirstCall));
@ -26,30 +15,5 @@ internal class SqlClientInitializer
#endif #endif
} }
private void InitializeOnFirstCall(ILifespanManager lifespanManager) protected abstract void InitializeOnFirstCall(ILifespanManager lifespanManager);
{
if (Interlocked.Exchange(ref _initialized, value: 1) != default)
{
// InitializeOnFirstCall() was already called before
return;
}
var instrumentationType = Type.GetType("OpenTelemetry.Instrumentation.SqlClient.SqlClientInstrumentation, OpenTelemetry.Instrumentation.SqlClient")!;
var options = new OpenTelemetry.Instrumentation.SqlClient.SqlClientTraceInstrumentationOptions
{
SetDbStatementForText = _tracerSettings.InstrumentationOptions.SqlClientSetDbStatementForText
};
_pluginManager.ConfigureTracesOptions(options);
var propertyInfo = instrumentationType.GetProperty("TracingOptions", BindingFlags.Static | BindingFlags.Public);
propertyInfo?.SetValue(null, options);
var instrumentation = instrumentationType.InvokeMember("AddTracingHandle", BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static, Type.DefaultBinder, null, []);
if (instrumentation != null)
{
lifespanManager.Track(instrumentation);
}
}
} }

View File

@ -0,0 +1,37 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0
using System.Reflection;
using OpenTelemetry.AutoInstrumentation.Plugins;
namespace OpenTelemetry.AutoInstrumentation.Loading.Initializers;
internal sealed class SqlClientMetricsInitializer : SqlClientInitializer
{
private readonly PluginManager _pluginManager;
private int _initialized;
public SqlClientMetricsInitializer(LazyInstrumentationLoader lazyInstrumentationLoader, PluginManager pluginManager)
: base(lazyInstrumentationLoader)
{
_pluginManager = pluginManager;
}
protected override void InitializeOnFirstCall(ILifespanManager lifespanManager)
{
if (Interlocked.Exchange(ref _initialized, value: 1) != default)
{
// InitializeOnFirstCall() was already called before
return;
}
var instrumentationType = Type.GetType("OpenTelemetry.Instrumentation.SqlClient.SqlClientInstrumentation, OpenTelemetry.Instrumentation.SqlClient")!;
var instrumentation = instrumentationType.InvokeMember("AddMetricHandle", BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static, Type.DefaultBinder, null, []);
if (instrumentation != null)
{
lifespanManager.Track(instrumentation);
}
}
}

View File

@ -0,0 +1,50 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0
using System.Reflection;
using OpenTelemetry.AutoInstrumentation.Configurations;
using OpenTelemetry.AutoInstrumentation.Plugins;
namespace OpenTelemetry.AutoInstrumentation.Loading.Initializers;
internal sealed class SqlClientTracerInitializer : SqlClientInitializer
{
private readonly PluginManager _pluginManager;
private readonly TracerSettings _tracerSettings;
private int _initialized;
public SqlClientTracerInitializer(LazyInstrumentationLoader lazyInstrumentationLoader, PluginManager pluginManager, TracerSettings tracerSettings)
: base(lazyInstrumentationLoader)
{
_pluginManager = pluginManager;
_tracerSettings = tracerSettings;
}
protected override void InitializeOnFirstCall(ILifespanManager lifespanManager)
{
if (Interlocked.Exchange(ref _initialized, value: 1) != default)
{
// InitializeOnFirstCall() was already called before
return;
}
var instrumentationType = Type.GetType("OpenTelemetry.Instrumentation.SqlClient.SqlClientInstrumentation, OpenTelemetry.Instrumentation.SqlClient")!;
var options = new OpenTelemetry.Instrumentation.SqlClient.SqlClientTraceInstrumentationOptions
{
SetDbStatementForText = _tracerSettings.InstrumentationOptions.SqlClientSetDbStatementForText
};
_pluginManager.ConfigureTracesOptions(options);
var propertyInfo = instrumentationType.GetProperty("TracingOptions", BindingFlags.Static | BindingFlags.Public);
propertyInfo?.SetValue(null, options);
var instrumentation = instrumentationType.InvokeMember("AddTracingHandle", BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static, Type.DefaultBinder, null, []);
if (instrumentation != null)
{
lifespanManager.Track(instrumentation);
}
}
}

View File

@ -2,6 +2,7 @@
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
using IntegrationTests.Helpers; using IntegrationTests.Helpers;
using OpenTelemetry.AutoInstrumentation.Configurations;
using Xunit.Abstractions; using Xunit.Abstractions;
namespace IntegrationTests; namespace IntegrationTests;
@ -38,4 +39,38 @@ public class SqlClientMicrosoftTests : TestHelper
collector.AssertExpectations(); collector.AssertExpectations();
} }
[SkippableTheory]
[Trait("Category", "EndToEnd")]
[Trait("Containers", "Linux")]
[MemberData(nameof(LibraryVersion.SqlClientMicrosoft), MemberType = typeof(LibraryVersion))]
public void SubmitMetrics(string packageVersion)
{
// Skip the test if fixture does not support current platform
_sqlServerFixture.SkipIfUnsupportedPlatform();
using var collector = new MockMetricsCollector(Output);
SetExporter(collector);
collector.Expect("OpenTelemetry.Instrumentation.SqlClient");
SetEnvironmentVariable("LONG_RUNNING", "true");
SetEnvironmentVariable("OTEL_METRIC_EXPORT_INTERVAL", "100");
SetEnvironmentVariable(ConfigurationKeys.Traces.TracesEnabled, bool.FalseString); // make sure that traces instrumentation is not needed
using var process = StartTestApplication(new TestSettings
{
Arguments = $"{_sqlServerFixture.Password} {_sqlServerFixture.Port}",
PackageVersion = packageVersion
});
try
{
collector.AssertExpectations();
}
finally
{
process?.Kill();
}
}
} }

View File

@ -3,7 +3,7 @@
#if NETFRAMEWORK #if NETFRAMEWORK
using IntegrationTests.Helpers; using IntegrationTests.Helpers;
using Xunit; using OpenTelemetry.AutoInstrumentation.Configurations;
using Xunit.Abstractions; using Xunit.Abstractions;
namespace IntegrationTests; namespace IntegrationTests;
@ -27,5 +27,30 @@ public class SqlClientSystemDataTests : TestHelper
collector.AssertExpectations(); collector.AssertExpectations();
} }
[Fact]
[Trait("Category", "EndToEnd")]
public void SubmitMetrics()
{
using var collector = new MockMetricsCollector(Output);
SetExporter(collector);
collector.Expect("OpenTelemetry.Instrumentation.SqlClient");
SetEnvironmentVariable("LONG_RUNNING", "true");
SetEnvironmentVariable("OTEL_METRIC_EXPORT_INTERVAL", "100");
SetEnvironmentVariable(ConfigurationKeys.Traces.TracesEnabled, bool.FalseString); // make sure that traces instrumentation is not needed
using var process = StartTestApplication();
try
{
collector.AssertExpectations();
}
finally
{
process?.Kill();
}
}
} }
#endif #endif

View File

@ -2,6 +2,7 @@
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
using IntegrationTests.Helpers; using IntegrationTests.Helpers;
using OpenTelemetry.AutoInstrumentation.Configurations;
using Xunit.Abstractions; using Xunit.Abstractions;
namespace IntegrationTests; namespace IntegrationTests;
@ -62,4 +63,38 @@ public class SqlClientSystemTests : TestHelper
collector.AssertExpectations(); collector.AssertExpectations();
} }
[SkippableTheory]
[Trait("Category", "EndToEnd")]
[Trait("Containers", "Linux")]
[MemberData(nameof(LibraryVersion.SqlClientSystem), MemberType = typeof(LibraryVersion))]
public void SubmitMetrics(string packageVersion)
{
// Skip the test if fixture does not support current platform
_sqlServerFixture.SkipIfUnsupportedPlatform();
using var collector = new MockMetricsCollector(Output);
SetExporter(collector);
collector.Expect("OpenTelemetry.Instrumentation.SqlClient");
SetEnvironmentVariable("LONG_RUNNING", "true");
SetEnvironmentVariable("OTEL_METRIC_EXPORT_INTERVAL", "100");
SetEnvironmentVariable(ConfigurationKeys.Traces.TracesEnabled, bool.FalseString); // make sure that traces instrumentation is not needed
using var process = StartTestApplication(new TestSettings
{
Arguments = $"{_sqlServerFixture.Password} {_sqlServerFixture.Port}",
PackageVersion = packageVersion
});
try
{
collector.AssertExpectations();
}
finally
{
process?.Kill();
}
}
} }

View File

@ -345,6 +345,7 @@ public class SettingsTests : IDisposable
#if NET #if NET
[InlineData("ASPNETCORE", MetricInstrumentation.AspNetCore)] [InlineData("ASPNETCORE", MetricInstrumentation.AspNetCore)]
#endif #endif
[InlineData("SQLCLIENT", MetricInstrumentation.SqlClient)]
internal void MeterSettings_Instrumentations_SupportedValues(string meterInstrumentation, MetricInstrumentation expectedMetricInstrumentation) internal void MeterSettings_Instrumentations_SupportedValues(string meterInstrumentation, MetricInstrumentation expectedMetricInstrumentation)
{ {
Environment.SetEnvironmentVariable(ConfigurationKeys.Metrics.MetricsInstrumentationEnabled, "false"); Environment.SetEnvironmentVariable(ConfigurationKeys.Metrics.MetricsInstrumentationEnabled, "false");

View File

@ -1,6 +1,7 @@
// Copyright The OpenTelemetry Authors // Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
using System.Diagnostics;
using Microsoft.Data.SqlClient; using Microsoft.Data.SqlClient;
using TestApplication.Shared; using TestApplication.Shared;
@ -32,6 +33,19 @@ public class Program
{ {
await ExecuteAsyncCommands(connection); await ExecuteAsyncCommands(connection);
} }
// The "LONG_RUNNING" environment variable is used by tests that access/receive
// data that takes time to be produced.
var longRunning = Environment.GetEnvironmentVariable("LONG_RUNNING");
if (longRunning == "true")
{
// In this case it is necessary to ensure that the test has a chance to read the
// expected data, only by keeping the application alive for some time that can
// be ensured. Anyway, tests that set "LONG_RUNNING" env var to true are expected
// to kill the process directly.
Console.WriteLine("LONG_RUNNING is true, waiting for process to be killed...");
Process.GetCurrentProcess().WaitForExit();
}
} }
private static void ExecuteCommands(SqlConnection connection) private static void ExecuteCommands(SqlConnection connection)

View File

@ -2,6 +2,7 @@
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
using System.Data.SqlClient; using System.Data.SqlClient;
using System.Diagnostics;
using TestApplication.Shared; using TestApplication.Shared;
namespace TestApplication.SqlClient.System; namespace TestApplication.SqlClient.System;
@ -31,6 +32,19 @@ public class Program
{ {
await ExecuteAsyncCommands(connection); await ExecuteAsyncCommands(connection);
} }
// The "LONG_RUNNING" environment variable is used by tests that access/receive
// data that takes time to be produced.
var longRunning = Environment.GetEnvironmentVariable("LONG_RUNNING");
if (longRunning == "true")
{
// In this case it is necessary to ensure that the test has a chance to read the
// expected data, only by keeping the application alive for some time that can
// be ensured. Anyway, tests that set "LONG_RUNNING" env var to true are expected
// to kill the process directly.
Console.WriteLine("LONG_RUNNING is true, waiting for process to be killed...");
Process.GetCurrentProcess().WaitForExit();
}
} }
private static void ExecuteCommands(SqlConnection connection) private static void ExecuteCommands(SqlConnection connection)

View File

@ -2,6 +2,7 @@
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
using System.Data.SqlClient; using System.Data.SqlClient;
using System.Diagnostics;
using TestApplication.Shared; using TestApplication.Shared;
namespace TestApplication.SqlClient.System; namespace TestApplication.SqlClient.System;
@ -33,6 +34,19 @@ public class Program
{ {
await ExecuteAsyncCommands(connection); await ExecuteAsyncCommands(connection);
} }
// The "LONG_RUNNING" environment variable is used by tests that access/receive
// data that takes time to be produced.
var longRunning = Environment.GetEnvironmentVariable("LONG_RUNNING");
if (longRunning == "true")
{
// In this case it is necessary to ensure that the test has a chance to read the
// expected data, only by keeping the application alive for some time that can
// be ensured. Anyway, tests that set "LONG_RUNNING" env var to true are expected
// to kill the process directly.
Console.WriteLine("LONG_RUNNING is true, waiting for process to be killed...");
Process.GetCurrentProcess().WaitForExit();
}
} }
private static void ExecuteCommands(SqlConnection connection) private static void ExecuteCommands(SqlConnection connection)