Skip to content

Commit 5ccd8b7

Browse files
committed
Add integration tests
1 parent d05eb4c commit 5ccd8b7

File tree

14 files changed

+640
-0
lines changed

14 files changed

+640
-0
lines changed

Datadog.Trace.sln

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -589,6 +589,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Generated", "Generated", "{
589589
tracer\build\PackageVersionsLatestSpecific.g.props = tracer\build\PackageVersionsLatestSpecific.g.props
590590
EndProjectSection
591591
EndProject
592+
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}"
593+
EndProject
592594
Global
593595
GlobalSection(SolutionConfigurationPlatforms) = preSolution
594596
Debug|Any CPU = Debug|Any CPU
@@ -1409,6 +1411,10 @@ Global
14091411
{2CA0D70C-DFC1-458A-871B-328AB6E87E3A}.Debug|Any CPU.Build.0 = Debug|Any CPU
14101412
{2CA0D70C-DFC1-458A-871B-328AB6E87E3A}.Release|Any CPU.ActiveCfg = Release|Any CPU
14111413
{2CA0D70C-DFC1-458A-871B-328AB6E87E3A}.Release|Any CPU.Build.0 = Release|Any CPU
1414+
{D6155F26-8245-4B66-8944-79C3DF9F9DA3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
1415+
{D6155F26-8245-4B66-8944-79C3DF9F9DA3}.Debug|Any CPU.Build.0 = Debug|Any CPU
1416+
{D6155F26-8245-4B66-8944-79C3DF9F9DA3}.Release|Any CPU.ActiveCfg = Release|Any CPU
1417+
{D6155F26-8245-4B66-8944-79C3DF9F9DA3}.Release|Any CPU.Build.0 = Release|Any CPU
14121418
EndGlobalSection
14131419
GlobalSection(SolutionProperties) = preSolution
14141420
HideSolutionNode = FALSE

tracer/dependabot/Datadog.Dependabot.Integrations.csproj

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@
2626
<!-- Latest package https://www.nuget.org/packages/AWSSDK.DynamoDBv2/3.7.401 -->
2727
<PackageReference Include="AWSSDK.DynamoDBv2" Version="3.7.401" />
2828

29+
<!-- Integration: AWSSDK.EventBridge -->
30+
<!-- Assembly: AWSSDK.EventBridge -->
31+
<!-- Latest package https://www.nuget.org/packages/AWSSDK.EventBridge/3.7.401.23 -->
32+
<PackageReference Include="AWSSDK.EventBridge" Version="3.7.401.23" />
33+
2934
<!-- Integration: AWSSDK.Kinesis -->
3035
<!-- Assembly: AWSSDK.Kinesis -->
3136
<!-- Latest package https://www.nuget.org/packages/AWSSDK.Kinesis/3.7.401.20 -->

tracer/missing-nullability-files.csv

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,7 @@ src/Datadog.Trace/Tagging/AspNetCoreMvcTags.cs
201201
src/Datadog.Trace/Tagging/AspNetCoreTags.cs
202202
src/Datadog.Trace/Tagging/AspNetTags.cs
203203
src/Datadog.Trace/Tagging/AwsDynamoDbTags.cs
204+
src/Datadog.Trace/Tagging/AwsEventBridgeTags.cs
204205
src/Datadog.Trace/Tagging/AwsKinesisTags.cs
205206
src/Datadog.Trace/Tagging/AwsSdkTags.cs
206207
src/Datadog.Trace/Tagging/AwsSnsTags.cs
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
// <copyright file="AwsEventBridgeTests.cs" company="Datadog">
2+
// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2 License.
3+
// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2017 Datadog, Inc.
4+
// </copyright>
5+
6+
using System;
7+
using System.Collections.Generic;
8+
using System.Linq;
9+
using System.Threading.Tasks;
10+
using Datadog.Trace.Configuration;
11+
using Datadog.Trace.TestHelpers;
12+
using FluentAssertions;
13+
using VerifyXunit;
14+
using Xunit;
15+
using Xunit.Abstractions;
16+
17+
namespace Datadog.Trace.ClrProfiler.IntegrationTests.AWS
18+
{
19+
[Trait("RequiresDockerDependency", "true")]
20+
[UsesVerify]
21+
public class AwsEventBridgeTests : TracingIntegrationTest
22+
{
23+
public AwsEventBridgeTests(ITestOutputHelper output)
24+
: base("AWS.EventBridge", output)
25+
{
26+
}
27+
28+
public static IEnumerable<object[]> GetEnabledConfig()
29+
=> from packageVersionArray in PackageVersions.AwsEventBridge
30+
from metadataSchemaVersion in new[] { "v0", "v1" }
31+
select new[] { packageVersionArray[0], metadataSchemaVersion };
32+
33+
public override Result ValidateIntegrationSpan(MockSpan span, string metadataSchemaVersion) => span.Tags["span.kind"] switch
34+
{
35+
SpanKinds.Consumer => span.IsAwsEventBridgeInbound(metadataSchemaVersion),
36+
SpanKinds.Producer => span.IsAwsEventBridgeOutbound(metadataSchemaVersion),
37+
SpanKinds.Client => span.IsAwsEventBridgeRequest(metadataSchemaVersion),
38+
_ => throw new ArgumentException($"span.Tags[\"span.kind\"] is not a supported value for the AWS EventBridge integration: {span.Tags["span.kind"]}", nameof(span)),
39+
};
40+
41+
[SkippableTheory]
42+
[MemberData(nameof(GetEnabledConfig))]
43+
[Trait("Category", "EndToEnd")]
44+
public async Task SubmitsTraces(string packageVersion, string metadataSchemaVersion)
45+
{
46+
SetEnvironmentVariable("DD_TRACE_SPAN_ATTRIBUTE_SCHEMA", metadataSchemaVersion);
47+
var isExternalSpan = metadataSchemaVersion == "v0";
48+
var clientSpanServiceName = isExternalSpan ? $"{EnvironmentHelper.FullSampleName}-aws-eventbridge" : EnvironmentHelper.FullSampleName;
49+
50+
using var telemetry = this.ConfigureTelemetry();
51+
using (var agent = EnvironmentHelper.GetMockAgent())
52+
using (await RunSampleAndWaitForExit(agent, packageVersion: packageVersion))
53+
{
54+
#if NETFRAMEWORK
55+
var expectedCount = 8;
56+
var frameworkName = "NetFramework";
57+
#else
58+
var expectedCount = 4;
59+
var frameworkName = "NetCore";
60+
#endif
61+
var spans = agent.WaitForSpans(expectedCount);
62+
var eventBridgeSpans = spans.Where(span => span.Tags.TryGetValue("component", out var component) && component == "aws-sdk");
63+
64+
eventBridgeSpans.Should().NotBeEmpty();
65+
ValidateIntegrationSpans(eventBridgeSpans, metadataSchemaVersion, expectedServiceName: clientSpanServiceName, isExternalSpan);
66+
67+
var host = Environment.GetEnvironmentVariable("AWS_SDK_HOST");
68+
69+
var settings = VerifyHelper.GetSpanVerifierSettings();
70+
71+
settings.UseFileName($"{nameof(AwsEventBridgeTests)}.{frameworkName}.Schema{metadataSchemaVersion.ToUpper()}");
72+
settings.AddSimpleScrubber("out.host: localhost", "out.host: aws_eventbridge");
73+
settings.AddSimpleScrubber("out.host: localstack", "out.host: aws_eventbridge");
74+
settings.AddSimpleScrubber("out.host: localstack_arm64", "out.host: aws_eventbridge");
75+
settings.AddSimpleScrubber("peer.service: localhost", "peer.service: aws_eventbridge");
76+
settings.AddSimpleScrubber("peer.service: localstack", "peer.service: aws_eventbridge");
77+
settings.AddSimpleScrubber("peer.service: localstack_arm64", "peer.service: aws_eventbridge");
78+
if (!string.IsNullOrWhiteSpace(host))
79+
{
80+
settings.AddSimpleScrubber(host, "localhost:00000");
81+
}
82+
83+
settings.DisableRequireUniquePrefix();
84+
85+
// Note: http.request spans are expected for the EventBridge APIs that don't have explicit support
86+
// (Only PutEvents and PutEventsAsync are supported right now)
87+
await VerifyHelper.VerifySpans(spans, settings);
88+
89+
telemetry.AssertIntegrationEnabled(IntegrationId.AwsEventBridge);
90+
}
91+
}
92+
}
93+
}

tracer/test/Datadog.Trace.TestHelpers/SpanMetadataAPI.cs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,27 @@ public static Result IsAwsSnsRequest(this MockSpan span, string metadataSchemaVe
116116
_ => span.IsAwsSnsRequestV0(),
117117
};
118118

119+
public static Result IsAwsEventBridgeInbound(this MockSpan span, string metadataSchemaVersion) =>
120+
metadataSchemaVersion switch
121+
{
122+
"v1" => span.IsAwsEventBridgeInboundV1(),
123+
_ => span.IsAwsEventBridgeRequestV0(),
124+
};
125+
126+
public static Result IsAwsEventBridgeOutbound(this MockSpan span, string metadataSchemaVersion) =>
127+
metadataSchemaVersion switch
128+
{
129+
"v1" => span.IsAwsEventBridgeOutboundV1(),
130+
_ => span.IsAwsEventBridgeRequestV0(),
131+
};
132+
133+
public static Result IsAwsEventBridgeRequest(this MockSpan span, string metadataSchemaVersion) =>
134+
metadataSchemaVersion switch
135+
{
136+
"v1" => span.IsAwsEventBridgeRequestV1(),
137+
_ => span.IsAwsEventBridgeRequestV0(),
138+
};
139+
119140
public static Result IsAzureServiceBusInbound(this MockSpan span, string metadataSchemaVersion, ISet<string> excludeTags = null) =>
120141
metadataSchemaVersion switch
121142
{

tracer/test/Datadog.Trace.TestHelpers/SpanMetadataV0Rules.cs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,26 @@ public static Result IsAwsSnsRequestV0(this MockSpan span) => Result.FromSpan(sp
216216
.Matches("component", "aws-sdk")
217217
.Matches("span.kind", "client"));
218218

219+
public static Result IsAwsEventBridgeRequestV0(this MockSpan span) => Result.FromSpan(span)
220+
.Properties(s => s
221+
.Matches(Name, "eventbridge.request")
222+
.Matches(Type, "http"))
223+
.Tags(s => s
224+
.Matches("aws.agent", "dotnet-aws-sdk")
225+
.IsPresent("aws.operation")
226+
.IsOptional("aws.region")
227+
.IsOptional("region")
228+
.IsPresent("aws.requestId")
229+
.Matches("aws.service", "EventBridge")
230+
.Matches("aws_service", "EventBridge")
231+
.IsPresent("eventbusname")
232+
.IsPresent("http.method")
233+
.IsPresent("http.status_code")
234+
.IsPresent("http.url")
235+
.IsOptional("_dd.base_service")
236+
.Matches("component", "aws-sdk")
237+
.Matches("span.kind", "client"));
238+
219239
public static Result IsAzureServiceBusInboundV0(this MockSpan span, ISet<string> excludeTags = null) => Result.FromSpan(span, excludeTags)
220240
.Properties(s => s
221241
.MatchesOneOf(Name, "servicebus.receive", "servicebus.process", "consumer")

tracer/test/Datadog.Trace.TestHelpers/SpanMetadataV1Rules.cs

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,69 @@ public static Result IsAwsSnsRequestV1(this MockSpan span) => Result.FromSpan(sp
324324
.Matches("component", "aws-sdk")
325325
.Matches("span.kind", "client"));
326326

327+
public static Result IsAwsEventBridgeInboundV1(this MockSpan span) => Result.FromSpan(span)
328+
.Properties(s => s
329+
.Matches(Name, "aws.eventbridge.process")
330+
.Matches(Type, "http"))
331+
.Tags(s => s
332+
.Matches("aws.agent", "dotnet-aws-sdk")
333+
.IsPresent("aws.operation")
334+
.IsOptional("aws.region")
335+
.IsOptional("region")
336+
.IsPresent("aws.requestId")
337+
.Matches("aws.service", "EventBridge")
338+
.Matches("aws_service", "EventBridge")
339+
.IsPresent("eventbusname")
340+
.IsPresent("http.method")
341+
.IsPresent("http.status_code")
342+
.IsPresent("http.url")
343+
.IsOptional("_dd.base_service")
344+
.Matches("component", "aws-sdk")
345+
.Matches("span.kind", "consumer"));
346+
347+
public static Result IsAwsEventBridgeOutboundV1(this MockSpan span) => Result.FromSpan(span)
348+
.Properties(s => s
349+
.Matches(Name, "aws.eventbridge.send")
350+
.Matches(Type, "http"))
351+
.Tags(s => s
352+
.Matches("aws.agent", "dotnet-aws-sdk")
353+
.IsPresent("aws.operation")
354+
.IsOptional("aws.region")
355+
.IsOptional("region")
356+
.IsPresent("aws.requestId")
357+
.Matches("aws.service", "EventBridge")
358+
.Matches("aws_service", "EventBridge")
359+
.IsPresent("eventbusname")
360+
.IsPresent("http.method")
361+
.IsPresent("http.status_code")
362+
.IsPresent("http.url")
363+
.IsPresent("peer.service")
364+
.IsOptional("peer.service.remapped_from")
365+
.MatchesOneOf("_dd.peer.service.source", "eventbusname", "peer.service")
366+
.Matches("component", "aws-sdk")
367+
.Matches("span.kind", "producer"));
368+
369+
public static Result IsAwsEventBridgeRequestV1(this MockSpan span) => Result.FromSpan(span)
370+
.Properties(s => s
371+
.Matches(Name, "aws.eventbridge.request")
372+
.Matches(Type, "http"))
373+
.Tags(s => s
374+
.Matches("aws.agent", "dotnet-aws-sdk")
375+
.IsPresent("aws.operation")
376+
.IsOptional("aws.region")
377+
.IsOptional("region")
378+
.IsPresent("aws.requestId")
379+
.Matches("aws.service", "EventBridge")
380+
.Matches("aws_service", "EventBridge")
381+
.IsPresent("eventbusname")
382+
.IsPresent("http.method")
383+
.IsPresent("http.status_code")
384+
.IsPresent("http.url")
385+
.IsPresent("peer.service")
386+
.IsOptional("peer.service.remapped_from")
387+
.Matches("component", "aws-sdk")
388+
.Matches("span.kind", "client"));
389+
327390
public static Result IsAzureServiceBusInboundV1(this MockSpan span, ISet<string> excludeTags = null) => Result.FromSpan(span, excludeTags)
328391
.Properties(s => s
329392
.MatchesOneOf(Name, "servicebus.receive", "servicebus.process", "consumer")
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
[
2+
{
3+
TraceId: Id_1,
4+
SpanId: Id_2,
5+
Name: async-methods,
6+
Resource: async-methods,
7+
Service: Samples.AWS.EventBridge,
8+
Tags: {
9+
env: integration_tests,
10+
language: dotnet,
11+
runtime-id: Guid_1
12+
},
13+
Metrics: {
14+
process_id: 0,
15+
_dd.top_level: 1.0,
16+
_dd.tracer_kr: 1.0,
17+
_sampling_priority_v1: 1.0
18+
}
19+
},
20+
{
21+
TraceId: Id_1,
22+
SpanId: Id_3,
23+
Name: http.request,
24+
Resource: POST localhost:00000/,
25+
Service: Samples.AWS.EventBridge-http-client,
26+
Type: http,
27+
ParentId: Id_2,
28+
Tags: {
29+
component: HttpMessageHandler,
30+
env: integration_tests,
31+
http-client-handler-type: System.Net.Http.HttpClientHandler,
32+
http.method: POST,
33+
http.status_code: 200,
34+
http.url: http://localhost:00000/,
35+
language: dotnet,
36+
out.host: aws_eventbridge,
37+
runtime-id: Guid_1,
38+
span.kind: client,
39+
_dd.base_service: Samples.AWS.EventBridge
40+
},
41+
Metrics: {
42+
_dd.top_level: 1.0
43+
}
44+
},
45+
{
46+
TraceId: Id_1,
47+
SpanId: Id_4,
48+
Name: eventbridge.request,
49+
Resource: EventBridge.PutEvents,
50+
Service: Samples.AWS.EventBridge-aws-eventbridge,
51+
Type: http,
52+
ParentId: Id_2,
53+
Tags: {
54+
aws.agent: dotnet-aws-sdk,
55+
aws.operation: PutEvents,
56+
aws.requestId: Guid_2,
57+
aws.service: EventBridge,
58+
aws_service: EventBridge,
59+
component: aws-sdk,
60+
env: integration_tests,
61+
eventbusname: MyEventBus,
62+
http.method: POST,
63+
http.status_code: 200,
64+
http.url: http://localhost:00000/,
65+
language: dotnet,
66+
runtime-id: Guid_1,
67+
span.kind: client,
68+
_dd.base_service: Samples.AWS.EventBridge
69+
},
70+
Metrics: {
71+
_dd.top_level: 1.0
72+
}
73+
},
74+
{
75+
TraceId: Id_1,
76+
SpanId: Id_5,
77+
Name: http.request,
78+
Resource: POST localhost:00000/,
79+
Service: Samples.AWS.EventBridge-http-client,
80+
Type: http,
81+
ParentId: Id_2,
82+
Tags: {
83+
component: HttpMessageHandler,
84+
env: integration_tests,
85+
http-client-handler-type: System.Net.Http.HttpClientHandler,
86+
http.method: POST,
87+
http.status_code: 200,
88+
http.url: http://localhost:00000/,
89+
language: dotnet,
90+
out.host: aws_eventbridge,
91+
runtime-id: Guid_1,
92+
span.kind: client,
93+
_dd.base_service: Samples.AWS.EventBridge
94+
},
95+
Metrics: {
96+
_dd.top_level: 1.0
97+
}
98+
}
99+
]

0 commit comments

Comments
 (0)