Skip to content

Commit 1558346

Browse files
Enable Native AOT testing in System.Text.Json. (#86975)
* Enable Native AOT testing in System.Text.Json. Fix #73431. * Enabled AOT testing for generic theories/MakeGenericMethod tests. Address misc feedback. * Remove hardcoded JsonSerializer calls from test suite.
1 parent 7febca6 commit 1558346

27 files changed

+474
-417
lines changed

src/libraries/Common/tests/TestUtilities/System/AssertExtensions.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,15 @@ public static void Equal<T>(HashSet<T> expected, HashSet<T> actual)
405405
}
406406
}
407407

408+
/// <summary>Validates that the two sets contains the same elements. XUnit doesn't display the full collections.</summary>
409+
public static void Equal<T>(ISet<T> expected, ISet<T> actual)
410+
{
411+
if (!actual.SetEquals(expected))
412+
{
413+
throw new XunitException($"Expected: {string.Join(", ", expected)}{Environment.NewLine}Actual: {string.Join(", ", actual)}");
414+
}
415+
}
416+
408417
/// <summary>
409418
/// Validates that the actual collection contains same items as expected collection. If the test fails, this will display:
410419
/// 1. Count if two collection count are different;

src/libraries/System.Text.Json/tests/Common/CollectionTests/CollectionTests.AsyncEnumerable.cs

Lines changed: 26 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,10 @@ public async Task WriteRootLevelAsyncEnumerable<TElement>(IEnumerable<TElement>
2323
return;
2424
}
2525

26-
JsonSerializerOptions options = new JsonSerializerOptions
27-
{
28-
DefaultBufferSize = bufferSize
29-
};
26+
JsonSerializerOptions options = Serializer.CreateOptions(makeReadOnly: false);
27+
options.DefaultBufferSize = bufferSize;
3028

31-
string expectedJson = JsonSerializer.Serialize(source);
29+
string expectedJson = JsonSerializer.Serialize(source, options);
3230

3331
using var stream = new Utf8MemoryStream();
3432
var asyncEnumerable = new MockedAsyncEnumerable<TElement>(source, delayInterval);
@@ -48,37 +46,10 @@ public async Task WriteNestedAsyncEnumerable<TElement>(IEnumerable<TElement> sou
4846
return;
4947
}
5048

51-
JsonSerializerOptions options = new JsonSerializerOptions
52-
{
53-
DefaultBufferSize = bufferSize
54-
};
49+
JsonSerializerOptions options = Serializer.CreateOptions(makeReadOnly: false);
50+
options.DefaultBufferSize = bufferSize;
5551

