-
Notifications
You must be signed in to change notification settings - Fork 383
Expand file tree
/
Copy pathTest_MemoryOwner{T}.cs
More file actions
155 lines (120 loc) · 5.27 KB
/
Test_MemoryOwner{T}.cs
File metadata and controls
155 lines (120 loc) · 5.27 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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Linq;
using CommunityToolkit.HighPerformance.Buffers;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using CommunityToolkit.HighPerformance.UnitTests.Buffers.Internals;
namespace CommunityToolkit.HighPerformance.UnitTests.Buffers;
[TestClass]
public class Test_MemoryOwnerOfT
{
[TestMethod]
public void Test_MemoryOwnerOfT_AllocateAndGetMemoryAndSpan()
{
using MemoryOwner<int>? buffer = MemoryOwner<int>.Allocate(127);
Assert.IsTrue(buffer.Length == 127);
Assert.IsTrue(buffer.Memory.Length == 127);
Assert.IsTrue(buffer.Span.Length == 127);
buffer.Span.Fill(42);
Assert.IsTrue(buffer.Memory.Span.ToArray().All(i => i == 42));
Assert.IsTrue(buffer.Span.ToArray().All(i => i == 42));
}
[TestMethod]
public void Test_MemoryOwnerOfT_AllocateFromCustomPoolAndGetMemoryAndSpan()
{
TrackingArrayPool<int>? pool = new();
using (MemoryOwner<int>? buffer = MemoryOwner<int>.Allocate(127, pool))
{
Assert.AreEqual(1, pool.RentedArrays.Count);
Assert.IsTrue(buffer.Length == 127);
Assert.IsTrue(buffer.Memory.Length == 127);
Assert.IsTrue(buffer.Span.Length == 127);
buffer.Span.Fill(42);
Assert.IsTrue(buffer.Memory.Span.ToArray().All(i => i == 42));
Assert.IsTrue(buffer.Span.ToArray().All(i => i == 42));
}
Assert.AreEqual(0, pool.RentedArrays.Count);
}
[TestMethod]
[ExpectedException(typeof(ArgumentOutOfRangeException))]
public void Test_MemoryOwnerOfT_InvalidRequestedSize()
{
using MemoryOwner<int>? buffer = MemoryOwner<int>.Allocate(-1);
Assert.Fail("You shouldn't be here");
}
[TestMethod]
[ExpectedException(typeof(ObjectDisposedException))]
public void Test_MemoryOwnerOfT_DisposedMemory()
{
MemoryOwner<int>? buffer = MemoryOwner<int>.Allocate(127);
buffer.Dispose();
_ = buffer.Memory;
}
[TestMethod]
[ExpectedException(typeof(ObjectDisposedException))]
public void Test_MemoryOwnerOfT_DisposedSpan()
{
MemoryOwner<int>? buffer = MemoryOwner<int>.Allocate(127);
buffer.Dispose();
_ = buffer.Span;
}
[TestMethod]
public void Test_MemoryOwnerOfT_MultipleDispose()
{
MemoryOwner<int>? buffer = MemoryOwner<int>.Allocate(127);
buffer.Dispose();
buffer.Dispose();
buffer.Dispose();
buffer.Dispose();
// This test consists in just getting here without crashes.
// We're validating that calling Dispose multiple times
// by accident doesn't cause issues, and just does nothing.
}
[TestMethod]
public void Test_MemoryOwnerOfT_PooledBuffersAndClear()
{
using (MemoryOwner<int>? buffer = MemoryOwner<int>.Allocate(127))
{
buffer.Span.Fill(42);
}
using (MemoryOwner<int>? buffer = MemoryOwner<int>.Allocate(127))
{
Assert.IsTrue(buffer.Span.ToArray().All(i => i == 42));
}
using (MemoryOwner<int>? buffer = MemoryOwner<int>.Allocate(127, AllocationMode.Clear))
{
Assert.IsTrue(buffer.Span.ToArray().All(i => i == 0));
}
}
[TestMethod]
public void Test_MemoryOwnerOfT_AllocateAndGetArray()
{
MemoryOwner<int>? buffer = MemoryOwner<int>.Allocate(127);
// Here we allocate a MemoryOwner<T> instance with a requested size of 127, which means it
// internally requests an array of size 127 from ArrayPool<T>.Shared. We then get the array
// segment, so we need to verify that (since buffer is not disposed) the returned array is
// not null, is of size >= the requested one (since ArrayPool<T> by definition returns an
// array that is at least of the requested size), and that the offset and count properties
// match our input values (same length, and offset at 0 since the buffer was not sliced).
ArraySegment<int> segment = buffer.DangerousGetArray();
Assert.IsNotNull(segment.Array);
Assert.IsTrue(segment.Array.Length >= buffer.Length);
Assert.AreEqual(0, segment.Offset);
Assert.AreEqual(buffer.Length, segment.Count);
MemoryOwner<int>? second = buffer.Slice(10, 80);
// The original buffer instance is disposed here, because calling Slice transfers
// the ownership of the internal buffer to the new instance (this is documented in
// XML docs for the MemoryOwner<T>.Slice method).
_ = Assert.ThrowsException<ObjectDisposedException>(() => buffer.DangerousGetArray());
segment = second.DangerousGetArray();
// Same as before, but we now also verify the initial offset != 0, as we used Slice
Assert.IsNotNull(segment.Array);
Assert.IsTrue(segment.Array.Length >= second.Length);
Assert.AreEqual(10, segment.Offset);
Assert.AreEqual(second.Length, segment.Count);
second.Dispose();
_ = Assert.ThrowsException<ObjectDisposedException>(() => second.DangerousGetArray());
}
}