Sin descripción
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

UnsafeAppendBufferTests.cs 9.2KB

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