A game about forced loneliness, made by TACStudios
1using System;
2using System.Text.RegularExpressions;
3using NUnit.Framework;
4using Unity.Burst;
5using Unity.Collections;
6using Unity.Collections.Tests;
7using Unity.Jobs;
8using UnityEngine;
9using UnityEngine.TestTools;
10
11internal class NativeRingQueueTests
12{
13
14 [Test]
15 public void NativeRingQueue_UseAfterFree_UsesCustomOwnerTypeName()
16 {
17 var test = new NativeRingQueue<int>(1, Allocator.Persistent, NativeArrayOptions.ClearMemory);
18 test.Dispose();
19#if ENABLE_UNITY_COLLECTIONS_CHECKS
20 NUnit.Framework.Assert.That(() => test.Dequeue(),
21 Throws.Exception.TypeOf<ObjectDisposedException>()
22 .With.Message.Contains($"The {test.GetType()} has been deallocated"));
23#endif
24 }
25
26 [Test]
27 public void NativeRingQueue_AtomicSafetyHandle_AllocatorTemp_UniqueStaticSafetyIds()
28 {
29 var test = new NativeRingQueue<int>(1, Allocator.Temp, NativeArrayOptions.ClearMemory);
30
31 // All collections that use Allocator.Temp share the same core AtomicSafetyHandle.
32 // This test verifies that containers can proceed to assign unique static safety IDs to each
33 // AtomicSafetyHandle value, which will not be shared by other containers using Allocator.Temp.
34 var test0 = new NativeRingQueue<int>(1, Allocator.Temp, NativeArrayOptions.ClearMemory);
35 var test1 = new NativeRingQueue<int>(1, Allocator.Temp, NativeArrayOptions.ClearMemory);
36 test0.Enqueue(123);
37 test0.Dispose();
38
39#if ENABLE_UNITY_COLLECTIONS_CHECKS
40 NUnit.Framework.Assert.That(() => test0.Dequeue(),
41 Throws.Exception.With.TypeOf<ObjectDisposedException>()
42 .With.Message.Contains($"The {test0.GetType()} has been deallocated"));
43#endif
44
45 test.Enqueue(123);
46 test1.Dispose();
47
48#if ENABLE_UNITY_COLLECTIONS_CHECKS
49 NUnit.Framework.Assert.That(() => test1.Dequeue(),
50 Throws.Exception.With.TypeOf<ObjectDisposedException>()
51 .With.Message.Contains($"The {test1.GetType()} has been deallocated"));
52#endif
53 }
54
55 [BurstCompile(CompileSynchronously = true)]
56 struct NativeRingQueueCreateAndUseAfterFreeBurst : IJob
57 {
58 public void Execute()
59 {
60 var test = new NativeRingQueue<int>(1, Allocator.Temp, NativeArrayOptions.ClearMemory);
61 test.Enqueue(123);
62 test.Dispose();
63
64 test.Enqueue(456);
65 }
66 }
67
68 [Test]
69 [TestRequiresCollectionChecks]
70 public void NativeRingQueue_CreateAndUseAfterFreeInBurstJob_UsesCustomOwnerTypeName()
71 {
72 var test = new NativeRingQueue<int>(1, Allocator.Persistent, NativeArrayOptions.ClearMemory);
73 test.Dispose();
74
75 var job = new NativeRingQueueCreateAndUseAfterFreeBurst
76 {
77 };
78
79 // Two things:
80 // 1. This exception is logged, not thrown; thus, we use LogAssert to detect it.
81 // 2. Calling write operation after container.Dispose() emits an unintuitive error message. For now, all this test cares about is whether it contains the
82 // expected type name.
83 job.Run();
84 LogAssert.Expect(LogType.Exception,
85 new Regex($"InvalidOperationException: The {Regex.Escape(test.GetType().ToString())} has been declared as \\[ReadOnly\\] in the job, but you are writing to it"));
86 }
87
88 struct NativeRingQueueUseInJob : IJob
89 {
90 public NativeRingQueue<int> Test;
91
92 public void Execute()
93 {
94 Test.Enqueue(456);
95 Test.Enqueue(789);
96 }
97 }
98
99 [Test]
100 public void NativeRingQueue_UseInJob()
101 {
102 var container = new NativeRingQueue<int>(10, Allocator.Persistent, NativeArrayOptions.ClearMemory);
103 Assert.AreEqual(0, container.Length);
104
105 var job = new NativeRingQueueUseInJob
106 {
107 Test = container,
108 };
109
110 Assert.DoesNotThrow(() => container.Enqueue(123));
111 Assert.AreEqual(1, container.Length);
112
113 var handle = job.Schedule();
114
115#if ENABLE_UNITY_COLLECTIONS_CHECKS
116 Assert.Throws<InvalidOperationException>(() => container.Enqueue(321));
117 Assert.Throws<InvalidOperationException>(() => container.TryDequeue(out _));
118#endif
119
120 handle.Complete();
121 Assert.AreEqual(3, container.Length);
122
123 Assert.DoesNotThrow(() => container.Enqueue(987));
124 Assert.AreEqual(4, container.Length);
125
126 int item;
127 Assert.True(container.TryDequeue(out item));
128 Assert.AreEqual(123, item);
129 Assert.AreEqual(3, container.Length);
130
131 Assert.AreEqual(456, container.Dequeue());
132 Assert.AreEqual(2, container.Length);
133
134 Assert.AreEqual(789, container.Dequeue());
135 Assert.AreEqual(1, container.Length);
136
137 Assert.AreEqual(987, container.Dequeue());
138 Assert.AreEqual(0, container.Length);
139
140 container.Dispose();
141 }
142}