1 //
2 // Copyright (c) 2010-2019 Antmicro
3 //
4 // This file is licensed under the MIT License.
5 // Full license text is available in 'licenses/MIT.txt'.
6 //
7 using NUnit.Framework;
8 using Antmicro.Renode.Core;
9 using System.Collections.Generic;
10 using System.Threading;
11 using Antmicro.Migrant;
12 using Antmicro.Renode.UnitTests.Utilities;
13 
14 namespace Antmicro.Renode.UnitTests
15 {
16     [TestFixture]
17     public class PseudorandomNumberGeneratorTests
18     {
19         [Test]
ShouldGenerateNumbersDeterministically()20         public void ShouldGenerateNumbersDeterministically()
21         {
22             var result1 = new List<int>();
23             var result2 = new List<int>();
24 
25             generator.ResetSeed(Seed);
26 
27             for (var i = 0; i < 10; ++i)
28             {
29                 result1.Add((int)tester.Execute(thread1, () => generator.Next()).ShouldFinish().Result);
30             }
31 
32             for (var i = 0; i < 10; ++i)
33             {
34                 result2.Add((int)tester.Execute(thread2, () => generator.Next()).ShouldFinish().Result);
35             }
36 
37             CollectionAssert.AreEqual(thread1Results, result1);
38             CollectionAssert.AreEqual(thread2Results, result2);
39         }
40 
41         [Test]
ShouldGenerateNumbersDeterministicallyMultithreaded()42         public void ShouldGenerateNumbersDeterministicallyMultithreaded()
43         {
44             var result1 = new List<int>();
45             var result2 = new List<int>();
46 
47             generator.ResetSeed(Seed);
48 
49             for (var i = 0; i < 10; ++i)
50             {
51                 result1.Add((int)tester.Execute(thread1, () => generator.Next()).ShouldFinish().Result);
52                 result2.Add((int)tester.Execute(thread2, () => generator.Next()).ShouldFinish().Result);
53             }
54 
55             CollectionAssert.AreEqual(thread1Results, result1);
56             CollectionAssert.AreEqual(thread2Results, result2);
57         }
58 
59         [Test]
ShouldHandleSerialization()60         public void ShouldHandleSerialization()
61         {
62             int test1Result = 0, test2Result = 0;
63             var generatorCopy = Serializer.DeepClone(generator);
64 
65             test1Result = (int)tester.Execute(thread1, () => generator.Next()).ShouldFinish().Result;
66             test2Result = (int)tester.Execute(thread1, () => generatorCopy.Next()).ShouldFinish().Result;
67 
68             Assert.AreEqual(test1Result, test2Result);
69         }
70 
71         [OneTimeSetUp]
SetUp()72         public void SetUp()
73         {
74             thread1 = tester.ObtainThread(Thread1Name);
75             thread2 = tester.ObtainThread(Thread2Name);
76             generator.ResetSeed(Seed);
77 
78             for (var i = 0; i < 10; ++i)
79             {
80                 thread1Results.Add((int)tester.Execute(thread1, () => generator.Next()).ShouldFinish().Result);
81             }
82 
83             for (var i = 0; i < 10; ++i)
84             {
85                 thread2Results.Add((int)tester.Execute(thread2, ()  => generator.Next()).ShouldFinish().Result);
86             }
87         }
88 
89         [OneTimeTearDown]
TearDown()90         public void TearDown()
91         {
92             tester.Finish();
93             tester.Dispose();
94         }
95 
96         private ThreadSyncTester.TestThread thread1;
97         private ThreadSyncTester.TestThread thread2;
98 
99         private readonly ThreadSyncTester tester = new ThreadSyncTester();
100         private readonly List<int> thread1Results = new List<int>();
101         private readonly List<int> thread2Results = new List<int>();
102         private readonly PseudorandomNumberGenerator generator = new PseudorandomNumberGenerator();
103 
104         private const int Seed = 0xC0DE;
105         private const string Thread1Name = "Thread1";
106         private const string Thread2Name = "Thread2";
107     }
108 }