1 //
2 // Copyright (c) 2010-2023 Antmicro
3 // Copyright (c) 2011-2015 Realtime Embedded
4 //
5 // This file is licensed under the MIT License.
6 // Full license text is available in 'licenses/MIT.txt'.
7 //
8 using Antmicro.Renode.Utilities.Collections;
9 using NUnit.Framework;
10 
11 namespace Antmicro.Renode.UnitTests.Collections
12 {
13     [TestFixture]
14     public class CircularBufferTests
15     {
16         [Test]
ShouldEnqueueAndDequeueWithoutWrap()17         public void ShouldEnqueueAndDequeueWithoutWrap()
18         {
19             var buffer = new CircularBuffer<int>(5);
20             for(var i = 0; i < 5; ++i)
21             {
22                 buffer.Enqueue(i);
23             }
24             for(var i = 0; i < 5; ++i)
25             {
26                 Assert.IsTrue(buffer.TryDequeue(out var result));
27                 Assert.AreEqual(i, result);
28             }
29         }
30 
31         [Test]
ShouldEnqueueAndDequeueWithWrap()32         public void ShouldEnqueueAndDequeueWithWrap()
33         {
34             var buffer = new CircularBuffer<int>(5);
35             for(var i = 0; i < 10; ++i)
36             {
37                 buffer.Enqueue(i);
38             }
39             for(var i = 5; i < 10; ++i)
40             {
41                 Assert.IsTrue(buffer.TryDequeue(out var result));
42                 Assert.AreEqual(i, result);
43             }
44         }
45 
46         [Test]
ShouldNotDequeueWhenEmpty()47         public void ShouldNotDequeueWhenEmpty()
48         {
49             var buffer = new CircularBuffer<int>(5);
50             for(var i = 0; i < 5; ++i)
51             {
52                 buffer.Enqueue(i);
53             }
54             for(var i = 0; i < 5; ++i)
55             {
56                 buffer.TryDequeue(out var _);
57             }
58             Assert.IsFalse(buffer.TryDequeue(out var __));
59         }
60 
61         [Test]
ShouldNotPeekWhenEmpty()62         public void ShouldNotPeekWhenEmpty()
63         {
64             var buffer = new CircularBuffer<int>(5);
65             for(var i = 0; i < 5; ++i)
66             {
67                 buffer.Enqueue(i);
68             }
69             for(var i = 0; i < 5; ++i)
70             {
71                 buffer.TryDequeue(out var _);
72             }
73             Assert.IsFalse(buffer.TryPeek(out var __));
74         }
75 
76         [Test]
ShouldNotChangeCountWhenPeeked()77         public void ShouldNotChangeCountWhenPeeked()
78         {
79             var buffer = new CircularBuffer<int>(5);
80             for(var i = 0; i < 5; ++i)
81             {
82                 buffer.Enqueue(i);
83             }
84             for(var i = 0; i < 5; ++i)
85             {
86                 buffer.TryPeek(out var _);
87             }
88             Assert.AreEqual(5, buffer.Count);
89         }
90 
91         [Test]
ShouldEnqueueAndPeekWithoutWrap()92         public void ShouldEnqueueAndPeekWithoutWrap()
93         {
94             var buffer = new CircularBuffer<int>(5);
95             for(var i = 0; i < 5; ++i)
96             {
97                 buffer.Enqueue(i);
98                 Assert.IsTrue(buffer.TryPeek(out var result));
99                 // The expected result is 0 because the first entry won't get
100                 // pushed off the end of the buffer.
101                 Assert.AreEqual(0, result);
102             }
103         }
104 
105         [Test]
ShouldEnqueueAndPeekWithWrap()106         public void ShouldEnqueueAndPeekWithWrap()
107         {
108             var buffer = new CircularBuffer<int>(5);
109             for(var i = 0; i < 10; ++i)
110             {
111                 buffer.Enqueue(i);
112                 Assert.IsTrue(buffer.TryPeek(out var result));
113                 // The first 5 pushes will return 0, then 1 2 3 4 5
114                 // i - 4 because Enqueue(5) pushes off the 0 so after it we have
115                 // i = 5 and we expect to read a 1
116                 Assert.AreEqual(i < 5 ? 0 : i - 4, result);
117             }
118         }
119 
120         [Test]
ShouldNeverWrapWithSingleElement()121         public void ShouldNeverWrapWithSingleElement()
122         {
123             var buffer = new CircularBuffer<int>(5);
124             for(var i = 0; i <= 10; i++)
125             {
126                 buffer.TryDequeue(out var _);
127                 buffer.Enqueue(i);
128                 Assert.IsFalse(buffer.IsWrapped);
129             }
130         }
131 
132         [Test]
ShouldSaveWithoutWrap()133         public void ShouldSaveWithoutWrap()
134         {
135             var buffer = new CircularBuffer<int>(5);
136             buffer.Enqueue(1);
137             buffer.Enqueue(2);
138             buffer.Enqueue(3);
139             CollectionAssert.AreEquivalent(new [] { 1, 2, 3 }, buffer);
140         }
141 
142         [Test]
ShouldSaveWithoutWrapArray()143         public void ShouldSaveWithoutWrapArray()
144         {
145             var buffer = new CircularBuffer<int>(5);
146             var array = new [] { 1, 2, 3, -1, 0 };
147             for(var i = 0; i < 3; i++)
148             {
149                 buffer.Enqueue(array[i]);
150             }
151             var copy = new int[5];
152             copy[3] = -1;
153             buffer.CopyTo(copy, 0);
154             CollectionAssert.AreEqual(array, copy);
155         }
156 
157         [Test]
ShouldSaveWithWrap()158         public void ShouldSaveWithWrap()
159         {
160             var buffer = new CircularBuffer<int>(4);
161             for(var i = 0; i < 6; i++)
162             {
163                 buffer.Enqueue(i);
164             }
165             Assert.AreEqual(buffer, new [] { 2, 3, 4, 5 });
166         }
167 
168         // This tests that the IEnumerator implementation works correctly
169         // when the buffer is exactly full.
170         [Test]
ShouldSaveWithExactSize()171         public void ShouldSaveWithExactSize()
172         {
173             var buffer = new CircularBuffer<int>(4);
174             for(var i = 0; i < 4; i++)
175             {
176                 buffer.Enqueue(i);
177             }
178             Assert.AreEqual(new [] { 0, 1, 2, 3 }, buffer);
179         }
180 
181         [Test]
ShouldSaveWithWrapArray()182         public void ShouldSaveWithWrapArray()
183         {
184             var buffer = new CircularBuffer<int>(4);
185             for(var i = 0; i < 6; i++)
186             {
187                 buffer.Enqueue(i);
188             }
189             var result = new [] { 2, 3, 4, 5 };
190             var copy = new int[4];
191             buffer.CopyTo(copy, 0);
192             Assert.AreEqual(result, copy);
193         }
194 
195         [Test]
ShouldDetectOverflow()196         public void ShouldDetectOverflow()
197         {
198             var buffer = new CircularBuffer<int>(3);
199             for(var i = 0; i < 3; i++)
200             {
201                 Assert.IsTrue(buffer.Enqueue(i));
202             }
203             Assert.IsFalse(buffer.Enqueue(3));
204         }
205 
206         [Test]
ShouldNotDetectOverflow()207         public void ShouldNotDetectOverflow()
208         {
209             var buffer = new CircularBuffer<int>(3);
210             for(var i = 0; i < 3; i++)
211             {
212                 buffer.Enqueue(i);
213             }
214             buffer.TryDequeue(out var _);
215             Assert.IsTrue(buffer.Enqueue(2));
216         }
217     }
218 }
219 
220