From 83126314531ecdeb2d49b9d833f0fbf6e068d448 Mon Sep 17 00:00:00 2001 From: Timothy Liu Date: Fri, 21 Oct 2022 01:12:52 +0800 Subject: [PATCH 1/2] test: :white_check_mark: add test code --- CSharp/Test/TestBasic/TestBasic.csproj | 22 +++ CSharp/Test/TestBasic/TestCongestion.cs | 71 ++++++++ CSharp/Test/TestBasic/TestFrameRate.cs | 55 ++++++ CSharp/Test/TestBasic/TestNormal.cs | 159 ++++++++++++++++++ CSharp/Test/TestBasic/Usings.cs | 2 + .../Test/TestConcurrency/TestConcurrency.cs | 67 ++++++++ .../TestConcurrency/TestConcurrency.csproj | 22 +++ CSharp/Test/TestConcurrency/Usings.cs | 2 + CSharp/TestConcurrency/Program.cs | 87 ---------- CSharp/TestConcurrency/TestConcurrency.csproj | 14 -- FrameRateTask.sln | 34 +++- 11 files changed, 427 insertions(+), 108 deletions(-) create mode 100644 CSharp/Test/TestBasic/TestBasic.csproj create mode 100644 CSharp/Test/TestBasic/TestCongestion.cs create mode 100644 CSharp/Test/TestBasic/TestFrameRate.cs create mode 100644 CSharp/Test/TestBasic/TestNormal.cs create mode 100644 CSharp/Test/TestBasic/Usings.cs create mode 100644 CSharp/Test/TestConcurrency/TestConcurrency.cs create mode 100644 CSharp/Test/TestConcurrency/TestConcurrency.csproj create mode 100644 CSharp/Test/TestConcurrency/Usings.cs delete mode 100644 CSharp/TestConcurrency/Program.cs delete mode 100644 CSharp/TestConcurrency/TestConcurrency.csproj diff --git a/CSharp/Test/TestBasic/TestBasic.csproj b/CSharp/Test/TestBasic/TestBasic.csproj new file mode 100644 index 0000000..44941e4 --- /dev/null +++ b/CSharp/Test/TestBasic/TestBasic.csproj @@ -0,0 +1,22 @@ + + + + net6.0 + enable + enable + + false + + + + + + + + + + + + + + diff --git a/CSharp/Test/TestBasic/TestCongestion.cs b/CSharp/Test/TestBasic/TestCongestion.cs new file mode 100644 index 0000000..f6aba61 --- /dev/null +++ b/CSharp/Test/TestBasic/TestCongestion.cs @@ -0,0 +1,71 @@ +namespace TestBasic +{ + [TestClass] + public class TestCongestion + { + [TestMethod] + public void TestDroppingFrame() + { + int cnt = 0; + int dropCnt = 0; + var frt = new FrameRateTaskExecutor + ( + () => true, + () => + { + if (cnt < 4) + { + Thread.Sleep(200); + } + ++cnt; + }, + 50, + () => 0, + maxTotalDuration: 1600 + ) + { + AllowTimeExceed = true, + MaxTolerantTimeExceedCount = 1, + TimeExceedAction = b => + { + if (b) + { + ++dropCnt; + } + } + }; + frt.Start(); + Assert.IsTrue(cnt > 800 / 50 && cnt < (800 / 50 + 4) + 4, $"The value of cnt: {cnt}"); + Assert.AreEqual(2, dropCnt); + } + + [TestMethod] + public void TestTimeExceed() + { + int cnt = 0; + try + { + new FrameRateTaskExecutor + ( + () => true, + () => + { + Thread.Sleep(200); + ++cnt; + }, + 10, + () => 0 + ) + { + AllowTimeExceed = false, + MaxTolerantTimeExceedCount = 4, + }.Start(); + Assert.Fail(); + } + catch (TimeExceedException) + { + Assert.AreEqual(5, cnt); + } + } + } +} diff --git a/CSharp/Test/TestBasic/TestFrameRate.cs b/CSharp/Test/TestBasic/TestFrameRate.cs new file mode 100644 index 0000000..c2deb97 --- /dev/null +++ b/CSharp/Test/TestBasic/TestFrameRate.cs @@ -0,0 +1,55 @@ +namespace TestBasic +{ + [TestClass] + public class TestFrameRate + { + [TestMethod] + public void TestInitialFrameRate() + { + var frt = new FrameRateTaskExecutor + ( + () => true, + () => { }, + 100, + () => 0, + maxTotalDuration: 2000 + ); + Assert.AreEqual(10u, frt.FrameRate); + } + + [TestMethod] + public void TestRunningFrameRate() + { + var frt = new FrameRateTaskExecutor + ( + () => true, + () => { }, + 100, + () => 0, + maxTotalDuration: 2000 + ); + Assert.AreEqual(10u, frt.FrameRate); + + int success = 1; + new Thread + ( + () => + { + while (!frt.Finished) + { + var frameRate = frt.FrameRate; + if (frameRate < 8 || frameRate > 12) + { + Interlocked.Exchange(ref success, 0); + break; + } + Thread.Sleep(500); + } + } + ).Start(); + frt.Start(); + + Assert.IsTrue(Interlocked.CompareExchange(ref success, 0, 0) == 1); + } + } +} diff --git a/CSharp/Test/TestBasic/TestNormal.cs b/CSharp/Test/TestBasic/TestNormal.cs new file mode 100644 index 0000000..f05c433 --- /dev/null +++ b/CSharp/Test/TestBasic/TestNormal.cs @@ -0,0 +1,159 @@ +namespace TestBasic +{ + [TestClass] + public class TestNormal + { + [TestMethod] + public void TestExecutionCount() + { + const int maxCnt = 8; + int cnt = 0; + new FrameRateTaskExecutor + ( + () => cnt < maxCnt, + () => + { + ++cnt; + }, + 10, + () => 0 + ) + { + AllowTimeExceed = true, + MaxTolerantTimeExceedCount = ulong.MaxValue, + }.Start(); + Assert.AreEqual(cnt, maxCnt); + } + + [TestMethod] + public void TestExecuted() + { + var task = new FrameRateTaskExecutor + ( + () => true, + () => false, + 10, + () => 0 + ) + { + AllowTimeExceed = true, + MaxTolerantTimeExceedCount = ulong.MaxValue, + }; + Assert.IsFalse(task.HasExecuted); + task.Start(); + Assert.IsTrue(task.HasExecuted); + } + + [TestMethod] + public void TestFinished() + { + var frt = new FrameRateTaskExecutor + ( + () => true, + () => false, + 10, + () => 0 + ) + { + AllowTimeExceed = true, + MaxTolerantTimeExceedCount = ulong.MaxValue, + }; + frt.Start(); + Assert.IsTrue(frt.Finished); + } + + [TestMethod] + public void TestCondition() + { + bool cond = true; + int cnt = 0; + new FrameRateTaskExecutor + ( + () => cond, + () => + { + Assert.IsTrue(cond); + Assert.IsTrue(cnt < 5); + if (cnt == 4) + { + cond = false; + } + ++cnt; + }, + 50, + () => 0 + ) + { + AllowTimeExceed = true, + MaxTolerantTimeExceedCount = ulong.MaxValue, + }.Start(); + Assert.AreEqual(5, cnt); + Assert.IsFalse(cond); + } + + [TestMethod] + public void TestBreakOut() + { + int cnt = 0; + new FrameRateTaskExecutor + ( + () => true, + () => + { + try + { + Assert.IsTrue(cnt < 5); + if (cnt == 4) + { + return false; + } + return true; + } + finally + { + ++cnt; + } + }, + 50, + () => 0 + ) + { + AllowTimeExceed = true, + MaxTolerantTimeExceedCount = ulong.MaxValue, + }.Start(); + Assert.AreEqual(5, cnt); + } + + [TestMethod] + public void TestValueTypeResult() + { + const int result = 8888; + var frt = new FrameRateTaskExecutor + ( + () => true, + () => false, + 10, + () => result + ); + frt.Start(); + Assert.IsTrue(frt.Finished); + Assert.AreEqual(frt.Result, result); + } + + [TestMethod] + public void TestReferenceTypeResult() + { + object result = new object(); + var frt = new FrameRateTaskExecutor + ( + () => true, + () => false, + 10, + () => result + ); + frt.Start(); + Assert.IsTrue(frt.Finished); + Assert.ReferenceEquals(result, frt.Result); // frt.Result and result should reference to the same object + } + } +} diff --git a/CSharp/Test/TestBasic/Usings.cs b/CSharp/Test/TestBasic/Usings.cs new file mode 100644 index 0000000..260ca2e --- /dev/null +++ b/CSharp/Test/TestBasic/Usings.cs @@ -0,0 +1,2 @@ +global using Microsoft.VisualStudio.TestTools.UnitTesting; +global using Timothy.FrameRateTask; diff --git a/CSharp/Test/TestConcurrency/TestConcurrency.cs b/CSharp/Test/TestConcurrency/TestConcurrency.cs new file mode 100644 index 0000000..49f9d17 --- /dev/null +++ b/CSharp/Test/TestConcurrency/TestConcurrency.cs @@ -0,0 +1,67 @@ +using System.Collections.Concurrent; + +namespace TestConcurrency +{ + [TestClass] + public class TestConcurrency + { + [TestMethod] + public void TestMethod() + { + const int endVal = 2; + int cnt = 0; + var result = new BlockingCollection(); + var threadQueue = new BlockingCollection(); + + FrameRateTaskExecutor executor = new FrameRateTaskExecutor( + () => cnt < endVal, + () => + { + result.Add(cnt); + ++cnt; + }, + 1, + () => 8888 + ) + { AllowTimeExceed = true }; + + Action action = () => + { + for (int i = 0; i < 10; ++i) + { + var thrd = new Thread(() => + { + if (executor.TryStart()) + { + result.Add(executor.Result); + } + }); + threadQueue.Add(thrd); + thrd.Start(); + }; + }; + for (int i = 0; i < 20; ++i) + { + var thrd = new Thread(() => action()); + threadQueue.Add(thrd); + thrd.Start(); + } + + while (threadQueue.Count > 0) + { + threadQueue.TryTake(out Thread? thrd); + if (thrd is not null) + { + thrd.Join(); + } + } + for (int i = 0; i < endVal; ++i) + { + Assert.IsTrue(result.TryTake(out int seq), "Get no number"); + Assert.AreEqual(i, seq, $"Get error number: {seq}"); + } + Assert.IsTrue(result.TryTake(out int res), "Get no result!"); + Assert.AreEqual(8888, res, $"Get error result: {res}"); + } + } +} diff --git a/CSharp/Test/TestConcurrency/TestConcurrency.csproj b/CSharp/Test/TestConcurrency/TestConcurrency.csproj new file mode 100644 index 0000000..44941e4 --- /dev/null +++ b/CSharp/Test/TestConcurrency/TestConcurrency.csproj @@ -0,0 +1,22 @@ + + + + net6.0 + enable + enable + + false + + + + + + + + + + + + + + diff --git a/CSharp/Test/TestConcurrency/Usings.cs b/CSharp/Test/TestConcurrency/Usings.cs new file mode 100644 index 0000000..260ca2e --- /dev/null +++ b/CSharp/Test/TestConcurrency/Usings.cs @@ -0,0 +1,2 @@ +global using Microsoft.VisualStudio.TestTools.UnitTesting; +global using Timothy.FrameRateTask; diff --git a/CSharp/TestConcurrency/Program.cs b/CSharp/TestConcurrency/Program.cs deleted file mode 100644 index 7aac9af..0000000 --- a/CSharp/TestConcurrency/Program.cs +++ /dev/null @@ -1,87 +0,0 @@ -using System; -using System.Threading; -using System.Diagnostics.CodeAnalysis; -using System.Collections.Concurrent; -using Timothy.FrameRateTask; - -namespace TestConcurrency -{ - internal class Program - { - static int Main(string[] args) - { - const int endVal = 2; - int cnt = 0; - var result = new BlockingCollection(); - var threadQueue = new BlockingCollection(); - - FrameRateTaskExecutor executor = new FrameRateTaskExecutor( - () => cnt < endVal, - () => - { - result.Add(cnt); - ++cnt; - }, - 1, - () => 8888 - ) - { AllowTimeExceed = true }; - - Action action = () => - { - for (int i = 0; i < 10; ++i) - { - var thrd = new Thread(() => - { - if (executor.TryStart()) - { - result.Add(executor.Result); - } - }); - threadQueue.Add(thrd); - thrd.Start(); - }; - }; - for (int i = 0; i < 20; ++i) - { - var thrd = new Thread(() => action()); - threadQueue.Add(thrd); - thrd.Start(); - } - - while (threadQueue.Count > 0) - { - threadQueue.TryTake(out Thread? thrd); - if (thrd is not null) - { - thrd.Join(); - } - } - for (int i = 0; i < endVal; ++i) - { - if (!result.TryTake(out int seq) || seq != i) - { - Console.WriteLine(); - if (result.Count > 0) - { - Console.Error.WriteLine($"Get error number: { seq }"); - } - else - { - Console.Error.WriteLine("Get no number!"); - } - return 1; - } - Console.Write(i.ToString() + ' '); - } - Console.WriteLine(); - if (!result.TryTake(out int res) || res != 8888) - { - Console.Error.WriteLine("Get error result!"); - return 1; - } - Console.WriteLine(res); - return 0; - } - } -} diff --git a/CSharp/TestConcurrency/TestConcurrency.csproj b/CSharp/TestConcurrency/TestConcurrency.csproj deleted file mode 100644 index c5c118d..0000000 --- a/CSharp/TestConcurrency/TestConcurrency.csproj +++ /dev/null @@ -1,14 +0,0 @@ - - - - Exe - net6.0 - enable - enable - - - - - - - diff --git a/FrameRateTask.sln b/FrameRateTask.sln index f363b45..eb13075 100644 --- a/FrameRateTask.sln +++ b/FrameRateTask.sln @@ -15,8 +15,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FrameRateTask", "CSharp\Fra EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "CSharp", "CSharp", "{C0855812-2EBC-415D-92D3-C3B100DB3203}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestConcurrency", "CSharp\TestConcurrency\TestConcurrency.csproj", "{BD4BCC77-7900-46A2-A213-D4E3F611E53E}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Example", "Example", "{3524A747-8514-4044-B1A1-049F1ACB3419}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "CSharp", "CSharp", "{47DC06C9-8A99-436D-B114-06EBA0FEF260}" @@ -31,6 +29,20 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CongestionRelief", "Example EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TemporaryCongestion", "Example\CSharp\TemporaryCongestion\TemporaryCongestion.csproj", "{C0F0BB0E-07FE-4D5B-84D6-99B390FEE480}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".github", ".github", "{4C14DAC8-1503-4B4B-A4BE-92DEB7FA0BDB}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{A3BCC22A-1330-4D1B-B2A5-16E91AA1BDD3}" + ProjectSection(SolutionItems) = preProject + .github\workflows\publish.yml = .github\workflows\publish.yml + .github\workflows\test.yml = .github\workflows\test.yml + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Test", "Test", "{2F814C2B-9C02-4188-AFBB-50572539ABCD}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestConcurrency", "CSharp\Test\TestConcurrency\TestConcurrency.csproj", "{FE78004B-F053-4C75-8427-8D17115FCA5C}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestBasic", "CSharp\Test\TestBasic\TestBasic.csproj", "{FF1EBDDC-F5B6-4304-AC05-7F325C21D10D}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -41,10 +53,6 @@ Global {07261E94-73FD-43C5-AAAA-8C61E7576E47}.Debug|Any CPU.Build.0 = Debug|Any CPU {07261E94-73FD-43C5-AAAA-8C61E7576E47}.Release|Any CPU.ActiveCfg = Release|Any CPU {07261E94-73FD-43C5-AAAA-8C61E7576E47}.Release|Any CPU.Build.0 = Release|Any CPU - {BD4BCC77-7900-46A2-A213-D4E3F611E53E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {BD4BCC77-7900-46A2-A213-D4E3F611E53E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {BD4BCC77-7900-46A2-A213-D4E3F611E53E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {BD4BCC77-7900-46A2-A213-D4E3F611E53E}.Release|Any CPU.Build.0 = Release|Any CPU {EB55C6F7-C336-4A59-9588-11F6943E9A62}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {EB55C6F7-C336-4A59-9588-11F6943E9A62}.Debug|Any CPU.Build.0 = Debug|Any CPU {EB55C6F7-C336-4A59-9588-11F6943E9A62}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -65,19 +73,31 @@ Global {C0F0BB0E-07FE-4D5B-84D6-99B390FEE480}.Debug|Any CPU.Build.0 = Debug|Any CPU {C0F0BB0E-07FE-4D5B-84D6-99B390FEE480}.Release|Any CPU.ActiveCfg = Release|Any CPU {C0F0BB0E-07FE-4D5B-84D6-99B390FEE480}.Release|Any CPU.Build.0 = Release|Any CPU + {FE78004B-F053-4C75-8427-8D17115FCA5C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FE78004B-F053-4C75-8427-8D17115FCA5C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FE78004B-F053-4C75-8427-8D17115FCA5C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FE78004B-F053-4C75-8427-8D17115FCA5C}.Release|Any CPU.Build.0 = Release|Any CPU + {FF1EBDDC-F5B6-4304-AC05-7F325C21D10D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FF1EBDDC-F5B6-4304-AC05-7F325C21D10D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FF1EBDDC-F5B6-4304-AC05-7F325C21D10D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FF1EBDDC-F5B6-4304-AC05-7F325C21D10D}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution {07261E94-73FD-43C5-AAAA-8C61E7576E47} = {C0855812-2EBC-415D-92D3-C3B100DB3203} - {BD4BCC77-7900-46A2-A213-D4E3F611E53E} = {C0855812-2EBC-415D-92D3-C3B100DB3203} {47DC06C9-8A99-436D-B114-06EBA0FEF260} = {3524A747-8514-4044-B1A1-049F1ACB3419} {EB55C6F7-C336-4A59-9588-11F6943E9A62} = {47DC06C9-8A99-436D-B114-06EBA0FEF260} {5EBEE786-AE2E-4417-83CF-0468BFCBDC76} = {47DC06C9-8A99-436D-B114-06EBA0FEF260} {CA4633C1-3423-4774-8575-58D1A69B9249} = {47DC06C9-8A99-436D-B114-06EBA0FEF260} {B548ECDD-C64F-44A1-8D3B-8708129D423C} = {47DC06C9-8A99-436D-B114-06EBA0FEF260} {C0F0BB0E-07FE-4D5B-84D6-99B390FEE480} = {47DC06C9-8A99-436D-B114-06EBA0FEF260} + {4C14DAC8-1503-4B4B-A4BE-92DEB7FA0BDB} = {64E26841-2083-4D77-9238-20D5C3A1F993} + {A3BCC22A-1330-4D1B-B2A5-16E91AA1BDD3} = {4C14DAC8-1503-4B4B-A4BE-92DEB7FA0BDB} + {2F814C2B-9C02-4188-AFBB-50572539ABCD} = {C0855812-2EBC-415D-92D3-C3B100DB3203} + {FE78004B-F053-4C75-8427-8D17115FCA5C} = {2F814C2B-9C02-4188-AFBB-50572539ABCD} + {FF1EBDDC-F5B6-4304-AC05-7F325C21D10D} = {2F814C2B-9C02-4188-AFBB-50572539ABCD} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {19AB3133-5CDE-47FD-94A8-16088C24D599} From a2ad7ed2d917d753fb2ec8a2e45b277daeddcb89 Mon Sep 17 00:00:00 2001 From: Timothy Liu Date: Fri, 21 Oct 2022 01:14:37 +0800 Subject: [PATCH 2/2] ci(test): :construction_worker: use ci to run test code --- .github/workflows/test.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 7e10fbb..98f97a4 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -23,5 +23,4 @@ jobs: run: dotnet build "./CSharp/FrameRateTask/FrameRateTask.csproj" -c Release - name: Run test code run: | - dotnet build "./CSharp/TestConcurrency/TestConcurrency.csproj" -c Release - dotnet run --project "./CSharp/TestConcurrency/TestConcurrency.csproj" -c Release + dotnet test "./FrameRateTask.sln" -c Release