56-
string expectedJson = JsonSerializer.Serialize(new { Data = source });
57-
58-
using var stream = new Utf8MemoryStream();
59-
var asyncEnumerable = new MockedAsyncEnumerable<TElement>(source, delayInterval);
60-
await StreamingSerializer.SerializeWrapper(stream, new AsyncEnumerableDto<TElement> { Data = asyncEnumerable }, options);
61-
62-
JsonTestHelper.AssertJsonEqual(expectedJson, stream.AsString());
63-
Assert.Equal(1, asyncEnumerable.TotalCreatedEnumerators);
64-
Assert.Equal(1, asyncEnumerable.TotalDisposedEnumerators);
65-
}
66-
67-
[Theory]
68-
[MemberData(nameof(GetAsyncEnumerableSources))]
69-
public async Task WriteNestedAsyncEnumerable_DTO<TElement>(IEnumerable<TElement> source, int delayInterval, int bufferSize)
70-
{
71-
if (StreamingSerializer?.IsAsyncSerializer != true)
72-
{
73-
return;
74-
}
75-
76-
JsonSerializerOptions options = new JsonSerializerOptions
77-
{
78-
DefaultBufferSize = bufferSize
79-
};
80-
81-
string expectedJson = JsonSerializer.Serialize(new { Data = source });
52+
string expectedJson = JsonSerializer.Serialize(new EnumerableDto<TElement> { Data = source }, options);
8253

8354
using var stream = new Utf8MemoryStream();
8455
var asyncEnumerable = new MockedAsyncEnumerable<TElement>(source, delayInterval);
@@ -100,11 +71,9 @@ public async Task WriteNestedAsyncEnumerable_Nullable<TElement>(IEnumerable<TEle
10071

10172
// Primarily tests the ability of NullableConverter to flow async serialization state
10273

103-
JsonSerializerOptions options = new JsonSerializerOptions
104-
{
105-
DefaultBufferSize = bufferSize,
106-
IncludeFields = true,
107-
};
74+
JsonSerializerOptions options = Serializer.CreateOptions(makeReadOnly: false);
75+
options.DefaultBufferSize = bufferSize;
76+
options.IncludeFields = true;
10877

10978
string expectedJson = JsonSerializer.Serialize<(IEnumerable<TElement>, bool)?>((source, false), options);
11079

@@ -164,11 +133,22 @@ await Assert.ThrowsAsync<TaskCanceledException>(async () =>
164133
Assert.Equal(1, longRunningEnumerable.TotalDisposedEnumerators);
165134
}
166135

136+
public class EnumerableDto<TElement>
137+
{
138+
public IEnumerable<TElement> Data { get; set; }
139+
}
140+
167141
public class AsyncEnumerableDto<TElement>
168142
{
169143
public IAsyncEnumerable<TElement> Data { get; set; }
170144
}
171145

146+
public class EnumerableDtoWithTwoProperties<TElement>
147+
{
148+
public IEnumerable<TElement> Data1 { get; set; }
149+
public IEnumerable<TElement> Data2 { get; set; }
150+
}
151+
172152
public class AsyncEnumerableDtoWithTwoProperties<TElement>
173153
{
174154
public IAsyncEnumerable<TElement> Data1 { get; set; }
@@ -184,12 +164,10 @@ public async Task WriteSequentialNestedAsyncEnumerables<TElement>(IEnumerable<TE
184164
return;
185165
}
186166

187-
JsonSerializerOptions options = new JsonSerializerOptions
188-
{
189-
DefaultBufferSize = bufferSize
190-
};
167+
JsonSerializerOptions options = Serializer.CreateOptions(makeReadOnly: false);
168+
options.DefaultBufferSize = bufferSize;
191169

192-
string expectedJson = JsonSerializer.Serialize(new { Data1 = source, Data2 = source });
170+
string expectedJson = JsonSerializer.Serialize(new EnumerableDtoWithTwoProperties<TElement> { Data1 = source, Data2 = source }, options);
193171

194172
using var stream = new Utf8MemoryStream();
195173
var asyncEnumerable = new MockedAsyncEnumerable<TElement>(source, delayInterval);
@@ -209,13 +187,11 @@ public async Task WriteAsyncEnumerableOfAsyncEnumerables<TElement>(IEnumerable<T
209187
return;
210188
}
211189

212-
JsonSerializerOptions options = new JsonSerializerOptions
213-
{
214-
DefaultBufferSize = bufferSize
215-
};
190+
JsonSerializerOptions options = Serializer.CreateOptions(makeReadOnly: false);
191+
options.DefaultBufferSize = bufferSize;
216192

217193
const int OuterEnumerableCount = 5;
218-
string expectedJson = JsonSerializer.Serialize(Enumerable.Repeat(source, OuterEnumerableCount));
194+
string expectedJson = JsonSerializer.Serialize(Enumerable.Repeat(source, OuterEnumerableCount), options);
219195

220196
var innerAsyncEnumerable = new MockedAsyncEnumerable<TElement>(source, delayInterval);
221197
var outerAsyncEnumerable =

src/libraries/System.Text.Json/tests/Common/CollectionTests/CollectionTests.Generic.Read.cs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -617,20 +617,19 @@ public async Task ReadNullableGenericStructISetWithNullJson()
617617
}
618618

619619
[Fact]
620-
[ActiveIssue("https://github.com/dotnet/runtime/issues/50721", typeof(PlatformDetection), nameof(PlatformDetection.IsBuiltWithAggressiveTrimming), nameof(PlatformDetection.IsBrowser))]
621620
public async Task ReadISetTOfHashSetT()
622621
{
623622
ISet<HashSet<int>> result = await Serializer.DeserializeWrapper<ISet<HashSet<int>>>(@"[[1,2],[3,4]]");
624623

625624
if (result.First().Contains(1))
626625
{
627-
Assert.Equal(new HashSet<int> { 1, 2 }, result.First());
628-
Assert.Equal(new HashSet<int> { 3, 4 }, result.Last());
626+
AssertExtensions.Equal(new HashSet<int> { 1, 2 }, result.First());
627+
AssertExtensions.Equal(new HashSet<int> { 3, 4 }, result.Last());
629628
}
630629
else
631630
{
632-
Assert.Equal(new HashSet<int> { 3, 4 }, result.First());
633-
Assert.Equal(new HashSet<int> { 1, 2 }, result.Last());
631+
AssertExtensions.Equal(new HashSet<int> { 3, 4 }, result.First());
632+
AssertExtensions.Equal(new HashSet<int> { 1, 2 }, result.Last());
634633
}
635634
}
636635

src/libraries/System.Text.Json/tests/Common/CollectionTests/CollectionTests.Generic.Write.cs

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,6 @@ public async Task GenericStructISetWrapperT()
384384
}
385385

386386
[Fact]
387-
[ActiveIssue("https://github.com/dotnet/runtime/issues/50721", typeof(PlatformDetection), nameof(PlatformDetection.IsBuiltWithAggressiveTrimming), nameof(PlatformDetection.IsBrowser))]
388387
public async Task WriteISetTOfISetT()
389388
{
390389
ISet<ISet<int>> input = new HashSet<ISet<int>>
@@ -433,7 +432,6 @@ public async Task WriteISetTOfISetT()
433432
}
434433

435434
[Fact]
436-
[ActiveIssue("https://github.com/dotnet/runtime/issues/50721", typeof(PlatformDetection), nameof(PlatformDetection.IsBuiltWithAggressiveTrimming), nameof(PlatformDetection.IsBrowser))]
437435
public async Task WriteISetTOfHashSetT()
438436
{
439437
ISet<HashSet<int>> input = new HashSet<HashSet<int>>
@@ -449,13 +447,13 @@ public async Task WriteISetTOfHashSetT()
449447

450448
if (input.First().Contains(1))
451449
{
452-
Assert.Equal(new HashSet<int> { 1, 2 }, input.First());
453-
Assert.Equal(new HashSet<int> { 3, 4 }, input.Last());
450+
AssertExtensions.Equal(new HashSet<int> { 1, 2 }, input.First());
451+
AssertExtensions.Equal(new HashSet<int> { 3, 4 }, input.Last());
454452
}
455453
else
456454
{
457-
Assert.Equal(new HashSet<int> { 3, 4 }, input.First());
458-
Assert.Equal(new HashSet<int> { 1, 2 }, input.Last());
455+
AssertExtensions.Equal(new HashSet<int> { 3, 4 }, input.First());
456+
AssertExtensions.Equal(new HashSet<int> { 1, 2 }, input.Last());
459457
}
460458
}
461459

@@ -649,13 +647,13 @@ public async Task WriteHashSetTOfHashSetT()
649647

650648
if (input.First().Contains(1))
651649
{
652-
Assert.Equal(new HashSet<int> { 1, 2 }, input.First());
653-
Assert.Equal(new HashSet<int> { 3, 4 }, input.Last());
650+
AssertExtensions.Equal(new HashSet<int> { 1, 2 }, input.First());
651+
AssertExtensions.Equal(new HashSet<int> { 3, 4 }, input.Last());
654652
}
655653
else
656654
{
657-
Assert.Equal(new HashSet<int> { 3, 4 }, input.First());
658-
Assert.Equal(new HashSet<int> { 1, 2 }, input.Last());
655+
AssertExtensions.Equal(new HashSet<int> { 3, 4 }, input.First());
656+
AssertExtensions.Equal(new HashSet<int> { 1, 2 }, input.Last());
659657
}
660658

661659
GenericHashSetWrapper<StringHashSetWrapper> input2 = new GenericHashSetWrapper<StringHashSetWrapper>(new List<StringHashSetWrapper>
@@ -696,7 +694,6 @@ public async Task WriteHashSetTOfArray()
696694
}
697695

698696
[Fact]
699-
[ActiveIssue("https://github.com/dotnet/runtime/issues/50721", typeof(PlatformDetection), nameof(PlatformDetection.IsBuiltWithAggressiveTrimming), nameof(PlatformDetection.IsBrowser))]
700697
public async Task WriteArrayOfHashSetT()
701698
{
702699
HashSet<int>[] input = new HashSet<int>[2];
@@ -707,8 +704,8 @@ public async Task WriteArrayOfHashSetT()
707704

708705
// Because order isn't guaranteed, roundtrip data to ensure write was accurate.
709706
input = await Serializer.DeserializeWrapper<HashSet<int>[]>(json);
710-
Assert.Equal(new HashSet<int> { 1, 2 }, input.First());
711-
Assert.Equal(new HashSet<int> { 3, 4 }, input.Last());
707+
AssertExtensions.Equal(new HashSet<int> { 1, 2 }, input.First());
708+
AssertExtensions.Equal(new HashSet<int> { 3, 4 }, input.Last());
712709
}
713710

714711
[Fact]

src/libraries/System.Text.Json/tests/Common/ConstructorTests/ConstructorTests.Cache.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ async Task SerializeObject(Type type, JsonSerializerOptions options)
6161
async Task RunTestAsync(Type type)
6262
{
6363
// Use local options to avoid obtaining already cached metadata from the default options.
64-
var options = new JsonSerializerOptions();
64+
JsonSerializerOptions options = Serializer.CreateOptions();
6565

6666
const int ThreadCount = 8;
6767
const int ConcurrentTestsCount = 4;
@@ -90,7 +90,7 @@ async Task RunTestAsync(Type type)
9090
public async Task PropertyCacheWithMinInputsFirst()
9191
{
9292
// Use local options to avoid obtaining already cached metadata from the default options.
93-
var options = new JsonSerializerOptions();
93+
JsonSerializerOptions options = Serializer.CreateOptions();
9494

9595
string json = "{}";
9696
await Serializer.DeserializeWrapper<ObjWCtorMixedParams>(json, options);
@@ -107,7 +107,7 @@ public async Task PropertyCacheWithMinInputsFirst()
107107
public async Task PropertyCacheWithMinInputsLast()
108108
{
109109
// Use local options to avoid obtaining already cached metadata from the default options.
110-
var options = new JsonSerializerOptions();
110+
JsonSerializerOptions options = Serializer.CreateOptions();
111111

112112
ObjWCtorMixedParams testObj = ObjWCtorMixedParams.GetInstance();
113113
testObj.Verify();

0 commit comments

Comments
 (0)