Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Activity.GetTagItem #47443

Merged
merged 2 commits into from
Jan 27, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ public string? Id
public System.Diagnostics.Activity SetTag(string key, object? value) { throw null; }
public System.Diagnostics.Activity SetBaggage(string key, string? value) { throw null; }
public string? GetBaggageItem(string key) { throw null; }
public object? GetTagItem(string key) { throw null; }
public System.Diagnostics.Activity SetEndTime(System.DateTime endTimeUtc) { throw null; }
public System.Diagnostics.Activity SetIdFormat(System.Diagnostics.ActivityIdFormat format) { throw null; }
public System.Diagnostics.Activity SetParentId(System.Diagnostics.ActivityTraceId traceId, System.Diagnostics.ActivitySpanId spanId, System.Diagnostics.ActivityTraceFlags activityTraceFlags = System.Diagnostics.ActivityTraceFlags.None) { throw null; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -329,11 +329,19 @@ public IEnumerable<ActivityLink> Links
return null;
}

/// <summary>
/// Returns the value of the Activity tag mapped to the input key/>.
/// Returns null if that key does not exist.
/// </summary>
/// <param name="key">The tag key string.</param>
/// <returns>The tag value mapped to the input key.</returns>
public object? GetTagItem(string key) => _tags?.Get(key) ?? null;

/* Constructors Builder methods */

/// <summary>
/// Note that Activity has a 'builder' pattern, where you call the constructor, a number of 'Set*' and 'Add*' APIs and then
/// call <see cref="Start"/> to build the activity. You MUST call <see cref="Start"/> before using it.
/// call <see cref="Start"/> to build the activity. You MUST call <see cref="Start"/> before using it.
/// </summary>
/// <param name="operationName">Operation's name <see cref="OperationName"/></param>
public Activity(string operationName)
Expand Down Expand Up @@ -1484,6 +1492,23 @@ public void Add(KeyValuePair<string, object?> value)
}
}

public object? Get(string key)
{
// We don't take the lock here so it is possible the Add/Remove operations mutate the list during the Get operation.
LinkedListNode<KeyValuePair<string, object?>>? current = _first;
tarekgh marked this conversation as resolved.
Show resolved Hide resolved
while (current != null)
{
if (current.Value.Key == key)
{
return current.Value.Value;
}

current = current.Next;
}
tarekgh marked this conversation as resolved.
Show resolved Hide resolved

return null;
}

public void Remove(string key)
{

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,12 +140,12 @@ public void TestSetBaggage()
Assert.Equal("5", a.GetBaggageItem("5"));

// Check not added item
Assert.Null(a.GetBaggageItem("6"));
Assert.Null(a.GetBaggageItem("6"));

// Adding none existing key with null value is no-op
a.SetBaggage("6", null);
Assert.Equal(5, a.Baggage.Count());
Assert.Null(a.GetBaggageItem("6"));
Assert.Null(a.GetBaggageItem("6"));

// Check updated item
a.SetBaggage("5", "5.1");
Expand All @@ -166,7 +166,7 @@ public void TestSetBaggage()
// Now Remove second item
a.SetBaggage("5", null);
Assert.Equal(4, a.Baggage.Count());
Assert.Null(a.GetBaggageItem("5"));
Assert.Null(a.GetBaggageItem("5"));
}

[ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))]
Expand Down Expand Up @@ -1606,6 +1606,57 @@ public void TestTagObjects()
}
}

[Fact]
public void TestGetTagItem()
{
Activity a = new Activity("GetTagItem");

// Test empty tags list
Assert.Equal(0, a.TagObjects.Count());
Assert.Null(a.GetTagItem("tag1"));

// Test adding first tag
a.AddTag("tag1", "value1");
Assert.Equal(1, a.TagObjects.Count());
Assert.Equal("value1", a.GetTagItem("tag1"));
Assert.Null(a.GetTagItem("tag2"));

// Test adding one more key
a.AddTag("tag2", "value2");
Assert.Equal(2, a.TagObjects.Count());
Assert.Equal("value1", a.GetTagItem("tag1"));
Assert.Equal("value2", a.GetTagItem("tag2"));

// Test adding duplicate key
a.AddTag("tag1", "value1-d");
Assert.Equal(3, a.TagObjects.Count());
Assert.Equal("value1", a.GetTagItem("tag1"));
Assert.Equal("value2", a.GetTagItem("tag2"));

// Test setting the key (overwrite the value)
a.SetTag("tag1", "value1-O");
Assert.Equal(3, a.TagObjects.Count());
Assert.Equal("value1-O", a.GetTagItem("tag1"));
Assert.Equal("value2", a.GetTagItem("tag2"));

// Test removing the key
a.SetTag("tag1", null);
Assert.Equal(2, a.TagObjects.Count());
Assert.Equal("value1-d", a.GetTagItem("tag1"));
Assert.Equal("value2", a.GetTagItem("tag2"));

a.SetTag("tag1", null);
Assert.Equal(1, a.TagObjects.Count());
Assert.Null(a.GetTagItem("tag1"));
Assert.Equal("value2", a.GetTagItem("tag2"));

a.SetTag("tag2", null);
Assert.Equal(0, a.TagObjects.Count());
Assert.Null(a.GetTagItem("tag1"));
Assert.Null(a.GetTagItem("tag2"));
}


[Theory]
[InlineData("key1", null, true, 1)]
[InlineData("key2", null, false, 0)]
Expand Down