Skip to content

Commit cf2ab99

Browse files
committed
- ComponentsActivitySourceTest
- cleanup
1 parent 0a4d488 commit cf2ab99

File tree

4 files changed

+266
-14
lines changed

4 files changed

+266
-14
lines changed

src/Components/Components/src/ComponentsActivitySource.cs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,9 @@ namespace Microsoft.AspNetCore.Components;
1111
internal class ComponentsActivitySource
1212
{
1313
internal const string Name = "Microsoft.AspNetCore.Components";
14-
internal const string OnEventName = $"{Name}.OnEvent";
14+
internal const string OnCircuitName = $"{Name}.OnCircuit";
1515
internal const string OnRouteName = $"{Name}.OnRoute";
16+
internal const string OnEventName = $"{Name}.OnEvent";
1617

1718
private ActivityContext _httpContext;
1819
private ActivityContext _circuitContext;
@@ -35,7 +36,7 @@ public static ActivityContext CaptureHttpContext()
3536
{
3637
_circuitId = circuitId;
3738

38-
var activity = ActivitySource.CreateActivity(OnRouteName, ActivityKind.Server, parentId: null, null, null);
39+
var activity = ActivitySource.CreateActivity(OnCircuitName, ActivityKind.Server, parentId: null, null, null);
3940
if (activity is not null)
4041
{
4142
if (activity.IsAllDataRequested)
@@ -56,10 +57,10 @@ public static ActivityContext CaptureHttpContext()
5657
return activity;
5758
}
5859

59-
public void FailCircuitActivity(Activity activity, Exception ex)
60+
public void FailCircuitActivity(Activity? activity, Exception ex)
6061
{
6162
_circuitContext = default;
62-
if (!activity.IsStopped)
63+
if (activity != null && !activity.IsStopped)
6364
{
6465
activity.SetTag("error.type", ex.GetType().FullName);
6566
activity.SetStatus(ActivityStatusCode.Error);
@@ -151,22 +152,22 @@ public void FailCircuitActivity(Activity activity, Exception ex)
151152
return activity;
152153
}
153154

154-
public static void FailEventActivity(Activity activity, Exception ex)
155+
public static void FailEventActivity(Activity? activity, Exception ex)
155156
{
156-
if (!activity.IsStopped)
157+
if (activity != null && !activity.IsStopped)
157158
{
158159
activity.SetTag("error.type", ex.GetType().FullName);
159160
activity.SetStatus(ActivityStatusCode.Error);
160161
activity.Stop();
161162
}
162163
}
163164

164-
public static async Task CaptureEventStopAsync(Task task, Activity activity)
165+
public static async Task CaptureEventStopAsync(Task task, Activity? activity)
165166
{
166167
try
167168
{
168169
await task;
169-
activity.Stop();
170+
activity?.Stop();
170171
}
171172
catch (Exception ex)
172173
{
Lines changed: 251 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,251 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using System.Diagnostics;
5+
6+
namespace Microsoft.AspNetCore.Components;
7+
8+
public class ComponentsActivitySourceTest
9+
{
10+
private readonly ActivityListener _listener;
11+
private readonly List<Activity> _activities;
12+
13+
public ComponentsActivitySourceTest()
14+
{
15+
_activities = new List<Activity>();
16+
_listener = new ActivityListener
17+
{
18+
ShouldListenTo = source => source.Name == ComponentsActivitySource.Name,
19+
Sample = (ref ActivityCreationOptions<ActivityContext> options) => ActivitySamplingResult.AllData,
20+
ActivityStarted = activity => _activities.Add(activity),
21+
ActivityStopped = activity => { }
22+
};
23+
ActivitySource.AddActivityListener(_listener);
24+
}
25+
26+
[Fact]
27+
public void Constructor_CreatesActivitySourceCorrectly()
28+
{
29+
// Arrange & Act
30+
var componentsActivitySource = new ComponentsActivitySource();
31+
32+
// Assert
33+
Assert.NotNull(componentsActivitySource);
34+
}
35+
36+
[Fact]
37+
public void CaptureHttpContext_ReturnsDefault_WhenNoCurrentActivity()
38+
{
39+
// Arrange
40+
Activity.Current = null;
41+
42+
// Act
43+
var result = ComponentsActivitySource.CaptureHttpContext();
44+
45+
// Assert
46+
Assert.Equal(default, result);
47+
}
48+
49+
[Fact]
50+
public void CaptureHttpContext_ReturnsDefault_WhenActivityHasWrongName()
51+
{
52+
// Arrange
53+
using var activity = new ActivitySource("Test").StartActivity("WrongName");
54+
Activity.Current = activity;
55+
56+
// Act
57+
var result = ComponentsActivitySource.CaptureHttpContext();
58+
59+
// Assert
60+
Assert.Equal(default, result);
61+
}
62+
63+
[Fact]
64+
public void StartCircuitActivity_CreatesAndStartsActivity()
65+
{
66+
// Arrange
67+
var componentsActivitySource = new ComponentsActivitySource();
68+
var circuitId = "test-circuit-id";
69+
var httpContext = new ActivityContext(ActivityTraceId.CreateRandom(), ActivitySpanId.CreateRandom(), ActivityTraceFlags.Recorded);
70+
71+
// Act
72+
var activity = componentsActivitySource.StartCircuitActivity(circuitId, httpContext);
73+
74+
// Assert
75+
Assert.NotNull(activity);
76+
Assert.Equal(ComponentsActivitySource.OnCircuitName, activity.OperationName);
77+
Assert.Equal($"CIRCUIT {circuitId}", activity.DisplayName);
78+
Assert.Equal(ActivityKind.Server, activity.Kind);
79+
Assert.True(activity.IsAllDataRequested);
80+
Assert.Equal(circuitId, activity.GetTagItem("circuit.id"));
81+
Assert.Contains(activity.Links, link => link.Context == httpContext);
82+
Assert.False(activity.IsStopped);
83+
}
84+
85+
[Fact]
86+
public void FailCircuitActivity_SetsErrorStatusAndStopsActivity()
87+
{
88+
// Arrange
89+
var componentsActivitySource = new ComponentsActivitySource();
90+
var circuitId = "test-circuit-id";
91+
var httpContext = default(ActivityContext);
92+
var activity = componentsActivitySource.StartCircuitActivity(circuitId, httpContext);
93+
var exception = new InvalidOperationException("Test exception");
94+
95+
// Act
96+
componentsActivitySource.FailCircuitActivity(activity, exception);
97+
98+
// Assert
99+
Assert.True(activity!.IsStopped);
100+
Assert.Equal(ActivityStatusCode.Error, activity.Status);
101+
Assert.Equal(exception.GetType().FullName, activity.GetTagItem("error.type"));
102+
}
103+
104+
[Fact]
105+
public void StartRouteActivity_CreatesAndStartsActivity()
106+
{
107+
// Arrange
108+
var componentsActivitySource = new ComponentsActivitySource();
109+
var componentType = "TestComponent";
110+
var route = "/test-route";
111+
112+
// First set up a circuit context
113+
componentsActivitySource.StartCircuitActivity("test-circuit-id", default);
114+
115+
// Act
116+
var activity = componentsActivitySource.StartRouteActivity(componentType, route);
117+
118+
// Assert
119+
Assert.NotNull(activity);
120+
Assert.Equal(ComponentsActivitySource.OnRouteName, activity.OperationName);
121+
Assert.Equal($"ROUTE {route} -> {componentType}", activity.DisplayName);
122+
Assert.Equal(ActivityKind.Server, activity.Kind);
123+
Assert.True(activity.IsAllDataRequested);
124+
Assert.Equal(componentType, activity.GetTagItem("component.type"));
125+
Assert.Equal(route, activity.GetTagItem("route"));
126+
Assert.Equal("test-circuit-id", activity.GetTagItem("circuit.id"));
127+
Assert.False(activity.IsStopped);
128+
}
129+
130+
[Fact]
131+
public void StartEventActivity_CreatesAndStartsActivity()
132+
{
133+
// Arrange
134+
var componentsActivitySource = new ComponentsActivitySource();
135+
var componentType = "TestComponent";
136+
var methodName = "OnClick";
137+
var attributeName = "onclick";
138+
139+
// First set up a circuit and route context
140+
componentsActivitySource.StartCircuitActivity("test-circuit-id", default);
141+
componentsActivitySource.StartRouteActivity("ParentComponent", "/parent");
142+
143+
// Act
144+
var activity = componentsActivitySource.StartEventActivity(componentType, methodName, attributeName);
145+
146+
// Assert
147+
Assert.NotNull(activity);
148+
Assert.Equal(ComponentsActivitySource.OnEventName, activity.OperationName);
149+
Assert.Equal($"EVENT {attributeName} -> {componentType}.{methodName}", activity.DisplayName);
150+
Assert.Equal(ActivityKind.Server, activity.Kind);
151+
Assert.True(activity.IsAllDataRequested);
152+
Assert.Equal(componentType, activity.GetTagItem("component.type"));
153+
Assert.Equal(methodName, activity.GetTagItem("component.method"));
154+
Assert.Equal(attributeName, activity.GetTagItem("attribute.name"));
155+
Assert.Equal("test-circuit-id", activity.GetTagItem("circuit.id"));
156+
Assert.False(activity.IsStopped);
157+
}
158+
159+
[Fact]
160+
public void FailEventActivity_SetsErrorStatusAndStopsActivity()
161+
{
162+
// Arrange
163+
var componentsActivitySource = new ComponentsActivitySource();
164+
var activity = componentsActivitySource.StartEventActivity("TestComponent", "OnClick", "onclick");
165+
var exception = new InvalidOperationException("Test exception");
166+
167+
// Act
168+
ComponentsActivitySource.FailEventActivity(activity, exception);
169+
170+
// Assert
171+
Assert.True(activity!.IsStopped);
172+
Assert.Equal(ActivityStatusCode.Error, activity.Status);
173+
Assert.Equal(exception.GetType().FullName, activity.GetTagItem("error.type"));
174+
}
175+
176+
[Fact]
177+
public async Task CaptureEventStopAsync_StopsActivityOnSuccessfulTask()
178+
{
179+
// Arrange
180+
var componentsActivitySource = new ComponentsActivitySource();
181+
var activity = componentsActivitySource.StartEventActivity("TestComponent", "OnClick", "onclick");
182+
var task = Task.CompletedTask;
183+
184+
// Act
185+
await ComponentsActivitySource.CaptureEventStopAsync(task, activity);
186+
187+
// Assert
188+
Assert.True(activity!.IsStopped);
189+
Assert.Equal(ActivityStatusCode.Unset, activity.Status);
190+
}
191+
192+
[Fact]
193+
public async Task CaptureEventStopAsync_FailsActivityOnException()
194+
{
195+
// Arrange
196+
var componentsActivitySource = new ComponentsActivitySource();
197+
var activity = componentsActivitySource.StartEventActivity("TestComponent", "OnClick", "onclick");
198+
var exception = new InvalidOperationException("Test exception");
199+
var task = Task.FromException(exception);
200+
201+
// Act
202+
await ComponentsActivitySource.CaptureEventStopAsync(task, activity);
203+
204+
// Assert
205+
Assert.True(activity!.IsStopped);
206+
Assert.Equal(ActivityStatusCode.Error, activity.Status);
207+
Assert.Equal(exception.GetType().FullName, activity.GetTagItem("error.type"));
208+
}
209+
210+
[Fact]
211+
public void StartCircuitActivity_HandlesNullValues()
212+
{
213+
// Arrange
214+
var componentsActivitySource = new ComponentsActivitySource();
215+
216+
// Act
217+
var activity = componentsActivitySource.StartCircuitActivity(null, default);
218+
219+
// Assert
220+
Assert.NotNull(activity);
221+
Assert.Equal("CIRCUIT ", activity.DisplayName);
222+
}
223+
224+
[Fact]
225+
public void StartRouteActivity_HandlesNullValues()
226+
{
227+
// Arrange
228+
var componentsActivitySource = new ComponentsActivitySource();
229+
230+
// Act
231+
var activity = componentsActivitySource.StartRouteActivity(null, null);
232+
233+
// Assert
234+
Assert.NotNull(activity);
235+
Assert.Equal("ROUTE unknown -> unknown", activity.DisplayName);
236+
}
237+
238+
[Fact]
239+
public void StartEventActivity_HandlesNullValues()
240+
{
241+
// Arrange
242+
var componentsActivitySource = new ComponentsActivitySource();
243+
244+
// Act
245+
var activity = componentsActivitySource.StartEventActivity(null, null, null);
246+
247+
// Assert
248+
Assert.NotNull(activity);
249+
Assert.Equal("EVENT unknown -> unknown.unknown", activity.DisplayName);
250+
}
251+
}

src/Components/Components/test/Rendering/ComponentsMetricsTest.cs renamed to src/Components/Components/test/ComponentsMetricsTest.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
using Microsoft.AspNetCore.InternalTesting;
1111
using Moq;
1212

13-
namespace Microsoft.AspNetCore.Components.Rendering;
13+
namespace Microsoft.AspNetCore.Components;
1414

1515
public class ComponentsMetricsTest
1616
{
@@ -106,7 +106,7 @@ public void EventFailed_RecordsException()
106106
ComponentsMetrics.MeterName, "aspnetcore.components.event.exception");
107107

108108
// Create a mock EventCallback
109-
var callback = new EventCallback(new TestComponent(), (Action)(() => { }));
109+
var callback = new EventCallback(new TestComponent(), () => { });
110110

111111
// Act
112112
componentsMetrics.EventFailed("ArgumentException", callback, "OnClick");
@@ -118,7 +118,7 @@ public void EventFailed_RecordsException()
118118
Assert.Equal(1, measurements[0].Value);
119119
Assert.Equal("ArgumentException", measurements[0].Tags["error.type"]);
120120
Assert.Equal("OnClick", measurements[0].Tags["attribute.name"]);
121-
Assert.Contains("Microsoft.AspNetCore.Components.Rendering.ComponentsMetricsTest+TestComponent", (string)measurements[0].Tags["component.type"]);
121+
Assert.Contains("Microsoft.AspNetCore.Components.ComponentsMetricsTest+TestComponent", (string)measurements[0].Tags["component.type"]);
122122
}
123123

124124
[Fact]
@@ -130,7 +130,7 @@ public async Task CaptureEventFailedAsync_RecordsException()
130130
ComponentsMetrics.MeterName, "aspnetcore.components.event.exception");
131131

132132
// Create a mock EventCallback
133-
var callback = new EventCallback(new TestComponent(), (Action)(() => { }));
133+
var callback = new EventCallback(new TestComponent(), () => { });
134134

135135
// Create a task that throws an exception
136136
var task = Task.FromException(new InvalidOperationException());
@@ -145,7 +145,7 @@ public async Task CaptureEventFailedAsync_RecordsException()
145145
Assert.Equal(1, measurements[0].Value);
146146
Assert.Equal("InvalidOperationException", measurements[0].Tags["error.type"]);
147147
Assert.Equal("OnClickAsync", measurements[0].Tags["attribute.name"]);
148-
Assert.Contains("Microsoft.AspNetCore.Components.Rendering.ComponentsMetricsTest+TestComponent", (string)measurements[0].Tags["component.type"]);
148+
Assert.Contains("Microsoft.AspNetCore.Components.ComponentsMetricsTest+TestComponent", (string)measurements[0].Tags["component.type"]);
149149
}
150150

151151
[Fact]

src/Components/Server/test/Circuits/CircuitIdFactoryTest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
namespace Microsoft.AspNetCore.Components.Server.Circuits;
77

8-
public class circuitIdFactoryTest
8+
public class CircuitIdFactoryTest
99
{
1010
[Fact]
1111
public void CreateCircuitId_Generates_NewRandomId()

0 commit comments

Comments
 (0)