Skip to content

Commit 0a4200d

Browse files
committed
Add Unit Tests for GC and strings
1 parent 8e133f2 commit 0a4200d

File tree

1 file changed

+119
-0
lines changed

1 file changed

+119
-0
lines changed
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
//
2+
// Copyright (c) .NET Foundation and Contributors
3+
// Portions Copyright (c) Microsoft Corporation. All rights reserved.
4+
// See LICENSE file in the project root for full license information.
5+
//
6+
7+
using nanoFramework.TestFramework;
8+
using System;
9+
10+
namespace NFUnitTestGC
11+
{
12+
[TestClass]
13+
public class TestGCWithStringArrays
14+
{
15+
[TestMethod]
16+
public void TestCompactionForNotFixedStringArray()
17+
{
18+
OutputHelper.WriteLine("Starting TestCompactionForNotFixedStringArray");
19+
20+
for (int loop = 0; loop < 10; loop++)
21+
{
22+
OutputHelper.WriteLine($"Starting iteration {loop}");
23+
24+
// First we create objects and holes that keeps some space that could be used by compaction
25+
26+
for (int loop = 0; loop < 10; loop++)
27+
{
28+
OutputHelper.WriteLine($"Starting iteration {loop}");
29+
30+
// First we create objects and holes that keeps some space that could be used by compaction.
31+
// Small count so compaction does not happen.
32+
HolderForString[] arrayOfStrings = new HolderForString[10];
33+
RunStringAllocations(arrayOfStrings);
34+
35+
// This is the array that we expect to move in during compaction.
36+
HolderForString[] testNativeBuffer = new HolderForString[100];
37+
// Fill it, so it is not optimized out
38+
for (int i = 0; i < testNativeBuffer.Length; i++)
39+
{
40+
testNativeBuffer[i] = new HolderForString(Guid.NewGuid().ToString());
41+
}
42+
43+
OutputHelper.WriteLine("Large HolderForString array created");
44+
OutputHelper.WriteLine("Forcing compaction to occurr");
45+
46+
// Causes compaction
47+
InitiateTimeSpanCompaction();
48+
49+
OutputHelper.WriteLine("Compaction occurred");
50+
OutputHelper.WriteLine("Checking arrays for corrupted data...");
51+
52+
int index = 0;
53+
54+
// Check that array content is not corrupted
55+
foreach (HolderForString holder in testNativeBuffer)
56+
{
57+
Assert.AreEqual(
58+
holder.StringHash,
59+
holder.StringContent.GetHashCode(),
60+
$"Array content comparison failed at position {index}. Expecting {holder.StringHash}, found {holder.StringContent.GetHashCode()}");
61+
index++;
62+
}
63+
64+
OutputHelper.WriteLine("No corruption detected in array");
65+
}
66+
67+
OutputHelper.WriteLine("Completed TestCompactionForNotFixedArray");
68+
}
69+
}
70+
71+
private TimeSpan GetRandomTimeSpan()
72+
{
73+
Random rand = new();
74+
75+
return TimeSpan.FromTicks(rand.Next() * 1000_000);
76+
}
77+
78+
// This function cause compaction to occur.
79+
// It is not so trivial as it need to fragment heap with referenced objects.
80+
void InitiateTimeSpanCompaction()
81+
{
82+
// Large count, so compaction happens during RunAllocations.
83+
HolderForTimeSpan[] arrayOfArrays = new HolderForTimeSpan[500];
84+
RunTimeSpanAllocations(arrayOfArrays);
85+
}
86+
87+
private void RunTimeSpanAllocations(HolderForTimeSpan[] arrObj)
88+
{
89+
90+
for (int i = 1; i < arrObj.Length; i++)
91+
{
92+
// Creates referenced object, which stays in memory until InitiateCompaction exits
93+
arrObj[i] = new HolderForTimeSpan(GetRandomTimeSpan());
94+
95+
// Tries to create larger object that would be later hole
96+
// This object could be garbage collected on each "i" cycle
97+
HolderForTimeSpan[] arr = new HolderForTimeSpan[50 * i];
98+
99+
// Creates some usage for array elements, so it is not optimized out
100+
arr[0] = new HolderForTimeSpan(TimeSpan.MinValue);
101+
arr[1] = new HolderForTimeSpan(TimeSpan.MaxValue);
102+
103+
Console.WriteLine($"On Cycle {i:D3} DateTime holder allocated");
104+
}
105+
}
106+
107+
private class HolderForString
108+
{
109+
public int StringHash { get; }
110+
public string StringContent { get; }
111+
112+
public HolderForString(string value)
113+
{
114+
StringContent = value;
115+
StringHash = value.GetHashCode();
116+
}
117+
}
118+
}
119+
}

0 commit comments

Comments
 (0)