Skip to content
Open
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
24 changes: 24 additions & 0 deletions C#/forSpbu/MyThreadPool.Test/MyThreadPool.Test.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<Project Sdk="Microsoft.NET.Sdk">

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

<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.5.0"/>
<PackageReference Include="NUnit" Version="3.13.3"/>
<PackageReference Include="NUnit3TestAdapter" Version="4.4.2"/>
<PackageReference Include="NUnit.Analyzers" Version="3.6.1"/>
<PackageReference Include="coverlet.collector" Version="3.2.0"/>
</ItemGroup>

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

</Project>
158 changes: 158 additions & 0 deletions C#/forSpbu/MyThreadPool.Test/MyThreadPoolTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
namespace MyThreadPool.Test;

public class MyThreadPoolTests
{
private class PoolTester
{
public int Counter { get; private set; }

public int Fst()
{
Counter++;
var result = 0;
for (int i = 0; i < 1000; i++)
{
result += i;
}

return result;
}
}

private static int TestFunc()
{
var result = 0;
for (int i = 0; i < 1000; i++)
{
result += i;
}

return result;
}

private MyThreadPool? _pool;
private int _processThreadsAmount;
private int _threadsAmount;

[SetUp]
public void Setup()
{
System.Diagnostics.Process.GetCurrentProcess().Refresh();
this._processThreadsAmount = System.Diagnostics.Process.GetCurrentProcess().Threads.Count;
this._threadsAmount = 4;
this._pool = new MyThreadPool(this._threadsAmount);
}

[Test]
public void SubmitResultTest()
{
Assert.That(_pool!.Submit(TestFunc).Result, Is.EqualTo(499500));
}

[Test]
public void SubmitContinueWithResultTest()
{
Assert.That(_pool!.Submit(TestFunc).ContinueWith((int result) => result + 1).Result, Is.EqualTo(499501));
}

[Test]
public void DoubleContinueWithResultTest()
{
Assert.That(_pool!.Submit(TestFunc).ContinueWith((int result) => result + 1).ContinueWith((int result) => result.ToString()).Result, Is.EqualTo("499501"));
}

[Test]
public void SubmitResultContinueWithResultTest()
{
var task = _pool!.Submit(TestFunc);


Assert.That(task.ContinueWith((int result) => result + 1).Result, Is.EqualTo(499501));
}

[Test]
public void LazyResultTest()
{
var tester = new PoolTester();
var task = _pool!.Submit(tester.Fst);

var res = task.Result;
Assert.That(tester.Counter, Is.EqualTo(1));
res = task.Result;
Assert.That(tester.Counter, Is.EqualTo(1));
}

[Test]
public void ExceptionResultTest()
{
var tester = new PoolTester();
var task = _pool!.Submit<int>(() => throw new NotImplementedException());

Assert.Throws<AggregateException>(() =>
{
var _ = task.Result;
});
}

[Test]
public void IsCompletedTest()
{
var startEvent = new ManualResetEvent(false);
var task = _pool!.Submit(() =>
{
startEvent.WaitOne();
return TestFunc();
});

Assert.That(task.IsCompleted, Is.False);
startEvent.Set();
var res = task.Result;
Assert.That(task.IsCompleted, Is.True);
res = task.Result;
Assert.That(task.IsCompleted, Is.True);
}

[Test]
public void ShutdownTest()
{
var fstTask = _pool!.Submit(TestFunc);
var secTask = _pool!.Submit(TestFunc);
_pool!.Shutdown();
System.Diagnostics.Process.GetCurrentProcess().Refresh();
Assert.That(System.Diagnostics.Process.GetCurrentProcess().Threads, Has.Count.EqualTo(_processThreadsAmount));

Assert.Multiple(() =>
{
Assert.That(fstTask.IsCompleted, Is.True);
Assert.That(secTask.IsCompleted, Is.True);
});

_pool!.Submit(TestFunc);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Это не должно быть возможно после Shutdown по условию

fstTask.ContinueWith((int result) => result + 1);
System.Diagnostics.Process.GetCurrentProcess().Refresh();
Assert.That(System.Diagnostics.Process.GetCurrentProcess().Threads, Has.Count.EqualTo(_processThreadsAmount));
}

[Test]
public void DoubleContinueWithTest()
{
var fstTask = _pool!.Submit(TestFunc);
var fstContinueTask = fstTask.ContinueWith((int result) => result + 1);
var secContinueTask = fstTask.ContinueWith((int result) => result.ToString());

Assert.Multiple(() =>
{
Assert.That(fstContinueTask.Result, Is.EqualTo(499501));
Assert.That(secContinueTask.Result, Is.EqualTo("499500"));
});
}

[Test]
public void ThreadsCountTest()
{
System.Diagnostics.Process.GetCurrentProcess().Refresh();
Assert.That(System.Diagnostics.Process.GetCurrentProcess().Threads, Has.Count.EqualTo(_processThreadsAmount + 4));
}


}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Не хватает тестов на конкурентный доступ к методам пула из нескольких потоков: submit задач из разных потоков, Submit и Shutdown одновременно, ContinueWith и Shutdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 change: 1 addition & 0 deletions C#/forSpbu/MyThreadPool.Test/Usings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
global using NUnit.Framework;
27 changes: 27 additions & 0 deletions C#/forSpbu/MyThreadPool/IMyTask.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
namespace MyThreadPool;

/// <summary>
/// Interface for my thread pool tasks
/// </summary>
/// <typeparam name="TResult">Task return value</typeparam>
public interface IMyTask<out TResult>
{
/// <summary>
/// Whether task is completed
/// </summary>
public bool IsCompleted { get; }

/// <summary>
/// Task result, blocks called thread
/// </summary>
/// <returns>task result</returns>
public TResult Result { get; }

/// <summary>
/// Continues task with given function, current task result is used as a parameter for the new one
/// </summary>
/// <param name="nextDelegate">New task delegate</param>
/// <typeparam name="TNewResult">New task return type</typeparam>
/// <returns>Returns created task</returns>
public IMyTask<TNewResult> ContinueWith<TNewResult>(Func<TResult, TNewResult> nextDelegate);
}
8 changes: 8 additions & 0 deletions C#/forSpbu/MyThreadPool/MyThreadCreationException.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace MyThreadPool;

public class MyThreadCreationException : Exception

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Надо комментарии

{
public MyThreadCreationException()
{
}
}
Loading