diff --git a/docker-compose.yml b/docker-compose.yml index bbd5fac6b772..64ffc3ddf675 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,4 +1,6 @@ services: + # Migrated Testcontainers services use the testcontainers profile so their pinned digests can be maintained + # without starting them during normal Compose workflows. # ARM64 dependencies localstack_arm64: image: localstack/localstack:4.14.0@sha256:3ebc37595918b8accb852f8048fef2aff047d465167edd655528065b07bc364a @@ -27,43 +29,19 @@ services: mysql_arm64: image: mysql/mysql-server:8.0@sha256:d6c8301b7834c5b9c2b733b10b7e630f441af7bc917c74dba379f24eeeb6a313 - environment: - - MYSQL_DATABASE=world - - MYSQL_ROOT_PASSWORD=mysqldb - - MYSQL_USER=mysqldb - - MYSQL_PASSWORD=mysqldb - ports: - - "3306" + profiles: ["testcontainers"] postgres_arm64: image: postgres:10.5-alpine@sha256:295a08ddd9efa1612c46033f0b96c3976f80f49c7ce29e05916b0af557806117 - environment: - - POSTGRES_PASSWORD=postgres - - POSTGRES_USER=postgres - - POSTGRES_DB=postgres - ports: - - "5432" + profiles: ["testcontainers"] rabbitmq_arm64: image: rabbitmq:3-management@sha256:e582c0bc7766f3342496d8485efb5a1df782b5ce3886ad017e2eaae442311f69 - command: rabbitmq-server - ports: - - "5672" - - "15672" + profiles: ["testcontainers"] servicestackredis_arm64: image: redis:4-alpine@sha256:aaf7c123077a5e45ab2328b5ef7e201b5720616efac498d55e65a7afbb96ae20 - command: redis-server --bind 0.0.0.0 - ports: - - "6379" - - sqledge_arm64: - image: mcr.microsoft.com/azure-sql-edge:latest@sha256:902628a8be89e35dfb7895ca31d602974c7bafde4d583a0d0873844feb1c42cf - ports: - - "1433" - environment: - - ACCEPT_EULA=Y - - SA_PASSWORD=Strong!Passw0rd + profiles: ["testcontainers"] cosmosdb-emulator_arm64: image: mcr.microsoft.com/cosmosdb/linux/azure-cosmos-emulator:vnext-preview@sha256:54d7bc334494c50cea867c270880671a7db080626a9732832b34c0d69342f9b0 @@ -71,24 +49,15 @@ services: stackexchangeredis_arm64: image: redis:4-alpine@sha256:aaf7c123077a5e45ab2328b5ef7e201b5720616efac498d55e65a7afbb96ae20 - hostname: stackexchangeredis_arm64 - command: redis-server --bind 0.0.0.0 - ports: - - "6379" + profiles: ["testcontainers"] stackexchangeredis_arm64-replica: image: redis:4-alpine@sha256:aaf7c123077a5e45ab2328b5ef7e201b5720616efac498d55e65a7afbb96ae20 - hostname: stackexchangeredis_arm64-replica - command: redis-server --bind 0.0.0.0 --slaveof stackexchangeredis_arm64 6379 - ports: - - "127.0.0.1:6390:6379" + profiles: ["testcontainers"] stackexchangeredis_arm64-single: image: redis:4-alpine@sha256:aaf7c123077a5e45ab2328b5ef7e201b5720616efac498d55e65a7afbb96ae20 - hostname: stackexchangeredis_arm64-single - command: redis-server --bind 0.0.0.0 - ports: - - "127.0.0.1:6391:6379" + profiles: ["testcontainers"] # Dependencies localstack: @@ -106,42 +75,23 @@ services: rabbitmq: image: rabbitmq:3-management@sha256:e582c0bc7766f3342496d8485efb5a1df782b5ce3886ad017e2eaae442311f69 - profiles: ["group1"] - command: rabbitmq-server - ports: - - "127.0.0.1:5672:5672" - - "127.0.0.1:15672:15672" + profiles: ["testcontainers"] servicestackredis: image: redis:4-alpine@sha256:aaf7c123077a5e45ab2328b5ef7e201b5720616efac498d55e65a7afbb96ae20 - profiles: ["group1"] - command: redis-server --bind 0.0.0.0 - ports: - - "127.0.0.1:6379:6379" + profiles: ["testcontainers"] stackexchangeredis: image: redis:4-alpine@sha256:aaf7c123077a5e45ab2328b5ef7e201b5720616efac498d55e65a7afbb96ae20 - profiles: ["group1"] - hostname: stackexchangeredis - command: redis-server --bind 0.0.0.0 - ports: - - "127.0.0.1:6389:6379" + profiles: ["testcontainers"] stackexchangeredis-replica: image: redis:4-alpine@sha256:aaf7c123077a5e45ab2328b5ef7e201b5720616efac498d55e65a7afbb96ae20 - profiles: ["group1"] - hostname: stackexchangeredis-replica - command: redis-server --bind 0.0.0.0 --slaveof stackexchangeredis 6379 - ports: - - "127.0.0.1:6390:6379" + profiles: ["testcontainers"] stackexchangeredis-single: image: redis:4-alpine@sha256:aaf7c123077a5e45ab2328b5ef7e201b5720616efac498d55e65a7afbb96ae20 - profiles: ["group1"] - hostname: stackexchangeredis-single - command: redis-server --bind 0.0.0.0 - ports: - - "127.0.0.1:6391:6379" + profiles: ["testcontainers"] mongo: image: mongo:5.0.31@sha256:54bcd8da3ea5eec561b68c605046c55c6b304387dc4c2bf5b3a5f5064fbb7495 @@ -151,11 +101,8 @@ services: command: mongod couchbase: - image: bentonam/couchbase-docker:community-5.0.1@sha256:847440848c80b95d82b12c8834856a14b1bfde854bd03b6acd0f9d0ac3484c63 - profiles: ["group1"] - ports: - - "8091-8094:8091-8094" - - "11210:11210" + image: couchbase:community-6.6.0@sha256:43103efdd4b562366c7a48afa977c4ad148e09c877da28a83a86b2c5ee2daa97 + profiles: ["testcontainers"] elasticsearch7: image: docker.elastic.co/elasticsearch/elasticsearch:7.14.1@sha256:2dcd2f31e246a8b13995ba24922da2edc3d88e65532ff301d0b92cb1be358af5 @@ -189,44 +136,19 @@ services: postgres: image: postgres:10.5-alpine@sha256:295a08ddd9efa1612c46033f0b96c3976f80f49c7ce29e05916b0af557806117 - profiles: ["group1"] - environment: - - POSTGRES_PASSWORD=postgres - - POSTGRES_USER=postgres - - POSTGRES_DB=postgres - ports: - - "127.0.0.1:5432:5432" + profiles: ["testcontainers"] mysql: image: mysql/mysql-server:8.0@sha256:d6c8301b7834c5b9c2b733b10b7e630f441af7bc917c74dba379f24eeeb6a313 - profiles: ["group1"] - environment: - - MYSQL_DATABASE=world - - MYSQL_ROOT_PASSWORD=mysqldb - - MYSQL_USER=mysqldb - - MYSQL_PASSWORD=mysqldb - ports: - - "127.0.0.1:3307:3306" + profiles: ["testcontainers"] mysql57: image: mysql/mysql-server:5.7@sha256:1178cdd375f758968cd834ac4057bae41307e64b7c69a9e145896e7b11f48064 - profiles: ["group1"] - environment: - - MYSQL_DATABASE=world - - MYSQL_ROOT_PASSWORD=mysqldb - - MYSQL_USER=mysqldb - - MYSQL_PASSWORD=mysqldb - ports: - - "127.0.0.1:3407:3306" + profiles: ["testcontainers"] sqlserver: image: mcr.microsoft.com/mssql/server:latest@sha256:2cd0aec4a3bfc3cf9205bed3f7922f4c6208f7c767dc62edcee308d0fd7d56d0 - profiles: ["group1"] - ports: - - "127.0.0.1:1433:1433" - environment: - - ACCEPT_EULA=Y - - SA_PASSWORD=Strong!Passw0rd + profiles: ["testcontainers"] sqledge: image: mcr.microsoft.com/azure-sql-edge:latest@sha256:902628a8be89e35dfb7895ca31d602974c7bafde4d583a0d0873844feb1c42cf @@ -291,50 +213,13 @@ services: ports: - "127.0.0.1:8585:8585" - # See https://github.com/confluentinc/cp-all-in-one/blob/6.1.1-post/cp-all-in-one/docker-compose.yml - # For original definitions kafka-zookeeper: image: confluentinc/cp-zookeeper:6.1.1@sha256:a7c0a20dce46a705300cd464e511e9c70ac55ec7e62c024867470a19ce210563 - profiles: ["group1"] - hostname: kafka-zookeeper - container_name: kafka-zookeeper - ports: - - "2181:2181" - restart: unless-stopped - environment: - ZOOKEEPER_CLIENT_PORT: 2181 - ZOOKEEPER_TICK_TIME: 2000 + profiles: ["testcontainers"] kafka-broker: image: confluentinc/cp-server:6.1.1@sha256:4a1ff92bd03e361759ba339c97b4c4b7dbb52d7cea478dda22d034261a8991e4 - profiles: ["group1"] - hostname: kafka-broker - container_name: kafka-broker - depends_on: - - kafka-zookeeper - ports: - - "9092:9092" - - "9101:9101" - restart: unless-stopped - environment: - KAFKA_BROKER_ID: 1 - KAFKA_ZOOKEEPER_CONNECT: 'kafka-zookeeper:2181' - KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT - KAFKA_AUTO_CREATE_TOPICS_ENABLE: "false" - KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka-broker:29092,PLAINTEXT_HOST://localhost:9092 - KAFKA_METRIC_REPORTERS: io.confluent.metrics.reporter.ConfluentMetricsReporter - KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1 - KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS: 0 - KAFKA_CONFLUENT_LICENSE_TOPIC_REPLICATION_FACTOR: 1 - KAFKA_CONFLUENT_BALANCER_TOPIC_REPLICATION_FACTOR: 1 - KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: 1 - KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1 - KAFKA_JMX_PORT: 9101 - KAFKA_JMX_HOSTNAME: localhost - CONFLUENT_METRICS_REPORTER_BOOTSTRAP_SERVERS: kafka-broker:29092 - CONFLUENT_METRICS_REPORTER_TOPIC_REPLICAS: 1 - CONFLUENT_METRICS_ENABLE: 'true' - CONFLUENT_SUPPORT_CUSTOMER_ID: 'anonymous' + profiles: ["testcontainers"] openldap: image: osixia/openldap:latest@sha256:3f68751292b43564a2586fc29fb7337573e2dad692b92d4e78e49ad5c22e567b @@ -436,24 +321,11 @@ services: - DiffEngine_Disabled=true - IncludeAllTestFrameworks - MONGO_HOST=mongo - - SERVICESTACK_REDIS_HOST=servicestackredis:6379 - - STACKEXCHANGE_REDIS_HOST=stackexchangeredis:6379,stackexchangeredis-replica:6379 - - STACKEXCHANGE_REDIS_SINGLE_HOST=stackexchangeredis-single:6379 - ELASTICSEARCH7_HOST=elasticsearch7:9200 - ELASTICSEARCH6_HOST=elasticsearch6:9200 - ELASTICSEARCH5_HOST=elasticsearch5:9200 - - SQLSERVER_CONNECTION_STRING=Server=sqlserver;User=sa;Password=Strong!Passw0rd;TrustServerCertificate=true - - POSTGRES_HOST=postgres - - MYSQL_HOST=mysql - - MYSQL_PORT=3306 - - MYSQL57_HOST=mysql57 - - MYSQL57_PORT=3306 - - RABBITMQ_HOST=rabbitmq - - KAFKA_BROKER_HOST=kafka-broker:29092 - AWS_SDK_HOST=localstack:4566 - ORACLE_HOST=oracle - - COUCHBASE_HOST=couchbase - - COUCHBASE_PORT=8091 - ASB_CONNECTION_STRING=Endpoint=sb://azureservicebus-emulator:5672;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=SAS_KEY_VALUE;UseDevelopmentEmulator=true; - EVENTHUBS_CONNECTION_STRING=Endpoint=sb://azure-eventhubs-emulator:5672;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=SAS_KEY_VALUE;UseDevelopmentEmulator=true; - COSMOSDB_ENDPOINT=https://cosmosdb-emulator:8081 @@ -653,22 +525,10 @@ services: image: andrewlock/wait-for-dependencies:latest@sha256:5d87561de8c019c3954298f707c1f6d7087f620a1ce36c3ec38cdfbc1ec4066e profiles: ["group1"] depends_on: - - servicestackredis - - stackexchangeredis - - stackexchangeredis-replica - - stackexchangeredis-single - - sqlserver - - postgres - - mysql - - mysql57 - - rabbitmq - - kafka-broker - - kafka-zookeeper - - couchbase - test-agent environment: - TIMEOUT_LENGTH=120 - command: servicestackredis:6379 stackexchangeredis:6379 stackexchangeredis-replica:6379 stackexchangeredis-single:6379 sqlserver:1433 postgres:5432 mysql:3306 mysql57:3306 rabbitmq:5672 kafka-broker:9092 kafka-zookeeper:2181 couchbase:11210 test-agent:8126 test-agent:4317 test-agent:4318 + command: test-agent:8126 test-agent:4317 test-agent:4318 StartDependencies.Group2: image: andrewlock/wait-for-dependencies:latest@sha256:5d87561de8c019c3954298f707c1f6d7087f620a1ce36c3ec38cdfbc1ec4066e @@ -699,6 +559,7 @@ services: command: dotnet /build/bin/Debug/_build.dll RunIntegrationTests volumes: - ./:/project + - /var/run/docker.sock:/var/run/docker.sock cap_add: - SYS_PTRACE environment: @@ -718,17 +579,9 @@ services: - DD_CLR_ENABLE_NGEN=${DD_CLR_ENABLE_NGEN:-1} - IncludeAllTestFrameworks - MONGO_HOST=mongo_arm64 - - SERVICESTACK_REDIS_HOST=servicestackredis_arm64:6379 - - STACKEXCHANGE_REDIS_HOST=stackexchangeredis_arm64:6379,stackexchangeredis_arm64-replica:6379 - - STACKEXCHANGE_REDIS_SINGLE_HOST=stackexchangeredis_arm64-single:6379 - ELASTICSEARCH7_HOST=elasticsearch7_arm64:9200 - ELASTICSEARCH6_HOST=elasticsearch7_arm64:9200 - ELASTICSEARCH5_HOST=elasticsearch7_arm64:9200 - - SQLSERVER_CONNECTION_STRING=Server=sqledge_arm64;User=sa;Password=Strong!Passw0rd;TrustServerCertificate=true - - POSTGRES_HOST=postgres_arm64 - - MYSQL_HOST=mysql_arm64 - - MYSQL_PORT=3306 - - RABBITMQ_HOST=rabbitmq_arm64 - AWS_SDK_HOST=localstack_arm64:4566 - COSMOSDB_ENDPOINT=https://cosmosdb-emulator_arm64:8081 - DD_LOGGER_DD_API_KEY @@ -760,16 +613,8 @@ services: - RANDOM_SEED - TEST_AGENT_HOST=test-agent depends_on: - - servicestackredis_arm64 - - stackexchangeredis_arm64 - - stackexchangeredis_arm64-replica - - stackexchangeredis_arm64-single - elasticsearch7_arm64 - - sqledge_arm64 - mongo_arm64 - - postgres_arm64 - - mysql_arm64 - - rabbitmq_arm64 - localstack_arm64 - test-agent - cosmosdb-emulator_arm64 @@ -777,22 +622,14 @@ services: StartDependencies.ARM64: image: andrewlock/wait-for-dependencies:latest@sha256:5d87561de8c019c3954298f707c1f6d7087f620a1ce36c3ec38cdfbc1ec4066e depends_on: - - servicestackredis_arm64 - - stackexchangeredis_arm64 - - stackexchangeredis_arm64-replica - - stackexchangeredis_arm64-single - elasticsearch7_arm64 - - sqledge_arm64 - mongo_arm64 - - postgres_arm64 - - mysql_arm64 - - rabbitmq_arm64 - localstack_arm64 - test-agent - cosmosdb-emulator_arm64 environment: - TIMEOUT_LENGTH=120 - command: servicestackredis_arm64:6379 stackexchangeredis_arm64:6379 stackexchangeredis_arm64-replica:6379 stackexchangeredis_arm64-single:6379 elasticsearch7_arm64:9200 sqledge_arm64:1433 mongo_arm64:27017 postgres_arm64:5432 mysql_arm64:3306 rabbitmq_arm64:5672 localstack_arm64:4566 test-agent:8126 test-agent:4317 test-agent:4318 cosmosdb-emulator_arm64:8081 + command: elasticsearch7_arm64:9200 mongo_arm64:27017 localstack_arm64:4566 test-agent:8126 test-agent:4317 test-agent:4318 cosmosdb-emulator_arm64:8081 IntegrationTests.ARM64.Debugger: build: @@ -865,20 +702,12 @@ services: StartDependencies.OSXARM64: image: andrewlock/wait-for-dependencies:latest@sha256:5d87561de8c019c3954298f707c1f6d7087f620a1ce36c3ec38cdfbc1ec4066e depends_on: - - servicestackredis_osx_arm64 - - stackexchangeredis_osx_arm64 - - stackexchangeredis_osx_arm64-replica - - stackexchangeredis_osx_arm64-single - elasticsearch7_osx_arm64 - - sqledge_osx_arm64 - mongo_osx_arm64 - - postgres_osx_arm64 - - mysql_osx_arm64 - - rabbitmq_osx_arm64 - localstack_osx_arm64 environment: - TIMEOUT_LENGTH=120 - command: servicestackredis_osx_arm64:6379 stackexchangeredis_osx_arm64:6379 stackexchangeredis_osx_arm64-replica:6379 stackexchangeredis_osx_arm64-single:6379 elasticsearch7_osx_arm64:9200 sqledge_osx_arm64:1433 mongo_osx_arm64:27017 postgres_osx_arm64:5432 mysql_osx_arm64:3306 rabbitmq_osx_arm64:5672 localstack_osx_arm64:4566 + command: elasticsearch7_osx_arm64:9200 mongo_osx_arm64:27017 localstack_osx_arm64:4566 # OSX ARM64 dependencies @@ -911,64 +740,31 @@ services: mysql_osx_arm64: image: mysql/mysql-server:8.0@sha256:d6c8301b7834c5b9c2b733b10b7e630f441af7bc917c74dba379f24eeeb6a313 - environment: - - MYSQL_DATABASE=world - - MYSQL_ROOT_PASSWORD=mysqldb - - MYSQL_USER=mysqldb - - MYSQL_PASSWORD=mysqldb - ports: - - "3306:3306" + profiles: ["testcontainers"] postgres_osx_arm64: image: postgres:10.5-alpine@sha256:295a08ddd9efa1612c46033f0b96c3976f80f49c7ce29e05916b0af557806117 - environment: - - POSTGRES_PASSWORD=postgres - - POSTGRES_USER=postgres - - POSTGRES_DB=postgres - ports: - - "5432:5432" + profiles: ["testcontainers"] rabbitmq_osx_arm64: image: rabbitmq:3-management@sha256:e582c0bc7766f3342496d8485efb5a1df782b5ce3886ad017e2eaae442311f69 - command: rabbitmq-server - ports: - - "5672:5672" - - "15672:15672" + profiles: ["testcontainers"] servicestackredis_osx_arm64: image: redis:4-alpine@sha256:aaf7c123077a5e45ab2328b5ef7e201b5720616efac498d55e65a7afbb96ae20 - command: redis-server --bind 0.0.0.0 - ports: - - "6379:6379" + profiles: ["testcontainers"] stackexchangeredis_osx_arm64: image: redis:4-alpine@sha256:aaf7c123077a5e45ab2328b5ef7e201b5720616efac498d55e65a7afbb96ae20 - hostname: stackexchangeredis_osx_arm64 - command: redis-server --bind 0.0.0.0 - ports: - - "6392:6379" + profiles: ["testcontainers"] stackexchangeredis_osx_arm64-replica: image: redis:4-alpine@sha256:aaf7c123077a5e45ab2328b5ef7e201b5720616efac498d55e65a7afbb96ae20 - hostname: stackexchangeredis_osx_arm64-replica - command: redis-server --bind 0.0.0.0 --slaveof stackexchangeredis_osx_arm64 6379 - ports: - - "6390:6379" + profiles: ["testcontainers"] stackexchangeredis_osx_arm64-single: image: redis:4-alpine@sha256:aaf7c123077a5e45ab2328b5ef7e201b5720616efac498d55e65a7afbb96ae20 - hostname: stackexchangeredis_osx_arm64-single - command: redis-server --bind 0.0.0.0 - ports: - - "6391:6379" - - sqledge_osx_arm64: - image: mcr.microsoft.com/azure-sql-edge:latest@sha256:902628a8be89e35dfb7895ca31d602974c7bafde4d583a0d0873844feb1c42cf - ports: - - "1433:1433" - environment: - - ACCEPT_EULA=Y - - SA_PASSWORD=Strong!Passw0rd + profiles: ["testcontainers"] # keep syncronized image version with tracer\test\Datadog.Trace.TestHelpers.AutoInstrumentation\Containers\AerospikeFixture.cs aerospike: diff --git a/tracer/build/_build/Build.Steps.cs b/tracer/build/_build/Build.Steps.cs index 32deb4539513..7e69a341e168 100644 --- a/tracer/build/_build/Build.Steps.cs +++ b/tracer/build/_build/Build.Steps.cs @@ -1867,6 +1867,7 @@ void CompileSamplesThatDependOnDatadogTrace() // Don't apply a custom filter to these tests, they should all be able to be run .When(!string.IsNullOrWhiteSpace(AddAreaFilter(Filter)), c => c.SetFilter(AddAreaFilter(Filter))) .When(TestAllPackageVersions, o => o.SetProcessEnvironmentVariable("TestAllPackageVersions", "true")) + .When(IsWin && string.IsNullOrEmpty(Environment.GetEnvironmentVariable("SQLSERVER_CONNECTION_STRING")), o => o.SetProcessEnvironmentVariable("SQLSERVER_CONNECTION_STRING", @"Server=(localdb)\MSSQLLocalDB;Integrated Security=true;Connection Timeout=60")) .When(CodeCoverageEnabled, ConfigureCodeCoverage) .CombineWith(parallelJobs, (s, project) => s .EnableTrxLogOutput(GetResultsDirectory(project)) @@ -1889,6 +1890,7 @@ void CompileSamplesThatDependOnDatadogTrace() .SetLogsDirectory(TestLogsDirectory) .When(!string.IsNullOrWhiteSpace(filter), c => c.SetFilter(filter)) .When(TestAllPackageVersions, o => o.SetProcessEnvironmentVariable("TestAllPackageVersions", "true")) + .When(IsWin && string.IsNullOrEmpty(Environment.GetEnvironmentVariable("SQLSERVER_CONNECTION_STRING")), o => o.SetProcessEnvironmentVariable("SQLSERVER_CONNECTION_STRING", @"Server=(localdb)\MSSQLLocalDB;Integrated Security=true;Connection Timeout=60")) .When(CodeCoverageEnabled, ConfigureCodeCoverage) .CombineWith(ClrProfilerIntegrationTests, (s, project) => s .EnableTrxLogOutput(GetResultsDirectory(project)) @@ -2037,6 +2039,7 @@ private string AddAreaFilter(string filter) .SetIsDebugRun(isDebugRun) .SetProcessEnvironmentVariable("MonitoringHomeDirectory", MonitoringHomeDirectory) .SetLogsDirectory(TestLogsDirectory) + .When(IsWin && string.IsNullOrEmpty(Environment.GetEnvironmentVariable("SQLSERVER_CONNECTION_STRING")), o => o.SetProcessEnvironmentVariable("SQLSERVER_CONNECTION_STRING", @"Server=(localdb)\MSSQLLocalDB;Integrated Security=true;Connection Timeout=60")) .When(CodeCoverageEnabled, ConfigureCodeCoverage) .CombineWith(ClrProfilerIntegrationTests, (s, project) => s .EnableTrxLogOutput(GetResultsDirectory(project)) diff --git a/tracer/build/_build/NukeExtensions/DotNetSettingsExtensions.cs b/tracer/build/_build/NukeExtensions/DotNetSettingsExtensions.cs index d685b370dc3c..1877d9201454 100644 --- a/tracer/build/_build/NukeExtensions/DotNetSettingsExtensions.cs +++ b/tracer/build/_build/NukeExtensions/DotNetSettingsExtensions.cs @@ -269,17 +269,9 @@ public static T SetLocalOsxEnvironmentVariables(this T toolSettings) { return toolSettings .SetProcessEnvironmentVariable("MONGO_HOST", "localhost") - .SetProcessEnvironmentVariable("SERVICESTACK_REDIS_HOST", "localhost:6379") - .SetProcessEnvironmentVariable("STACKEXCHANGE_REDIS_HOST", "localhost:6392,127.0.0.1:6390") - .SetProcessEnvironmentVariable("STACKEXCHANGE_REDIS_SINGLE_HOST", "localhost:6391") .SetProcessEnvironmentVariable("ELASTICSEARCH7_HOST", "localhost:9200") .SetProcessEnvironmentVariable("ELASTICSEARCH6_HOST", "localhost:9200") .SetProcessEnvironmentVariable("ELASTICSEARCH5_HOST", "localhost:9200") - .SetProcessEnvironmentVariable("SQLSERVER_CONNECTION_STRING", "Server=localhost;User=sa;Password=Strong!Passw0rd") - .SetProcessEnvironmentVariable("POSTGRES_HOST", "localhost") - .SetProcessEnvironmentVariable("MYSQL_HOST", "localhost") - .SetProcessEnvironmentVariable("MYSQL_PORT", "3306") - .SetProcessEnvironmentVariable("RABBITMQ_HOST", "localhost") .SetProcessEnvironmentVariable("AWS_SDK_HOST", "localhost:4566"); } diff --git a/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/AdoNet/DapperTests.cs b/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/AdoNet/DapperTests.cs index 630e7175ee4c..c9e2d9b618e4 100644 --- a/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/AdoNet/DapperTests.cs +++ b/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/AdoNet/DapperTests.cs @@ -4,7 +4,9 @@ // using System.Threading.Tasks; +using Datadog.Trace.ClrProfiler.IntegrationTests.Helpers; using Datadog.Trace.TestHelpers; +using Datadog.Trace.TestHelpers.AutoInstrumentation.Containers; using Xunit; using Xunit.Abstractions; @@ -12,12 +14,14 @@ namespace Datadog.Trace.ClrProfiler.IntegrationTests.AdoNet { [Trait("RequiresDockerDependency", "true")] [Trait("DockerGroup", "1")] + [Collection(PostgresCollection.Name)] public class DapperTests : TracingIntegrationTest { - public DapperTests(ITestOutputHelper output) + public DapperTests(ITestOutputHelper output, PostgresFixture postgresFixture) : base("Dapper", output) { SetServiceVersion("1.0.0"); + ConfigureContainers(postgresFixture); } // Assert Npgsql because the Dapper application uses Postgres for the actual client diff --git a/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/AdoNet/MicrosoftDataSqlClientTests.cs b/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/AdoNet/MicrosoftDataSqlClientTests.cs index 829f9cfd4e5a..5af05af0504c 100644 --- a/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/AdoNet/MicrosoftDataSqlClientTests.cs +++ b/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/AdoNet/MicrosoftDataSqlClientTests.cs @@ -10,6 +10,7 @@ using Datadog.Trace.ClrProfiler.IntegrationTests.Helpers; using Datadog.Trace.Configuration; using Datadog.Trace.TestHelpers; +using Datadog.Trace.TestHelpers.AutoInstrumentation.Containers; using FluentAssertions; using Xunit; using Xunit.Abstractions; @@ -18,12 +19,14 @@ namespace Datadog.Trace.ClrProfiler.IntegrationTests.AdoNet { [Trait("RequiresDockerDependency", "true")] [Trait("DockerGroup", "1")] + [Collection(SqlServerCollection.Name)] public class MicrosoftDataSqlClientTests : TracingIntegrationTest { - public MicrosoftDataSqlClientTests(ITestOutputHelper output) + public MicrosoftDataSqlClientTests(ITestOutputHelper output, SqlServerFixture sqlServerFixture) : base("Microsoft.Data.SqlClient", output) { SetServiceVersion("1.0.0"); + ConfigureContainers(sqlServerFixture); } public override Result ValidateIntegrationSpan(MockSpan span, string metadataSchemaVersion) => span.IsSqlClient(metadataSchemaVersion); diff --git a/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/AdoNet/MySqlCommandTests.cs b/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/AdoNet/MySqlCommandTests.cs index d41bbef6350c..05b7b8b2dd31 100644 --- a/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/AdoNet/MySqlCommandTests.cs +++ b/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/AdoNet/MySqlCommandTests.cs @@ -12,6 +12,7 @@ using Datadog.Trace.ClrProfiler.IntegrationTests.Helpers; using Datadog.Trace.Configuration; using Datadog.Trace.TestHelpers; +using Datadog.Trace.TestHelpers.AutoInstrumentation.Containers; using FluentAssertions; using VerifyXunit; using Xunit; @@ -22,12 +23,19 @@ namespace Datadog.Trace.ClrProfiler.IntegrationTests.AdoNet [Trait("RequiresDockerDependency", "true")] [Trait("DockerGroup", "1")] [UsesVerify] + [Collection(MySqlCollection.Name)] public class MySqlCommandTests : TracingIntegrationTest { - public MySqlCommandTests(ITestOutputHelper output) + private readonly MySql8Fixture _mySql8Fixture; + private readonly MySql57Fixture _mySql57Fixture; + + public MySqlCommandTests(ITestOutputHelper output, MySql8Fixture mySql8Fixture, MySql57Fixture mySql57Fixture) : base("MySql", output) { + _mySql8Fixture = mySql8Fixture; + _mySql57Fixture = mySql57Fixture; SetServiceVersion("1.0.0"); + ConfigureContainers(mySql8Fixture, mySql57Fixture); } public override Result ValidateIntegrationSpan(MockSpan span, string metadataSchemaVersion) => span.IsMySql(metadataSchemaVersion); @@ -121,6 +129,12 @@ private async Task SubmitsTraces(string packageVersion, string metadataSchemaVer var settings = VerifyHelper.GetSpanVerifierSettings(); settings.AddRegexScrubber(new Regex("MySql-Test-[a-zA-Z0-9]{32}"), "MySql-Test-GUID"); + settings.AddSimpleScrubber($"out.host: {_mySql8Fixture.Host}", "out.host: mysql"); + if (_mySql57Fixture.Host is { } mySql57Host) + { + settings.AddSimpleScrubber($"out.host: {mySql57Host}", "out.host: mysql"); + } + settings.AddSimpleScrubber("out.host: localhost", "out.host: mysql"); settings.AddSimpleScrubber("out.host: mysql57", "out.host: mysql"); settings.AddSimpleScrubber("out.host: mysql_arm64", "out.host: mysql"); diff --git a/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/AdoNet/MySqlConnectorTests.cs b/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/AdoNet/MySqlConnectorTests.cs index d6a65e4419a4..1eab27fa048d 100644 --- a/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/AdoNet/MySqlConnectorTests.cs +++ b/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/AdoNet/MySqlConnectorTests.cs @@ -10,6 +10,7 @@ using Datadog.Trace.ClrProfiler.IntegrationTests.Helpers; using Datadog.Trace.Configuration; using Datadog.Trace.TestHelpers; +using Datadog.Trace.TestHelpers.AutoInstrumentation.Containers; using FluentAssertions; using Xunit; using Xunit.Abstractions; @@ -18,12 +19,14 @@ namespace Datadog.Trace.ClrProfiler.IntegrationTests.AdoNet { [Trait("RequiresDockerDependency", "true")] [Trait("DockerGroup", "1")] + [Collection(MySqlConnectorCollection.Name)] public class MySqlConnectorTests : TracingIntegrationTest { - public MySqlConnectorTests(ITestOutputHelper output) + public MySqlConnectorTests(ITestOutputHelper output, MySql8Fixture mySqlFixture) : base("MySqlConnector", output) { SetServiceVersion("1.0.0"); + ConfigureContainers(mySqlFixture); } public override Result ValidateIntegrationSpan(MockSpan span, string metadataSchemaVersion) => span.IsMySql(metadataSchemaVersion); diff --git a/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/AdoNet/NpgsqlCommandTests.cs b/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/AdoNet/NpgsqlCommandTests.cs index 41685a8ccb67..52e2eaca9bc3 100644 --- a/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/AdoNet/NpgsqlCommandTests.cs +++ b/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/AdoNet/NpgsqlCommandTests.cs @@ -11,6 +11,7 @@ using Datadog.Trace.ClrProfiler.IntegrationTests.Helpers; using Datadog.Trace.Configuration; using Datadog.Trace.TestHelpers; +using Datadog.Trace.TestHelpers.AutoInstrumentation.Containers; using FluentAssertions; using VerifyXunit; using Xunit; @@ -21,12 +22,17 @@ namespace Datadog.Trace.ClrProfiler.IntegrationTests.AdoNet [Trait("RequiresDockerDependency", "true")] [Trait("DockerGroup", "1")] [UsesVerify] + [Collection(PostgresCollection.Name)] public class NpgsqlCommandTests : TracingIntegrationTest { - public NpgsqlCommandTests(ITestOutputHelper output) + private readonly PostgresFixture _postgresFixture; + + public NpgsqlCommandTests(ITestOutputHelper output, PostgresFixture postgresFixture) : base("Npgsql", output) { + _postgresFixture = postgresFixture; SetServiceVersion("1.0.0"); + ConfigureContainers(postgresFixture); } public override Result ValidateIntegrationSpan(MockSpan span, string metadataSchemaVersion) => span.IsNpgsql(metadataSchemaVersion); @@ -77,6 +83,7 @@ public async Task SubmitsTraces( var settings = VerifyHelper.GetSpanVerifierSettings(); settings.AddRegexScrubber(new Regex("Npgsql-Test-[a-zA-Z0-9]{32}"), "Npgsql-Test-GUID"); + settings.AddSimpleScrubber($"out.host: {_postgresFixture.Host}", "out.host: postgres"); settings.AddSimpleScrubber("out.host: localhost", "out.host: postgres"); settings.AddSimpleScrubber("out.host: postgres_arm64", "out.host: postgres"); diff --git a/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/AdoNet/SystemDataSqlClientTests.cs b/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/AdoNet/SystemDataSqlClientTests.cs index 2cddaa7f3a29..1282ef06b7a9 100644 --- a/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/AdoNet/SystemDataSqlClientTests.cs +++ b/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/AdoNet/SystemDataSqlClientTests.cs @@ -12,6 +12,7 @@ using Datadog.Trace.Configuration; using Datadog.Trace.ExtensionMethods; using Datadog.Trace.TestHelpers; +using Datadog.Trace.TestHelpers.AutoInstrumentation.Containers; using FluentAssertions; using VerifyXunit; using Xunit; @@ -22,12 +23,17 @@ namespace Datadog.Trace.ClrProfiler.IntegrationTests.AdoNet [Trait("RequiresDockerDependency", "true")] [Trait("DockerGroup", "1")] [UsesVerify] + [Collection(SqlServerCollection.Name)] public class SystemDataSqlClientTests : TracingIntegrationTest { - public SystemDataSqlClientTests(ITestOutputHelper output) + private readonly SqlServerFixture _sqlServerFixture; + + public SystemDataSqlClientTests(ITestOutputHelper output, SqlServerFixture sqlServerFixture) : base("SqlServer", output) { + _sqlServerFixture = sqlServerFixture; SetServiceVersion("1.0.0"); + ConfigureContainers(sqlServerFixture); } public override Result ValidateIntegrationSpan(MockSpan span, string metadataSchemaVersion) => span.IsSqlClient(metadataSchemaVersion); @@ -97,6 +103,12 @@ public async Task SubmitsTraces( builder.Append(filtered); }); + if (_sqlServerFixture.HostAndPort is { } hostAndPort) + { + settings.AddSimpleScrubber($"out.host: {hostAndPort}", "out.host: sqlserver"); + settings.AddSimpleScrubber($"peer.service: {hostAndPort}", "peer.service: sqlserver"); + } + settings.AddSimpleScrubber("out.host: localhost", "out.host: sqlserver"); settings.AddSimpleScrubber("out.host: (localdb)\\MSSQLLocalDB", "out.host: sqlserver"); settings.AddSimpleScrubber("out.host: sqledge_arm64", "out.host: sqlserver"); diff --git a/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/AerospikeTests.cs b/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/AerospikeTests.cs index 63cb6c7aa8bd..47ecbed11028 100644 --- a/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/AerospikeTests.cs +++ b/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/AerospikeTests.cs @@ -7,6 +7,7 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using Datadog.Trace.ClrProfiler.IntegrationTests.Helpers; using Datadog.Trace.Configuration; using Datadog.Trace.TestHelpers; using Datadog.Trace.TestHelpers.AutoInstrumentation.Containers; @@ -21,7 +22,8 @@ namespace Datadog.Trace.ClrProfiler.IntegrationTests [Trait("RequiresDockerDependency", "true")] [Trait("DockerGroup", "2")] [UsesVerify] - public class AerospikeTests : TracingIntegrationTest, IClassFixture + [Collection(AerospikeCollection.Name)] + public class AerospikeTests : TracingIntegrationTest { public AerospikeTests(ITestOutputHelper output, AerospikeFixture aerospikeFixture) : base("Aerospike", output) diff --git a/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/Couchbase3Tests.cs b/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/Couchbase3Tests.cs index 3834d75b17cc..b7862b1874d5 100644 --- a/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/Couchbase3Tests.cs +++ b/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/Couchbase3Tests.cs @@ -8,8 +8,10 @@ using System.Linq; using System.Text.RegularExpressions; using System.Threading.Tasks; +using Datadog.Trace.ClrProfiler.IntegrationTests.Helpers; using Datadog.Trace.Configuration; using Datadog.Trace.TestHelpers; +using Datadog.Trace.TestHelpers.AutoInstrumentation.Containers; using FluentAssertions.Execution; using VerifyXunit; using Xunit; @@ -20,12 +22,17 @@ namespace Datadog.Trace.ClrProfiler.IntegrationTests [UsesVerify] [Trait("RequiresDockerDependency", "true")] [Trait("DockerGroup", "1")] + [Collection(CouchbaseCollection.Name)] public class Couchbase3Tests : TracingIntegrationTest { - public Couchbase3Tests(ITestOutputHelper output) + private readonly CouchbaseFixture _couchbaseFixture; + + public Couchbase3Tests(ITestOutputHelper output, CouchbaseFixture couchbaseFixture) : base("Couchbase3", output) { + _couchbaseFixture = couchbaseFixture; SetServiceVersion("1.0.0"); + ConfigureContainers(couchbaseFixture); } public static IEnumerable GetEnabledConfig() @@ -74,6 +81,10 @@ public async Task SubmitTraces(string packageVersion, string metadataSchemaVersi settings.AddSimpleScrubber("db.couchbase.seed.nodes: localhost", "db.couchbase.seed.nodes: couchbase"); settings.AddSimpleScrubber("out.host: localhost", "out.host: couchbase"); settings.AddSimpleScrubber("peer.service: localhost", "peer.service: couchbase"); + settings.AddRegexScrubber(new Regex($@"db.couchbase.seed.nodes: {Regex.Escape(_couchbaseFixture.Host)}(?::[0-9]+)?"), "db.couchbase.seed.nodes: couchbase"); + settings.AddSimpleScrubber($"out.host: {_couchbaseFixture.Host}", "out.host: couchbase"); + settings.AddRegexScrubber(new Regex($@"peer.service: {Regex.Escape(_couchbaseFixture.Host)}(?::[0-9]+)?"), "peer.service: couchbase"); + settings.AddSimpleScrubber($"couchbase.operation.bucket: {_couchbaseFixture.BucketName}", "couchbase.operation.bucket: default"); // theres' a fair amount less in 3.0.7 - fewer spans, different terminology etc @@ -126,7 +137,7 @@ private static string GetVersionSuffix(string packageVersion) return "_3_4"; } - return string.Empty; + return version < new Version("3.8.0") ? string.Empty : "_3_8"; } private static Version GetPackageVersion(string packageVersion) diff --git a/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/CouchbaseTests.cs b/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/CouchbaseTests.cs index 6d4644e9699c..a35bc54853b1 100644 --- a/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/CouchbaseTests.cs +++ b/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/CouchbaseTests.cs @@ -6,9 +6,11 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using Datadog.Trace.ClrProfiler.IntegrationTests.Helpers; using Datadog.Trace.Configuration; using Datadog.Trace.ExtensionMethods; using Datadog.Trace.TestHelpers; +using Datadog.Trace.TestHelpers.AutoInstrumentation.Containers; using Xunit; using Xunit.Abstractions; @@ -16,12 +18,14 @@ namespace Datadog.Trace.ClrProfiler.IntegrationTests { [Trait("RequiresDockerDependency", "true")] [Trait("DockerGroup", "1")] + [Collection(CouchbaseCollection.Name)] public class CouchbaseTests : TracingIntegrationTest { - public CouchbaseTests(ITestOutputHelper output) + public CouchbaseTests(ITestOutputHelper output, CouchbaseFixture couchbaseFixture) : base("Couchbase", output) { SetServiceVersion("1.0.0"); + ConfigureContainers(couchbaseFixture); } public static IEnumerable GetEnabledConfig() diff --git a/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/CustomTestFramework.cs b/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/CustomTestFramework.cs index a81d67e89b12..8048439bd367 100644 --- a/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/CustomTestFramework.cs +++ b/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/CustomTestFramework.cs @@ -12,7 +12,7 @@ namespace Datadog.Trace.ClrProfiler.IntegrationTests { - public class CustomTestFramework : TestHelpers.AutoInstrumentation.DockerTestFramework + public class CustomTestFramework : TestHelpers.CustomTestFramework { public CustomTestFramework(IMessageSink messageSink) : base(messageSink, typeof(Instrumentation)) diff --git a/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/DataStreamsMonitoringKafkaTests.cs b/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/DataStreamsMonitoringKafkaTests.cs index 65204d18f733..cc9adfe20da6 100644 --- a/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/DataStreamsMonitoringKafkaTests.cs +++ b/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/DataStreamsMonitoringKafkaTests.cs @@ -7,8 +7,10 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using Datadog.Trace.ClrProfiler.IntegrationTests.Helpers; using Datadog.Trace.Configuration; using Datadog.Trace.TestHelpers; +using Datadog.Trace.TestHelpers.AutoInstrumentation.Containers; using Datadog.Trace.TestHelpers.DataStreamsMonitoring; using FluentAssertions; using FluentAssertions.Execution; @@ -19,15 +21,16 @@ namespace Datadog.Trace.ClrProfiler.IntegrationTests; [UsesVerify] -[Collection(nameof(KafkaTests.KafkaTestsCollection))] +[Collection(KafkaCollection.Name)] [Trait("RequiresDockerDependency", "true")] [Trait("DockerGroup", "1")] public class DataStreamsMonitoringKafkaTests : TestHelper { - public DataStreamsMonitoringKafkaTests(ITestOutputHelper output) + public DataStreamsMonitoringKafkaTests(ITestOutputHelper output, KafkaFixture kafkaFixture) : base("DataStreams.Kafka", output) { SetServiceVersion("1.0.0"); + ConfigureContainers(kafkaFixture); } public static IEnumerable GetKafkaTestData() diff --git a/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/DataStreamsMonitoringRabbitMQTests.cs b/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/DataStreamsMonitoringRabbitMQTests.cs index c30d7d85c92e..a7f3163578bc 100644 --- a/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/DataStreamsMonitoringRabbitMQTests.cs +++ b/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/DataStreamsMonitoringRabbitMQTests.cs @@ -7,8 +7,10 @@ using System.Collections.Immutable; using System.Linq; using System.Threading.Tasks; +using Datadog.Trace.ClrProfiler.IntegrationTests.Helpers; using Datadog.Trace.Configuration; using Datadog.Trace.TestHelpers; +using Datadog.Trace.TestHelpers.AutoInstrumentation.Containers; using Datadog.Trace.TestHelpers.DataStreamsMonitoring; using FluentAssertions; using FluentAssertions.Execution; @@ -22,12 +24,14 @@ namespace Datadog.Trace.ClrProfiler.IntegrationTests; [UsesVerify] [Trait("RequiresDockerDependency", "true")] [Trait("DockerGroup", "1")] +[Collection(RabbitMqCollection.Name)] public class DataStreamsMonitoringRabbitMQTests : TestHelper { - public DataStreamsMonitoringRabbitMQTests(ITestOutputHelper output) + public DataStreamsMonitoringRabbitMQTests(ITestOutputHelper output, RabbitMqFixture rabbitMqFixture) : base("DataStreams.RabbitMQ", output) { SetServiceVersion("1.0.0"); + ConfigureContainers(rabbitMqFixture); } [SkippableTheory] diff --git a/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/Datadog.Trace.ClrProfiler.IntegrationTests.csproj b/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/Datadog.Trace.ClrProfiler.IntegrationTests.csproj index dd3a4309eab1..0e8c9543bb64 100644 --- a/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/Datadog.Trace.ClrProfiler.IntegrationTests.csproj +++ b/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/Datadog.Trace.ClrProfiler.IntegrationTests.csproj @@ -32,7 +32,7 @@ - + diff --git a/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/Helpers/ContainersCollection.cs b/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/Helpers/ContainersCollection.cs new file mode 100644 index 000000000000..8439c89b0c65 --- /dev/null +++ b/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/Helpers/ContainersCollection.cs @@ -0,0 +1,70 @@ +// +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2017 Datadog, Inc. +// +#pragma warning disable SA1649 // File name should match first type name (this will just store all the classes) +#pragma warning disable SA1402 // File may only contain a single type (this will just store all the classes) +using Datadog.Trace.TestHelpers.AutoInstrumentation.Containers; +using Xunit; + +namespace Datadog.Trace.ClrProfiler.IntegrationTests.Helpers +{ + // Container-backed collections must set DisableParallelization = true. CustomTestFramework only auto-serializes + // collections whose display name contains the assembly namespace, which named [CollectionDefinition]s lose. + [CollectionDefinition(Name, DisableParallelization = true)] + public class AerospikeCollection : ICollectionFixture + { + public const string Name = "Aerospike"; + } + + [CollectionDefinition(Name, DisableParallelization = true)] + public class ServiceStackRedisCollection : ICollectionFixture + { + public const string Name = "ServiceStackRedis"; + } + + [CollectionDefinition(Name, DisableParallelization = true)] + public class SqlServerCollection : ICollectionFixture + { + public const string Name = "SqlServer"; + } + + [CollectionDefinition(Name, DisableParallelization = true)] + public class PostgresCollection : ICollectionFixture + { + public const string Name = "Postgres"; + } + + [CollectionDefinition(Name, DisableParallelization = true)] + public class MySqlCollection : ICollectionFixture, ICollectionFixture + { + public const string Name = "MySql"; + } + + [CollectionDefinition(Name, DisableParallelization = true)] + public class MySqlConnectorCollection : ICollectionFixture + { + public const string Name = "MySqlConnector"; + } + + [CollectionDefinition(Name, DisableParallelization = true)] + public class RabbitMqCollection : ICollectionFixture + { + public const string Name = "RabbitMq"; + } + + [CollectionDefinition(Name, DisableParallelization = true)] + public class KafkaCollection : ICollectionFixture + { + public const string Name = "Kafka"; + } + + [CollectionDefinition(Name, DisableParallelization = true)] + public class CouchbaseCollection : ICollectionFixture + { + public const string Name = "Couchbase"; + } +} + +#pragma warning restore SA1649 // File name should match first type name +#pragma warning restore SA1402 // File may only contain a single type diff --git a/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/KafkaTests.cs b/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/KafkaTests.cs index e6747c218a0f..9de624282466 100644 --- a/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/KafkaTests.cs +++ b/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/KafkaTests.cs @@ -9,8 +9,10 @@ using System.Linq; using System.Text.RegularExpressions; using System.Threading.Tasks; +using Datadog.Trace.ClrProfiler.IntegrationTests.Helpers; using Datadog.Trace.Configuration; using Datadog.Trace.TestHelpers; +using Datadog.Trace.TestHelpers.AutoInstrumentation.Containers; using FluentAssertions; using FluentAssertions.Execution; using Xunit; @@ -18,7 +20,7 @@ namespace Datadog.Trace.ClrProfiler.IntegrationTests { - [Collection(nameof(KafkaTestsCollection))] + [Collection(KafkaCollection.Name)] [Trait("RequiresDockerDependency", "true")] [Trait("DockerGroup", "1")] public class KafkaTests : TracingIntegrationTest @@ -38,10 +40,11 @@ public class KafkaTests : TracingIntegrationTest private const string ErrorProducerResourceName = "Produce Topic INVALID-TOPIC"; - public KafkaTests(ITestOutputHelper output) + public KafkaTests(ITestOutputHelper output, KafkaFixture kafkaFixture) : base("Kafka", output) { SetServiceVersion("1.0.0"); + ConfigureContainers(kafkaFixture); } public static IEnumerable GetEnabledConfig() @@ -209,10 +212,5 @@ private string GetSuccessfulResourceName(string type, string topic) { return $"{type} Topic {topic}"; } - - [CollectionDefinition(nameof(KafkaTestsCollection), DisableParallelization = true)] - public class KafkaTestsCollection - { - } } } diff --git a/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/RabbitMQTests.cs b/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/RabbitMQTests.cs index af004a62650c..342dedc41d51 100644 --- a/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/RabbitMQTests.cs +++ b/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/RabbitMQTests.cs @@ -9,9 +9,11 @@ using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; +using Datadog.Trace.ClrProfiler.IntegrationTests.Helpers; using Datadog.Trace.Configuration; using Datadog.Trace.ExtensionMethods; using Datadog.Trace.TestHelpers; +using Datadog.Trace.TestHelpers.AutoInstrumentation.Containers; using FluentAssertions.Execution; using VerifyXunit; using Xunit; @@ -22,12 +24,17 @@ namespace Datadog.Trace.ClrProfiler.IntegrationTests [UsesVerify] [Trait("RequiresDockerDependency", "true")] [Trait("DockerGroup", "1")] + [Collection(RabbitMqCollection.Name)] public class RabbitMQTests : TracingIntegrationTest { - public RabbitMQTests(ITestOutputHelper output) + private readonly RabbitMqFixture _rabbitMqFixture; + + public RabbitMQTests(ITestOutputHelper output, RabbitMqFixture rabbitMqFixture) : base("RabbitMQ", output) { + _rabbitMqFixture = rabbitMqFixture; SetServiceVersion("1.0.0"); + ConfigureContainers(rabbitMqFixture); } public static IEnumerable GetEnabledConfig() @@ -78,6 +85,8 @@ public async Task SubmitTraces(string packageVersion, string metadataSchemaVersi // We generate a new queue name for the "default" queue with each run settings.AddScrubber(QueueScrubber.ReplaceRabbitMqQueues); + settings.AddSimpleScrubber($"out.host: {_rabbitMqFixture.Host}", "out.host: rabbitmq"); + settings.AddSimpleScrubber($"peer.service: {_rabbitMqFixture.Host}", "peer.service: rabbitmq"); settings.AddSimpleScrubber("out.host: localhost", "out.host: rabbitmq"); settings.AddSimpleScrubber("out.host: rabbitmq_arm64", "out.host: rabbitmq"); settings.AddSimpleScrubber("peer.service: localhost", "peer.service: rabbitmq"); diff --git a/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/ServiceStackRedisTests.cs b/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/ServiceStackRedisTests.cs index ae359488f067..96a6d98d95d2 100644 --- a/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/ServiceStackRedisTests.cs +++ b/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/ServiceStackRedisTests.cs @@ -3,13 +3,14 @@ // This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2017 Datadog, Inc. // -using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using Datadog.Trace.ClrProfiler.IntegrationTests.Helpers; using Datadog.Trace.Configuration; using Datadog.Trace.ExtensionMethods; using Datadog.Trace.TestHelpers; +using Datadog.Trace.TestHelpers.AutoInstrumentation.Containers; using FluentAssertions; using FluentAssertions.Execution; using VerifyXunit; @@ -21,12 +22,17 @@ namespace Datadog.Trace.ClrProfiler.IntegrationTests [Trait("RequiresDockerDependency", "true")] [Trait("DockerGroup", "1")] [UsesVerify] + [Collection(ServiceStackRedisCollection.Name)] public class ServiceStackRedisTests : TracingIntegrationTest { - public ServiceStackRedisTests(ITestOutputHelper output) + private readonly ServiceStackRedisFixture _redisFixture; + + public ServiceStackRedisTests(ITestOutputHelper output, ServiceStackRedisFixture redisFixture) : base("ServiceStack.Redis", output) { + _redisFixture = redisFixture; SetServiceVersion("1.0.0"); + ConfigureContainers(redisFixture); } public static IEnumerable GetEnabledConfig() @@ -64,9 +70,9 @@ public async Task SubmitsTraces(string packageVersion, string metadataSchemaVers spans.Count.Should().Be(expectedSpans); ValidateIntegrationSpans(spans, metadataSchemaVersion, expectedServiceName: clientSpanServiceName, isExternalSpan); - var host = Environment.GetEnvironmentVariable("SERVICESTACK_REDIS_HOST") ?? "localhost:6379"; - var port = host.Substring(host.IndexOf(':') + 1); - host = host.Substring(0, host.IndexOf(':')); + var redisHost = _redisFixture.GetEnvironmentVariables().First(kvp => kvp.Key == "SERVICESTACK_REDIS_HOST").Value; + var port = redisHost.Substring(redisHost.IndexOf(':') + 1); + var host = redisHost.Substring(0, redisHost.IndexOf(':')); var settings = VerifyHelper.GetSpanVerifierSettings(); settings.UseFileName($"{nameof(ServiceStackRedisTests)}.RunServiceStack" + $".Schema{metadataSchemaVersion.ToUpper()}"); diff --git a/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/SmokeTests/ServiceBusMinimalMassTransitTest.cs b/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/SmokeTests/ServiceBusMinimalMassTransitTest.cs index f387d92dd64c..0b08d02f8c97 100644 --- a/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/SmokeTests/ServiceBusMinimalMassTransitTest.cs +++ b/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/SmokeTests/ServiceBusMinimalMassTransitTest.cs @@ -4,6 +4,8 @@ // using System.Threading.Tasks; +using Datadog.Trace.ClrProfiler.IntegrationTests.Helpers; +using Datadog.Trace.TestHelpers.AutoInstrumentation.Containers; using Xunit; using Xunit.Abstractions; @@ -11,11 +13,17 @@ namespace Datadog.Trace.ClrProfiler.IntegrationTests.SmokeTests { [Trait("RequiresDockerDependency", "true")] [Trait("DockerGroup", "2")] + [Collection(SqlServerCollection.Name)] public class ServiceBusMinimalMassTransitTest : SmokeTestBase { - public ServiceBusMinimalMassTransitTest(ITestOutputHelper output) + public ServiceBusMinimalMassTransitTest(ITestOutputHelper output, SqlServerFixture sqlServerFixture) : base(output, "ServiceBus.Minimal.MassTransit", maxTestRunSeconds: 60) { + foreach (var variable in sqlServerFixture.GetEnvironmentVariables()) + { + SetEnvironmentVariable(variable.Key, variable.Value); + } + AssumeSuccessOnTimeout = true; } diff --git a/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/SmokeTests/ServiceBusMinimalNServiceBusTest.cs b/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/SmokeTests/ServiceBusMinimalNServiceBusTest.cs index b408411db20a..b3d2f8bf5aab 100644 --- a/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/SmokeTests/ServiceBusMinimalNServiceBusTest.cs +++ b/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/SmokeTests/ServiceBusMinimalNServiceBusTest.cs @@ -4,6 +4,8 @@ // using System.Threading.Tasks; +using Datadog.Trace.ClrProfiler.IntegrationTests.Helpers; +using Datadog.Trace.TestHelpers.AutoInstrumentation.Containers; using Xunit; using Xunit.Abstractions; @@ -11,11 +13,16 @@ namespace Datadog.Trace.ClrProfiler.IntegrationTests.SmokeTests { [Trait("RequiresDockerDependency", "true")] [Trait("DockerGroup", "2")] + [Collection(SqlServerCollection.Name)] public class ServiceBusMinimalNServiceBusTest : SmokeTestBase { - public ServiceBusMinimalNServiceBusTest(ITestOutputHelper output) + public ServiceBusMinimalNServiceBusTest(ITestOutputHelper output, SqlServerFixture sqlServerFixture) : base(output, "ServiceBus.Minimal.NServiceBus", maxTestRunSeconds: 90) { + foreach (var variable in sqlServerFixture.GetEnvironmentVariables()) + { + SetEnvironmentVariable(variable.Key, variable.Value); + } } [SkippableFact] diff --git a/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/SmokeTests/ServiceBusMinimalRebusTest.cs b/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/SmokeTests/ServiceBusMinimalRebusTest.cs index 78162ec857b1..4a583134ff37 100644 --- a/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/SmokeTests/ServiceBusMinimalRebusTest.cs +++ b/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/SmokeTests/ServiceBusMinimalRebusTest.cs @@ -4,6 +4,8 @@ // using System.Threading.Tasks; +using Datadog.Trace.ClrProfiler.IntegrationTests.Helpers; +using Datadog.Trace.TestHelpers.AutoInstrumentation.Containers; using Xunit; using Xunit.Abstractions; @@ -11,11 +13,16 @@ namespace Datadog.Trace.ClrProfiler.IntegrationTests.SmokeTests { [Trait("RequiresDockerDependency", "true")] [Trait("DockerGroup", "2")] + [Collection(SqlServerCollection.Name)] public class ServiceBusMinimalRebusTest : SmokeTestBase { - public ServiceBusMinimalRebusTest(ITestOutputHelper output) + public ServiceBusMinimalRebusTest(ITestOutputHelper output, SqlServerFixture sqlServerFixture) : base(output, "ServiceBus.Minimal.Rebus", maxTestRunSeconds: 90) { + foreach (var variable in sqlServerFixture.GetEnvironmentVariables()) + { + SetEnvironmentVariable(variable.Key, variable.Value); + } } [SkippableFact] diff --git a/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/SmokeTests/StackExchangeRedisAssemblyConflictLegacyProjectSmokeTest.cs b/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/SmokeTests/StackExchangeRedisAssemblyConflictLegacyProjectSmokeTest.cs index b53b927535ce..9a37f4c79b3f 100644 --- a/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/SmokeTests/StackExchangeRedisAssemblyConflictLegacyProjectSmokeTest.cs +++ b/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/SmokeTests/StackExchangeRedisAssemblyConflictLegacyProjectSmokeTest.cs @@ -5,6 +5,7 @@ using System.Threading.Tasks; using Datadog.Trace.ClrProfiler.IntegrationTests.TestCollections; +using Datadog.Trace.TestHelpers.AutoInstrumentation.Containers; using Xunit; using Xunit.Abstractions; @@ -14,9 +15,13 @@ namespace Datadog.Trace.ClrProfiler.IntegrationTests.SmokeTests [Collection(nameof(StackExchangeRedisTestCollection))] public class StackExchangeRedisAssemblyConflictLegacyProjectSmokeTest : SmokeTestBase { - public StackExchangeRedisAssemblyConflictLegacyProjectSmokeTest(ITestOutputHelper output) + public StackExchangeRedisAssemblyConflictLegacyProjectSmokeTest(ITestOutputHelper output, StackExchangeRedisFixture redisFixture) : base(output, "StackExchange.Redis.AssemblyConflict.LegacyProject", maxTestRunSeconds: 30) { + foreach (var variable in redisFixture.GetEnvironmentVariables()) + { + SetEnvironmentVariable(variable.Key, variable.Value); + } } [Fact] diff --git a/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/SmokeTests/StackExchangeRedisAssemblyConflictSdkProjectSmokeTest.cs b/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/SmokeTests/StackExchangeRedisAssemblyConflictSdkProjectSmokeTest.cs index 4f3b534c998e..70cd6eeb5b8c 100644 --- a/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/SmokeTests/StackExchangeRedisAssemblyConflictSdkProjectSmokeTest.cs +++ b/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/SmokeTests/StackExchangeRedisAssemblyConflictSdkProjectSmokeTest.cs @@ -6,6 +6,7 @@ using System.Threading.Tasks; using Datadog.Trace.ClrProfiler.IntegrationTests.TestCollections; using Datadog.Trace.TestHelpers; +using Datadog.Trace.TestHelpers.AutoInstrumentation.Containers; using Xunit; using Xunit.Abstractions; @@ -16,21 +17,20 @@ namespace Datadog.Trace.ClrProfiler.IntegrationTests.SmokeTests [Collection(nameof(StackExchangeRedisTestCollection))] public class StackExchangeRedisAssemblyConflictSdkProjectSmokeTest : SmokeTestBase { - public StackExchangeRedisAssemblyConflictSdkProjectSmokeTest(ITestOutputHelper output) + public StackExchangeRedisAssemblyConflictSdkProjectSmokeTest(ITestOutputHelper output, StackExchangeRedisFixture redisFixture) : base(output, "StackExchange.Redis.AssemblyConflict.SdkProject", maxTestRunSeconds: 30) { + foreach (var variable in redisFixture.GetEnvironmentVariables()) + { + SetEnvironmentVariable(variable.Key, variable.Value); + } } [SkippableFact] [Trait("Category", "Smoke")] public async Task NoExceptions() { - if (EnvironmentTools.IsWindows()) - { - Output.WriteLine("Ignored for Windows"); - return; - } - + Skip.If(EnvironmentTools.IsWindows(), "Ignored for Windows"); await CheckForSmoke(shouldDeserializeTraces: false); } } diff --git a/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/SmokeTests/StackExchangeRedisStackOverflowExceptionSmokeTest.cs b/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/SmokeTests/StackExchangeRedisStackOverflowExceptionSmokeTest.cs index e2eae88258b6..f3052893c123 100644 --- a/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/SmokeTests/StackExchangeRedisStackOverflowExceptionSmokeTest.cs +++ b/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/SmokeTests/StackExchangeRedisStackOverflowExceptionSmokeTest.cs @@ -6,6 +6,7 @@ using System.Threading.Tasks; using Datadog.Trace.ClrProfiler.IntegrationTests.TestCollections; using Datadog.Trace.TestHelpers; +using Datadog.Trace.TestHelpers.AutoInstrumentation.Containers; using Xunit; using Xunit.Abstractions; @@ -16,21 +17,20 @@ namespace Datadog.Trace.ClrProfiler.IntegrationTests.SmokeTests [Collection(nameof(StackExchangeRedisTestCollection))] public class StackExchangeRedisStackOverflowExceptionSmokeTest : SmokeTestBase { - public StackExchangeRedisStackOverflowExceptionSmokeTest(ITestOutputHelper output) + public StackExchangeRedisStackOverflowExceptionSmokeTest(ITestOutputHelper output, StackExchangeRedisFixture redisFixture) : base(output, "StackExchange.Redis.StackOverflowException", maxTestRunSeconds: 30) { + foreach (var variable in redisFixture.GetEnvironmentVariables()) + { + SetEnvironmentVariable(variable.Key, variable.Value); + } } [SkippableFact] [Trait("Category", "Smoke")] public async Task NoExceptions() { - if (EnvironmentTools.IsWindows()) - { - Output.WriteLine("Ignored for Windows"); - return; - } - + Skip.If(EnvironmentTools.IsWindows(), "Ignored for Windows"); await CheckForSmoke(shouldDeserializeTraces: false); } } diff --git a/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/StackExchangeRedisTests.cs b/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/StackExchangeRedisTests.cs index b459d5d50501..8d946b6ac032 100644 --- a/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/StackExchangeRedisTests.cs +++ b/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/StackExchangeRedisTests.cs @@ -6,10 +6,12 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Text.RegularExpressions; using System.Threading.Tasks; using Datadog.Trace.ClrProfiler.IntegrationTests.TestCollections; using Datadog.Trace.Configuration; using Datadog.Trace.TestHelpers; +using Datadog.Trace.TestHelpers.AutoInstrumentation.Containers; using FluentAssertions; using FluentAssertions.Execution; using VerifyXunit; @@ -24,10 +26,14 @@ namespace Datadog.Trace.ClrProfiler.IntegrationTests [UsesVerify] public class StackExchangeRedisTests : TracingIntegrationTest { - public StackExchangeRedisTests(ITestOutputHelper output) + private readonly StackExchangeRedisFixture _redisFixture; + + public StackExchangeRedisTests(ITestOutputHelper output, StackExchangeRedisFixture redisFixture) : base("StackExchange.Redis", output) { + _redisFixture = redisFixture; SetServiceVersion("1.0.0"); + ConfigureContainers(redisFixture); } private enum PackageVersion @@ -79,30 +85,12 @@ public async Task SubmitsTraces(string packageVersion, string metadataSchemaVers var spans = await agent.WaitForSpansAsync(expectedCount); ValidateIntegrationSpans(spans, metadataSchemaVersion, expectedServiceName: clientSpanServiceName, isExternalSpan); - var host = Environment.GetEnvironmentVariable("STACKEXCHANGE_REDIS_HOST") ?? "localhost:6389"; - var port = host.Substring(host.IndexOf(':') + 1); - host = host.Substring(0, host.IndexOf(':')); - var settings = VerifyHelper.GetSpanVerifierSettings(); settings.UseFileName($"{nameof(StackExchangeRedisTests)}.{calculatedVersion}" + $".Schema{metadataSchemaVersion.ToUpper()}"); settings.DisableRequireUniquePrefix(); settings.AddSimpleScrubber($" {TestPrefix}StackExchange.Redis.", " StackExchange.Redis."); - if (EnvironmentTools.IsOsx()) - { - settings.AddSimpleScrubber("out.host: localhost", "out.host: stackexchangeredis"); - settings.AddSimpleScrubber("peer.service: localhost", "peer.service: stackexchangeredis"); - settings.AddSimpleScrubber("out.host: 127.0.0.1", "out.host: stackexchangeredis-replica"); - settings.AddSimpleScrubber("peer.service: 127.0.0.1", "peer.service: stackexchangeredis-replica"); - settings.AddSimpleScrubber("out.port: 6390", "out.port: 6379"); - settings.AddSimpleScrubber("out.port: 6391", "out.port: 6379"); - settings.AddSimpleScrubber("out.port: 6392", "out.port: 6379"); - } - else - { - settings.AddSimpleScrubber($"out.host: {host}", "out.host: stackexchangeredis"); - settings.AddSimpleScrubber($"peer.service: {host}", "peer.service: stackexchangeredis"); - settings.AddSimpleScrubber($"out.port: {port}", "out.port: 6379"); - } + AddEndpointScrubbers(settings, _redisFixture.PrimaryHost, _redisFixture.PrimaryPort, "stackexchangeredis"); + AddEndpointScrubbers(settings, _redisFixture.ReplicaHost, _redisFixture.ReplicaPort, "stackexchangeredis-replica"); await VerifyHelper.VerifySpans( spans, @@ -118,6 +106,22 @@ await VerifyHelper.VerifySpans( await telemetry.AssertIntegrationEnabledAsync(IntegrationId.StackExchangeRedis); } + private static void AddEndpointScrubbers(VerifyTests.VerifySettings settings, string host, ushort port, string normalizedHost) + { + var escapedHost = Regex.Escape(host); + var endpointWithPeerService = new Regex($@"out\.host: {escapedHost},\r?\n([ \t]+)out\.port: {port},\r?\n\1peer\.service: [^,\r\n]+,"); + var endpoint = new Regex($@"out\.host: {escapedHost},\r?\n([ \t]+)out\.port: {port},"); + settings.AddScrubber( + builder => + { + var scrubbed = endpointWithPeerService.Replace( + builder.ToString(), + $"out.host: {normalizedHost},\n out.port: 6379,\n peer.service: {normalizedHost},"); + scrubbed = endpoint.Replace(scrubbed, $"out.host: {normalizedHost},\n out.port: 6379,"); + builder.Clear().Append(scrubbed); + }); + } + private static PackageVersion GetPackageVersion(string packageVersionString) { if (string.IsNullOrEmpty(packageVersionString)) diff --git a/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/TestCollections/StackExchangeRedisTestCollection.cs b/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/TestCollections/StackExchangeRedisTestCollection.cs index 44d85212ab55..2af93c3c933c 100644 --- a/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/TestCollections/StackExchangeRedisTestCollection.cs +++ b/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/TestCollections/StackExchangeRedisTestCollection.cs @@ -3,12 +3,13 @@ // This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2017 Datadog, Inc. // +using Datadog.Trace.TestHelpers.AutoInstrumentation.Containers; using Xunit; namespace Datadog.Trace.ClrProfiler.IntegrationTests.TestCollections { [CollectionDefinition(nameof(StackExchangeRedisTestCollection), DisableParallelization = true)] - public class StackExchangeRedisTestCollection + public class StackExchangeRedisTestCollection : ICollectionFixture { } } diff --git a/tracer/test/Datadog.Trace.Security.IntegrationTests/IAST/AspNetCore5IastDbTests.cs b/tracer/test/Datadog.Trace.Security.IntegrationTests/IAST/AspNetCore5IastDbTests.cs index 9db1428b3569..aef4aa4e4916 100644 --- a/tracer/test/Datadog.Trace.Security.IntegrationTests/IAST/AspNetCore5IastDbTests.cs +++ b/tracer/test/Datadog.Trace.Security.IntegrationTests/IAST/AspNetCore5IastDbTests.cs @@ -10,17 +10,25 @@ using System.Threading.Tasks; using Datadog.Trace.Security.IntegrationTests.Iast; using Datadog.Trace.TestHelpers; +using Datadog.Trace.TestHelpers.AutoInstrumentation.Containers; using Xunit; using Xunit.Abstractions; namespace Datadog.Trace.Security.IntegrationTests.IAST; [Trait("RequiresDockerDependency", "true")] +[Collection(AspNetCore5IastDbTestsCollection.Name)] public class AspNetCore5IastDbTests : AspNetCore5IastTests { - public AspNetCore5IastDbTests(AspNetCoreTestFixture fixture, ITestOutputHelper outputHelper) + public AspNetCore5IastDbTests( + AspNetCoreTestFixture fixture, + ITestOutputHelper outputHelper, + SqlServerFixture sqlServerFixture, + PostgresFixture postgresFixture, + MySql8Fixture mySqlFixture) : base(fixture, outputHelper, enableIast: true, testName: "AspNetCore5IastDbTestsIastEnabled", samplingRate: 100, vulnerabilitiesPerRequest: 200, isIastDeduplicationEnabled: false, sampleName: "AspNetCore5") { + ConfigureContainers(sqlServerFixture, postgresFixture, mySqlFixture); } [SkippableTheory] diff --git a/tracer/test/Datadog.Trace.Security.IntegrationTests/IAST/AspNetCore5IastDbTestsCollection.cs b/tracer/test/Datadog.Trace.Security.IntegrationTests/IAST/AspNetCore5IastDbTestsCollection.cs new file mode 100644 index 000000000000..2689eeb13f23 --- /dev/null +++ b/tracer/test/Datadog.Trace.Security.IntegrationTests/IAST/AspNetCore5IastDbTestsCollection.cs @@ -0,0 +1,19 @@ +// +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2017 Datadog, Inc. +// + +#if NETCOREAPP3_0_OR_GREATER + +using Datadog.Trace.TestHelpers.AutoInstrumentation.Containers; +using Xunit; + +namespace Datadog.Trace.Security.IntegrationTests.IAST; + +[CollectionDefinition(Name, DisableParallelization = true)] +public class AspNetCore5IastDbTestsCollection : ICollectionFixture, ICollectionFixture, ICollectionFixture +{ + public const string Name = "AspNetCore5IastDbTests"; +} + +#endif diff --git a/tracer/test/Datadog.Trace.TestHelpers.AutoInstrumentation/Containers/AerospikeFixture.cs b/tracer/test/Datadog.Trace.TestHelpers.AutoInstrumentation/Containers/AerospikeFixture.cs index 2bd2819cb097..7c4112436712 100644 --- a/tracer/test/Datadog.Trace.TestHelpers.AutoInstrumentation/Containers/AerospikeFixture.cs +++ b/tracer/test/Datadog.Trace.TestHelpers.AutoInstrumentation/Containers/AerospikeFixture.cs @@ -30,24 +30,22 @@ protected override async Task InitializeResources(Action registe // pinning to a known good version because the latest version // (6.3.0.5 at time of issue) causes 'Server memory error' and flake // Keep syncronized image version with docker-compose.yml - var container = new ContainerBuilder() - .WithImage("aerospike/aerospike-server:6.2.0.6") + var container = new ContainerBuilder("aerospike/aerospike-server:6.2.0.6") .WithPortBinding(AerospikePort, true) .WithCreateParameterModifier(p => - { - p.HostConfig ??= new HostConfig(); - p.HostConfig.Ulimits = new List + { + p.HostConfig ??= new HostConfig(); + p.HostConfig.Ulimits = new List { // Aerospike requires a minimum of 15000 file descriptors, otherwise it'll fail to start // Some versions of dockerengine set a lower limit (1024) new Ulimit { Name = "nofile", Soft = 15000, Hard = 15000 } }; - }) - .WithWaitStrategy(Wait.ForUnixContainer().UntilPortIsAvailable(AerospikePort)) + }) + .WithWaitStrategy(Wait.ForUnixContainer().UntilInternalTcpPortIsAvailable(AerospikePort)) .Build(); - await container.StartAsync(); - registerResource("container", container); + await StartContainerAsync(container).ConfigureAwait(false); } } diff --git a/tracer/test/Datadog.Trace.TestHelpers.AutoInstrumentation/Containers/ContainerFixture.cs b/tracer/test/Datadog.Trace.TestHelpers.AutoInstrumentation/Containers/ContainerFixture.cs index 649251d7d202..7740130ed62c 100644 --- a/tracer/test/Datadog.Trace.TestHelpers.AutoInstrumentation/Containers/ContainerFixture.cs +++ b/tracer/test/Datadog.Trace.TestHelpers.AutoInstrumentation/Containers/ContainerFixture.cs @@ -8,35 +8,107 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Net; using System.Threading.Tasks; +using Docker.DotNet; +using DotNet.Testcontainers.Containers; +using Microsoft.Extensions.Logging; using Xunit; namespace Datadog.Trace.TestHelpers.AutoInstrumentation.Containers; public abstract class ContainerFixture : IAsyncLifetime { - private IReadOnlyDictionary? _resources; + private const int MaxContainerStartAttempts = 3; + private static readonly TimeSpan ContainerStartRetryDelay = TimeSpan.FromSeconds(10); + + private readonly Dictionary _resources = new(); + private readonly List _resourcesForDisposal = []; public async Task InitializeAsync() { - _resources = await ContainersRegistry.GetOrAdd(GetType(), InitializeResources); + try + { + await InitializeResources(RegisterResource).ConfigureAwait(false); + } + catch + { + await DisposeResourcesAsync().ConfigureAwait(false); + throw; + } } - // Do not implement, the ContainersRegistry is responsible for disposing the containers - public Task DisposeAsync() => Task.CompletedTask; + public Task DisposeAsync() => DisposeResourcesAsync(); public virtual IEnumerable> GetEnvironmentVariables() => Enumerable.Empty>(); protected abstract Task InitializeResources(Action registerResource); - protected T GetResource(string key) => (T)_resources![key]; + protected T GetResource(string key) => (T)_resources[key]; + + protected static async Task StartContainerAsync(IContainer container) + { + var attempt = 1; + while (true) + { + try + { + await container.StartAsync().ConfigureAwait(false); + return; + } + catch (DockerApiException exception) when (attempt < MaxContainerStartAttempts && IsTransientSystemdCgroupFailure(exception)) + { + container.Logger.LogWarning( + "Docker failed to start container {ContainerId} because its systemd cgroup request was interrupted. Retrying in {RetryDelaySeconds} seconds (attempt {NextAttempt}/{MaxAttempts}).", + container.Id, + ContainerStartRetryDelay.TotalSeconds, + attempt + 1, + MaxContainerStartAttempts); + + attempt++; + await Task.Delay(ContainerStartRetryDelay).ConfigureAwait(false); + } + } + } + + private static bool IsTransientSystemdCgroupFailure(DockerApiException exception) + { + var responseBody = exception.ResponseBody; + return exception.StatusCode == HttpStatusCode.InternalServerError + && responseBody is not null + && responseBody.IndexOf("unable to apply cgroup configuration", StringComparison.Ordinal) >= 0 + && responseBody.IndexOf("Message recipient disconnected from message bus without replying", StringComparison.Ordinal) >= 0; + } - private async Task> InitializeResources() + private void RegisterResource(string key, object resource) { - var resources = new Dictionary(); + _resources.Add(key, resource); + _resourcesForDisposal.Add(resource); + } - await InitializeResources(resources.Add).ConfigureAwait(false); + private async Task DisposeResourcesAsync() + { + for (var i = _resourcesForDisposal.Count - 1; i >= 0; i--) + { + try + { + var resource = _resourcesForDisposal[i]; + if (resource is IAsyncDisposable asyncDisposable) + { + await asyncDisposable.DisposeAsync().ConfigureAwait(false); + } + else if (resource is IDisposable disposable) + { + disposable.Dispose(); + } + } + catch + { + // Continue disposing the remaining resources. + } + } - return resources; + _resources.Clear(); + _resourcesForDisposal.Clear(); } } diff --git a/tracer/test/Datadog.Trace.TestHelpers.AutoInstrumentation/Containers/ContainersRegistry.cs b/tracer/test/Datadog.Trace.TestHelpers.AutoInstrumentation/Containers/ContainersRegistry.cs deleted file mode 100644 index 7c7d6f85e530..000000000000 --- a/tracer/test/Datadog.Trace.TestHelpers.AutoInstrumentation/Containers/ContainersRegistry.cs +++ /dev/null @@ -1,72 +0,0 @@ -// -// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2 License. -// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2017 Datadog, Inc. -// - -#nullable enable - -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Threading.Tasks; - -namespace Datadog.Trace.TestHelpers.AutoInstrumentation.Containers; - -public static class ContainersRegistry -{ - private static readonly ConcurrentDictionary>> Resources = new(); - - public static async Task> GetOrAdd(Type type, Func>> createResources) - { - if (!Resources.TryGetValue(type, out var task)) - { - var tcs = new TaskCompletionSource>(TaskCreationOptions.RunContinuationsAsynchronously); - - task = Resources.GetOrAdd(type, tcs.Task); - - if (task == tcs.Task) - { - try - { - var resources = await createResources().ConfigureAwait(false); - tcs.SetResult(resources); - } - catch (Exception ex) - { - tcs.SetException(ex); - } - } - } - - return await task.ConfigureAwait(false); - } - - public static async Task DisposeAll() - { - foreach (var resourceGroup in Resources.Values) - { - try - { - var resources = await resourceGroup.ConfigureAwait(false); - - foreach (var resource in resources.Values) - { - if (resource is IAsyncDisposable asyncDisposable) - { - await asyncDisposable.DisposeAsync().ConfigureAwait(false); - } - else if (resource is IDisposable disposable) - { - disposable.Dispose(); - } - } - } - catch - { - // Exceptions are expected here, if the container failed to initialize - } - } - - Resources.Clear(); - } -} diff --git a/tracer/test/Datadog.Trace.TestHelpers.AutoInstrumentation/Containers/CouchbaseFixture.cs b/tracer/test/Datadog.Trace.TestHelpers.AutoInstrumentation/Containers/CouchbaseFixture.cs new file mode 100644 index 000000000000..4544f96baa4c --- /dev/null +++ b/tracer/test/Datadog.Trace.TestHelpers.AutoInstrumentation/Containers/CouchbaseFixture.cs @@ -0,0 +1,233 @@ +// +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2017 Datadog, Inc. +// + +#nullable enable + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Net.Http; +using System.Net.Http.Headers; +using System.Net.NetworkInformation; +using System.Net.Sockets; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; +using Docker.DotNet.Models; +using DotNet.Testcontainers.Builders; +using DotNet.Testcontainers.Containers; + +namespace Datadog.Trace.TestHelpers.AutoInstrumentation.Containers; + +public class CouchbaseFixture : ContainerFixture +{ + private const ushort ManagementPort = 8091; + private const ushort ManagementSslPort = 18091; + private const ushort ViewPort = 8092; + private const ushort ViewSslPort = 18092; + private const ushort QueryPort = 8093; + private const ushort QuerySslPort = 18093; + private const ushort KeyValuePort = 11210; + private const ushort KeyValueSslPort = 11207; + private const string Image = "couchbase:community-6.6.0@sha256:43103efdd4b562366c7a48afa977c4ad148e09c877da28a83a86b2c5ee2daa97"; + private const string AdministratorUsername = "Administrator"; + private const string Username = "default"; + private const string Password = "password"; + + private string? _host; + private ushort _managementPort; + private ushort _keyValuePort; + + public string Host => _host!; + + public string BucketName => "default"; + + public override IEnumerable> GetEnvironmentVariables() + { + yield return new("COUCHBASE_HOST", Host); + yield return new("COUCHBASE_PORT", _managementPort.ToString()); + yield return new("COUCHBASE_CONNECTION_STRING", $"{Host}:{_keyValuePort}"); + yield return new("COUCHBASE_USERNAME", Username); + yield return new("COUCHBASE_PASSWORD", Password); + yield return new("COUCHBASE_BUCKET", BucketName); + } + + protected override async Task InitializeResources(Action registerResource) + { + // When these tests run in the outer Compose container, Testcontainers reaches published ports through the + // Docker host. Couchbase also binds its configured node hostname, so it must share the host network in that + // scenario. Otherwise, trying to configure the Docker host address as the node hostname fails with eaddrnotavail. + var useHostNetwork = RuntimeInformation.IsOSPlatform(OSPlatform.Linux) + && !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("CONTAINER_HOSTNAME")); + var dockerHost = useHostNetwork ? GetDockerHost() : null; + var builder = new ContainerBuilder(Image) + .WithWaitStrategy(Wait.ForUnixContainer().UntilInternalTcpPortIsAvailable(ManagementPort)); + + if (useHostNetwork) + { + builder = builder.WithCreateParameterModifier(p => + { + p.HostConfig ??= new HostConfig(); + p.HostConfig.NetworkMode = "host"; + }); + } + else + { + // SDK 2.4 predates Couchbase's external-network selection, so it requires the advertised standard ports. + builder = builder.WithPortBinding(ManagementPort, false) + .WithPortBinding(ManagementSslPort, false) + .WithPortBinding(ViewPort, false) + .WithPortBinding(ViewSslPort, false) + .WithPortBinding(QueryPort, false) + .WithPortBinding(QuerySslPort, false) + .WithPortBinding(KeyValuePort, false) + .WithPortBinding(KeyValueSslPort, false); + } + + var container = builder.Build(); + + registerResource("container", container); + await StartContainerAsync(container).ConfigureAwait(false); + var host = dockerHost ?? container.Hostname; + var managementPort = useHostNetwork ? ManagementPort : container.GetMappedPublicPort(ManagementPort); + var keyValuePort = useHostNetwork ? KeyValuePort : container.GetMappedPublicPort(KeyValuePort); + + await ConfigureCouchbaseAsync(container, host, useHostNetwork).ConfigureAwait(false); + + _host = host; + _managementPort = managementPort; + _keyValuePort = keyValuePort; + } + + private static string GetDockerHost() + => NetworkInterface.GetAllNetworkInterfaces() + .SelectMany(networkInterface => networkInterface.GetIPProperties().GatewayAddresses) + .Select(gateway => gateway.Address) + .FirstOrDefault(address => address.AddressFamily == AddressFamily.InterNetwork + && !IPAddress.IsLoopback(address))?.ToString() + ?? throw new InvalidOperationException("Unable to determine the Docker host from the container's default gateway."); + + private static async Task ConfigureCouchbaseAsync(IContainer container, string host, bool useHostNetwork) + { + var managementPort = useHostNetwork ? ManagementPort : container.GetMappedPublicPort(ManagementPort); + var managementSslPort = useHostNetwork ? ManagementSslPort : container.GetMappedPublicPort(ManagementSslPort); + var viewPort = useHostNetwork ? ViewPort : container.GetMappedPublicPort(ViewPort); + var viewSslPort = useHostNetwork ? ViewSslPort : container.GetMappedPublicPort(ViewSslPort); + var queryPort = useHostNetwork ? QueryPort : container.GetMappedPublicPort(QueryPort); + var querySslPort = useHostNetwork ? QuerySslPort : container.GetMappedPublicPort(QuerySslPort); + var keyValuePort = useHostNetwork ? KeyValuePort : container.GetMappedPublicPort(KeyValuePort); + var keyValueSslPort = useHostNetwork ? KeyValueSslPort : container.GetMappedPublicPort(KeyValueSslPort); + + using var client = new HttpClient + { + BaseAddress = new UriBuilder(Uri.UriSchemeHttp, host, managementPort).Uri, + Timeout = TimeSpan.FromSeconds(5), + }; + + await WaitForSuccessAsync(client, "/pools").ConfigureAwait(false); + await PostFormAsync(client, "/node/controller/rename", new() { ["hostname"] = host }).ConfigureAwait(false); + await PostFormAsync(client, "/node/controller/setupServices", new() { ["services"] = "kv,index,n1ql" }).ConfigureAwait(false); + await PostFormAsync(client, "/pools/default", new() { ["memoryQuota"] = "256", ["indexMemoryQuota"] = "256" }).ConfigureAwait(false); + await PutFormAsync( + client, + "/node/controller/setupAlternateAddresses/external", + new() + { + ["hostname"] = host, + ["mgmt"] = managementPort.ToString(), + ["mgmtSSL"] = managementSslPort.ToString(), + ["kv"] = keyValuePort.ToString(), + ["kvSSL"] = keyValueSslPort.ToString(), + ["capi"] = viewPort.ToString(), + ["capiSSL"] = viewSslPort.ToString(), + ["n1ql"] = queryPort.ToString(), + ["n1qlSSL"] = querySslPort.ToString(), + }).ConfigureAwait(false); + await PostFormAsync( + client, + "/pools/default/buckets", + new() { ["name"] = "default", ["ramQuotaMB"] = "100", ["replicaNumber"] = "0" }).ConfigureAwait(false); + await PostFormAsync( + client, + "/settings/web", + new() { ["username"] = AdministratorUsername, ["password"] = Password, ["port"] = "SAME" }).ConfigureAwait(false); + + var credentials = Convert.ToBase64String(Encoding.ASCII.GetBytes($"{AdministratorUsername}:{Password}")); + client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", credentials); + await PutFormAsync( + client, + $"/settings/rbac/users/local/{Username}", + new() { ["name"] = Username, ["password"] = Password, ["roles"] = "admin" }).ConfigureAwait(false); + await WaitForSuccessAsync( + client, + "/pools/default/buckets/default", + content => content.IndexOf(@"""status"":""healthy""", StringComparison.OrdinalIgnoreCase) >= 0).ConfigureAwait(false); + + using var queryClient = new HttpClient + { + BaseAddress = new UriBuilder(Uri.UriSchemeHttp, host, queryPort).Uri, + Timeout = TimeSpan.FromSeconds(5), + }; + queryClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", credentials); + await WaitForSuccessAsync(queryClient, "/admin/ping").ConfigureAwait(false); + await WaitForSuccessAsync( + client, + "/pools/default/nodeServices", + content => content.IndexOf(@"""n1ql"":8093", StringComparison.OrdinalIgnoreCase) >= 0).ConfigureAwait(false); + } + + private static Task PostFormAsync(HttpClient client, string path, Dictionary form) + => SendFormAsync(client, HttpMethod.Post, path, form); + + private static Task PutFormAsync(HttpClient client, string path, Dictionary form) + => SendFormAsync(client, HttpMethod.Put, path, form); + + private static async Task SendFormAsync(HttpClient client, HttpMethod method, string path, Dictionary form) + { + using var request = new HttpRequestMessage(method, path) + { + Content = new FormUrlEncodedContent(form.Select(static pair => new KeyValuePair(pair.Key, pair.Value))), + }; + using var response = await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false); + + if (!response.IsSuccessStatusCode) + { + var content = await response.Content.ReadAsStringAsync().ConfigureAwait(false); + throw new InvalidOperationException($"Couchbase request '{path}' failed with status {(int)response.StatusCode}: {content}"); + } + } + + private static async Task WaitForSuccessAsync(HttpClient client, string path, Func? responsePredicate = null) + { + var timeout = DateTime.UtcNow.AddMinutes(2); + + while (DateTime.UtcNow < timeout) + { + try + { + using var response = await client.GetAsync(path).ConfigureAwait(false); + if (response.IsSuccessStatusCode) + { + var content = await response.Content.ReadAsStringAsync().ConfigureAwait(false); + if (responsePredicate is null || responsePredicate(content)) + { + return; + } + } + } + catch (HttpRequestException) + { + } + catch (TaskCanceledException) + { + } + + await Task.Delay(TimeSpan.FromSeconds(1)).ConfigureAwait(false); + } + + throw new TimeoutException($"Couchbase endpoint '{path}' did not become ready."); + } +} diff --git a/tracer/test/Datadog.Trace.TestHelpers.AutoInstrumentation/Containers/KafkaFixture.cs b/tracer/test/Datadog.Trace.TestHelpers.AutoInstrumentation/Containers/KafkaFixture.cs new file mode 100644 index 000000000000..6e30c6cce5d1 --- /dev/null +++ b/tracer/test/Datadog.Trace.TestHelpers.AutoInstrumentation/Containers/KafkaFixture.cs @@ -0,0 +1,55 @@ +// +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2017 Datadog, Inc. +// + +#nullable enable + +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using DotNet.Testcontainers.Builders; +using DotNet.Testcontainers.Containers; +using Testcontainers.Kafka; + +namespace Datadog.Trace.TestHelpers.AutoInstrumentation.Containers; + +public class KafkaFixture : ContainerFixture +{ + private const int ZooKeeperPort = 2181; + private const string ZooKeeperAlias = "kafka-zookeeper"; + private const string ZooKeeperImage = "confluentinc/cp-zookeeper:6.1.1@sha256:a7c0a20dce46a705300cd464e511e9c70ac55ec7e62c024867470a19ce210563"; + private const string KafkaImage = "confluentinc/cp-server:6.1.1@sha256:4a1ff92bd03e361759ba339c97b4c4b7dbb52d7cea478dda22d034261a8991e4"; + + private KafkaContainer KafkaContainer => GetResource("container"); + + public override IEnumerable> GetEnvironmentVariables() + { + yield return new("KAFKA_BROKER_HOST", KafkaContainer.GetBootstrapAddress()); + } + + protected override async Task InitializeResources(Action registerResource) + { + var network = new NetworkBuilder().Build(); + var zooKeeperContainer = new ContainerBuilder(ZooKeeperImage) + .WithNetwork(network) + .WithNetworkAliases(ZooKeeperAlias) + .WithEnvironment("ZOOKEEPER_CLIENT_PORT", ZooKeeperPort.ToString()) + .WithEnvironment("ZOOKEEPER_TICK_TIME", "2000") + .WithWaitStrategy(Wait.ForUnixContainer().UntilInternalTcpPortIsAvailable(ZooKeeperPort)) + .Build(); + var kafkaContainer = new KafkaBuilder(KafkaImage) + .WithNetwork(network) + .WithZooKeeper($"{ZooKeeperAlias}:{ZooKeeperPort}") + .WithPortBinding(KafkaBuilder.ZooKeeperPort, true) + .WithEnvironment("KAFKA_AUTO_CREATE_TOPICS_ENABLE", "false") + .Build(); + + registerResource("network", network); + registerResource("zookeeper", zooKeeperContainer); + registerResource("container", kafkaContainer); + await network.CreateAsync().ConfigureAwait(false); + await StartContainerAsync(zooKeeperContainer).ConfigureAwait(false); + await StartContainerAsync(kafkaContainer).ConfigureAwait(false); + } +} diff --git a/tracer/test/Datadog.Trace.TestHelpers.AutoInstrumentation/Containers/MySql57Fixture.cs b/tracer/test/Datadog.Trace.TestHelpers.AutoInstrumentation/Containers/MySql57Fixture.cs new file mode 100644 index 000000000000..3863f6ae8b75 --- /dev/null +++ b/tracer/test/Datadog.Trace.TestHelpers.AutoInstrumentation/Containers/MySql57Fixture.cs @@ -0,0 +1,67 @@ +// +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2017 Datadog, Inc. +// + +#nullable enable + +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using System.Threading.Tasks; +using DotNet.Testcontainers.Builders; +using DotNet.Testcontainers.Containers; + +namespace Datadog.Trace.TestHelpers.AutoInstrumentation.Containers; + +public class MySql57Fixture : ContainerFixture +{ + private const int MySqlPort = 3306; + private const string Username = "mysqldb"; + private const string Password = "mysqldb"; + private const string Database = "world"; + private const string Image = "mysql/mysql-server:5.7@sha256:1178cdd375f758968cd834ac4057bae41307e64b7c69a9e145896e7b11f48064"; + + private IContainer? _container; + + public string? Host => _container?.Hostname; + + public ushort? Port => _container?.GetMappedPublicPort(MySqlPort); + + public override IEnumerable> GetEnvironmentVariables() + { + if (Host is { } host && Port is { } port) + { + yield return new("MYSQL57_HOST", host); + yield return new("MYSQL57_PORT", port.ToString()); + } + } + + protected override async Task InitializeResources(Action registerResource) + { + // The old MySql.Data tests are marked ArmUnsupported, but their collection also contains MySQL 8 tests. + if (RuntimeInformation.ProcessArchitecture == Architecture.Arm64) + { + return; + } + + var container = new ContainerBuilder(Image) + .WithPortBinding(MySqlPort, true) + .WithEnvironment("MYSQL_DATABASE", Database) + .WithEnvironment("MYSQL_ROOT_PASSWORD", Password) + .WithEnvironment("MYSQL_USER", Username) + .WithEnvironment("MYSQL_PASSWORD", Password) + .WithWaitStrategy( + Wait.ForUnixContainer() + // mysqladmin can reach the temporary server used by the image's initialization script. + // Wait for that phase to finish before probing the final server. + .UntilMessageIsLogged("MySQL init process done. Ready for start up.") + .UntilCommandIsCompleted("mysqladmin", "ping", "--silent", "-h", "localhost", "-u", "root", $"-p{Password}")) + .Build(); + + registerResource("container", container); + await StartContainerAsync(container).ConfigureAwait(false); + + _container = container; + } +} diff --git a/tracer/test/Datadog.Trace.TestHelpers.AutoInstrumentation/Containers/MySql8Fixture.cs b/tracer/test/Datadog.Trace.TestHelpers.AutoInstrumentation/Containers/MySql8Fixture.cs new file mode 100644 index 000000000000..8b5a0e4aebaf --- /dev/null +++ b/tracer/test/Datadog.Trace.TestHelpers.AutoInstrumentation/Containers/MySql8Fixture.cs @@ -0,0 +1,55 @@ +// +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2017 Datadog, Inc. +// + +#nullable enable + +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using DotNet.Testcontainers.Builders; +using DotNet.Testcontainers.Containers; + +namespace Datadog.Trace.TestHelpers.AutoInstrumentation.Containers; + +public class MySql8Fixture : ContainerFixture +{ + private const int MySqlPort = 3306; + private const string Username = "mysqldb"; + private const string Password = "mysqldb"; + private const string Database = "world"; + private const string Image = "mysql/mysql-server:8.0@sha256:d6c8301b7834c5b9c2b733b10b7e630f441af7bc917c74dba379f24eeeb6a313"; + + public string Host => Container.Hostname; + + public ushort Port => Container.GetMappedPublicPort(MySqlPort); + + private IContainer Container => GetResource("container"); + + public override IEnumerable> GetEnvironmentVariables() + { + yield return new("MYSQL_HOST", Host); + yield return new("MYSQL_PORT", Port.ToString()); + } + + protected override async Task InitializeResources(Action registerResource) + { + var container = new ContainerBuilder(Image) + .WithPortBinding(MySqlPort, true) + .WithEnvironment("MYSQL_DATABASE", Database) + .WithEnvironment("MYSQL_ROOT_PASSWORD", Password) + .WithEnvironment("MYSQL_USER", Username) + .WithEnvironment("MYSQL_PASSWORD", Password) + .WithWaitStrategy( + Wait.ForUnixContainer() + // mysqladmin can reach the temporary server used by the image's initialization script. + // Wait for that phase to finish before probing the final server. + .UntilMessageIsLogged("MySQL init process done. Ready for start up.") + .UntilCommandIsCompleted("mysqladmin", "ping", "--silent", "-h", "localhost", "-u", "root", $"-p{Password}")) + .Build(); + + registerResource("container", container); + await StartContainerAsync(container).ConfigureAwait(false); + } +} diff --git a/tracer/test/Datadog.Trace.TestHelpers.AutoInstrumentation/Containers/PostgresFixture.cs b/tracer/test/Datadog.Trace.TestHelpers.AutoInstrumentation/Containers/PostgresFixture.cs new file mode 100644 index 000000000000..a9d68fab4388 --- /dev/null +++ b/tracer/test/Datadog.Trace.TestHelpers.AutoInstrumentation/Containers/PostgresFixture.cs @@ -0,0 +1,48 @@ +// +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2017 Datadog, Inc. +// + +#nullable enable + +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using DotNet.Testcontainers.Builders; +using DotNet.Testcontainers.Containers; + +namespace Datadog.Trace.TestHelpers.AutoInstrumentation.Containers; + +public class PostgresFixture : ContainerFixture +{ + private const int PostgresPort = 5432; + private const string Username = "postgres"; + private const string Password = "postgres"; + private const string Database = "postgres"; + private const string Image = "postgres:10.5-alpine@sha256:295a08ddd9efa1612c46033f0b96c3976f80f49c7ce29e05916b0af557806117"; + + public string Host => Container.Hostname; + + public ushort Port => Container.GetMappedPublicPort(PostgresPort); + + private IContainer Container => GetResource("container"); + + public override IEnumerable> GetEnvironmentVariables() + { + yield return new("POSTGRES_CONNECTION_STRING", $"Host={Host};Port={Port};Username={Username};Password={Password};Database={Database}"); + } + + protected override async Task InitializeResources(Action registerResource) + { + var container = new ContainerBuilder(Image) + .WithPortBinding(PostgresPort, true) + .WithEnvironment("POSTGRES_USER", Username) + .WithEnvironment("POSTGRES_PASSWORD", Password) + .WithEnvironment("POSTGRES_DB", Database) + .WithWaitStrategy(Wait.ForUnixContainer().UntilCommandIsCompleted("pg_isready", "-h", "localhost", "-U", Username)) + .Build(); + + registerResource("container", container); + await StartContainerAsync(container).ConfigureAwait(false); + } +} diff --git a/tracer/test/Datadog.Trace.TestHelpers.AutoInstrumentation/Containers/RabbitMqFixture.cs b/tracer/test/Datadog.Trace.TestHelpers.AutoInstrumentation/Containers/RabbitMqFixture.cs new file mode 100644 index 000000000000..857e0fbc8373 --- /dev/null +++ b/tracer/test/Datadog.Trace.TestHelpers.AutoInstrumentation/Containers/RabbitMqFixture.cs @@ -0,0 +1,45 @@ +// +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2017 Datadog, Inc. +// + +#nullable enable + +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using DotNet.Testcontainers.Containers; +using Testcontainers.RabbitMq; + +namespace Datadog.Trace.TestHelpers.AutoInstrumentation.Containers; + +public class RabbitMqFixture : ContainerFixture +{ + private const string Image = "rabbitmq:3-management@sha256:e582c0bc7766f3342496d8485efb5a1df782b5ce3886ad017e2eaae442311f69"; + private const string Username = "guest"; + private const string Password = "guest"; + + public string Host => Container.Hostname; + + public ushort Port => Container.GetMappedPublicPort(RabbitMqBuilder.RabbitMqPort); + + private IContainer Container => GetResource("container"); + + public override IEnumerable> GetEnvironmentVariables() + { + yield return new("RABBITMQ_HOST", Host); + yield return new("RABBITMQ_PORT", Port.ToString()); + } + + protected override async Task InitializeResources(Action registerResource) + { + // Preserve the RabbitMQ.Client default credentials used by the samples. + var container = new RabbitMqBuilder(Image) + .WithUsername(Username) + .WithPassword(Password) + .Build(); + + registerResource("container", container); + await StartContainerAsync(container).ConfigureAwait(false); + } +} diff --git a/tracer/test/Datadog.Trace.TestHelpers.AutoInstrumentation/Containers/ServiceStackRedisFixture.cs b/tracer/test/Datadog.Trace.TestHelpers.AutoInstrumentation/Containers/ServiceStackRedisFixture.cs new file mode 100644 index 000000000000..679f21e63959 --- /dev/null +++ b/tracer/test/Datadog.Trace.TestHelpers.AutoInstrumentation/Containers/ServiceStackRedisFixture.cs @@ -0,0 +1,52 @@ +// +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2017 Datadog, Inc. +// + +#nullable enable + +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using System.Threading.Tasks; +using DotNet.Testcontainers.Builders; +using DotNet.Testcontainers.Containers; + +namespace Datadog.Trace.TestHelpers.AutoInstrumentation.Containers; + +public class ServiceStackRedisFixture : ContainerFixture +{ + private const int RedisPort = 6379; + private const string DefaultHostConfiguration = "localhost:6379"; + + private string? _hostConfiguration; + + protected IContainer Container => GetResource("container"); + + public override IEnumerable> GetEnvironmentVariables() + { + yield return new( + "SERVICESTACK_REDIS_HOST", + _hostConfiguration ?? $"{Container.Hostname}:{Container.GetMappedPublicPort(RedisPort)}"); + } + + protected override async Task InitializeResources(Action registerResource) + { + var hostConfiguration = Environment.GetEnvironmentVariable("SERVICESTACK_REDIS_HOST"); + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) || !string.IsNullOrEmpty(hostConfiguration)) + { + _hostConfiguration = string.IsNullOrEmpty(hostConfiguration) ? DefaultHostConfiguration : hostConfiguration; + return; + } + + // Keep synchronized with the image version in docker-compose.yml. + var container = new ContainerBuilder("redis:4-alpine@sha256:aaf7c123077a5e45ab2328b5ef7e201b5720616efac498d55e65a7afbb96ae20") + .WithCommand("redis-server", "--bind", "0.0.0.0") + .WithPortBinding(RedisPort, true) + .WithWaitStrategy(Wait.ForUnixContainer().UntilInternalTcpPortIsAvailable(RedisPort)) + .Build(); + + registerResource("container", container); + await StartContainerAsync(container).ConfigureAwait(false); + } +} diff --git a/tracer/test/Datadog.Trace.TestHelpers.AutoInstrumentation/Containers/SqlServerFixture.cs b/tracer/test/Datadog.Trace.TestHelpers.AutoInstrumentation/Containers/SqlServerFixture.cs new file mode 100644 index 000000000000..252cf2b9a7f3 --- /dev/null +++ b/tracer/test/Datadog.Trace.TestHelpers.AutoInstrumentation/Containers/SqlServerFixture.cs @@ -0,0 +1,98 @@ +// +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2017 Datadog, Inc. +// + +#nullable enable + +using System; +using System.Collections.Generic; +using System.Data.Common; +using System.Runtime.InteropServices; +using System.Threading.Tasks; +using DotNet.Testcontainers.Builders; +using DotNet.Testcontainers.Containers; +using Testcontainers.MsSql; + +namespace Datadog.Trace.TestHelpers.AutoInstrumentation.Containers; + +public class SqlServerFixture : ContainerFixture +{ + private const int SqlServerPort = 1433; + private const string Password = "Strong!Passw0rd"; + private const string SqlServerImage = "mcr.microsoft.com/mssql/server:latest@sha256:2cd0aec4a3bfc3cf9205bed3f7922f4c6208f7c767dc62edcee308d0fd7d56d0"; + private const string AzureSqlEdgeImage = "mcr.microsoft.com/azure-sql-edge:latest@sha256:902628a8be89e35dfb7895ca31d602974c7bafde4d583a0d0873844feb1c42cf"; + + private string? _connectionString; + + public string? HostAndPort { get; private set; } + + public override IEnumerable> GetEnvironmentVariables() + { + if (_connectionString is not null) + { + yield return new("SQLSERVER_CONNECTION_STRING", _connectionString); + } + } + + protected override async Task InitializeResources(Action registerResource) + { + var connectionString = Environment.GetEnvironmentVariable("SQLSERVER_CONNECTION_STRING"); + if (!string.IsNullOrEmpty(connectionString)) + { + _connectionString = connectionString; + HostAndPort = GetHost(connectionString); + return; + } + + // Windows provides LocalDB. + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + return; + } + + IContainer container; + if (RuntimeInformation.ProcessArchitecture == Architecture.Arm64) + { + // mssql/server has no native arm64 image. Azure SQL Edge does not include the sqlcmd binary + // used by MsSqlBuilder's readiness check, so wait for its ready message instead. Explicitly + // bound the wait because Testcontainers defaults to one hour. + container = new ContainerBuilder(AzureSqlEdgeImage) + .WithPortBinding(SqlServerPort, true) + .WithEnvironment("ACCEPT_EULA", "Y") + .WithEnvironment("MSSQL_SA_PASSWORD", Password) + .WithWaitStrategy( + Wait.ForUnixContainer() + .UntilMessageIsLogged( + "SQL Server is now ready for client connections", + strategy => strategy.WithTimeout(TimeSpan.FromMinutes(2)))) + .Build(); + } + else + { + container = new MsSqlBuilder(SqlServerImage) + .WithPassword(Password) + .Build(); + } + + registerResource("container", container); + await StartContainerAsync(container).ConfigureAwait(false); + + HostAndPort = $"{container.Hostname},{container.GetMappedPublicPort(SqlServerPort)}"; + _connectionString = $"Server={HostAndPort};User=sa;Password={Password};TrustServerCertificate=True"; + } + + private static string? GetHost(string connectionString) + { + var builder = new DbConnectionStringBuilder { ConnectionString = connectionString }; + foreach (var name in new[] { "Server", "Data Source", "DataSource", "Network Address", "NetworkAddress", "Address", "Addr", "Host", "Hostname", "Host Name" }) + { + if (builder.TryGetValue(name, out var value) && value is string host) + { + return host; + } + } + + return null; + } +} diff --git a/tracer/test/Datadog.Trace.TestHelpers.AutoInstrumentation/Containers/StackExchangeRedisFixture.cs b/tracer/test/Datadog.Trace.TestHelpers.AutoInstrumentation/Containers/StackExchangeRedisFixture.cs new file mode 100644 index 000000000000..14a8c2996e97 --- /dev/null +++ b/tracer/test/Datadog.Trace.TestHelpers.AutoInstrumentation/Containers/StackExchangeRedisFixture.cs @@ -0,0 +1,167 @@ +// +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2017 Datadog, Inc. +// + +#nullable enable + +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using System.Threading.Tasks; +using DotNet.Testcontainers.Builders; +using DotNet.Testcontainers.Containers; + +namespace Datadog.Trace.TestHelpers.AutoInstrumentation.Containers; + +public class StackExchangeRedisFixture : ContainerFixture +{ + private const int RedisPort = 6379; + private const string PrimaryAlias = "stackexchangeredis"; + private const string DefaultHostConfiguration = "localhost:6379,localhost:6380"; + + private Endpoint? _primaryEndpoint; + private Endpoint? _replicaEndpoint; + private string? _hostConfiguration; + private string? _singleHostConfiguration; + + public string PrimaryHost => _primaryEndpoint!.Host; + + public ushort PrimaryPort => _primaryEndpoint!.Port; + + public string ReplicaHost => _replicaEndpoint!.Host; + + public ushort ReplicaPort => _replicaEndpoint!.Port; + + public override IEnumerable> GetEnvironmentVariables() + { + if (_hostConfiguration is null || _singleHostConfiguration is null) + { + yield break; + } + + yield return new("STACKEXCHANGE_REDIS_HOST", _hostConfiguration); + yield return new("STACKEXCHANGE_REDIS_SINGLE_HOST", _singleHostConfiguration); + } + + protected override async Task InitializeResources(Action registerResource) + { + // Windows tests use an existing Redis instance because CI does not provide Docker. + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + var hostConfiguration = Environment.GetEnvironmentVariable("STACKEXCHANGE_REDIS_HOST"); + _hostConfiguration = string.IsNullOrEmpty(hostConfiguration) ? DefaultHostConfiguration : hostConfiguration; + var endpoints = ParseEndpoints(_hostConfiguration); + _primaryEndpoint = endpoints[0]; + _replicaEndpoint = endpoints.Count > 1 ? endpoints[1] : endpoints[0]; + var singleHostConfiguration = Environment.GetEnvironmentVariable("STACKEXCHANGE_REDIS_SINGLE_HOST"); + _singleHostConfiguration = string.IsNullOrEmpty(singleHostConfiguration) ? endpoints[0].ToString() : singleHostConfiguration; + return; + } + + // Keep synchronized with the image version in docker-compose.yml. + const string image = "redis:4-alpine@sha256:aaf7c123077a5e45ab2328b5ef7e201b5720616efac498d55e65a7afbb96ae20"; + + var network = new NetworkBuilder().Build(); + var primaryContainer = new ContainerBuilder(image) + .WithCommand("redis-server", "--bind", "0.0.0.0") + .WithNetwork(network) + .WithNetworkAliases(PrimaryAlias) + .WithPortBinding(RedisPort, true) + .WithWaitStrategy(Wait.ForUnixContainer().UntilInternalTcpPortIsAvailable(RedisPort)) + .Build(); + var replicaContainer = new ContainerBuilder(image) + .WithCommand("redis-server", "--bind", "0.0.0.0", "--slaveof", PrimaryAlias, "6379") + .WithNetwork(network) + .WithPortBinding(RedisPort, true) + .WithWaitStrategy( + Wait.ForUnixContainer() + .UntilInternalTcpPortIsAvailable(RedisPort) + .UntilCommandIsCompleted("sh", "-c", "redis-cli info replication | grep -q 'master_link_status:up'")) + .Build(); + var singleContainer = new ContainerBuilder(image) + .WithCommand("redis-server", "--bind", "0.0.0.0") + .WithNetwork(network) + .WithPortBinding(RedisPort, true) + .WithWaitStrategy(Wait.ForUnixContainer().UntilInternalTcpPortIsAvailable(RedisPort)) + .Build(); + + registerResource("network", network); + registerResource("primary", primaryContainer); + registerResource("replica", replicaContainer); + registerResource("single", singleContainer); + await network.CreateAsync().ConfigureAwait(false); + await StartContainerAsync(primaryContainer).ConfigureAwait(false); + await Task.WhenAll(StartContainerAsync(replicaContainer), StartContainerAsync(singleContainer)).ConfigureAwait(false); + + _primaryEndpoint = new Endpoint(primaryContainer.Hostname, primaryContainer.GetMappedPublicPort(RedisPort)); + _replicaEndpoint = new Endpoint(replicaContainer.Hostname, replicaContainer.GetMappedPublicPort(RedisPort)); + _hostConfiguration = $"{_primaryEndpoint},{_replicaEndpoint}"; + _singleHostConfiguration = $"{singleContainer.Hostname}:{singleContainer.GetMappedPublicPort(RedisPort)}"; + } + + private static List ParseEndpoints(string configuration) + { + var endpoints = new List(); + foreach (var value in configuration.Split(',')) + { + var trimmedValue = value.Trim(); + if (trimmedValue.Length == 0 || trimmedValue.Contains("=")) + { + continue; + } + + endpoints.Add(Endpoint.Parse(trimmedValue)); + if (endpoints.Count == 2) + { + break; + } + } + + if (endpoints.Count == 0) + { + throw new InvalidOperationException("STACKEXCHANGE_REDIS_HOST must contain at least one Redis endpoint."); + } + + return endpoints; + } + + private sealed class Endpoint + { + public Endpoint(string host, ushort port) + { + Host = host; + Port = port; + } + + public string Host { get; } + + public ushort Port { get; } + + public static Endpoint Parse(string value) + { + if (value[0] == '[') + { + var closingBracketIndex = value.IndexOf(']'); + if (closingBracketIndex > 0) + { + var host = value.Substring(1, closingBracketIndex - 1); + var portValue = value.Substring(closingBracketIndex + 1).TrimStart(':'); + return new Endpoint(host, ParsePort(portValue)); + } + } + + var separatorIndex = value.LastIndexOf(':'); + if (separatorIndex > 0 && ushort.TryParse(value.Substring(separatorIndex + 1), out var port)) + { + return new Endpoint(value.Substring(0, separatorIndex), port); + } + + return new Endpoint(value, RedisPort); + } + + public override string ToString() => Host.IndexOf(':') >= 0 ? $"[{Host}]:{Port}" : $"{Host}:{Port}"; + + private static ushort ParsePort(string value) => ushort.TryParse(value, out var port) ? port : (ushort)RedisPort; + } +} diff --git a/tracer/test/Datadog.Trace.TestHelpers.AutoInstrumentation/Datadog.Trace.TestHelpers.AutoInstrumentation.csproj b/tracer/test/Datadog.Trace.TestHelpers.AutoInstrumentation/Datadog.Trace.TestHelpers.AutoInstrumentation.csproj index 499642cefe0f..be3eb5d4de62 100644 --- a/tracer/test/Datadog.Trace.TestHelpers.AutoInstrumentation/Datadog.Trace.TestHelpers.AutoInstrumentation.csproj +++ b/tracer/test/Datadog.Trace.TestHelpers.AutoInstrumentation/Datadog.Trace.TestHelpers.AutoInstrumentation.csproj @@ -1,8 +1,12 @@ + - + + + + diff --git a/tracer/test/Datadog.Trace.TestHelpers.AutoInstrumentation/DockerTestFramework.cs b/tracer/test/Datadog.Trace.TestHelpers.AutoInstrumentation/DockerTestFramework.cs deleted file mode 100644 index 1d998299f215..000000000000 --- a/tracer/test/Datadog.Trace.TestHelpers.AutoInstrumentation/DockerTestFramework.cs +++ /dev/null @@ -1,59 +0,0 @@ -// -// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2 License. -// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2017 Datadog, Inc. -// - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Datadog.Trace.TestHelpers.AutoInstrumentation.Containers; -using Xunit; -using Xunit.Abstractions; -using Xunit.Sdk; - -namespace Datadog.Trace.TestHelpers.AutoInstrumentation; - -public class DockerTestFramework : CustomTestFramework -{ - public DockerTestFramework(IMessageSink messageSink) - : base(messageSink) - { - } - - public DockerTestFramework(IMessageSink messageSink, Type typeTestedAssembly) - : base(messageSink, typeTestedAssembly) - { - } - - protected override async Task RunTestCollectionsCallback(IMessageSink diagnosticsMessageSink, IEnumerable testCases) - { - var containerFixtures = testCases - .Select(t => t.Method.ToRuntimeMethod().DeclaringType) - .Where(t => t.GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IClassFixture<>))) - .ToList(); - - foreach (var type in containerFixtures) - { - // Retrieve all the types of container fixtures - var fixtureTypes = type.GetInterfaces() - .Where(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IClassFixture<>)) - .Select(i => i.GetGenericArguments()[0]) - .Where(t => typeof(ContainerFixture).IsAssignableFrom(t)) - .ToList(); - - foreach (var fixtureType in fixtureTypes) - { - try - { - var fixture = (ContainerFixture)Activator.CreateInstance(fixtureType); - await fixture!.InitializeAsync(); - } - catch (Exception ex) - { - DiagnosticMessageSink.OnMessage(new DiagnosticMessage($"ERROR: {fixtureType.Name} ({ex.Message})")); - } - } - } - } -} diff --git a/tracer/test/snapshots/Couchbase3Tests.SchemaV0.verified.txt b/tracer/test/snapshots/Couchbase3Tests.SchemaV0.verified.txt index 7b2913dfa20a..7282cecde5b5 100644 --- a/tracer/test/snapshots/Couchbase3Tests.SchemaV0.verified.txt +++ b/tracer/test/snapshots/Couchbase3Tests.SchemaV0.verified.txt @@ -187,13 +187,13 @@ TraceId: Id_15, SpanId: Id_16, Name: couchbase.query, - Resource: Hello, + Resource: NoOp, Service: Samples.Couchbase3-couchbase, Type: db, Tags: { component: Couchbase, - couchbase.operation.code: Hello, - couchbase.operation.key: obfuscated, + couchbase.operation.code: NoOp, + couchbase.operation.key: , db.couchbase.seed.nodes: couchbase, env: integration_tests, language: dotnet, @@ -213,13 +213,13 @@ TraceId: Id_17, SpanId: Id_18, Name: couchbase.query, - Resource: Hello, + Resource: NoOp, Service: Samples.Couchbase3-couchbase, Type: db, Tags: { component: Couchbase, - couchbase.operation.code: Hello, - couchbase.operation.key: obfuscated, + couchbase.operation.code: NoOp, + couchbase.operation.key: , db.couchbase.seed.nodes: couchbase, env: integration_tests, language: dotnet, @@ -239,6 +239,58 @@ TraceId: Id_19, SpanId: Id_20, Name: couchbase.query, + Resource: SaslList, + Service: Samples.Couchbase3-couchbase, + Type: db, + Tags: { + component: Couchbase, + couchbase.operation.code: SaslList, + couchbase.operation.key: , + db.couchbase.seed.nodes: couchbase, + env: integration_tests, + language: dotnet, + runtime-id: Guid_1, + span.kind: client, + _dd.base_service: Samples.Couchbase3, + _dd.svc_src: couchbase + }, + Metrics: { + process_id: 0, + _dd.top_level: 1.0, + _dd.tracer_kr: 1.0, + _sampling_priority_v1: 1.0 + } + }, + { + TraceId: Id_21, + SpanId: Id_22, + Name: couchbase.query, + Resource: SaslList, + Service: Samples.Couchbase3-couchbase, + Type: db, + Tags: { + component: Couchbase, + couchbase.operation.code: SaslList, + couchbase.operation.key: , + db.couchbase.seed.nodes: couchbase, + env: integration_tests, + language: dotnet, + runtime-id: Guid_1, + span.kind: client, + _dd.base_service: Samples.Couchbase3, + _dd.svc_src: couchbase + }, + Metrics: { + process_id: 0, + _dd.top_level: 1.0, + _dd.tracer_kr: 1.0, + _sampling_priority_v1: 1.0 + } + }, + { + TraceId: Id_23, + SpanId: Id_24, + Name: couchbase.query, Resource: SelectBucket, Service: Samples.Couchbase3-couchbase, Type: db, @@ -262,8 +314,8 @@ } }, { - TraceId: Id_21, - SpanId: Id_22, + TraceId: Id_25, + SpanId: Id_26, Name: couchbase.query, Resource: SelectBucket, Service: Samples.Couchbase3-couchbase, @@ -288,8 +340,8 @@ } }, { - TraceId: Id_23, - SpanId: Id_24, + TraceId: Id_27, + SpanId: Id_28, Name: couchbase.query, Resource: Set, Service: Samples.Couchbase3-couchbase, diff --git a/tracer/test/snapshots/Couchbase3Tests.SchemaV1.verified.txt b/tracer/test/snapshots/Couchbase3Tests.SchemaV1.verified.txt index e8408ab96e75..8782d778479b 100644 --- a/tracer/test/snapshots/Couchbase3Tests.SchemaV1.verified.txt +++ b/tracer/test/snapshots/Couchbase3Tests.SchemaV1.verified.txt @@ -194,13 +194,13 @@ TraceId: Id_15, SpanId: Id_16, Name: couchbase.query, - Resource: Hello, + Resource: NoOp, Service: Samples.Couchbase3, Type: db, Tags: { component: Couchbase, - couchbase.operation.code: Hello, - couchbase.operation.key: obfuscated, + couchbase.operation.code: NoOp, + couchbase.operation.key: , db.couchbase.seed.nodes: couchbase, env: integration_tests, language: dotnet, @@ -221,13 +221,13 @@ TraceId: Id_17, SpanId: Id_18, Name: couchbase.query, - Resource: Hello, + Resource: NoOp, Service: Samples.Couchbase3, Type: db, Tags: { component: Couchbase, - couchbase.operation.code: Hello, - couchbase.operation.key: obfuscated, + couchbase.operation.code: NoOp, + couchbase.operation.key: , db.couchbase.seed.nodes: couchbase, env: integration_tests, language: dotnet, @@ -248,6 +248,60 @@ TraceId: Id_19, SpanId: Id_20, Name: couchbase.query, + Resource: SaslList, + Service: Samples.Couchbase3, + Type: db, + Tags: { + component: Couchbase, + couchbase.operation.code: SaslList, + couchbase.operation.key: , + db.couchbase.seed.nodes: couchbase, + env: integration_tests, + language: dotnet, + peer.service: couchbase, + runtime-id: Guid_1, + span.kind: client, + version: 1.0.0, + _dd.peer.service.source: db.couchbase.seed.nodes + }, + Metrics: { + process_id: 0, + _dd.top_level: 1.0, + _dd.tracer_kr: 1.0, + _sampling_priority_v1: 1.0 + } + }, + { + TraceId: Id_21, + SpanId: Id_22, + Name: couchbase.query, + Resource: SaslList, + Service: Samples.Couchbase3, + Type: db, + Tags: { + component: Couchbase, + couchbase.operation.code: SaslList, + couchbase.operation.key: , + db.couchbase.seed.nodes: couchbase, + env: integration_tests, + language: dotnet, + peer.service: couchbase, + runtime-id: Guid_1, + span.kind: client, + version: 1.0.0, + _dd.peer.service.source: db.couchbase.seed.nodes + }, + Metrics: { + process_id: 0, + _dd.top_level: 1.0, + _dd.tracer_kr: 1.0, + _sampling_priority_v1: 1.0 + } + }, + { + TraceId: Id_23, + SpanId: Id_24, + Name: couchbase.query, Resource: SelectBucket, Service: Samples.Couchbase3, Type: db, @@ -272,8 +326,8 @@ } }, { - TraceId: Id_21, - SpanId: Id_22, + TraceId: Id_25, + SpanId: Id_26, Name: couchbase.query, Resource: SelectBucket, Service: Samples.Couchbase3, @@ -299,8 +353,8 @@ } }, { - TraceId: Id_23, - SpanId: Id_24, + TraceId: Id_27, + SpanId: Id_28, Name: couchbase.query, Resource: Set, Service: Samples.Couchbase3, diff --git a/tracer/test/snapshots/Couchbase3Tests_3_8.SchemaV0.verified.txt b/tracer/test/snapshots/Couchbase3Tests_3_8.SchemaV0.verified.txt new file mode 100644 index 000000000000..6a4328036058 --- /dev/null +++ b/tracer/test/snapshots/Couchbase3Tests_3_8.SchemaV0.verified.txt @@ -0,0 +1,372 @@ +[ + { + TraceId: Id_1, + SpanId: Id_2, + Name: couchbase.query, + Resource: Delete, + Service: Samples.Couchbase3-couchbase, + Type: db, + Tags: { + component: Couchbase, + couchbase.operation.bucket: default, + couchbase.operation.code: Delete, + couchbase.operation.key: my-document-key, + db.couchbase.seed.nodes: couchbase, + env: integration_tests, + language: dotnet, + runtime-id: Guid_1, + span.kind: client, + _dd.base_service: Samples.Couchbase3, + _dd.svc_src: couchbase + }, + Metrics: { + process_id: 0, + _dd.top_level: 1.0, + _dd.tracer_kr: 1.0, + _sampling_priority_v1: 1.0 + } + }, + { + TraceId: Id_3, + SpanId: Id_4, + Name: couchbase.query, + Resource: Delete, + Service: Samples.Couchbase3-couchbase, + Type: db, + Error: 1, + Tags: { + component: Couchbase, + couchbase.operation.bucket: default, + couchbase.operation.code: Delete, + couchbase.operation.key: does-not-exist, + db.couchbase.seed.nodes: couchbase, + env: integration_tests, + error.msg: KeyNotFound, + language: dotnet, + runtime-id: Guid_1, + span.kind: client, + _dd.base_service: Samples.Couchbase3, + _dd.svc_src: couchbase + }, + Metrics: { + process_id: 0, + _dd.top_level: 1.0, + _dd.tracer_kr: 1.0, + _sampling_priority_v1: 1.0 + } + }, + { + TraceId: Id_5, + SpanId: Id_6, + Name: couchbase.query, + Resource: Get, + Service: Samples.Couchbase3-couchbase, + Type: db, + Tags: { + component: Couchbase, + couchbase.operation.bucket: default, + couchbase.operation.code: Get, + couchbase.operation.key: my-document-key, + db.couchbase.seed.nodes: couchbase, + env: integration_tests, + language: dotnet, + runtime-id: Guid_1, + span.kind: client, + _dd.base_service: Samples.Couchbase3, + _dd.svc_src: couchbase + }, + Metrics: { + process_id: 0, + _dd.top_level: 1.0, + _dd.tracer_kr: 1.0, + _sampling_priority_v1: 1.0 + } + }, + { + TraceId: Id_7, + SpanId: Id_8, + Name: couchbase.query, + Resource: GetErrorMap, + Service: Samples.Couchbase3-couchbase, + Type: db, + Tags: { + component: Couchbase, + couchbase.operation.code: GetErrorMap, + couchbase.operation.key: , + db.couchbase.seed.nodes: couchbase, + env: integration_tests, + language: dotnet, + runtime-id: Guid_1, + span.kind: client, + _dd.base_service: Samples.Couchbase3, + _dd.svc_src: couchbase + }, + Metrics: { + process_id: 0, + _dd.top_level: 1.0, + _dd.tracer_kr: 1.0, + _sampling_priority_v1: 1.0 + } + }, + { + TraceId: Id_9, + SpanId: Id_10, + Name: couchbase.query, + Resource: GetErrorMap, + Service: Samples.Couchbase3-couchbase, + Type: db, + Tags: { + component: Couchbase, + couchbase.operation.code: GetErrorMap, + couchbase.operation.key: , + db.couchbase.seed.nodes: couchbase, + env: integration_tests, + language: dotnet, + runtime-id: Guid_1, + span.kind: client, + _dd.base_service: Samples.Couchbase3, + _dd.svc_src: couchbase + }, + Metrics: { + process_id: 0, + _dd.top_level: 1.0, + _dd.tracer_kr: 1.0, + _sampling_priority_v1: 1.0 + } + }, + { + TraceId: Id_11, + SpanId: Id_12, + Name: couchbase.query, + Resource: Hello, + Service: Samples.Couchbase3-couchbase, + Type: db, + Tags: { + component: Couchbase, + couchbase.operation.code: Hello, + couchbase.operation.key: obfuscated, + db.couchbase.seed.nodes: couchbase, + env: integration_tests, + language: dotnet, + runtime-id: Guid_1, + span.kind: client, + _dd.base_service: Samples.Couchbase3, + _dd.svc_src: couchbase + }, + Metrics: { + process_id: 0, + _dd.top_level: 1.0, + _dd.tracer_kr: 1.0, + _sampling_priority_v1: 1.0 + } + }, + { + TraceId: Id_13, + SpanId: Id_14, + Name: couchbase.query, + Resource: Hello, + Service: Samples.Couchbase3-couchbase, + Type: db, + Tags: { + component: Couchbase, + couchbase.operation.code: Hello, + couchbase.operation.key: obfuscated, + db.couchbase.seed.nodes: couchbase, + env: integration_tests, + language: dotnet, + runtime-id: Guid_1, + span.kind: client, + _dd.base_service: Samples.Couchbase3, + _dd.svc_src: couchbase + }, + Metrics: { + process_id: 0, + _dd.top_level: 1.0, + _dd.tracer_kr: 1.0, + _sampling_priority_v1: 1.0 + } + }, + { + TraceId: Id_15, + SpanId: Id_16, + Name: couchbase.query, + Resource: NoOp, + Service: Samples.Couchbase3-couchbase, + Type: db, + Tags: { + component: Couchbase, + couchbase.operation.code: NoOp, + couchbase.operation.key: , + db.couchbase.seed.nodes: couchbase, + env: integration_tests, + language: dotnet, + runtime-id: Guid_1, + span.kind: client, + _dd.base_service: Samples.Couchbase3, + _dd.svc_src: couchbase + }, + Metrics: { + process_id: 0, + _dd.top_level: 1.0, + _dd.tracer_kr: 1.0, + _sampling_priority_v1: 1.0 + } + }, + { + TraceId: Id_17, + SpanId: Id_18, + Name: couchbase.query, + Resource: NoOp, + Service: Samples.Couchbase3-couchbase, + Type: db, + Tags: { + component: Couchbase, + couchbase.operation.code: NoOp, + couchbase.operation.key: , + db.couchbase.seed.nodes: couchbase, + env: integration_tests, + language: dotnet, + runtime-id: Guid_1, + span.kind: client, + _dd.base_service: Samples.Couchbase3, + _dd.svc_src: couchbase + }, + Metrics: { + process_id: 0, + _dd.top_level: 1.0, + _dd.tracer_kr: 1.0, + _sampling_priority_v1: 1.0 + } + }, + { + TraceId: Id_19, + SpanId: Id_20, + Name: couchbase.query, + Resource: SaslList, + Service: Samples.Couchbase3-couchbase, + Type: db, + Tags: { + component: Couchbase, + couchbase.operation.code: SaslList, + couchbase.operation.key: , + db.couchbase.seed.nodes: couchbase, + env: integration_tests, + language: dotnet, + runtime-id: Guid_1, + span.kind: client, + _dd.base_service: Samples.Couchbase3, + _dd.svc_src: couchbase + }, + Metrics: { + process_id: 0, + _dd.top_level: 1.0, + _dd.tracer_kr: 1.0, + _sampling_priority_v1: 1.0 + } + }, + { + TraceId: Id_21, + SpanId: Id_22, + Name: couchbase.query, + Resource: SaslList, + Service: Samples.Couchbase3-couchbase, + Type: db, + Tags: { + component: Couchbase, + couchbase.operation.code: SaslList, + couchbase.operation.key: , + db.couchbase.seed.nodes: couchbase, + env: integration_tests, + language: dotnet, + runtime-id: Guid_1, + span.kind: client, + _dd.base_service: Samples.Couchbase3, + _dd.svc_src: couchbase + }, + Metrics: { + process_id: 0, + _dd.top_level: 1.0, + _dd.tracer_kr: 1.0, + _sampling_priority_v1: 1.0 + } + }, + { + TraceId: Id_23, + SpanId: Id_24, + Name: couchbase.query, + Resource: SelectBucket, + Service: Samples.Couchbase3-couchbase, + Type: db, + Tags: { + component: Couchbase, + couchbase.operation.code: SelectBucket, + couchbase.operation.key: default, + db.couchbase.seed.nodes: couchbase, + env: integration_tests, + language: dotnet, + runtime-id: Guid_1, + span.kind: client, + _dd.base_service: Samples.Couchbase3, + _dd.svc_src: couchbase + }, + Metrics: { + process_id: 0, + _dd.top_level: 1.0, + _dd.tracer_kr: 1.0, + _sampling_priority_v1: 1.0 + } + }, + { + TraceId: Id_25, + SpanId: Id_26, + Name: couchbase.query, + Resource: SelectBucket, + Service: Samples.Couchbase3-couchbase, + Type: db, + Tags: { + component: Couchbase, + couchbase.operation.code: SelectBucket, + couchbase.operation.key: default, + db.couchbase.seed.nodes: couchbase, + env: integration_tests, + language: dotnet, + runtime-id: Guid_1, + span.kind: client, + _dd.base_service: Samples.Couchbase3, + _dd.svc_src: couchbase + }, + Metrics: { + process_id: 0, + _dd.top_level: 1.0, + _dd.tracer_kr: 1.0, + _sampling_priority_v1: 1.0 + } + }, + { + TraceId: Id_27, + SpanId: Id_28, + Name: couchbase.query, + Resource: Set, + Service: Samples.Couchbase3-couchbase, + Type: db, + Tags: { + component: Couchbase, + couchbase.operation.bucket: default, + couchbase.operation.code: Set, + couchbase.operation.key: my-document-key, + db.couchbase.seed.nodes: couchbase, + env: integration_tests, + language: dotnet, + runtime-id: Guid_1, + span.kind: client, + _dd.base_service: Samples.Couchbase3, + _dd.svc_src: couchbase + }, + Metrics: { + process_id: 0, + _dd.top_level: 1.0, + _dd.tracer_kr: 1.0, + _sampling_priority_v1: 1.0 + } + } +] \ No newline at end of file diff --git a/tracer/test/snapshots/Couchbase3Tests_3_8.SchemaV1.verified.txt b/tracer/test/snapshots/Couchbase3Tests_3_8.SchemaV1.verified.txt new file mode 100644 index 000000000000..af9bae346fdc --- /dev/null +++ b/tracer/test/snapshots/Couchbase3Tests_3_8.SchemaV1.verified.txt @@ -0,0 +1,386 @@ +[ + { + TraceId: Id_1, + SpanId: Id_2, + Name: couchbase.query, + Resource: Delete, + Service: Samples.Couchbase3, + Type: db, + Tags: { + component: Couchbase, + couchbase.operation.bucket: default, + couchbase.operation.code: Delete, + couchbase.operation.key: my-document-key, + db.couchbase.seed.nodes: couchbase, + env: integration_tests, + language: dotnet, + peer.service: couchbase, + runtime-id: Guid_1, + span.kind: client, + version: 1.0.0, + _dd.peer.service.source: db.couchbase.seed.nodes + }, + Metrics: { + process_id: 0, + _dd.top_level: 1.0, + _dd.tracer_kr: 1.0, + _sampling_priority_v1: 1.0 + } + }, + { + TraceId: Id_3, + SpanId: Id_4, + Name: couchbase.query, + Resource: Delete, + Service: Samples.Couchbase3, + Type: db, + Error: 1, + Tags: { + component: Couchbase, + couchbase.operation.bucket: default, + couchbase.operation.code: Delete, + couchbase.operation.key: does-not-exist, + db.couchbase.seed.nodes: couchbase, + env: integration_tests, + error.msg: KeyNotFound, + language: dotnet, + peer.service: couchbase, + runtime-id: Guid_1, + span.kind: client, + version: 1.0.0, + _dd.peer.service.source: db.couchbase.seed.nodes + }, + Metrics: { + process_id: 0, + _dd.top_level: 1.0, + _dd.tracer_kr: 1.0, + _sampling_priority_v1: 1.0 + } + }, + { + TraceId: Id_5, + SpanId: Id_6, + Name: couchbase.query, + Resource: Get, + Service: Samples.Couchbase3, + Type: db, + Tags: { + component: Couchbase, + couchbase.operation.bucket: default, + couchbase.operation.code: Get, + couchbase.operation.key: my-document-key, + db.couchbase.seed.nodes: couchbase, + env: integration_tests, + language: dotnet, + peer.service: couchbase, + runtime-id: Guid_1, + span.kind: client, + version: 1.0.0, + _dd.peer.service.source: db.couchbase.seed.nodes + }, + Metrics: { + process_id: 0, + _dd.top_level: 1.0, + _dd.tracer_kr: 1.0, + _sampling_priority_v1: 1.0 + } + }, + { + TraceId: Id_7, + SpanId: Id_8, + Name: couchbase.query, + Resource: GetErrorMap, + Service: Samples.Couchbase3, + Type: db, + Tags: { + component: Couchbase, + couchbase.operation.code: GetErrorMap, + couchbase.operation.key: , + db.couchbase.seed.nodes: couchbase, + env: integration_tests, + language: dotnet, + peer.service: couchbase, + runtime-id: Guid_1, + span.kind: client, + version: 1.0.0, + _dd.peer.service.source: db.couchbase.seed.nodes + }, + Metrics: { + process_id: 0, + _dd.top_level: 1.0, + _dd.tracer_kr: 1.0, + _sampling_priority_v1: 1.0 + } + }, + { + TraceId: Id_9, + SpanId: Id_10, + Name: couchbase.query, + Resource: GetErrorMap, + Service: Samples.Couchbase3, + Type: db, + Tags: { + component: Couchbase, + couchbase.operation.code: GetErrorMap, + couchbase.operation.key: , + db.couchbase.seed.nodes: couchbase, + env: integration_tests, + language: dotnet, + peer.service: couchbase, + runtime-id: Guid_1, + span.kind: client, + version: 1.0.0, + _dd.peer.service.source: db.couchbase.seed.nodes + }, + Metrics: { + process_id: 0, + _dd.top_level: 1.0, + _dd.tracer_kr: 1.0, + _sampling_priority_v1: 1.0 + } + }, + { + TraceId: Id_11, + SpanId: Id_12, + Name: couchbase.query, + Resource: Hello, + Service: Samples.Couchbase3, + Type: db, + Tags: { + component: Couchbase, + couchbase.operation.code: Hello, + couchbase.operation.key: obfuscated, + db.couchbase.seed.nodes: couchbase, + env: integration_tests, + language: dotnet, + peer.service: couchbase, + runtime-id: Guid_1, + span.kind: client, + version: 1.0.0, + _dd.peer.service.source: db.couchbase.seed.nodes + }, + Metrics: { + process_id: 0, + _dd.top_level: 1.0, + _dd.tracer_kr: 1.0, + _sampling_priority_v1: 1.0 + } + }, + { + TraceId: Id_13, + SpanId: Id_14, + Name: couchbase.query, + Resource: Hello, + Service: Samples.Couchbase3, + Type: db, + Tags: { + component: Couchbase, + couchbase.operation.code: Hello, + couchbase.operation.key: obfuscated, + db.couchbase.seed.nodes: couchbase, + env: integration_tests, + language: dotnet, + peer.service: couchbase, + runtime-id: Guid_1, + span.kind: client, + version: 1.0.0, + _dd.peer.service.source: db.couchbase.seed.nodes + }, + Metrics: { + process_id: 0, + _dd.top_level: 1.0, + _dd.tracer_kr: 1.0, + _sampling_priority_v1: 1.0 + } + }, + { + TraceId: Id_15, + SpanId: Id_16, + Name: couchbase.query, + Resource: NoOp, + Service: Samples.Couchbase3, + Type: db, + Tags: { + component: Couchbase, + couchbase.operation.code: NoOp, + couchbase.operation.key: , + db.couchbase.seed.nodes: couchbase, + env: integration_tests, + language: dotnet, + peer.service: couchbase, + runtime-id: Guid_1, + span.kind: client, + version: 1.0.0, + _dd.peer.service.source: db.couchbase.seed.nodes + }, + Metrics: { + process_id: 0, + _dd.top_level: 1.0, + _dd.tracer_kr: 1.0, + _sampling_priority_v1: 1.0 + } + }, + { + TraceId: Id_17, + SpanId: Id_18, + Name: couchbase.query, + Resource: NoOp, + Service: Samples.Couchbase3, + Type: db, + Tags: { + component: Couchbase, + couchbase.operation.code: NoOp, + couchbase.operation.key: , + db.couchbase.seed.nodes: couchbase, + env: integration_tests, + language: dotnet, + peer.service: couchbase, + runtime-id: Guid_1, + span.kind: client, + version: 1.0.0, + _dd.peer.service.source: db.couchbase.seed.nodes + }, + Metrics: { + process_id: 0, + _dd.top_level: 1.0, + _dd.tracer_kr: 1.0, + _sampling_priority_v1: 1.0 + } + }, + { + TraceId: Id_19, + SpanId: Id_20, + Name: couchbase.query, + Resource: SaslList, + Service: Samples.Couchbase3, + Type: db, + Tags: { + component: Couchbase, + couchbase.operation.code: SaslList, + couchbase.operation.key: , + db.couchbase.seed.nodes: couchbase, + env: integration_tests, + language: dotnet, + peer.service: couchbase, + runtime-id: Guid_1, + span.kind: client, + version: 1.0.0, + _dd.peer.service.source: db.couchbase.seed.nodes + }, + Metrics: { + process_id: 0, + _dd.top_level: 1.0, + _dd.tracer_kr: 1.0, + _sampling_priority_v1: 1.0 + } + }, + { + TraceId: Id_21, + SpanId: Id_22, + Name: couchbase.query, + Resource: SaslList, + Service: Samples.Couchbase3, + Type: db, + Tags: { + component: Couchbase, + couchbase.operation.code: SaslList, + couchbase.operation.key: , + db.couchbase.seed.nodes: couchbase, + env: integration_tests, + language: dotnet, + peer.service: couchbase, + runtime-id: Guid_1, + span.kind: client, + version: 1.0.0, + _dd.peer.service.source: db.couchbase.seed.nodes + }, + Metrics: { + process_id: 0, + _dd.top_level: 1.0, + _dd.tracer_kr: 1.0, + _sampling_priority_v1: 1.0 + } + }, + { + TraceId: Id_23, + SpanId: Id_24, + Name: couchbase.query, + Resource: SelectBucket, + Service: Samples.Couchbase3, + Type: db, + Tags: { + component: Couchbase, + couchbase.operation.code: SelectBucket, + couchbase.operation.key: default, + db.couchbase.seed.nodes: couchbase, + env: integration_tests, + language: dotnet, + peer.service: couchbase, + runtime-id: Guid_1, + span.kind: client, + version: 1.0.0, + _dd.peer.service.source: db.couchbase.seed.nodes + }, + Metrics: { + process_id: 0, + _dd.top_level: 1.0, + _dd.tracer_kr: 1.0, + _sampling_priority_v1: 1.0 + } + }, + { + TraceId: Id_25, + SpanId: Id_26, + Name: couchbase.query, + Resource: SelectBucket, + Service: Samples.Couchbase3, + Type: db, + Tags: { + component: Couchbase, + couchbase.operation.code: SelectBucket, + couchbase.operation.key: default, + db.couchbase.seed.nodes: couchbase, + env: integration_tests, + language: dotnet, + peer.service: couchbase, + runtime-id: Guid_1, + span.kind: client, + version: 1.0.0, + _dd.peer.service.source: db.couchbase.seed.nodes + }, + Metrics: { + process_id: 0, + _dd.top_level: 1.0, + _dd.tracer_kr: 1.0, + _sampling_priority_v1: 1.0 + } + }, + { + TraceId: Id_27, + SpanId: Id_28, + Name: couchbase.query, + Resource: Set, + Service: Samples.Couchbase3, + Type: db, + Tags: { + component: Couchbase, + couchbase.operation.bucket: default, + couchbase.operation.code: Set, + couchbase.operation.key: my-document-key, + db.couchbase.seed.nodes: couchbase, + env: integration_tests, + language: dotnet, + peer.service: couchbase, + runtime-id: Guid_1, + span.kind: client, + version: 1.0.0, + _dd.peer.service.source: db.couchbase.seed.nodes + }, + Metrics: { + process_id: 0, + _dd.top_level: 1.0, + _dd.tracer_kr: 1.0, + _sampling_priority_v1: 1.0 + } + } +] \ No newline at end of file diff --git a/tracer/test/test-applications/integrations/Samples.Couchbase/Program.cs b/tracer/test/test-applications/integrations/Samples.Couchbase/Program.cs index 2a66ab70f392..fba43617650d 100644 --- a/tracer/test/test-applications/integrations/Samples.Couchbase/Program.cs +++ b/tracer/test/test-applications/integrations/Samples.Couchbase/Program.cs @@ -50,8 +50,8 @@ private async Task RunAllExamples() { var config = GetConnectionConfig(); _cluster = new Cluster(config); - _cluster.Authenticate("default", "password"); - _bucket = _cluster.OpenBucket("default"); + _cluster.Authenticate(Username(), Password()); + _bucket = _cluster.OpenBucket(BucketName()); RetrieveAndUpdate(); await RetrieveAndUpdateAsync(); } @@ -91,6 +91,12 @@ private static string Host() return $"{host}:{port}"; } + private static string Username() => Environment.GetEnvironmentVariable("COUCHBASE_USERNAME") ?? "default"; + + private static string Password() => Environment.GetEnvironmentVariable("COUCHBASE_PASSWORD") ?? "password"; + + private static string BucketName() => Environment.GetEnvironmentVariable("COUCHBASE_BUCKET") ?? "default"; + public void RetrieveAndUpdate() { var key = "SampleApp-" + DateTime.Now.Ticks; diff --git a/tracer/test/test-applications/integrations/Samples.Couchbase3/Program.cs b/tracer/test/test-applications/integrations/Samples.Couchbase3/Program.cs index c4dea968532e..8aceee897f48 100644 --- a/tracer/test/test-applications/integrations/Samples.Couchbase3/Program.cs +++ b/tracer/test/test-applications/integrations/Samples.Couchbase3/Program.cs @@ -23,9 +23,9 @@ internal class Program private static async Task Main() { var options = new ClusterOptions() - .WithConnectionString("couchbase://" + Host()) - .WithCredentials(username: "default", password: "password") - .WithBuckets("default"); + .WithConnectionString("couchbase://" + ConnectionString()) + .WithCredentials(username: Username(), password: Password()) + .WithBuckets(BucketName()); ICluster cluster = null; @@ -43,9 +43,9 @@ private static async Task Main() } // get a bucket reference - var bucket = await cluster.BucketAsync("default"); + var bucket = await cluster.BucketAsync(BucketName()); - // get a user-defined collection reference + // get a collection reference #if COUCHBASE_3_0 var collection = bucket.DefaultCollection(); #else @@ -83,9 +83,12 @@ private static async Task Main() return 0; } - private static string Host() - { - return Environment.GetEnvironmentVariable("COUCHBASE_HOST") ?? "localhost"; - } + private static string ConnectionString() => Environment.GetEnvironmentVariable("COUCHBASE_CONNECTION_STRING") ?? "localhost"; + + private static string Username() => Environment.GetEnvironmentVariable("COUCHBASE_USERNAME") ?? "default"; + + private static string Password() => Environment.GetEnvironmentVariable("COUCHBASE_PASSWORD") ?? "password"; + + private static string BucketName() => Environment.GetEnvironmentVariable("COUCHBASE_BUCKET") ?? "default"; } } diff --git a/tracer/test/test-applications/integrations/Samples.DataStreams.RabbitMQ/Program.cs b/tracer/test/test-applications/integrations/Samples.DataStreams.RabbitMQ/Program.cs index 4ce8b5bf9e02..24131af4adbb 100644 --- a/tracer/test/test-applications/integrations/Samples.DataStreams.RabbitMQ/Program.cs +++ b/tracer/test/test-applications/integrations/Samples.DataStreams.RabbitMQ/Program.cs @@ -22,12 +22,13 @@ public static class Program private static readonly string DirectRoutingKey = nameof(DirectRoutingKey); private static readonly string Message = nameof(Message); private static readonly string Host = Environment.GetEnvironmentVariable("RABBITMQ_HOST") ?? "localhost"; + private static readonly int Port = int.TryParse(Environment.GetEnvironmentVariable("RABBITMQ_PORT"), out var port) ? port : 5672; public static async Task Main(string[] args) { await SampleHelpers.WaitForDiscoveryService(); - var factory = new ConnectionFactory() { HostName = Host }; + var factory = new ConnectionFactory() { HostName = Host, Port = Port }; #if RABBITMQ_7_0 using var connection = await factory.CreateConnectionAsync(); using var model = await connection.CreateChannelAsync(); diff --git a/tracer/test/test-applications/integrations/Samples.RabbitMQ/Program.cs b/tracer/test/test-applications/integrations/Samples.RabbitMQ/Program.cs index 987cca5c349d..cd242d026ec0 100644 --- a/tracer/test/test-applications/integrations/Samples.RabbitMQ/Program.cs +++ b/tracer/test/test-applications/integrations/Samples.RabbitMQ/Program.cs @@ -35,10 +35,15 @@ private static string Host() return Environment.GetEnvironmentVariable("RABBITMQ_HOST") ?? "localhost"; } + private static int Port() + { + return int.TryParse(Environment.GetEnvironmentVariable("RABBITMQ_PORT"), out var port) ? port : 5672; + } + public static async Task Main(string[] args) { // connecting takes 2 to 3 seconds, we re-use the connection to save time - var factory = new ConnectionFactory() { HostName = Host() }; + var factory = new ConnectionFactory() { HostName = Host(), Port = Port() }; #if RABBITMQ_5_0 && !RABBITMQ_7_0 factory.DispatchConsumersAsync = true; #endif @@ -51,7 +56,7 @@ public static async Task Main(string[] args) await RunProducersAndConsumers(asyncConnection, useQueue: true, ConsumerType.ExternalExplicit, isAsyncConsumer: true); } - factory = new ConnectionFactory() { HostName = Host() }; + factory = new ConnectionFactory() { HostName = Host(), Port = Port() }; using (var syncConnection = await Helper.CreateConnectionAsync(factory)) { // Test a derived type for the sync consumer from the library