-
Notifications
You must be signed in to change notification settings - Fork 418
Expand file tree
/
Copy pathObservabilityTests.cs
More file actions
131 lines (112 loc) · 5.02 KB
/
ObservabilityTests.cs
File metadata and controls
131 lines (112 loc) · 5.02 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
using System.CommandLine.Parsing;
using FluentAssertions;
using System.Linq;
using Xunit;
using System.Diagnostics;
using System.Collections.Generic;
using System.Threading.Tasks;
using Xunit.Abstractions;
namespace System.CommandLine.Tests
{
public class ObservabilityTests
{
private readonly ITestOutputHelper log;
public ObservabilityTests(ITestOutputHelper output)
{
log = output;
}
[Fact]
public void It_creates_activity_spans_for_parsing()
{
var (listener, activities) = SetupListener();
var command = new Command("the-command")
{
new Option<string>("--option")
};
var args = new[] { "--option", "the-argument" };
var result = command.Parse(args);
listener.Dispose();
activities
.Should()
.ContainSingle(
a => a.OperationName == "System.CommandLine.Parse"
&& a.Status == ActivityStatusCode.Ok
&& a.Tags.Any(t => t.Key == "command" && t.Value == "the-command"));
}
[Fact]
public void It_creates_activity_spans_for_parsing_errors()
{
var (listener, activities) = SetupListener();
var command = new Command("the-command")
{
new Option<string>("--option")
};
var args = new[] { "--opt", "the-argument" };
var result = command.Parse(args);
listener.Dispose();
activities
.Should()
.ContainSingle(
a => a.OperationName == "System.CommandLine.Parse"
&& a.Status == ActivityStatusCode.Error
&& a.Tags.Any(t => t.Key == "command" && t.Value == "the-command")
&& a.Baggage.Any(t => t.Key == "errors"));
}
[Fact]
public async Task It_creates_activity_spans_for_invocations()
{
var (listener, activities) = SetupListener();
var command = new Command("the-command");
command.SetAction(async (pr, ctok) => await Task.FromResult(0));
var result = await command.Parse(Array.Empty<string>()).InvokeAsync();
listener.Dispose();
activities
.Should()
.ContainSingle(
a => a.OperationName == "System.CommandLine.Invoke"
&& a.DisplayName == "the-command"
&& a.Status == ActivityStatusCode.Ok
&& a.Tags.Any(t => t.Key == "command" && t.Value == "the-command")
&& a.Tags.Any(t => t.Key == "invoke.type" && t.Value == "async")
&& a.TagObjects.Any(t => t.Key == "exitcode" && (int)t.Value == 0));
}
[Fact]
public async Task It_creates_activity_spans_for_invocation_errors()
{
var (listener, activities) = SetupListener();
var command = new Command("the-command");
#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously
command.SetAction(async (pr, ctok) =>
{
throw new Exception("Something went wrong");
});
#pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously
var result = await command.Parse(Array.Empty<string>()).InvokeAsync();
listener.Dispose();
foreach (var x in activities)
{
log.WriteLine($"{x.DisplayName}({x.OperationName})/{x.Status}({x.Duration}) - {x.TagObjects} - {string.Join(",", x.Events.Select((k) => $"{k.Name},{k.Tags}"))}");
}
activities
.Should()
.ContainSingle(
a => a.OperationName == "System.CommandLine.Invoke"
&& a.DisplayName == "the-command"
&& a.Status == ActivityStatusCode.Error
&& a.Tags.Any(t => t.Key == "command" && t.Value == "the-command")
&& a.Tags.Any(t => t.Key == "invoke.type" && t.Value == "async")
&& a.TagObjects.Any(t => t.Key == "exitcode" && (int)t.Value == 1)
&& a.Events.Any(t => t.Name == "exception"));
}
private static (ActivityListener, List<Activity>) SetupListener()
{
List<Activity> activities = new();
var listener = new ActivityListener();
listener.ShouldListenTo = s => true;
listener.Sample = (ref ActivityCreationOptions<ActivityContext> options) => ActivitySamplingResult.AllData;
listener.ActivityStopped = a => activities.Add(a);
ActivitySource.AddActivityListener(listener);
return new(listener, activities);
}
}
}