Skip to content

Commit 216fa1f

Browse files
Misc improvements (#1744)
1 parent 33d3b22 commit 216fa1f

33 files changed

+413
-107
lines changed

src/Sentry/Internal/SerializableExtensions.cs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,21 @@ public static async Task<string> SerializeToStringAsync(
2222
#endif
2323
{
2424
await serializable.SerializeAsync(stream, logger, cancellationToken).ConfigureAwait(false);
25-
return Encoding.UTF8.GetString(stream.ToArray());
25+
26+
stream.Seek(0, SeekOrigin.Begin);
27+
using var reader = new StreamReader(stream);
28+
return await reader.ReadToEndAsync().ConfigureAwait(false);
2629
}
2730
}
2831

2932
public static string SerializeToString(this ISerializable serializable, IDiagnosticLogger logger)
3033
{
3134
using var stream = new MemoryStream();
3235
serializable.Serialize(stream, logger);
33-
return Encoding.UTF8.GetString(stream.ToArray());
36+
37+
stream.Seek(0, SeekOrigin.Begin);
38+
using var reader = new StreamReader(stream);
39+
return reader.ReadToEnd();
3440
}
3541
}
3642
}

test/Directory.Build.props

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,16 +35,25 @@
3535
<Using Include="NSubstitute"/>
3636
<Using Include="NSubstitute.Core"/>
3737
<Using Include="NSubstitute.ReturnsExtensions"/>
38-
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.1.0" />
38+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.2.0" />
3939
<PackageReference Include="NSubstitute" Version="4.3.0" />
40-
<PackageReference Include="FluentAssertions" Version="6.6.0" />
40+
<PackageReference Include="FluentAssertions" Version="6.7.0" />
4141
<PackageReference Include="xunit" Version="2.4.1" />
42-
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3" />
4342
<PackageReference Include="Xunit.SkippableFact" Version="1.4.13" />
4443
<PackageReference Include="Verify.Xunit" Version="17.1.4" />
4544
<PackageReference Include="Verify.DiffPlex" Version="1.3.0" />
4645
<PackageReference Include="PublicApiGenerator" Version="10.3.0" />
47-
<PackageReference Include="GitHubActionsTestLogger" Version="2.0.0" />
46+
<PackageReference Include="GitHubActionsTestLogger" Version="2.0.1" />
47+
</ItemGroup>
48+
49+
<ItemGroup Condition="'$(TargetFramework)' != 'net461' And '$(TargetFramework)' != 'netcoreapp3.0' And '$(TargetFramework)' != 'netcoreapp2.1'">
50+
<!-- This should be the current version -->
51+
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5" />
52+
</ItemGroup>
53+
54+
<ItemGroup Condition="'$(TargetFramework)' == 'net461' Or '$(TargetFramework)' == 'netcoreapp3.0' Or '$(TargetFramework)' == 'netcoreapp2.1'">
55+
<!-- This is the last version compatible with these targets -->
56+
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3" />
4857
</ItemGroup>
4958

5059
</Project>
Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,37 @@
1+
using System.Buffers;
12
using System.Text.Json;
23

34
internal static class JsonSerializableExtensions
45
{
5-
public static string ToJsonString(this IJsonSerializable serializable)
6+
public static string ToJsonString(this IJsonSerializable serializable, IDiagnosticLogger logger) =>
7+
WriteToJsonString(writer => writer.WriteSerializableValue(serializable, logger));
8+
9+
public static string ToJsonString(this object @object, IDiagnosticLogger logger) =>
10+
WriteToJsonString(writer => writer.WriteDynamicValue(@object, logger));
11+
12+
private static string WriteToJsonString(Action<Utf8JsonWriter> writeAction)
613
{
14+
#if NETCOREAPP3_0_OR_GREATER
15+
// This implementation is better, as it uses fewer allocations
16+
var buffer = new ArrayBufferWriter<byte>();
17+
18+
using var writer = new Utf8JsonWriter(buffer);
19+
writeAction(writer);
20+
writer.Flush();
21+
22+
return Encoding.UTF8.GetString(buffer.WrittenSpan);
23+
#else
24+
// This implementation is compatible with older targets
725
using var stream = new MemoryStream();
8-
using var writer = new Utf8JsonWriter(stream);
926

10-
writer.WriteSerializableValue(serializable, new TraceDiagnosticLogger(SentryLevel.Debug));
27+
using var writer = new Utf8JsonWriter(stream);
28+
writeAction(writer);
1129
writer.Flush();
1230

13-
return Encoding.UTF8.GetString(stream.ToArray());
31+
// Using a reader will avoid copying to an intermediate byte array
32+
stream.Seek(0, SeekOrigin.Begin);
33+
using var reader = new StreamReader(stream);
34+
return reader.ReadToEnd();
35+
#endif
1436
}
1537
}

