Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
22 changes: 22 additions & 0 deletions CSharp/Test/TestBasic/TestBasic.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>

<IsPackable>false</IsPackable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.1.0" />
<PackageReference Include="MSTest.TestAdapter" Version="2.2.8" />
<PackageReference Include="MSTest.TestFramework" Version="2.2.8" />
<PackageReference Include="coverlet.collector" Version="3.1.2" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\FrameRateTask\FrameRateTask.csproj" />
</ItemGroup>

</Project>
71 changes: 71 additions & 0 deletions CSharp/Test/TestBasic/TestCongestion.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
namespace TestBasic
{
[TestClass]
public class TestCongestion
{
[TestMethod]
public void TestDroppingFrame()
{
int cnt = 0;
int dropCnt = 0;
var frt = new FrameRateTaskExecutor<int>
(
() => 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<int>
(
() => true,
() =>
{
Thread.Sleep(200);
++cnt;
},
10,
() => 0
)
{
AllowTimeExceed = false,
MaxTolerantTimeExceedCount = 4,
}.Start();
Assert.Fail();
}
catch (TimeExceedException)
{
Assert.AreEqual(5, cnt);
}
}
}
}
55 changes: 55 additions & 0 deletions CSharp/Test/TestBasic/TestFrameRate.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
namespace TestBasic
{
[TestClass]
public class TestFrameRate
{
[TestMethod]
public void TestInitialFrameRate()
{
var frt = new FrameRateTaskExecutor<int>
(
() => true,
() => { },
100,
() => 0,
maxTotalDuration: 2000
);
Assert.AreEqual(10u, frt.FrameRate);
}

[TestMethod]
public void TestRunningFrameRate()
{
var frt = new FrameRateTaskExecutor<int>
(
() => 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);
}
}
}
159 changes: 159 additions & 0 deletions CSharp/Test/TestBasic/TestNormal.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
namespace TestBasic
{
[TestClass]
public class TestNormal
{
[TestMethod]
public void TestExecutionCount()
{
const int maxCnt = 8;
int cnt = 0;
new FrameRateTaskExecutor<int>
(
() => cnt < maxCnt,
() =>
{
++cnt;
},
10,
() => 0
)
{
AllowTimeExceed = true,
MaxTolerantTimeExceedCount = ulong.MaxValue,
}.Start();
Assert.AreEqual(cnt, maxCnt);
}

[TestMethod]
public void TestExecuted()
{
var task = new FrameRateTaskExecutor<int>
(
() => 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<int>
(
() => 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<int>
(
() => 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<int>
(
() => 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<int>
(
() => 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<object>
(
() => 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
}
}
}
2 changes: 2 additions & 0 deletions CSharp/Test/TestBasic/Usings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
global using Microsoft.VisualStudio.TestTools.UnitTesting;
global using Timothy.FrameRateTask;
67 changes: 67 additions & 0 deletions CSharp/Test/TestConcurrency/TestConcurrency.cs
Original file line number Diff line number Diff line change
@@ -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<int>();
var threadQueue = new BlockingCollection<Thread>();

FrameRateTaskExecutor<int> executor = new FrameRateTaskExecutor<int>(
() => 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}");
}
}
}
Loading