diff options
author | Lluis Sanchez <llsan@microsoft.com> | 2022-06-16 13:51:43 +0300 |
---|---|---|
committer | Lluis Sanchez <llsan@microsoft.com> | 2022-09-13 20:38:42 +0300 |
commit | 9ac75d4641bb7b58075c9d6fc8ac92dbb32a4fbf (patch) | |
tree | b5169d113971893cb02d0e6dd09093716e7bf41e /Test | |
parent | 6f0d811b6823b378d1db44f5d2bb6aab7d684a83 (diff) |
Add multi-threading tests
And fixed threading issue.
Diffstat (limited to 'Test')
-rw-r--r-- | Test/UnitTests/TestMultithreading.cs | 195 | ||||
-rw-r--r-- | Test/UnitTests/UnitTests.csproj | 1 |
2 files changed, 196 insertions, 0 deletions
diff --git a/Test/UnitTests/TestMultithreading.cs b/Test/UnitTests/TestMultithreading.cs new file mode 100644 index 0000000..fd3cbcf --- /dev/null +++ b/Test/UnitTests/TestMultithreading.cs @@ -0,0 +1,195 @@ + +using System; +using System.IO; +using NUnit.Framework; +using Mono.Addins; +using SimpleApp; +using System.Threading; +using System.Diagnostics; +using System.Linq; + +namespace UnitTests +{ + [TestFixture ()] + public class TestMultiThreading: TestBase + { + public override void Setup () + { + base.Setup (); + GlobalInfoCondition.Value = "res"; + } + + [Test] + public void ChildConditionAttributeMultithread () + { + int threads = 50; + using var testData = new TestData(threads); + + GlobalInfoCondition.Value = ""; + + testData.StartThreads (RunChildConditionAttributeTest); + + for (int n = 0; n < 20; n++) { + Console.WriteLine ("Step " + n); + testData.CheckCounters (0, 10000); + + GlobalInfoCondition.Value = "foo"; + + testData.CheckCounters (1, 1000); + + GlobalInfoCondition.Value = ""; + } + } + + void RunChildConditionAttributeTest (int index, TestData data) + { + while (!data.Stopped) { + var writers = AddinManager.GetExtensionObjects<IWriter> ("/SimpleApp/ConditionedWriters"); + data.Counters [index] = writers.Length; + } + } + + [Test] + public void EnableDisableMultithread () + { + int threads = 50; + int steps = 20; + + using var testData = new TestData (threads); + + testData.StartThreads ((index, data) => { + while (!data.Stopped) { + var writers = AddinManager.GetExtensionObjects<IWriter> ("/SimpleApp/Writers"); + testData.Counters [index] = writers.Length; + } + }); + + for (int n = 0; n < steps; n++) { + Console.WriteLine ("Step " + n); + + testData.CheckCounters (4, 10000); + + var ainfo1 = AddinManager.Registry.GetAddin ("SimpleApp.HelloWorldExtension"); + ainfo1.Enabled = false; + + testData.CheckCounters (3, 1000); + + var ainfo2 = AddinManager.Registry.GetAddin ("SimpleApp.FileContentExtension"); + ainfo2.Enabled = false; + + testData.CheckCounters (2, 1000); + + ainfo1.Enabled = true; + ainfo2.Enabled = true; + } + } + + [Test] + public void EventsMultithread () + { + int threads = 50; + int steps = 20; + + var testData = new TestData (threads); + + GlobalInfoCondition.Value = ""; + + testData.StartThreads (RunEventsMultithread); + + for (int n = 0; n < steps; n++) { + Console.WriteLine ("Step " + n); + testData.CheckCounters (0, 10000); + + GlobalInfoCondition.Value = "foo"; + + testData.CheckCounters (1, 1000); + + GlobalInfoCondition.Value = ""; + } + } + + void RunEventsMultithread (int index, TestData data) + { + while (!data.Stopped) { + int count = 0; + ExtensionNodeEventHandler handler = (s, args) => { + count++; + }; + AddinManager.AddExtensionNodeHandler("/SimpleApp/ConditionedWriters", handler); + data.Counters [index] = count; + AddinManager.RemoveExtensionNodeHandler ("/SimpleApp/ConditionedWriters", handler); + } + } + + [Test] + public void ChildConditionWithContextMultithread () + { + int threads = 50; + using var testData = new TestData (threads); + + GlobalInfoCondition.Value = ""; + + testData.StartThreads (RunChildConditionWithContextMultithread); + + for (int n = 0; n < 20; n++) { + Console.WriteLine ("Step " + n); + testData.CheckCounters (0, 10000); + + GlobalInfoCondition.Value = "foo"; + + testData.CheckCounters (1, 1000); + + GlobalInfoCondition.Value = ""; + } + } + + void RunChildConditionWithContextMultithread (int index, TestData data) + { + var ctx = AddinManager.CreateExtensionContext (); + var writers = ctx.GetExtensionNode ("/SimpleApp/ConditionedWriters"); + while (!data.Stopped) { + data.Counters [index] = writers.ChildNodes.Count; + } + } + class TestData: IDisposable + { + int numThreads; + + public bool Stopped; + public int [] Counters; + + public TestData (int numThreads) + { + this.numThreads = numThreads; + Counters = new int [numThreads]; + } + + public void CheckCounters (int expectedResult, int timeout) + { + var sw = Stopwatch.StartNew (); + do { + if (Counters.All (c => c == expectedResult)) + return; + Thread.Sleep (10); + } while (sw.ElapsedMilliseconds < timeout); + + Assert.Fail (); + } + + public void Dispose () + { + Stopped = true; + } + + public void StartThreads (Action<int, TestData> threadAction) + { + for (int n = 0; n < numThreads; n++) { + Counters [n] = -1; + var index = n; + var t = new Thread (() => threadAction(index, this)); + t.Start (); + } + } + } + } +} diff --git a/Test/UnitTests/UnitTests.csproj b/Test/UnitTests/UnitTests.csproj index 28d5659..aae8ac1 100644 --- a/Test/UnitTests/UnitTests.csproj +++ b/Test/UnitTests/UnitTests.csproj @@ -13,6 +13,7 @@ <SignAssembly>True</SignAssembly> <AssemblyOriginatorKeyFile>..\..\mono-addins.snk</AssemblyOriginatorKeyFile> <TargetFrameworks>net472;net6.0</TargetFrameworks> + <LangVersion>9.0</LangVersion> </PropertyGroup> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> <DebugSymbols>True</DebugSymbols> |