test/Sentry.Tests/Internals/ClientReportTests.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
using System.Text.Json;
2+
using Sentry.Testing;
23

34
namespace Sentry.Tests.Internals;
45

56
public class ClientReportTests
67
{
8+
private readonly IDiagnosticLogger _testOutputLogger;
79
private readonly ClientReport _testClientReport;
810
private const string TestJsonString =
911
"{" +
@@ -13,8 +15,10 @@ public class ClientReportTests
1315
"{\"reason\":\"event_processor\",\"category\":\"security\",\"quantity\":3}]" +
1416
"}";
1517

16-
public ClientReportTests()
18+
public ClientReportTests(ITestOutputHelper output)
1719
{
20+
_testOutputLogger = new TestOutputDiagnosticLogger(output);
21+
1822
var timestamp = DateTimeOffset.MaxValue;
1923
var discardedEvents = new Dictionary<DiscardReasonWithCategory, int>
2024
{
@@ -28,7 +32,7 @@ public ClientReportTests()
2832
[Fact]
2933
public void Serializes()
3034
{
31-
var jsonString = _testClientReport.ToJsonString();
35+
var jsonString = _testClientReport.ToJsonString(_testOutputLogger);
3236
Assert.Equal(TestJsonString, jsonString);
3337
}
3438

test/Sentry.Tests/Internals/Http/HttpTransportTests.cs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,13 @@ namespace Sentry.Tests.Internals.Http;
1010

1111
public class HttpTransportTests
1212
{
13+
private readonly IDiagnosticLogger _testOutputLogger;
14+
15+
public HttpTransportTests(ITestOutputHelper output)
16+
{
17+
_testOutputLogger = new TestOutputDiagnosticLogger(output);
18+
}
19+
1320
[Fact]
1421
public async Task SendEnvelopeAsync_CancellationToken_PassedToClient()
1522
{
@@ -278,7 +285,7 @@ public async Task SendEnvelopeAsync_ItemRateLimit_DropsItem()
278285
new SentryOptions
279286
{
280287
Dsn = DsnSamples.ValidDsnWithSecret,
281-
DiagnosticLogger = new TraceDiagnosticLogger(SentryLevel.Debug),
288+
DiagnosticLogger = _testOutputLogger,
282289
SendClientReports = false,
283290
Debug = true
284291
},
@@ -317,7 +324,7 @@ public async Task SendEnvelopeAsync_ItemRateLimit_DropsItem()
317324
new EmptySerializable())
318325
});
319326

320-
var expectedEnvelopeSerialized = await expectedEnvelope.SerializeToStringAsync(new TraceDiagnosticLogger(SentryLevel.Debug));
327+
var expectedEnvelopeSerialized = await expectedEnvelope.SerializeToStringAsync(_testOutputLogger);
321328

322329
// Act
323330
await httpTransport.SendEnvelopeAsync(envelope);
@@ -345,7 +352,7 @@ public async Task SendEnvelopeAsync_RateLimited_CountsDiscardedEventsCorrectly()
345352
var options = new SentryOptions
346353
{
347354
Dsn = DsnSamples.ValidDsnWithSecret,
348-
DiagnosticLogger = new TraceDiagnosticLogger(SentryLevel.Debug),
355+
DiagnosticLogger = _testOutputLogger,
349356
SendClientReports = true,
350357
Debug = true
351358
};
@@ -402,7 +409,7 @@ public async Task SendEnvelopeAsync_RateLimited_CountsDiscardedEventsCorrectly()
402409
EnvelopeItem.FromClientReport(expectedClientReport)
403410
});
404411

405-
var expectedEnvelopeSerialized = await expectedEnvelope.SerializeToStringAsync(new TraceDiagnosticLogger(SentryLevel.Debug));
412+
var expectedEnvelopeSerialized = await expectedEnvelope.SerializeToStringAsync(_testOutputLogger);
406413

