1 //
2 // Copyright (c) 2010-2024 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 
9 using System;
10 using NUnit.Framework;
11 using Antmicro.Renode.Core;
12 using Antmicro.Renode.Exceptions;
13 
14 using Range = Antmicro.Renode.Core.Range;
15 
16 namespace Antmicro.Renode.UnitTests
17 {
18     [TestFixture]
19     public class RangeTests
20     {
21         [Test]
CreateRangeWithExtensions()22         public void CreateRangeWithExtensions()
23         {
24             var rangeAt0x1000Size0x100 = new Range(0x1000, 0x100);
25             Assert.AreEqual(rangeAt0x1000Size0x100, 0x1000.By(0x100));
26             Assert.AreEqual(rangeAt0x1000Size0x100, 0x1000.To(0x10FF));
27 
28             var oneByteRange = new Range(0x0, 1);
29             Assert.AreEqual(oneByteRange, 0x0.By(1));
30             Assert.AreEqual(oneByteRange, 0x0.To(0x0));
31         }
32 
33         [Test]
ShouldHandleCreatingRangeFromZeroToUlongMaxValue()34         public void ShouldHandleCreatingRangeFromZeroToUlongMaxValue()
35         {
36             // `Range.Size` is `ulong` so the full ulong range with size 2^64 simply isn't
37             // supported. Other constructors use `ulong` size so they have no problem with
38             // handling such a range. Let's make sure the exception occurs and isn't nasty.
39             Assert.Throws<RecoverableException>(
40                 () => 0x0.To(ulong.MaxValue),
41                 "<0, 2^64-1> ranges aren't currently supported"
42             );
43         }
44 
45         [Test]
ShouldHandleCreatingRangeWithInvalidEndAddress()46         public void ShouldHandleCreatingRangeWithInvalidEndAddress()
47         {
48             Assert.Throws<RecoverableException>(
49                 () => 0x1000.To(0x100),
50                 "the start address can't be higher than the end address"
51             );
52         }
53 
54         [Test]
ShouldHandleCreatingRangeWithInvalidSize()55         public void ShouldHandleCreatingRangeWithInvalidSize()
56         {
57             var size = ulong.MaxValue;
58             var startAddress = (ulong)0x1000;
59 
60             var expectedExceptionReason = $"size is too large: 0x{size:X}";
61             Assert.Throws<RecoverableException>(() => new Range(startAddress, size), expectedExceptionReason);
62             Assert.Throws<RecoverableException>(() => startAddress.By(size), expectedExceptionReason);
63         }
64 
65         [Test]
ShouldIntersectRange()66         public void ShouldIntersectRange()
67         {
68             var range1 = new Range(0x1000, 0x200);
69             var range2 = new Range(0x1100, 0x300);
70             var expectedResult = new Range(0x1100, 0x100);
71             var intersection1 = range1.Intersect(range2);
72             var intersection2 = range2.Intersect(range1);
73             Assert.AreEqual(expectedResult, intersection1);
74             Assert.AreEqual(expectedResult, intersection2);
75         }
76 
77         [Test]
ShouldIntersectRangesWithOneCommonAddress()78         public void ShouldIntersectRangesWithOneCommonAddress()
79         {
80             var range1 = new Range(0x1000, 0x200);
81             var range2 = new Range(0x11ff, 0x300);
82             var expectedResult = new Range(0x11ff, 0x1);
83             var intersection = range1.Intersect(range2);
84             Assert.AreEqual(expectedResult, intersection);
85         }
86 
87         [Test]
ShouldShiftRange()88         public void ShouldShiftRange()
89         {
90             var range = new Range(0x2200, 0x200);
91             var expectedResult = new Range(0x2500, 0x200);
92             var result = range.ShiftBy(0x300);
93             Assert.AreEqual(expectedResult, result);
94         }
95 
96         [Test]
ShouldContainFirstAddress()97         public void ShouldContainFirstAddress()
98         {
99             var range = new Range(0x1600, 0xA00);
100             Assert.IsTrue(range.Contains(0x1600));
101         }
102 
103         [Test]
ShouldContainLastAddress()104         public void ShouldContainLastAddress()
105         {
106             var range = new Range(0x1600, 0xA00);
107             Assert.IsTrue(range.Contains(0x1fff));
108         }
109 
110         [Test]
ShouldNotContainNearbyAddresses()111         public void ShouldNotContainNearbyAddresses()
112         {
113             var range = new Range(0x600, 0x100);
114             Assert.IsFalse(range.Contains(0x5FF));
115             Assert.IsFalse(range.Contains(0x700));
116         }
117 
118         [Test]
ShouldContainItself()119         public void ShouldContainItself()
120         {
121             var range = new Range(0x1000, 0x1200);
122             Assert.IsTrue(range.Contains(range));
123         }
124 
125         [Test]
SubtractNoIntersection()126         public void SubtractNoIntersection()
127         {
128             var range = new Range(0x1600, 0xA00);
129             var sub = new Range(0x1000, 0x200);
130             CollectionAssert.AreEquivalent(new [] { range }, range.Subtract(sub));
131         }
132 
133         [Test]
SubtractContaining()134         public void SubtractContaining()
135         {
136             var range = new Range(0x1600, 0xA00);
137             var sub = new Range(0x1000, 0x1200);
138             CollectionAssert.IsEmpty(range.Subtract(sub));
139         }
140 
141         [Test]
SubtractItself()142         public void SubtractItself()
143         {
144             var range = new Range(0x1600, 0xA00);
145             CollectionAssert.IsEmpty(range.Subtract(range));
146         }
147 
148         [Test]
SubtractLeft()149         public void SubtractLeft()
150         {
151             var range = new Range(0x1600, 0xA00);
152             var sub = new Range(0x1000, 0x800);
153             var expected = new Range(0x1800, 0x800);
154             CollectionAssert.AreEquivalent(new [] { expected }, range.Subtract(sub));
155         }
156 
157         [Test]
SubtractRight()158         public void SubtractRight()
159         {
160             var range = new Range(0x1600, 0xA00);
161             var sub = new Range(0x1800, 0x800);
162             var expected = new Range(0x1600, 0x200);
163             CollectionAssert.AreEquivalent(new [] { expected }, range.Subtract(sub));
164         }
165 
166         [Test]
SubtractContained()167         public void SubtractContained()
168         {
169             var range = new Range(0x1600, 0xA00);
170             var sub = new Range(0x1800, 0x200);
171             var expected1 = new Range(0x1600, 0x200);
172             var expected2 = new Range(0x1A00, 0x600);
173             CollectionAssert.AreEquivalent(new [] { expected1, expected2 }, range.Subtract(sub));
174         }
175 
176         [Test]
MinimalRangesCollectionAdd()177         public void MinimalRangesCollectionAdd()
178         {
179             var ranges = new MinimalRangesCollection();
180             Assert.AreEqual(ranges.Count, 0);
181 
182             ranges.Add(new Range(0x1000, 0x400));
183             ranges.Add(new Range(0x1800, 0x800));
184             Assert.AreEqual(ranges.Count, 2);
185 
186             ranges.Add(new Range(0x0, 0x1000));
187             Assert.AreEqual(ranges.Count, 2);
188 
189             ranges.Add(new Range(0x2000, 0x400));
190             Assert.AreEqual(ranges.Count, 2);
191 
192             ranges.Add(new Range(0x1000, 0x1000));
193             Assert.AreEqual(ranges.Count, 1);
194 
195             var expected = new Range(0x0, 0x2400);
196             CollectionAssert.AreEquivalent(new [] { expected }, ranges);
197         }
198 
199         [Test]
MinimalRangesCollectionRemoveOutside()200         public void MinimalRangesCollectionRemoveOutside()
201         {
202             var ranges = new MinimalRangesCollection();
203             var range = new Range(0x1000, 0x1000);
204             ranges.Add(range);
205 
206             Assert.IsFalse(ranges.Remove(new Range(0x0, 0x1000)));
207             Assert.IsFalse(ranges.Remove(new Range(0x2000, 0x1000)));
208             Assert.IsFalse(ranges.Remove(new Range(0x8000, 0x1000)));
209 
210             CollectionAssert.AreEquivalent(new [] { range }, ranges);
211         }
212 
213         [Test]
MinimalRangesCollectionRemoveSubrange()214         public void MinimalRangesCollectionRemoveSubrange()
215         {
216             var ranges = new MinimalRangesCollection();
217             var modifiedRange = new Range(0x1000, 0x1000);
218             var untouchedRange = new Range(0x8000, 0x1000);
219             ranges.Add(modifiedRange);
220             ranges.Add(untouchedRange);
221 
222             var sub = new Range(0x1400, 0x800);
223             var wasRemoved = ranges.Remove(sub);
224             Assert.IsTrue(wasRemoved);
225 
226             var expected1 = new Range(0x1000, 0x400);
227             var expected2 = new Range(0x1C00, 0x400);
228             CollectionAssert.AreEquivalent(new [] { expected1, expected2, untouchedRange }, ranges);
229         }
230     }
231 }
232 
233