diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml
index f28c7a51e3e..3127c132789 100644
--- a/.github/workflows/integration.yml
+++ b/.github/workflows/integration.yml
@@ -11,18 +11,6 @@ on:
- '**.md'
jobs:
- sql-test:
- runs-on: ubuntu-latest
- strategy:
- fail-fast: false
- matrix:
- version: [net6.0,net7.0]
- steps:
- - uses: actions/checkout@v3
-
- - name: Run sql docker-compose.integration
- run: docker-compose --file=test/OpenTelemetry.Instrumentation.SqlClient.Tests/docker-compose.yml --file=build/docker-compose.${{ matrix.version }}.yml --project-directory=. up --exit-code-from=tests --build
-
w3c-trace-context-test:
runs-on: ubuntu-latest
strategy:
diff --git a/build/Common.nonprod.props b/build/Common.nonprod.props
index fc4cb09c5a8..2f550fb8ff0 100644
--- a/build/Common.nonprod.props
+++ b/build/Common.nonprod.props
@@ -42,6 +42,7 @@
[6.0.0,)
[17.4.1]
[4.18.3,5.0)
+ 3.0.0
[6.4.0,7.0)
[1.0.0,2.0)
[6.4.0]
diff --git a/src/OpenTelemetry.Exporter.Jaeger/ApacheThrift/Protocol/TBinaryProtocol.cs b/src/OpenTelemetry.Exporter.Jaeger/ApacheThrift/Protocol/TBinaryProtocol.cs
index 820f5ee51a5..4a3454aa40f 100644
--- a/src/OpenTelemetry.Exporter.Jaeger/ApacheThrift/Protocol/TBinaryProtocol.cs
+++ b/src/OpenTelemetry.Exporter.Jaeger/ApacheThrift/Protocol/TBinaryProtocol.cs
@@ -192,7 +192,7 @@ public override void WriteDouble(double d)
WriteI64(BitConverter.DoubleToInt64Bits(d));
}
-#if NETSTANDARD2_1_OR_GREATER
+#if NETSTANDARD2_1_OR_GREATER || NET6_0_OR_GREATER
public override void WriteBinary(ReadOnlySpan bytes)
{
WriteI32(bytes.Length);
diff --git a/src/OpenTelemetry.Exporter.Jaeger/ApacheThrift/Protocol/TCompactProtocol.cs b/src/OpenTelemetry.Exporter.Jaeger/ApacheThrift/Protocol/TCompactProtocol.cs
index 29155a4eec1..75f62278d35 100644
--- a/src/OpenTelemetry.Exporter.Jaeger/ApacheThrift/Protocol/TCompactProtocol.cs
+++ b/src/OpenTelemetry.Exporter.Jaeger/ApacheThrift/Protocol/TCompactProtocol.cs
@@ -356,7 +356,7 @@ public override void WriteDouble(double d)
Transport.Write(PreAllocatedBuffer, 0, 8);
}
-#if NETSTANDARD2_1_OR_GREATER
+#if NETSTANDARD2_1_OR_GREATER || NET6_0_OR_GREATER
public override void WriteBinary(ReadOnlySpan bytes)
{
Int32ToVarInt((uint)bytes.Length, ref PreAllocatedVarInt);
diff --git a/src/OpenTelemetry.Exporter.Jaeger/ApacheThrift/Protocol/TProtocol.cs b/src/OpenTelemetry.Exporter.Jaeger/ApacheThrift/Protocol/TProtocol.cs
index fdba44886d7..ae88af98a4c 100644
--- a/src/OpenTelemetry.Exporter.Jaeger/ApacheThrift/Protocol/TProtocol.cs
+++ b/src/OpenTelemetry.Exporter.Jaeger/ApacheThrift/Protocol/TProtocol.cs
@@ -143,7 +143,7 @@ protected virtual void Dispose(bool disposing)
public virtual void WriteString(string s)
{
-#if NETSTANDARD2_1_OR_GREATER
+#if NETSTANDARD2_1_OR_GREATER || NET6_0_OR_GREATER
if (s.Length <= 128)
{
Span buffer = stackalloc byte[256];
@@ -165,7 +165,7 @@ public virtual void WriteString(string s)
}
}
-#if NETSTANDARD2_1_OR_GREATER
+#if NETSTANDARD2_1_OR_GREATER || NET6_0_OR_GREATER
public abstract void WriteBinary(ReadOnlySpan bytes);
#endif
diff --git a/src/OpenTelemetry.Exporter.Jaeger/CHANGELOG.md b/src/OpenTelemetry.Exporter.Jaeger/CHANGELOG.md
index cf675a45c3f..80d91226941 100644
--- a/src/OpenTelemetry.Exporter.Jaeger/CHANGELOG.md
+++ b/src/OpenTelemetry.Exporter.Jaeger/CHANGELOG.md
@@ -2,6 +2,9 @@
## Unreleased
+* Enabled performance optimizations for .NET 6.0+ runtimes.
+ ([#4349](https://github.com/open-telemetry/opentelemetry-dotnet/pull/4349))
+
## 1.5.0-alpha.1
Released 2023-Mar-07
diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/MetricItemExtensions.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/MetricItemExtensions.cs
index f63d95f3647..c839a771f1e 100644
--- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/MetricItemExtensions.cs
+++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/MetricItemExtensions.cs
@@ -335,6 +335,7 @@ internal static OtlpMetrics.Metric ToOtlpMetric(this Metric metric)
var exponentialHistogramData = metricPoint.GetExponentialHistogramData();
dataPoint.Scale = exponentialHistogramData.Scale;
+ dataPoint.ZeroCount = (ulong)exponentialHistogramData.ZeroCount;
dataPoint.Positive = new OtlpMetrics.ExponentialHistogramDataPoint.Types.Buckets();
dataPoint.Positive.Offset = exponentialHistogramData.PositiveBuckets.Offset;
diff --git a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpMetricsExporterTests.cs b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpMetricsExporterTests.cs
index 9b6e8f5c87f..62e3c10d6b7 100644
--- a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpMetricsExporterTests.cs
+++ b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpMetricsExporterTests.cs
@@ -383,6 +383,8 @@ public void TestCounterToOtlpMetric(string name, string description, string unit
[Theory]
[InlineData("test_counter", null, null, 123L, null, MetricReaderTemporalityPreference.Cumulative)]
[InlineData("test_counter", null, null, null, 123.45, MetricReaderTemporalityPreference.Cumulative)]
+ [InlineData("test_counter", null, null, -123L, null, MetricReaderTemporalityPreference.Cumulative)]
+ [InlineData("test_counter", null, null, null, -123.45, MetricReaderTemporalityPreference.Cumulative)]
[InlineData("test_counter", null, null, 123L, null, MetricReaderTemporalityPreference.Delta)]
[InlineData("test_counter", "description", "unit", 123L, null, MetricReaderTemporalityPreference.Cumulative)]
[InlineData("test_counter", null, null, 123L, null, MetricReaderTemporalityPreference.Delta, "key1", "value1", "key2", 123)]
@@ -472,6 +474,8 @@ public void TestUpDownCounterToOtlpMetric(string name, string description, strin
[Theory]
[InlineData("test_histogram", null, null, 123L, null, MetricReaderTemporalityPreference.Cumulative)]
[InlineData("test_histogram", null, null, null, 123.45, MetricReaderTemporalityPreference.Cumulative)]
+ [InlineData("test_histogram", null, null, -123L, null, MetricReaderTemporalityPreference.Cumulative)]
+ [InlineData("test_histogram", null, null, null, -123.45, MetricReaderTemporalityPreference.Cumulative)]
[InlineData("test_histogram", null, null, 123L, null, MetricReaderTemporalityPreference.Delta)]
[InlineData("test_histogram", "description", "unit", 123L, null, MetricReaderTemporalityPreference.Cumulative)]
[InlineData("test_histogram", null, null, 123L, null, MetricReaderTemporalityPreference.Delta, "key1", "value1", "key2", 123)]
@@ -497,11 +501,13 @@ public void TestExponentialHistogramToOtlpMetric(string name, string description
{
var histogram = meter.CreateHistogram(name, unit, description);
histogram.Record(longValue.Value, attributes);
+ histogram.Record(0, attributes);
}
else
{
var histogram = meter.CreateHistogram(name, unit, description);
histogram.Record(doubleValue.Value, attributes);
+ histogram.Record(0, attributes);
}
provider.ForceFlush();
@@ -537,23 +543,49 @@ public void TestExponentialHistogramToOtlpMetric(string name, string description
Assert.True(dataPoint.StartTimeUnixNano > 0);
Assert.True(dataPoint.TimeUnixNano > 0);
- Assert.Equal(1UL, dataPoint.Count);
+ Assert.Equal(20, dataPoint.Scale);
+ Assert.Equal(2UL, dataPoint.Count);
+ Assert.Equal(1UL, dataPoint.ZeroCount);
if (longValue.HasValue)
{
+ // Known issue: Negative measurements affect the Sum. Per the spec, they should not.
Assert.Equal((double)longValue, dataPoint.Sum);
+ if (longValue > 0)
+ {
+ Assert.True(dataPoint.Positive.Offset > 0);
+ Assert.Equal(1UL, dataPoint.Positive.BucketCounts[0]);
+ Assert.True(dataPoint.Negative.Offset == 0);
+ Assert.Empty(dataPoint.Negative.BucketCounts);
+ }
+ else
+ {
+ Assert.True(dataPoint.Negative.Offset > 0);
+ Assert.Equal(1UL, dataPoint.Negative.BucketCounts[0]);
+ Assert.True(dataPoint.Positive.Offset == 0);
+ Assert.Empty(dataPoint.Positive.BucketCounts);
+ }
}
else
{
+ // Known issue: Negative measurements affect the Sum. Per the spec, they should not.
Assert.Equal(doubleValue, dataPoint.Sum);
+ if (doubleValue > 0)
+ {
+ Assert.True(dataPoint.Positive.Offset > 0);
+ Assert.Equal(1UL, dataPoint.Positive.BucketCounts[0]);
+ Assert.True(dataPoint.Negative.Offset == 0);
+ Assert.Empty(dataPoint.Negative.BucketCounts);
+ }
+ else
+ {
+ Assert.True(dataPoint.Negative.Offset > 0);
+ Assert.Equal(1UL, dataPoint.Negative.BucketCounts[0]);
+ Assert.True(dataPoint.Positive.Offset == 0);
+ Assert.Empty(dataPoint.Positive.BucketCounts);
+ }
}
- Assert.Equal(0UL, dataPoint.ZeroCount);
- Assert.Equal(20, dataPoint.Scale);
- Assert.True(dataPoint.Positive.Offset > 0);
- Assert.Equal(1UL, dataPoint.Positive.BucketCounts[0]);
- Assert.True(dataPoint.Negative.Offset <= 0);
-
if (attributes.Length > 0)
{
OtlpTestHelpers.AssertOtlpAttributes(attributes, dataPoint.Attributes);
@@ -569,6 +601,8 @@ public void TestExponentialHistogramToOtlpMetric(string name, string description
[Theory]
[InlineData("test_histogram", null, null, 123L, null, MetricReaderTemporalityPreference.Cumulative)]
[InlineData("test_histogram", null, null, null, 123.45, MetricReaderTemporalityPreference.Cumulative)]
+ [InlineData("test_histogram", null, null, -123L, null, MetricReaderTemporalityPreference.Cumulative)]
+ [InlineData("test_histogram", null, null, null, -123.45, MetricReaderTemporalityPreference.Cumulative)]
[InlineData("test_histogram", null, null, 123L, null, MetricReaderTemporalityPreference.Delta)]
[InlineData("test_histogram", "description", "unit", 123L, null, MetricReaderTemporalityPreference.Cumulative)]
[InlineData("test_histogram", null, null, 123L, null, MetricReaderTemporalityPreference.Delta, "key1", "value1", "key2", 123)]
@@ -632,6 +666,7 @@ public void TestHistogramToOtlpMetric(string name, string description, string un
Assert.Equal(1UL, dataPoint.Count);
+ // Known issue: Negative measurements affect the Sum. Per the spec, they should not.
if (longValue.HasValue)
{
Assert.Equal((double)longValue, dataPoint.Sum);
diff --git a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/Dockerfile b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/Dockerfile
deleted file mode 100644
index 1083201dec8..00000000000
--- a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/Dockerfile
+++ /dev/null
@@ -1,22 +0,0 @@
-# Create a container for running the OpenTelemetry SQL Client integration tests.
-# This should be run from the root of the repo:
-# docker build --file test/OpenTelemetry.Instrumentation.SqlClient.Tests/Dockerfile .
-
-ARG BUILD_SDK_VERSION=7.0
-ARG TEST_SDK_VERSION=7.0
-
-FROM mcr.microsoft.com/dotnet/sdk:${BUILD_SDK_VERSION} AS build
-ARG PUBLISH_CONFIGURATION=Release
-ARG PUBLISH_FRAMEWORK=net7.0
-WORKDIR /repo
-COPY . ./
-RUN ls -la /repo
-WORKDIR "/repo/test/OpenTelemetry.Instrumentation.SqlClient.Tests"
-RUN dotnet publish "OpenTelemetry.Instrumentation.SqlClient.Tests.csproj" -c "${PUBLISH_CONFIGURATION}" -f "${PUBLISH_FRAMEWORK}" -o /drop -p:IntegrationBuild=true -p:TARGET_FRAMEWORK=${PUBLISH_FRAMEWORK}
-
-FROM mcr.microsoft.com/dotnet/sdk:${TEST_SDK_VERSION} AS final
-ADD https://github.com/ufoscout/docker-compose-wait/releases/download/2.7.3/wait /wait
-RUN chmod +x /wait
-WORKDIR /test
-COPY --from=build /drop .
-ENTRYPOINT ["dotnet", "vstest", "OpenTelemetry.Instrumentation.SqlClient.Tests.dll", "--logger:console;verbosity=detailed"]
diff --git a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/OpenTelemetry.Instrumentation.SqlClient.Tests.csproj b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/OpenTelemetry.Instrumentation.SqlClient.Tests.csproj
index 3d0c9a1acba..67a1af302c9 100644
--- a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/OpenTelemetry.Instrumentation.SqlClient.Tests.csproj
+++ b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/OpenTelemetry.Instrumentation.SqlClient.Tests.csproj
@@ -11,6 +11,7 @@
+
@@ -21,6 +22,8 @@
+
+
all
diff --git a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientIntegrationTests.cs b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientIntegrationTests.cs
new file mode 100644
index 00000000000..45f4408d61f
--- /dev/null
+++ b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientIntegrationTests.cs
@@ -0,0 +1,131 @@
+//
+// 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.
+//
+
+using System.Data;
+using System.Diagnostics;
+using System.Runtime.InteropServices;
+using DotNet.Testcontainers.Containers;
+using Microsoft.Data.SqlClient;
+using OpenTelemetry.Tests;
+using OpenTelemetry.Trace;
+using Testcontainers.MsSql;
+using Testcontainers.SqlEdge;
+using Xunit;
+
+namespace OpenTelemetry.Instrumentation.SqlClient.Tests
+{
+ public sealed class SqlClientIntegrationTests : IAsyncLifetime
+ {
+ // The Microsoft SQL Server Docker image is not compatible with ARM devices, such as Macs with Apple Silicon.
+ private readonly IContainer databaseContainer = Architecture.Arm64.Equals(RuntimeInformation.ProcessArchitecture) ? new SqlEdgeBuilder().Build() : new MsSqlBuilder().Build();
+
+ public Task InitializeAsync()
+ {
+ return this.databaseContainer.StartAsync();
+ }
+
+ public Task DisposeAsync()
+ {
+ return this.databaseContainer.DisposeAsync().AsTask();
+ }
+
+ [Trait("CategoryName", "SqlIntegrationTests")]
+ [EnabledOnDockerPlatformTheory(EnabledOnDockerPlatformTheoryAttribute.DockerPlatform.Linux)]
+ [InlineData(CommandType.Text, "select 1/1", false)]
+ [InlineData(CommandType.Text, "select 1/1", false, true)]
+ [InlineData(CommandType.Text, "select 1/0", false, false, true)]
+ [InlineData(CommandType.Text, "select 1/0", false, false, true, false, false)]
+ [InlineData(CommandType.Text, "select 1/0", false, false, true, true, false)]
+ [InlineData(CommandType.StoredProcedure, "sp_who", false)]
+ [InlineData(CommandType.StoredProcedure, "sp_who", true)]
+ public void SuccessfulCommandTest(
+ CommandType commandType,
+ string commandText,
+ bool captureStoredProcedureCommandName,
+ bool captureTextCommandContent = false,
+ bool isFailure = false,
+ bool recordException = false,
+ bool shouldEnrich = true)
+ {
+#if NETFRAMEWORK
+ // Disable things not available on netfx
+ recordException = false;
+ shouldEnrich = false;
+#endif
+
+ var sampler = new TestSampler();
+ var activities = new List();
+ using var tracerProvider = Sdk.CreateTracerProviderBuilder()
+ .SetSampler(sampler)
+ .AddInMemoryExporter(activities)
+ .AddSqlClientInstrumentation(options =>
+ {
+#if !NETFRAMEWORK
+ options.SetDbStatementForStoredProcedure = captureStoredProcedureCommandName;
+ options.SetDbStatementForText = captureTextCommandContent;
+#else
+ options.SetDbStatementForText = captureStoredProcedureCommandName || captureTextCommandContent;
+#endif
+ options.RecordException = recordException;
+ if (shouldEnrich)
+ {
+ options.Enrich = SqlClientTests.ActivityEnrichment;
+ }
+ })
+ .Build();
+
+ using SqlConnection sqlConnection = new SqlConnection(this.GetConnectionString());
+
+ sqlConnection.Open();
+
+ string dataSource = sqlConnection.DataSource;
+
+ sqlConnection.ChangeDatabase("master");
+
+ using SqlCommand sqlCommand = new SqlCommand(commandText, sqlConnection)
+ {
+ CommandType = commandType,
+ };
+
+ try
+ {
+ sqlCommand.ExecuteNonQuery();
+ }
+ catch
+ {
+ }
+
+ Assert.Single(activities);
+ var activity = activities[0];
+
+ SqlClientTests.VerifyActivityData(commandType, commandText, captureStoredProcedureCommandName, captureTextCommandContent, isFailure, recordException, shouldEnrich, dataSource, activity);
+ SqlClientTests.VerifySamplingParameters(sampler.LatestSamplingParameters);
+ }
+
+ private string GetConnectionString()
+ {
+ switch (this.databaseContainer)
+ {
+ case SqlEdgeContainer container:
+ return container.GetConnectionString();
+ case MsSqlContainer container:
+ return container.GetConnectionString();
+ default:
+ throw new InvalidOperationException($"Container type ${this.databaseContainer.GetType().Name} not supported.");
+ }
+ }
+ }
+}
diff --git a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTests.cs b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTests.cs
index b72bcbacf5a..b7124668b22 100644
--- a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTests.cs
+++ b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTests.cs
@@ -27,19 +27,8 @@ namespace OpenTelemetry.Instrumentation.SqlClient.Tests
{
public class SqlClientTests : IDisposable
{
- /*
- To run the integration tests, set the OTEL_SQLCONNECTIONSTRING machine-level environment variable to a valid Sql Server connection string.
-
- To use Docker...
- 1) Run: docker run -d --name sql2019 -e "ACCEPT_EULA=Y" -e "SA_PASSWORD=Pass@word" -p 5433:1433 mcr.microsoft.com/mssql/server:2019-latest
- 2) Set OTEL_SQLCONNECTIONSTRING as: Data Source=127.0.0.1,5433; User ID=sa; Password=Pass@word
- */
-
- private const string SqlConnectionStringEnvVarName = "OTEL_SQLCONNECTIONSTRING";
private const string TestConnectionString = "Data Source=(localdb)\\MSSQLLocalDB;Database=master";
- private static readonly string SqlConnectionString = SkipUnlessEnvVarFoundTheoryAttribute.GetEnvironmentVariable(SqlConnectionStringEnvVarName);
-
private readonly FakeSqlClientDiagnosticSource fakeSqlClientDiagnosticSource;
public SqlClientTests()
@@ -81,79 +70,6 @@ public void SqlClient_NamedOptions()
Assert.Equal(1, namedExporterOptionsConfigureOptionsInvocations);
}
- [Trait("CategoryName", "SqlIntegrationTests")]
- [SkipUnlessEnvVarFoundTheory(SqlConnectionStringEnvVarName)]
- [InlineData(CommandType.Text, "select 1/1", false)]
- [InlineData(CommandType.Text, "select 1/1", false, true)]
- [InlineData(CommandType.Text, "select 1/0", false, false, true)]
- [InlineData(CommandType.Text, "select 1/0", false, false, true, false, false)]
- [InlineData(CommandType.Text, "select 1/0", false, false, true, true, false)]
- [InlineData(CommandType.StoredProcedure, "sp_who", false)]
- [InlineData(CommandType.StoredProcedure, "sp_who", true)]
- public void SuccessfulCommandTest(
- CommandType commandType,
- string commandText,
- bool captureStoredProcedureCommandName,
- bool captureTextCommandContent = false,
- bool isFailure = false,
- bool recordException = false,
- bool shouldEnrich = true)
- {
-#if NETFRAMEWORK
- // Disable things not available on netfx
- recordException = false;
- shouldEnrich = false;
-#endif
-
- var sampler = new TestSampler();
- var activities = new List();
- using var tracerProvider = Sdk.CreateTracerProviderBuilder()
- .SetSampler(sampler)
- .AddInMemoryExporter(activities)
- .AddSqlClientInstrumentation(options =>
- {
-#if !NETFRAMEWORK
- options.SetDbStatementForStoredProcedure = captureStoredProcedureCommandName;
- options.SetDbStatementForText = captureTextCommandContent;
-#else
- options.SetDbStatementForText = captureStoredProcedureCommandName || captureTextCommandContent;
-#endif
- options.RecordException = recordException;
- if (shouldEnrich)
- {
- options.Enrich = ActivityEnrichment;
- }
- })
- .Build();
-
- using SqlConnection sqlConnection = new SqlConnection(SqlConnectionString);
-
- sqlConnection.Open();
-
- string dataSource = sqlConnection.DataSource;
-
- sqlConnection.ChangeDatabase("master");
-
- using SqlCommand sqlCommand = new SqlCommand(commandText, sqlConnection)
- {
- CommandType = commandType,
- };
-
- try
- {
- sqlCommand.ExecuteNonQuery();
- }
- catch
- {
- }
-
- Assert.Single(activities);
- var activity = activities[0];
-
- VerifyActivityData(commandType, commandText, captureStoredProcedureCommandName, captureTextCommandContent, isFailure, recordException, shouldEnrich, dataSource, activity);
- VerifySamplingParameters(sampler.LatestSamplingParameters);
- }
-
// DiagnosticListener-based instrumentation is only available on .NET Core
#if !NETFRAMEWORK
[Theory]
@@ -384,7 +300,7 @@ public void ShouldNotCollectTelemetryAndShouldNotPropagateExceptionWhenFilterThr
}
#endif
- private static void VerifyActivityData(
+ internal static void VerifyActivityData(
CommandType commandType,
string commandText,
bool captureStoredProcedureCommandName,
@@ -464,7 +380,7 @@ private static void VerifyActivityData(
Assert.Equal(dataSource, activity.GetTagValue(SemanticConventions.AttributePeerService));
}
- private static void VerifySamplingParameters(SamplingParameters samplingParameters)
+ internal static void VerifySamplingParameters(SamplingParameters samplingParameters)
{
Assert.NotNull(samplingParameters.Tags);
Assert.Contains(
@@ -473,7 +389,7 @@ private static void VerifySamplingParameters(SamplingParameters samplingParamete
&& (string)kvp.Value == SqlActivitySourceHelper.MicrosoftSqlServerDatabaseSystemName);
}
- private static void ActivityEnrichment(Activity activity, string method, object obj)
+ internal static void ActivityEnrichment(Activity activity, string method, object obj)
{
activity.SetTag("enriched", "yes");
diff --git a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/docker-compose.yml b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/docker-compose.yml
deleted file mode 100644
index 2c4b2b2763a..00000000000
--- a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/docker-compose.yml
+++ /dev/null
@@ -1,25 +0,0 @@
-# Start a sql container and then run OpenTelemetry sql integration tests.
-# This should be run from the root of the repo:
-# opentelemetry>docker-compose --file=test/OpenTelemetry.Instrumentation.SqlClient.Tests/docker-compose.yml --project-directory=. up --exit-code-from=tests --build
-version: '3.7'
-
-services:
- sql:
- image: mcr.microsoft.com/mssql/server:2019-latest
- environment:
- - ACCEPT_EULA=Y
- # Note: This password is for the ephemeral sql instance running in the container used for tests. Nothing that needs to be handled securely.
- - SA_PASSWORD=Pass@word18
- ports:
- - "1433:1433"
-
- tests:
- build:
- context: .
- dockerfile: ./test/OpenTelemetry.Instrumentation.SqlClient.Tests/Dockerfile
- entrypoint: ["bash", "-c", "/wait && dotnet vstest OpenTelemetry.Instrumentation.SqlClient.Tests.dll --TestCaseFilter:CategoryName=SqlIntegrationTests"]
- environment:
- - OTEL_SQLCONNECTIONSTRING=Data Source=sql; User ID=sa; Password=Pass@word18
- - WAIT_HOSTS=sql:1433
- depends_on:
- - sql
diff --git a/test/OpenTelemetry.Tests/Shared/EnabledOnDockerPlatformTheoryAttribute.cs b/test/OpenTelemetry.Tests/Shared/EnabledOnDockerPlatformTheoryAttribute.cs
new file mode 100644
index 00000000000..fd99e0c4499
--- /dev/null
+++ b/test/OpenTelemetry.Tests/Shared/EnabledOnDockerPlatformTheoryAttribute.cs
@@ -0,0 +1,86 @@
+//
+// 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.
+//
+
+using System.Diagnostics;
+using System.Text;
+using Xunit;
+
+namespace OpenTelemetry.Tests;
+
+///
+/// This skips tests if the required Docker engine is not available.
+///
+internal class EnabledOnDockerPlatformTheoryAttribute : TheoryAttribute
+{
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public EnabledOnDockerPlatformTheoryAttribute(DockerPlatform dockerPlatform)
+ {
+ const string executable = "docker";
+
+ var stdout = new StringBuilder();
+ var stderr = new StringBuilder();
+
+ void AppendStdout(object sender, DataReceivedEventArgs e) => stdout.Append(e.Data);
+ void AppendStderr(object sender, DataReceivedEventArgs e) => stderr.Append(e.Data);
+
+ var processStartInfo = new ProcessStartInfo();
+ processStartInfo.FileName = executable;
+ processStartInfo.Arguments = string.Join(" ", "version", "--format '{{.Server.Os}}'");
+ processStartInfo.RedirectStandardOutput = true;
+ processStartInfo.RedirectStandardError = true;
+ processStartInfo.UseShellExecute = false;
+
+ var process = new Process();
+ process.StartInfo = processStartInfo;
+ process.OutputDataReceived += AppendStdout;
+ process.ErrorDataReceived += AppendStderr;
+
+ try
+ {
+ process.Start();
+ process.BeginOutputReadLine();
+ process.BeginErrorReadLine();
+ process.WaitForExit();
+ }
+ finally
+ {
+ process.OutputDataReceived -= AppendStdout;
+ process.ErrorDataReceived -= AppendStderr;
+ }
+
+ if (0.Equals(process.ExitCode) && stdout.ToString().Contains(dockerPlatform.ToString().ToLowerInvariant()))
+ {
+ return;
+ }
+
+ this.Skip = $"The Docker {dockerPlatform} engine is not available.";
+ }
+
+ public enum DockerPlatform
+ {
+ ///
+ /// Docker Linux engine.
+ ///
+ Linux,
+
+ ///
+ /// Docker Windows engine.
+ ///
+ Windows,
+ }
+}