From 80e9f3ae61fe3686462d93161a37ba277de1335d Mon Sep 17 00:00:00 2001 From: Zach Montoya Date: Fri, 22 Nov 2024 13:02:59 -0800 Subject: [PATCH 1/8] SpanLink API Update: Remove DecoratedSpan property so that we only operate on SpanContext --- tracer/src/Datadog.Trace/Span.cs | 2 +- tracer/src/Datadog.Trace/SpanLink.cs | 16 +++------------- .../test/Datadog.Trace.Tests/SpanLinksTests.cs | 9 ++++++--- 3 files changed, 10 insertions(+), 17 deletions(-) diff --git a/tracer/src/Datadog.Trace/Span.cs b/tracer/src/Datadog.Trace/Span.cs index a1ec204a9d64..7b1547b20ca1 100644 --- a/tracer/src/Datadog.Trace/Span.cs +++ b/tracer/src/Datadog.Trace/Span.cs @@ -550,7 +550,7 @@ internal SpanLink AddSpanLink(Span spanLinkToAdd, List(); - var spanLink = new SpanLink(spanLinkToAdd, this, attributes); + var spanLink = new SpanLink(spanLinkToAdd, attributes); SpanLinks.Add(spanLink); return spanLink; } diff --git a/tracer/src/Datadog.Trace/SpanLink.cs b/tracer/src/Datadog.Trace/SpanLink.cs index 627536e90693..fc6bc00b6e9f 100644 --- a/tracer/src/Datadog.Trace/SpanLink.cs +++ b/tracer/src/Datadog.Trace/SpanLink.cs @@ -25,17 +25,15 @@ internal class SpanLink /// in OpenTelemetry that's called a Span Context, which may also include tracestate and trace flags. /// /// The context of the spanlink to extract attributes from - /// Reference to the span you're adding SpanLinks to /// Optional dictionary of attributes to take for the spanlink. - public SpanLink(SpanContext spanLinkContext, Span decoratedSpan, List>? attributes = null) + public SpanLink(SpanContext spanLinkContext, List>? attributes = null) { Context = spanLinkContext; - DecoratedSpan = decoratedSpan; Attributes = attributes; } - public SpanLink(Span spanToLink, Span decoratedSpan, List>? attributes = null) - : this(spanToLink.Context, decoratedSpan, attributes) + public SpanLink(Span spanToLink, List>? attributes = null) + : this(spanToLink.Context, attributes) { } @@ -43,8 +41,6 @@ public SpanLink(Span spanToLink, Span decoratedSpan, List /// Adds an Attribute to the SpanLink. /// @@ -52,12 +48,6 @@ public SpanLink(Span spanToLink, Span decoratedSpan, Listvalue of attribute public void AddAttribute(string name, string value) { - if (DecoratedSpan.IsFinished) - { - Log.Warning("AddAttribute should not be called after the decorated span was closed"); - return; - } - var newAttribute = new KeyValuePair(name, value); Attributes ??= []; diff --git a/tracer/test/Datadog.Trace.Tests/SpanLinksTests.cs b/tracer/test/Datadog.Trace.Tests/SpanLinksTests.cs index ce2904f34d41..830c02f2fe2b 100644 --- a/tracer/test/Datadog.Trace.Tests/SpanLinksTests.cs +++ b/tracer/test/Datadog.Trace.Tests/SpanLinksTests.cs @@ -3,10 +3,12 @@ // This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2017 Datadog, Inc. // +using System.Collections.Generic; using Castle.Core.Internal; using Datadog.Trace.Agent; using Datadog.Trace.Configuration; using Datadog.Trace.Sampling; +using FluentAssertions; using Moq; using Xunit; @@ -39,7 +41,7 @@ public void AddLink_InCloseSpan() } [Fact] - public void AddAttribute_ToLink_InCloseSpan() + public void AddAttribute_Succeeds_AfterSpanFinished() { var parentScope = (Scope)_tracer.StartActive("Parent"); var childScope = (Scope)_tracer.StartActive("Child"); @@ -48,8 +50,9 @@ public void AddAttribute_ToLink_InCloseSpan() var childSpan = childScope.Span; var spanLink = childSpan.AddSpanLink(parentSpan); childSpan.Finish(); - spanLink.AddAttribute("should", "return null"); - Assert.Null(spanLink.Attributes); + spanLink.AddAttribute("key", "value"); + + spanLink.Attributes.Should().BeEquivalentTo(new[] { new KeyValuePair("key", "value") }); } } } From 342b5fc4813df16cf3b3b970b2fff9fd8a6841d7 Mon Sep 17 00:00:00 2001 From: Zach Montoya Date: Tue, 19 Nov 2024 17:02:10 -0800 Subject: [PATCH 2/8] Update Span.AddSpanLink API to accept a SpanLink instead of a Span. This updated interface is eaiser to use from instrumentations when there are no Spans for incoming headers, only span contexts. --- tracer/src/Datadog.Trace/Activity/OtlpHelpers.cs | 4 ++-- tracer/src/Datadog.Trace/Span.cs | 10 +++------- .../MessagePack/SpanMessagePackFormatterTests.cs | 9 ++++++--- tracer/test/Datadog.Trace.Tests/SpanLinksTests.cs | 15 ++++++++++----- 4 files changed, 21 insertions(+), 17 deletions(-) diff --git a/tracer/src/Datadog.Trace/Activity/OtlpHelpers.cs b/tracer/src/Datadog.Trace/Activity/OtlpHelpers.cs index 91ad56f5a3bf..920e98193008 100644 --- a/tracer/src/Datadog.Trace/Activity/OtlpHelpers.cs +++ b/tracer/src/Datadog.Trace/Activity/OtlpHelpers.cs @@ -254,8 +254,8 @@ private static void ExtractActivityLinks(Span span, IActivity5? activity spanContext.LastParentId = traceState.LastParent; spanContext.PropagatedTags = traceTags; - var extractedSpan = new Span(spanContext, DateTimeOffset.Now, new CommonTags()); - var spanLink = span.AddSpanLink(extractedSpan); + var spanLink = new SpanLink(spanContext); + span.AddSpanLink(spanLink); if (duckLink.Tags is not null) { diff --git a/tracer/src/Datadog.Trace/Span.cs b/tracer/src/Datadog.Trace/Span.cs index 7b1547b20ca1..93cd9afccc6d 100644 --- a/tracer/src/Datadog.Trace/Span.cs +++ b/tracer/src/Datadog.Trace/Span.cs @@ -538,21 +538,17 @@ private void WriteCloseDebugMessage() /// /// Adds a SpanLink to the current Span if the Span is active. /// - /// The Span to add as a SpanLink - /// List of KeyValue pairings of attributes to add to the SpanLink. Defaults to null - /// returns the SpanLink on success or null on failure (span is closed already) - internal SpanLink AddSpanLink(Span spanLinkToAdd, List> attributes = null) + /// The SpanLink to add + internal void AddSpanLink(SpanLink spanLink) { if (IsFinished) { Log.Warning("AddSpanLink should not be called after the span was closed"); - return null; + return; } SpanLinks ??= new List(); - var spanLink = new SpanLink(spanLinkToAdd, attributes); SpanLinks.Add(spanLink); - return spanLink; } } } diff --git a/tracer/test/Datadog.Trace.Tests/Agent/MessagePack/SpanMessagePackFormatterTests.cs b/tracer/test/Datadog.Trace.Tests/Agent/MessagePack/SpanMessagePackFormatterTests.cs index 967b6e638c6b..37d70d17631f 100644 --- a/tracer/test/Datadog.Trace.Tests/Agent/MessagePack/SpanMessagePackFormatterTests.cs +++ b/tracer/test/Datadog.Trace.Tests/Agent/MessagePack/SpanMessagePackFormatterTests.cs @@ -141,11 +141,14 @@ public void SpanLink_Tag_Serialization() new("pair", "false"), new("arbitrary", "56709") }; - spans[0].AddSpanLink(spans[1], attributesToAdd); - var tmpSpanLink = spans[1].AddSpanLink(spans[2]); + spans[0].AddSpanLink(new SpanLink(spans[1].Context, attributesToAdd)); + + var tmpSpanLink = new SpanLink(spans[2].Context); + spans[1].AddSpanLink(tmpSpanLink); tmpSpanLink.AddAttribute("attribute1", "value1"); tmpSpanLink.AddAttribute("attribute2", "value2"); - spans[1].AddSpanLink(spans[0]); + + spans[1].AddSpanLink(new SpanLink(spans[0].Context)); foreach (var span in spans) { diff --git a/tracer/test/Datadog.Trace.Tests/SpanLinksTests.cs b/tracer/test/Datadog.Trace.Tests/SpanLinksTests.cs index 830c02f2fe2b..513b5352777b 100644 --- a/tracer/test/Datadog.Trace.Tests/SpanLinksTests.cs +++ b/tracer/test/Datadog.Trace.Tests/SpanLinksTests.cs @@ -28,31 +28,36 @@ public SpanLinksTests() } [Fact] - public void AddLink_InCloseSpan() + public void AddLink_AfterSpanFinished_IsNoOp() { var parentScope = (Scope)_tracer.StartActive("Parent"); var childScope = (Scope)_tracer.StartActive("Child"); var parentSpan = parentScope.Span; var childSpan = childScope.Span; + var spanLink = new SpanLink(parentSpan.Context); childSpan.Finish(); - Assert.Null(childSpan.AddSpanLink(parentSpan)); + + childSpan.AddSpanLink(spanLink); + childSpan.SpanLinks.Should().BeNullOrEmpty(); } [Fact] - public void AddAttribute_Succeeds_AfterSpanFinished() + public void AddAttribute_BeforeSpanFinished_IsSuccessful() { var parentScope = (Scope)_tracer.StartActive("Parent"); var childScope = (Scope)_tracer.StartActive("Child"); var parentSpan = parentScope.Span; var childSpan = childScope.Span; - var spanLink = childSpan.AddSpanLink(parentSpan); - childSpan.Finish(); + var spanLink = new SpanLink(parentSpan.Context); + + childSpan.AddSpanLink(spanLink); spanLink.AddAttribute("key", "value"); spanLink.Attributes.Should().BeEquivalentTo(new[] { new KeyValuePair("key", "value") }); + childSpan.Finish(); } } } From 274ca4623b7cfc6887c1046ed77d90255154393b Mon Sep 17 00:00:00 2001 From: Zach Montoya Date: Fri, 22 Nov 2024 13:33:53 -0800 Subject: [PATCH 3/8] Updates to make the SpanLink API more similar to the Activity API: - Rename the method from AddSpanLink to AddLink (this also mirrors the suggestion from OpenTelemetry Tracing API spec) - Return the Span object instead of returning nothing --- tracer/src/Datadog.Trace/Activity/OtlpHelpers.cs | 2 +- tracer/src/Datadog.Trace/Span.cs | 7 ++++--- .../Agent/MessagePack/SpanMessagePackFormatterTests.cs | 6 +++--- tracer/test/Datadog.Trace.Tests/SpanLinksTests.cs | 4 ++-- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/tracer/src/Datadog.Trace/Activity/OtlpHelpers.cs b/tracer/src/Datadog.Trace/Activity/OtlpHelpers.cs index 920e98193008..e457c0ffccf5 100644 --- a/tracer/src/Datadog.Trace/Activity/OtlpHelpers.cs +++ b/tracer/src/Datadog.Trace/Activity/OtlpHelpers.cs @@ -255,7 +255,7 @@ private static void ExtractActivityLinks(Span span, IActivity5? activity spanContext.PropagatedTags = traceTags; var spanLink = new SpanLink(spanContext); - span.AddSpanLink(spanLink); + span.AddLink(spanLink); if (duckLink.Tags is not null) { diff --git a/tracer/src/Datadog.Trace/Span.cs b/tracer/src/Datadog.Trace/Span.cs index 93cd9afccc6d..b5ffd341ae98 100644 --- a/tracer/src/Datadog.Trace/Span.cs +++ b/tracer/src/Datadog.Trace/Span.cs @@ -539,16 +539,17 @@ private void WriteCloseDebugMessage() /// Adds a SpanLink to the current Span if the Span is active. /// /// The SpanLink to add - internal void AddSpanLink(SpanLink spanLink) + internal Span AddLink(SpanLink spanLink) { if (IsFinished) { - Log.Warning("AddSpanLink should not be called after the span was closed"); - return; + Log.Warning("AddLink should not be called after the span was closed"); + return this; } SpanLinks ??= new List(); SpanLinks.Add(spanLink); + return this; } } } diff --git a/tracer/test/Datadog.Trace.Tests/Agent/MessagePack/SpanMessagePackFormatterTests.cs b/tracer/test/Datadog.Trace.Tests/Agent/MessagePack/SpanMessagePackFormatterTests.cs index 37d70d17631f..f859e9a7f0e5 100644 --- a/tracer/test/Datadog.Trace.Tests/Agent/MessagePack/SpanMessagePackFormatterTests.cs +++ b/tracer/test/Datadog.Trace.Tests/Agent/MessagePack/SpanMessagePackFormatterTests.cs @@ -141,14 +141,14 @@ public void SpanLink_Tag_Serialization() new("pair", "false"), new("arbitrary", "56709") }; - spans[0].AddSpanLink(new SpanLink(spans[1].Context, attributesToAdd)); + spans[0].AddLink(new SpanLink(spans[1].Context, attributesToAdd)); var tmpSpanLink = new SpanLink(spans[2].Context); - spans[1].AddSpanLink(tmpSpanLink); + spans[1].AddLink(tmpSpanLink); tmpSpanLink.AddAttribute("attribute1", "value1"); tmpSpanLink.AddAttribute("attribute2", "value2"); - spans[1].AddSpanLink(new SpanLink(spans[0].Context)); + spans[1].AddLink(new SpanLink(spans[0].Context)); foreach (var span in spans) { diff --git a/tracer/test/Datadog.Trace.Tests/SpanLinksTests.cs b/tracer/test/Datadog.Trace.Tests/SpanLinksTests.cs index 513b5352777b..55aeb08bbe0f 100644 --- a/tracer/test/Datadog.Trace.Tests/SpanLinksTests.cs +++ b/tracer/test/Datadog.Trace.Tests/SpanLinksTests.cs @@ -39,7 +39,7 @@ public void AddLink_AfterSpanFinished_IsNoOp() childSpan.Finish(); - childSpan.AddSpanLink(spanLink); + childSpan.AddLink(spanLink); childSpan.SpanLinks.Should().BeNullOrEmpty(); } @@ -53,7 +53,7 @@ public void AddAttribute_BeforeSpanFinished_IsSuccessful() var childSpan = childScope.Span; var spanLink = new SpanLink(parentSpan.Context); - childSpan.AddSpanLink(spanLink); + childSpan.AddLink(spanLink); spanLink.AddAttribute("key", "value"); spanLink.Attributes.Should().BeEquivalentTo(new[] { new KeyValuePair("key", "value") }); From 56fbd234c4b85598c5ecd5c4220de1b87c17bdd5 Mon Sep 17 00:00:00 2001 From: Zach Montoya Date: Fri, 22 Nov 2024 14:09:34 -0800 Subject: [PATCH 4/8] Add small doc comment for new Span return --- tracer/src/Datadog.Trace/Span.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/tracer/src/Datadog.Trace/Span.cs b/tracer/src/Datadog.Trace/Span.cs index b5ffd341ae98..941a62bf0310 100644 --- a/tracer/src/Datadog.Trace/Span.cs +++ b/tracer/src/Datadog.Trace/Span.cs @@ -539,6 +539,7 @@ private void WriteCloseDebugMessage() /// Adds a SpanLink to the current Span if the Span is active. /// /// The SpanLink to add + /// This span to allow method chaining. internal Span AddLink(SpanLink spanLink) { if (IsFinished) From f5451ff7ed1e1665f2bd35f26e0b848f0ee424aa Mon Sep 17 00:00:00 2001 From: Zach Montoya Date: Tue, 3 Dec 2024 13:39:38 -0800 Subject: [PATCH 5/8] Delete SpanLink constructor that accepts a Span --- tracer/src/Datadog.Trace/SpanLink.cs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/tracer/src/Datadog.Trace/SpanLink.cs b/tracer/src/Datadog.Trace/SpanLink.cs index fc6bc00b6e9f..1028963845da 100644 --- a/tracer/src/Datadog.Trace/SpanLink.cs +++ b/tracer/src/Datadog.Trace/SpanLink.cs @@ -32,11 +32,6 @@ public SpanLink(SpanContext spanLinkContext, List>? Attributes = attributes; } - public SpanLink(Span spanToLink, List>? attributes = null) - : this(spanToLink.Context, attributes) - { - } - public List>? Attributes { get; private set; } public SpanContext Context { get; } From 57db1435e9be61370b3c460838e2c8a4282981c6 Mon Sep 17 00:00:00 2001 From: Zach Montoya Date: Tue, 3 Dec 2024 13:55:48 -0800 Subject: [PATCH 6/8] Re-organize unit tests somewhat --- .../Datadog.Trace.Tests/SpanLinksTests.cs | 16 ---------- tracer/test/Datadog.Trace.Tests/SpanTests.cs | 32 +++++++++++++++++++ 2 files changed, 32 insertions(+), 16 deletions(-) diff --git a/tracer/test/Datadog.Trace.Tests/SpanLinksTests.cs b/tracer/test/Datadog.Trace.Tests/SpanLinksTests.cs index 55aeb08bbe0f..17c70a4b7ee0 100644 --- a/tracer/test/Datadog.Trace.Tests/SpanLinksTests.cs +++ b/tracer/test/Datadog.Trace.Tests/SpanLinksTests.cs @@ -27,22 +27,6 @@ public SpanLinksTests() _tracer = new Tracer(settings, writerMock.Object, samplerMock.Object, scopeManager: null, statsd: null); } - [Fact] - public void AddLink_AfterSpanFinished_IsNoOp() - { - var parentScope = (Scope)_tracer.StartActive("Parent"); - var childScope = (Scope)_tracer.StartActive("Child"); - - var parentSpan = parentScope.Span; - var childSpan = childScope.Span; - var spanLink = new SpanLink(parentSpan.Context); - - childSpan.Finish(); - - childSpan.AddLink(spanLink); - childSpan.SpanLinks.Should().BeNullOrEmpty(); - } - [Fact] public void AddAttribute_BeforeSpanFinished_IsSuccessful() { diff --git a/tracer/test/Datadog.Trace.Tests/SpanTests.cs b/tracer/test/Datadog.Trace.Tests/SpanTests.cs index 6a217d299e88..b583c40536b9 100644 --- a/tracer/test/Datadog.Trace.Tests/SpanTests.cs +++ b/tracer/test/Datadog.Trace.Tests/SpanTests.cs @@ -69,6 +69,38 @@ public void SetPeerServiceTag_CallsRemapper() span.GetTag(Tags.PeerServiceRemappedFrom).Should().Be("a-peer-service"); } + [Fact] + public void AddLink_BeforeSpanFinished_IsSuccessful() + { + var parentScope = (Scope)_tracer.StartActive("Parent"); + var childScope = (Scope)_tracer.StartActive("Child"); + + var parentSpan = parentScope.Span; + var childSpan = childScope.Span; + var spanLink = new SpanLink(parentSpan.Context); + + childSpan.AddLink(spanLink); + childSpan.Finish(); + + childSpan.SpanLinks.Should().ContainSingle(); + } + + [Fact] + public void AddLink_AfterSpanFinished_IsNoOp() + { + var parentScope = (Scope)_tracer.StartActive("Parent"); + var childScope = (Scope)_tracer.StartActive("Child"); + + var parentSpan = parentScope.Span; + var childSpan = childScope.Span; + var spanLink = new SpanLink(parentSpan.Context); + + childSpan.Finish(); + childSpan.AddLink(spanLink); + + childSpan.SpanLinks.Should().BeNullOrEmpty(); + } + [Fact] public void Finish_StartTimeInThePastWithNoEndTime_DurationProperlyComputed() { From 03c531513393a3fa3ba3988475433bedc9e863bd Mon Sep 17 00:00:00 2001 From: Zach Montoya Date: Thu, 19 Dec 2024 13:43:19 -0800 Subject: [PATCH 7/8] Remove the SpanLink.AddAttribute method. This aligns the API with the OpenTelemetry Tracing API and Activity API --- .../src/Datadog.Trace/Activity/OtlpHelpers.cs | 10 ++-- tracer/src/Datadog.Trace/SpanLink.cs | 15 +----- .../SpanMessagePackFormatterTests.cs | 9 ++-- .../Datadog.Trace.Tests/SpanLinksTests.cs | 47 ------------------- 4 files changed, 12 insertions(+), 69 deletions(-) delete mode 100644 tracer/test/Datadog.Trace.Tests/SpanLinksTests.cs diff --git a/tracer/src/Datadog.Trace/Activity/OtlpHelpers.cs b/tracer/src/Datadog.Trace/Activity/OtlpHelpers.cs index e457c0ffccf5..816daca016ce 100644 --- a/tracer/src/Datadog.Trace/Activity/OtlpHelpers.cs +++ b/tracer/src/Datadog.Trace/Activity/OtlpHelpers.cs @@ -254,9 +254,7 @@ private static void ExtractActivityLinks(Span span, IActivity5? activity spanContext.LastParentId = traceState.LastParent; spanContext.PropagatedTags = traceTags; - var spanLink = new SpanLink(spanContext); - span.AddLink(spanLink); - + List> attributes = new(); if (duckLink.Tags is not null) { foreach (var kvp in duckLink.Tags) @@ -271,18 +269,20 @@ private static void ExtractActivityLinks(Span span, IActivity5? activity { if (item?.ToString() is { } value) { - spanLink.AddAttribute($"{kvp.Key}.{index}", value); + attributes.Add(new($"{kvp.Key}.{index}", value)); index++; } } } else if (kvp.Value?.ToString() is { } kvpValue) { - spanLink.AddAttribute(kvp.Key, kvpValue); + attributes.Add(new(kvp.Key, kvpValue)); } } } } + + span.AddLink(new SpanLink(spanContext, attributes)); } } diff --git a/tracer/src/Datadog.Trace/SpanLink.cs b/tracer/src/Datadog.Trace/SpanLink.cs index 1028963845da..393d3bc944d8 100644 --- a/tracer/src/Datadog.Trace/SpanLink.cs +++ b/tracer/src/Datadog.Trace/SpanLink.cs @@ -34,18 +34,5 @@ public SpanLink(SpanContext spanLinkContext, List>? public List>? Attributes { get; private set; } - public SpanContext Context { get; } - - /// - /// Adds an Attribute to the SpanLink. - /// - /// name of attribute - /// value of attribute - public void AddAttribute(string name, string value) - { - var newAttribute = new KeyValuePair(name, value); - Attributes ??= []; - - Attributes.Add(newAttribute); - } + public SpanContext Context { get; } } diff --git a/tracer/test/Datadog.Trace.Tests/Agent/MessagePack/SpanMessagePackFormatterTests.cs b/tracer/test/Datadog.Trace.Tests/Agent/MessagePack/SpanMessagePackFormatterTests.cs index f859e9a7f0e5..0af46c1b4506 100644 --- a/tracer/test/Datadog.Trace.Tests/Agent/MessagePack/SpanMessagePackFormatterTests.cs +++ b/tracer/test/Datadog.Trace.Tests/Agent/MessagePack/SpanMessagePackFormatterTests.cs @@ -143,10 +143,13 @@ public void SpanLink_Tag_Serialization() }; spans[0].AddLink(new SpanLink(spans[1].Context, attributesToAdd)); - var tmpSpanLink = new SpanLink(spans[2].Context); + var tmpSpanLinkAttributesToAdd = new List> + { + new("attribute1", "value1"), + new("attribute2", "value2"), + }; + var tmpSpanLink = new SpanLink(spans[2].Context, tmpSpanLinkAttributesToAdd); spans[1].AddLink(tmpSpanLink); - tmpSpanLink.AddAttribute("attribute1", "value1"); - tmpSpanLink.AddAttribute("attribute2", "value2"); spans[1].AddLink(new SpanLink(spans[0].Context)); diff --git a/tracer/test/Datadog.Trace.Tests/SpanLinksTests.cs b/tracer/test/Datadog.Trace.Tests/SpanLinksTests.cs deleted file mode 100644 index 17c70a4b7ee0..000000000000 --- a/tracer/test/Datadog.Trace.Tests/SpanLinksTests.cs +++ /dev/null @@ -1,47 +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.Collections.Generic; -using Castle.Core.Internal; -using Datadog.Trace.Agent; -using Datadog.Trace.Configuration; -using Datadog.Trace.Sampling; -using FluentAssertions; -using Moq; -using Xunit; - -namespace Datadog.Trace.Tests -{ - public class SpanLinksTests - { - private readonly Tracer _tracer; - - public SpanLinksTests() - { - var settings = new TracerSettings(); - var writerMock = new Mock(); - var samplerMock = new Mock(); - - _tracer = new Tracer(settings, writerMock.Object, samplerMock.Object, scopeManager: null, statsd: null); - } - - [Fact] - public void AddAttribute_BeforeSpanFinished_IsSuccessful() - { - var parentScope = (Scope)_tracer.StartActive("Parent"); - var childScope = (Scope)_tracer.StartActive("Child"); - - var parentSpan = parentScope.Span; - var childSpan = childScope.Span; - var spanLink = new SpanLink(parentSpan.Context); - - childSpan.AddLink(spanLink); - spanLink.AddAttribute("key", "value"); - - spanLink.Attributes.Should().BeEquivalentTo(new[] { new KeyValuePair("key", "value") }); - childSpan.Finish(); - } - } -} From 0646b86ca9cecee93954bcf55dc41dca606d8a58 Mon Sep 17 00:00:00 2001 From: Zach Montoya Date: Thu, 19 Dec 2024 13:52:29 -0800 Subject: [PATCH 8/8] Add stronger SpanLink test with trace-id and span-id check --- tracer/test/Datadog.Trace.Tests/SpanTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tracer/test/Datadog.Trace.Tests/SpanTests.cs b/tracer/test/Datadog.Trace.Tests/SpanTests.cs index b583c40536b9..9ebae42de3b5 100644 --- a/tracer/test/Datadog.Trace.Tests/SpanTests.cs +++ b/tracer/test/Datadog.Trace.Tests/SpanTests.cs @@ -82,7 +82,7 @@ public void AddLink_BeforeSpanFinished_IsSuccessful() childSpan.AddLink(spanLink); childSpan.Finish(); - childSpan.SpanLinks.Should().ContainSingle(); + childSpan.SpanLinks.Should().ContainSingle().Which.Should().Match(spanLink => spanLink.Context.TraceId128 == parentSpan.TraceId128 && spanLink.Context.SpanId == parentSpan.SpanId); } [Fact]