407414
// Act
408415
await httpTransport.SendEnvelopeAsync(envelope);
@@ -425,7 +432,7 @@ public async Task SendEnvelopeAsync_Fails_RestoresDiscardedEventCounts()
425432
var options = new SentryOptions
426433
{
427434
Dsn = DsnSamples.ValidDsnWithSecret,
428-
DiagnosticLogger = new TraceDiagnosticLogger(SentryLevel.Debug),
435+
DiagnosticLogger = _testOutputLogger,
429436
SendClientReports = true,
430437
Debug = true
431438
};
@@ -469,7 +476,7 @@ public async Task SendEnvelopeAsync_RateLimited_DoesNotRestoreDiscardedEventCoun
469476
var options = new SentryOptions
470477
{
471478
Dsn = DsnSamples.ValidDsnWithSecret,
472-
DiagnosticLogger = new TraceDiagnosticLogger(SentryLevel.Debug),
479+
DiagnosticLogger = _testOutputLogger,
473480
SendClientReports = true,
474481
Debug = true
475482
};

test/Sentry.Tests/Internals/JsonTests.cs

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,16 @@
11
using System.Reflection;
22
using System.Text.Json;
3+
using Sentry.Testing;
34

45
namespace Sentry.Tests.Internals;
56

67
public class JsonTests
78
{
8-
public static string ToJsonString(object @object)
9+
private readonly IDiagnosticLogger _testOutputLogger;
10+
11+
public JsonTests(ITestOutputHelper output)
912
{
10-
using var stream = new MemoryStream();
11-
using (var writer = new Utf8JsonWriter(stream))
12-
{
13-
writer.WriteDynamicValue(@object, new TraceDiagnosticLogger(SentryLevel.Debug));
14-
}
15-
return Encoding.UTF8.GetString(stream.ToArray());
13+
_testOutputLogger = new TestOutputDiagnosticLogger(output);
1614
}
1715

1816
public static Exception GenerateException(string description)
@@ -83,7 +81,7 @@ public void WriteDynamicValue_ExceptionParameter_SerializedException()
8381
var expectedData = new KeyValuePair<string, string>("a", "b");
8482
var ex = GenerateException(expectedMessage);
8583
ex.Data.Add(expectedData.Key, expectedData.Value);
86-
var expectedStackTrace = ToJsonString(ex.StackTrace);
84+
var expectedStackTrace = ex.StackTrace.ToJsonString(_testOutputLogger);
8785
var expectedSerializedData = new[]
8886
{
8987
$"\"Message\":\"{expectedMessage}\"",
@@ -94,7 +92,7 @@ public void WriteDynamicValue_ExceptionParameter_SerializedException()
9492
};
9593

9694
// Act
97-
var serializedString = ToJsonString(ex);
95+
var serializedString = ex.ToJsonString(_testOutputLogger);
9896

9997
// Assert
10098
Assert.All(expectedSerializedData, expectedData => Assert.Contains(expectedData, serializedString));
@@ -111,7 +109,7 @@ public void WriteDynamicValue_ClassWithExceptionParameter_SerializedClassWithExc
111109
var data = new DataWithSerializableObject<Exception>(ex);
112110

113111
// Act
114-
var serializedString = ToJsonString(data);
112+
var serializedString = data.ToJsonString(_testOutputLogger);
115113
var exceptionDeserialized = JsonSerializer.Deserialize<ExceptionMock>(serializedString);
116114

117115
// Assert
@@ -137,7 +135,7 @@ public void WriteDynamicValue_TypeParameter_FullNameTypeOutput()
137135
var expectedValue = "\"System.Exception\"";
138136

139137
// Act
140-
var serializedString = ToJsonString(type);
138+
var serializedString = type.ToJsonString(_testOutputLogger);
141139

142140
// Assert
143141
Assert.Equal(expectedValue, serializedString);
@@ -157,7 +155,7 @@ public void WriteDynamicValue_ClassWithTypeParameter_ClassFormatted()
157155
"}";
158156

159157
// Act
160-
var serializedString = ToJsonString(data);
158+
var serializedString = data.ToJsonString(_testOutputLogger);
161159

162160
// Assert
163161
Assert.Equal(expectedSerializedData, serializedString);
@@ -171,7 +169,7 @@ public void WriteDynamicValue_ClassWithAssembly_SerializedClassWithNullAssembly(
171169
var data = new DataAndNonSerializableObject<Assembly>(AppDomain.CurrentDomain.GetAssemblies()[0]);
172170

173171
// Act
174-
var serializedString = ToJsonString(data);
172+
var serializedString = data.ToJsonString(_testOutputLogger);
175173

176174
// Assert
177175
Assert.Equal(expectedSerializedData, serializedString);
@@ -202,7 +200,7 @@ public void WriteDynamicValue_ClassWithTimeZone_SerializedClassWithTimeZoneInfo(
202200
var data = new DataWithSerializableObject<TimeZoneInfo>(timeZone);
203201

204202
// Act
205-
var serializedString = ToJsonString(data);
203+
var serializedString = data.ToJsonString(_testOutputLogger);
206204

207205
// Assert
208206
Assert.All(expectedSerializedData, expectedData => Assert.Contains(expectedData, serializedString));
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
allocated_bytes: 1,
3+
fragmented_bytes: 2,
4+
heap_size_bytes: 3,
5+
high_memory_load_threshold_bytes: 4,
6+
memory_load_bytes: 6,
7+
total_available_memory_bytes: 5
8+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
allocated_bytes: 1,
3+
compacted: true,
4+
concurrent: false,
5+
finalization_pending_count: 12,
6+
fragmented_bytes: 2,
7+
heap_size_bytes: 3,
8+
high_memory_load_threshold_bytes: 4,
9+
index: 11,
10+
memory_load_bytes: 6,
11+
pause_durations: [
12+
1000
13+
],
14+
pause_time_percentage: 10,
15+
pinned_objects_count: 9,
16+
promoted_bytes: 8,
17+
total_available_memory_bytes: 5,
18+
total_committed_bytes: 7
19+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
allocated_bytes: 1,
3+
compacted: true,
4+
concurrent: false,
5+
finalization_pending_count: 12,
6+
fragmented_bytes: 2,
7+
heap_size_bytes: 3,
8+
high_memory_load_threshold_bytes: 4,
9+
index: 11,
10+
memory_load_bytes: 6,
11+
pause_durations: [
12+
1000
13+
],
14+
pause_time_percentage: 10,
15+
pinned_objects_count: 9,
16+
promoted_bytes: 8,
17+
total_available_memory_bytes: 5,
18+
total_committed_bytes: 7
19+
}
Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,31 @@
1+
using Sentry.Testing;
2+
13
#if NETCOREAPP3_1_OR_GREATER
2-
using System.Text.Json;
34

5+
namespace Sentry.Tests.Internals;
6+
7+
[UsesVerify]
48
public class MemoryInfoTests
59
{
10+
private readonly IDiagnosticLogger _testOutputLogger;
11+
12+
public MemoryInfoTests(ITestOutputHelper output)
13+
{
14+
_testOutputLogger = new TestOutputDiagnosticLogger(output);
15+
}
16+
617
[Fact]
7-
public void WriteTo()
18+
public Task WriteTo()
819
{
920
#if NET5_0_OR_GREATER
10-
var info = new MemoryInfo(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, true, false, new[] { TimeSpan.FromSeconds(1) });
21+
var info = new MemoryInfo(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, true, false, new[] {TimeSpan.FromSeconds(1)});
1122
#else
1223
var info = new MemoryInfo(1, 2, 3, 4, 5, 6);
1324
#endif
25+
var json = info.ToJsonString(_testOutputLogger);
1426

15-
var stream = new MemoryStream();
16-
var writer = new Utf8JsonWriter(stream, new JsonWriterOptions { Indented = true });
17-
info.WriteTo(writer, null);
18-
writer.Flush();
19-
var json = Encoding.UTF8.GetString(stream.ToArray());
20-
Assert.NotNull(json);
21-
Assert.NotEmpty(json);
22-
//Validate json
23-
var serializer = new Newtonsoft.Json.JsonSerializer();
24-
serializer.Deserialize(new Newtonsoft.Json.JsonTextReader(new StringReader(json)));
27+
return VerifyJson(json).UniqueForTargetFrameworkAndVersion();
2528
}
2629
}
30+
2731
#endif

0 commit comments

Comments
 (0)