Skip to content

Commit

Permalink
Add integration tests
Browse files Browse the repository at this point in the history
  • Loading branch information
nhulston committed Sep 27, 2024
1 parent d05eb4c commit 5ccd8b7
Show file tree
Hide file tree
Showing 14 changed files with 640 additions and 0 deletions.
6 changes: 6 additions & 0 deletions Datadog.Trace.sln
Original file line number Diff line number Diff line change
Expand Up @@ -589,6 +589,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Generated", "Generated", "{
tracer\build\PackageVersionsLatestSpecific.g.props = tracer\build\PackageVersionsLatestSpecific.g.props
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Samples.AWS.EventBridge", "tracer\test\test-applications\integrations\Samples.AWS.EventBridge\Samples.AWS.EventBridge.csproj", "{D6155F26-8245-4B66-8944-79C3DF9F9DA3}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -1409,6 +1411,10 @@ Global
{2CA0D70C-DFC1-458A-871B-328AB6E87E3A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2CA0D70C-DFC1-458A-871B-328AB6E87E3A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2CA0D70C-DFC1-458A-871B-328AB6E87E3A}.Release|Any CPU.Build.0 = Release|Any CPU
{D6155F26-8245-4B66-8944-79C3DF9F9DA3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D6155F26-8245-4B66-8944-79C3DF9F9DA3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D6155F26-8245-4B66-8944-79C3DF9F9DA3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D6155F26-8245-4B66-8944-79C3DF9F9DA3}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
5 changes: 5 additions & 0 deletions tracer/dependabot/Datadog.Dependabot.Integrations.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@
<!-- Latest package https://www.nuget.org/packages/AWSSDK.DynamoDBv2/3.7.401 -->
<PackageReference Include="AWSSDK.DynamoDBv2" Version="3.7.401" />

<!-- Integration: AWSSDK.EventBridge -->
<!-- Assembly: AWSSDK.EventBridge -->
<!-- Latest package https://www.nuget.org/packages/AWSSDK.EventBridge/3.7.401.23 -->
<PackageReference Include="AWSSDK.EventBridge" Version="3.7.401.23" />

<!-- Integration: AWSSDK.Kinesis -->
<!-- Assembly: AWSSDK.Kinesis -->
<!-- Latest package https://www.nuget.org/packages/AWSSDK.Kinesis/3.7.401.20 -->
Expand Down
1 change: 1 addition & 0 deletions tracer/missing-nullability-files.csv
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@ src/Datadog.Trace/Tagging/AspNetCoreMvcTags.cs
src/Datadog.Trace/Tagging/AspNetCoreTags.cs
src/Datadog.Trace/Tagging/AspNetTags.cs
src/Datadog.Trace/Tagging/AwsDynamoDbTags.cs
src/Datadog.Trace/Tagging/AwsEventBridgeTags.cs
src/Datadog.Trace/Tagging/AwsKinesisTags.cs
src/Datadog.Trace/Tagging/AwsSdkTags.cs
src/Datadog.Trace/Tagging/AwsSnsTags.cs
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
// <copyright file="AwsEventBridgeTests.cs" company="Datadog">
// 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.
// </copyright>

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Datadog.Trace.Configuration;
using Datadog.Trace.TestHelpers;
using FluentAssertions;
using VerifyXunit;
using Xunit;
using Xunit.Abstractions;

namespace Datadog.Trace.ClrProfiler.IntegrationTests.AWS
{
[Trait("RequiresDockerDependency", "true")]
[UsesVerify]
public class AwsEventBridgeTests : TracingIntegrationTest
{
public AwsEventBridgeTests(ITestOutputHelper output)
: base("AWS.EventBridge", output)
{
}

public static IEnumerable<object[]> GetEnabledConfig()
=> from packageVersionArray in PackageVersions.AwsEventBridge
from metadataSchemaVersion in new[] { "v0", "v1" }
select new[] { packageVersionArray[0], metadataSchemaVersion };

public override Result ValidateIntegrationSpan(MockSpan span, string metadataSchemaVersion) => span.Tags["span.kind"] switch
{
SpanKinds.Consumer => span.IsAwsEventBridgeInbound(metadataSchemaVersion),
SpanKinds.Producer => span.IsAwsEventBridgeOutbound(metadataSchemaVersion),
SpanKinds.Client => span.IsAwsEventBridgeRequest(metadataSchemaVersion),
_ => throw new ArgumentException($"span.Tags[\"span.kind\"] is not a supported value for the AWS EventBridge integration: {span.Tags["span.kind"]}", nameof(span)),
};

[SkippableTheory]
[MemberData(nameof(GetEnabledConfig))]
[Trait("Category", "EndToEnd")]
public async Task SubmitsTraces(string packageVersion, string metadataSchemaVersion)
{
SetEnvironmentVariable("DD_TRACE_SPAN_ATTRIBUTE_SCHEMA", metadataSchemaVersion);
var isExternalSpan = metadataSchemaVersion == "v0";
var clientSpanServiceName = isExternalSpan ? $"{EnvironmentHelper.FullSampleName}-aws-eventbridge" : EnvironmentHelper.FullSampleName;

using var telemetry = this.ConfigureTelemetry();
using (var agent = EnvironmentHelper.GetMockAgent())
using (await RunSampleAndWaitForExit(agent, packageVersion: packageVersion))
{
#if NETFRAMEWORK
var expectedCount = 8;
var frameworkName = "NetFramework";
#else
var expectedCount = 4;
var frameworkName = "NetCore";
#endif
var spans = agent.WaitForSpans(expectedCount);
var eventBridgeSpans = spans.Where(span => span.Tags.TryGetValue("component", out var component) && component == "aws-sdk");

eventBridgeSpans.Should().NotBeEmpty();
ValidateIntegrationSpans(eventBridgeSpans, metadataSchemaVersion, expectedServiceName: clientSpanServiceName, isExternalSpan);

var host = Environment.GetEnvironmentVariable("AWS_SDK_HOST");

var settings = VerifyHelper.GetSpanVerifierSettings();

settings.UseFileName($"{nameof(AwsEventBridgeTests)}.{frameworkName}.Schema{metadataSchemaVersion.ToUpper()}");
settings.AddSimpleScrubber("out.host: localhost", "out.host: aws_eventbridge");
settings.AddSimpleScrubber("out.host: localstack", "out.host: aws_eventbridge");
settings.AddSimpleScrubber("out.host: localstack_arm64", "out.host: aws_eventbridge");
settings.AddSimpleScrubber("peer.service: localhost", "peer.service: aws_eventbridge");
settings.AddSimpleScrubber("peer.service: localstack", "peer.service: aws_eventbridge");
settings.AddSimpleScrubber("peer.service: localstack_arm64", "peer.service: aws_eventbridge");
if (!string.IsNullOrWhiteSpace(host))
{
settings.AddSimpleScrubber(host, "localhost:00000");
}

settings.DisableRequireUniquePrefix();

// Note: http.request spans are expected for the EventBridge APIs that don't have explicit support
// (Only PutEvents and PutEventsAsync are supported right now)
await VerifyHelper.VerifySpans(spans, settings);

telemetry.AssertIntegrationEnabled(IntegrationId.AwsEventBridge);
}
}
}
}
21 changes: 21 additions & 0 deletions tracer/test/Datadog.Trace.TestHelpers/SpanMetadataAPI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,27 @@ public static Result IsAwsSnsRequest(this MockSpan span, string metadataSchemaVe
_ => span.IsAwsSnsRequestV0(),
};

public static Result IsAwsEventBridgeInbound(this MockSpan span, string metadataSchemaVersion) =>
metadataSchemaVersion switch
{
"v1" => span.IsAwsEventBridgeInboundV1(),
_ => span.IsAwsEventBridgeRequestV0(),
};

public static Result IsAwsEventBridgeOutbound(this MockSpan span, string metadataSchemaVersion) =>
metadataSchemaVersion switch
{
"v1" => span.IsAwsEventBridgeOutboundV1(),
_ => span.IsAwsEventBridgeRequestV0(),
};

public static Result IsAwsEventBridgeRequest(this MockSpan span, string metadataSchemaVersion) =>
metadataSchemaVersion switch
{
"v1" => span.IsAwsEventBridgeRequestV1(),
_ => span.IsAwsEventBridgeRequestV0(),
};

public static Result IsAzureServiceBusInbound(this MockSpan span, string metadataSchemaVersion, ISet<string> excludeTags = null) =>
metadataSchemaVersion switch
{
Expand Down
20 changes: 20 additions & 0 deletions tracer/test/Datadog.Trace.TestHelpers/SpanMetadataV0Rules.cs
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,26 @@ public static Result IsAwsSnsRequestV0(this MockSpan span) => Result.FromSpan(sp
.Matches("component", "aws-sdk")
.Matches("span.kind", "client"));

public static Result IsAwsEventBridgeRequestV0(this MockSpan span) => Result.FromSpan(span)
.Properties(s => s
.Matches(Name, "eventbridge.request")
.Matches(Type, "http"))
.Tags(s => s
.Matches("aws.agent", "dotnet-aws-sdk")
.IsPresent("aws.operation")
.IsOptional("aws.region")
.IsOptional("region")
.IsPresent("aws.requestId")
.Matches("aws.service", "EventBridge")
.Matches("aws_service", "EventBridge")
.IsPresent("eventbusname")
.IsPresent("http.method")
.IsPresent("http.status_code")
.IsPresent("http.url")
.IsOptional("_dd.base_service")
.Matches("component", "aws-sdk")
.Matches("span.kind", "client"));

public static Result IsAzureServiceBusInboundV0(this MockSpan span, ISet<string> excludeTags = null) => Result.FromSpan(span, excludeTags)
.Properties(s => s
.MatchesOneOf(Name, "servicebus.receive", "servicebus.process", "consumer")
Expand Down
63 changes: 63 additions & 0 deletions tracer/test/Datadog.Trace.TestHelpers/SpanMetadataV1Rules.cs
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,69 @@ public static Result IsAwsSnsRequestV1(this MockSpan span) => Result.FromSpan(sp
.Matches("component", "aws-sdk")
.Matches("span.kind", "client"));

public static Result IsAwsEventBridgeInboundV1(this MockSpan span) => Result.FromSpan(span)
.Properties(s => s
.Matches(Name, "aws.eventbridge.process")
.Matches(Type, "http"))
.Tags(s => s
.Matches("aws.agent", "dotnet-aws-sdk")
.IsPresent("aws.operation")
.IsOptional("aws.region")
.IsOptional("region")
.IsPresent("aws.requestId")
.Matches("aws.service", "EventBridge")
.Matches("aws_service", "EventBridge")
.IsPresent("eventbusname")
.IsPresent("http.method")
.IsPresent("http.status_code")
.IsPresent("http.url")
.IsOptional("_dd.base_service")
.Matches("component", "aws-sdk")
.Matches("span.kind", "consumer"));

public static Result IsAwsEventBridgeOutboundV1(this MockSpan span) => Result.FromSpan(span)
.Properties(s => s
.Matches(Name, "aws.eventbridge.send")
.Matches(Type, "http"))
.Tags(s => s
.Matches("aws.agent", "dotnet-aws-sdk")
.IsPresent("aws.operation")
.IsOptional("aws.region")
.IsOptional("region")
.IsPresent("aws.requestId")
.Matches("aws.service", "EventBridge")
.Matches("aws_service", "EventBridge")
.IsPresent("eventbusname")
.IsPresent("http.method")
.IsPresent("http.status_code")
.IsPresent("http.url")
.IsPresent("peer.service")
.IsOptional("peer.service.remapped_from")
.MatchesOneOf("_dd.peer.service.source", "eventbusname", "peer.service")
.Matches("component", "aws-sdk")
.Matches("span.kind", "producer"));

public static Result IsAwsEventBridgeRequestV1(this MockSpan span) => Result.FromSpan(span)
.Properties(s => s
.Matches(Name, "aws.eventbridge.request")
.Matches(Type, "http"))
.Tags(s => s
.Matches("aws.agent", "dotnet-aws-sdk")
.IsPresent("aws.operation")
.IsOptional("aws.region")
.IsOptional("region")
.IsPresent("aws.requestId")
.Matches("aws.service", "EventBridge")
.Matches("aws_service", "EventBridge")
.IsPresent("eventbusname")
.IsPresent("http.method")
.IsPresent("http.status_code")
.IsPresent("http.url")
.IsPresent("peer.service")
.IsOptional("peer.service.remapped_from")
.Matches("component", "aws-sdk")
.Matches("span.kind", "client"));

public static Result IsAzureServiceBusInboundV1(this MockSpan span, ISet<string> excludeTags = null) => Result.FromSpan(span, excludeTags)
.Properties(s => s
.MatchesOneOf(Name, "servicebus.receive", "servicebus.process", "consumer")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
[
{
TraceId: Id_1,
SpanId: Id_2,
Name: async-methods,
Resource: async-methods,
Service: Samples.AWS.EventBridge,
Tags: {
env: integration_tests,
language: dotnet,
runtime-id: Guid_1
},
Metrics: {
process_id: 0,
_dd.top_level: 1.0,
_dd.tracer_kr: 1.0,
_sampling_priority_v1: 1.0
}
},
{
TraceId: Id_1,
SpanId: Id_3,
Name: http.request,
Resource: POST localhost:00000/,
Service: Samples.AWS.EventBridge-http-client,
Type: http,
ParentId: Id_2,
Tags: {
component: HttpMessageHandler,
env: integration_tests,
http-client-handler-type: System.Net.Http.HttpClientHandler,
http.method: POST,
http.status_code: 200,
http.url: http://localhost:00000/,
language: dotnet,
out.host: aws_eventbridge,
runtime-id: Guid_1,
span.kind: client,
_dd.base_service: Samples.AWS.EventBridge
},
Metrics: {
_dd.top_level: 1.0
}
},
{
TraceId: Id_1,
SpanId: Id_4,
Name: eventbridge.request,
Resource: EventBridge.PutEvents,
Service: Samples.AWS.EventBridge-aws-eventbridge,
Type: http,
ParentId: Id_2,
Tags: {
aws.agent: dotnet-aws-sdk,
aws.operation: PutEvents,
aws.requestId: Guid_2,
aws.service: EventBridge,
aws_service: EventBridge,
component: aws-sdk,
env: integration_tests,
eventbusname: MyEventBus,
http.method: POST,
http.status_code: 200,
http.url: http://localhost:00000/,
language: dotnet,
runtime-id: Guid_1,
span.kind: client,
_dd.base_service: Samples.AWS.EventBridge
},
Metrics: {
_dd.top_level: 1.0
}
},
{
TraceId: Id_1,
SpanId: Id_5,
Name: http.request,
Resource: POST localhost:00000/,
Service: Samples.AWS.EventBridge-http-client,
Type: http,
ParentId: Id_2,
Tags: {
component: HttpMessageHandler,
env: integration_tests,
http-client-handler-type: System.Net.Http.HttpClientHandler,
http.method: POST,
http.status_code: 200,
http.url: http://localhost:00000/,
language: dotnet,
out.host: aws_eventbridge,
runtime-id: Guid_1,
span.kind: client,
_dd.base_service: Samples.AWS.EventBridge
},
Metrics: {
_dd.top_level: 1.0
}
}
]
Loading

0 comments on commit 5ccd8b7

Please sign in to comment.