A game about forced loneliness, made by TACStudios
at master 312 lines 9.5 kB view raw
1using System; 2using NUnit.Framework; 3using Unity.Burst; 4using Unity.Collections; 5using Unity.Collections.LowLevel.Unsafe; 6using Unity.Collections.Tests; 7using Unity.Jobs; 8 9internal class UnsafeAppendBufferTests : CollectionsTestCommonBase 10{ 11 struct TestHeader 12 { 13 public int Type; 14 public int PayloadSize; 15 } 16 17 [Test] 18 public void UnsafeAppendBuffer_DisposeAllocated() 19 { 20 var buffer = new UnsafeAppendBuffer(1, 8, Allocator.Temp); 21 Assert.True(buffer.IsCreated); 22 Assert.True(buffer.IsEmpty); 23 buffer.Dispose(); 24 } 25 26 [Test] 27 unsafe public void UnsafeAppendBuffer_DisposeExternal() 28 { 29 var data = stackalloc int[1]; 30 var buffer = new UnsafeAppendBuffer(data, sizeof(int)); 31 buffer.Add(5); 32 buffer.Dispose(); 33 Assert.AreEqual(5, data[0]); 34 } 35 36 [Test] 37 [TestRequiresDotsDebugOrCollectionChecks] 38 public void UnsafeAppendBuffer_ThrowZeroAlignment() 39 { 40 Assert.Throws<ArgumentException>(() => 41 { 42 var buffer = new UnsafeAppendBuffer(0, 0, Allocator.Temp); 43 }); 44 } 45 46 void AddAndVerify<T>(ref UnsafeAppendBuffer buffer, T value, ref int expectedLength) where T : unmanaged 47 { 48 buffer.Add(value); 49 expectedLength += UnsafeUtility.SizeOf<T>(); 50 Assert.AreEqual(expectedLength, buffer.Length); 51 } 52 53 [Test] 54 public unsafe void UnsafeAppendBuffer_AddAndPop_UnalignedRead() 55 { 56 int expectedLength = 0; 57 byte value = 0; 58 var buffer = new UnsafeAppendBuffer(0, 8, Allocator.Temp); 59 Assert.IsTrue(buffer.IsEmpty); 60 Assert.AreEqual(expectedLength, buffer.Length); 61 62 AddAndVerify<int>(ref buffer, value++, ref expectedLength); 63 AddAndVerify<byte>(ref buffer, value++, ref expectedLength); 64 AddAndVerify<int>(ref buffer, value++, ref expectedLength); 65 Assert.AreEqual(9, buffer.Length); 66 AddAndVerify<byte>(ref buffer, value++, ref expectedLength); 67 AddAndVerify<int>(ref buffer, value++, ref expectedLength); 68 Assert.AreEqual(14, buffer.Length); 69 70 { 71 var array = new NativeArray<int>(3, Allocator.Temp); 72 for (int i = 0; i < array.Length; ++i) 73 array[i] = value++; 74 75 int oldLen = buffer.Length; 76 buffer.AddArray<int>(array.GetUnsafePtr(), 3); 77 78 Assert.AreEqual(30, buffer.Length); 79 } 80 81 { 82 var array = new NativeArray<int>(3, Allocator.Temp); 83 for (int i = 0; i < array.Length; ++i) 84 array[i] = value++; 85 86 int oldLen = buffer.Length; 87 buffer.AddArray<int>(array.GetUnsafePtr(), 3); 88 89 Assert.AreEqual(46, buffer.Length); 90 } 91 92 // popping 93 94 // array elements + count 95 for (int i = 0; i < 3; ++i) 96 { 97 Assert.AreEqual(--value, buffer.Pop<int>()); 98 } 99 Assert.AreEqual(3, buffer.Pop<int>()); 100 101 // array elements + count 102 for (int i = 0; i < 3; ++i) 103 { 104 Assert.AreEqual(--value, buffer.Pop<int>()); 105 } 106 Assert.AreEqual(3, buffer.Pop<int>()); 107 108 Assert.AreEqual(--value, buffer.Pop<int>()); 109 Assert.AreEqual(--value, buffer.Pop<byte>()); 110 Assert.AreEqual(--value, buffer.Pop<int>()); 111 Assert.AreEqual(--value, buffer.Pop<byte>()); 112 Assert.AreEqual(--value, buffer.Pop<int>()); 113 114 Assert.IsTrue(buffer.IsEmpty); 115 Assert.AreEqual(0, buffer.Length); 116 } 117 118 [Test] 119 public unsafe void UnsafeAppendBuffer_AddAndRead_UnalignedRead() 120 { 121 var buffer = new UnsafeAppendBuffer(0, 8, Allocator.Temp); 122 buffer.Add<byte>(1); 123 buffer.Add<float>(1.0f); 124 var reader = buffer.AsReader(); 125 Assert.AreEqual(reader.ReadNext<byte>(), 1); 126 Assert.AreEqual(reader.ReadNext<float>(), 1.0f); 127 buffer.Dispose(); 128 } 129 130 [Test] 131 public unsafe void UnsafeAppendBuffer_PushHeadersWithPackets() 132 { 133 var buffer = new UnsafeAppendBuffer(0, 8, Allocator.Temp); 134 var scratchPayload = stackalloc byte[1024]; 135 var expectedSize = 0; 136 for (int i = 0; i < 1024; i++) 137 { 138 var packeType = i; 139 var packetSize = i; 140 141 buffer.Add(new TestHeader 142 { 143 Type = packeType, 144 PayloadSize = packetSize 145 }); 146 expectedSize += UnsafeUtility.SizeOf<TestHeader>(); 147 148 buffer.Add(scratchPayload, i); 149 expectedSize += i; 150 } 151 Assert.True(expectedSize == buffer.Length); 152 153 buffer.Dispose(); 154 } 155 156 [Test] 157 public unsafe void UnsafeAppendBuffer_ReadHeadersWithPackets() 158 { 159 var buffer = new UnsafeAppendBuffer(0, 8, Allocator.Temp); 160 var scratchPayload = stackalloc byte[1024]; 161 for (int i = 0; i < 1024; i++) 162 { 163 var packeType = i; 164 var packetSize = i; 165 166 buffer.Add(new TestHeader 167 { 168 Type = packeType, 169 PayloadSize = packetSize 170 }); 171 172 UnsafeUtility.MemSet(scratchPayload, (byte)(i & 0xff), packetSize); 173 174 buffer.Add(scratchPayload, i); 175 } 176 177 var reader = buffer.AsReader(); 178 for (int i = 0; i < 1024; i++) 179 { 180 var packetHeader = reader.ReadNext<TestHeader>(); 181 Assert.AreEqual(i, packetHeader.Type); 182 Assert.AreEqual(i, packetHeader.PayloadSize); 183 if (packetHeader.PayloadSize > 0) 184 { 185 var packetPayload = reader.ReadNext(packetHeader.PayloadSize); 186 Assert.AreEqual((byte)(i & 0xff), *(byte*)packetPayload); 187 } 188 } 189 Assert.True(reader.EndOfBuffer); 190 191 buffer.Dispose(); 192 } 193 194 [Test] 195 public unsafe void UnsafeAppendBuffer_AddAndPop() 196 { 197 var buffer = new UnsafeAppendBuffer(0, 8, Allocator.Temp); 198 199 buffer.Add<int>(123); 200 buffer.Add<int>(234); 201 buffer.Add<int>(345); 202 203 { 204 var array = new NativeArray<int>(3, Allocator.Temp); 205 buffer.Pop(array.GetUnsafePtr(), 3 * UnsafeUtility.SizeOf<int>()); 206 CollectionAssert.AreEqual(new[] {123, 234, 345}, array); 207 } 208 209 { 210 var array = new NativeArray<int>(4, Allocator.Temp); 211 array.CopyFrom(new[] {987, 876, 765, 654}); 212 buffer.Add(array.GetUnsafePtr(), 4 * UnsafeUtility.SizeOf<int>()); 213 } 214 215 Assert.AreEqual(654, buffer.Pop<int>()); 216 Assert.AreEqual(765, buffer.Pop<int>()); 217 Assert.AreEqual(876, buffer.Pop<int>()); 218 Assert.AreEqual(987, buffer.Pop<int>()); 219 220 buffer.Dispose(); 221 } 222 223 [Test] 224 public unsafe void UnsafeAppendBuffer_ReadNextArray() 225 { 226 var values = new NativeArray<int>(new[] {123, 234, 345}, Allocator.Temp); 227 var buffer = new UnsafeAppendBuffer(0, 8, Allocator.Temp); 228 buffer.Add(values); 229 230 var array = (int*)buffer.AsReader().ReadNextArray<int>(out var count); 231 232 Assert.AreEqual(values.Length, count); 233 for (int i = 0; i < count; ++i) 234 { 235 Assert.AreEqual(values[i], array[i]); 236 } 237 238 values.Dispose(); 239 buffer.Dispose(); 240 } 241 242 [Test] 243 public unsafe void UnsafeAppendBuffer_DisposeJob() 244 { 245 var sizeOf = UnsafeUtility.SizeOf<int>(); 246 var alignOf = UnsafeUtility.AlignOf<int>(); 247 248 var container = new UnsafeAppendBuffer(5, 16, Allocator.Persistent); 249 250 var disposeJob = container.Dispose(default); 251 252 Assert.IsTrue(container.Ptr == null); 253 254 disposeJob.Complete(); 255 } 256 257 [Test] 258 public void UnsafeAppendBuffer_CustomAllocatorTest() 259 { 260 AllocatorManager.Initialize(); 261 var allocatorHelper = new AllocatorHelper<CustomAllocatorTests.CountingAllocator>(AllocatorManager.Persistent); 262 ref var allocator = ref allocatorHelper.Allocator; 263 allocator.Initialize(); 264 265 using (var container = new UnsafeAppendBuffer(1, 1, allocator.Handle)) 266 { 267 } 268 269 Assert.IsTrue(allocator.WasUsed); 270 allocator.Dispose(); 271 allocatorHelper.Dispose(); 272 AllocatorManager.Shutdown(); 273 } 274 275 [BurstCompile] 276 struct BurstedCustomAllocatorJob : IJob 277 { 278 [NativeDisableUnsafePtrRestriction] 279 public unsafe CustomAllocatorTests.CountingAllocator* Allocator; 280 281 public void Execute() 282 { 283 unsafe 284 { 285 using (var container = new UnsafeAppendBuffer(1, 1, Allocator->Handle)) 286 { 287 } 288 } 289 } 290 } 291 292 [Test] 293 public unsafe void UnsafeAppendBuffer_BurstedCustomAllocatorTest() 294 { 295 AllocatorManager.Initialize(); 296 var allocatorHelper = new AllocatorHelper<CustomAllocatorTests.CountingAllocator>(AllocatorManager.Persistent); 297 ref var allocator = ref allocatorHelper.Allocator; 298 allocator.Initialize(); 299 300 var allocatorPtr = (CustomAllocatorTests.CountingAllocator*)UnsafeUtility.AddressOf<CustomAllocatorTests.CountingAllocator>(ref allocator); 301 unsafe 302 { 303 var handle = new BurstedCustomAllocatorJob {Allocator = allocatorPtr}.Schedule(); 304 handle.Complete(); 305 } 306 307 Assert.IsTrue(allocator.WasUsed); 308 allocator.Dispose(); 309 allocatorHelper.Dispose(); 310 AllocatorManager.Shutdown(); 311 } 312}