Files
2025-06-25 15:00:51 +02:00

183 lines
5.0 KiB
ObjectPascal

unit TestTasks;
interface
uses
DUnitX.TestFramework,
System.SysUtils,
System.Classes,
System.SyncObjs,
Myc.Core.Tasks,
Myc.Signals,
Myc.Core.Signals,
Myc.Core.Atomic;
type
[TestFixture]
[IgnoreMemoryLeaks(true)]
TMycTaskFactoryTests = class(TObject)
private
FFactory: IThreadPool;
public
[Setup]
procedure Setup;
[TearDown]
procedure TearDown;
[Test]
procedure TestFactoryCreationAndTeardown;
[Test]
procedure TestWaitForAlreadySetState;
[Test]
procedure TestThreadInfoMethods;
[Test]
procedure TestExceptionPropagationFromJob;
[Test]
procedure TestRunJobAfterFactoryTeardown;
[Test]
procedure TestWaitForInWorkerThreadRaisesException;
end;
implementation
{ TMycTaskFactoryTests }
procedure TMycTaskFactoryTests.Setup;
begin
FFactory := TMycTaskFactory.Create;
end;
procedure TMycTaskFactoryTests.TearDown;
begin
if Assigned(FFactory) then
begin
FFactory.Teardown;
FFactory := nil;
end;
end;
procedure TMycTaskFactoryTests.TestFactoryCreationAndTeardown;
begin
Assert.IsNotNull(FFactory, 'Factory should be created');
end;
procedure TMycTaskFactoryTests.TestWaitForAlreadySetState;
var
alreadySetLatch: TLatch.ILatch;
startTime, endTime: Cardinal;
begin
// TMycLatch.CreateLatch(0) will return TMycLatch.Null
alreadySetLatch := TLatch.CreateLatch(0); // Changed from Signals.CreateLatch
Assert.IsTrue(alreadySetLatch.State.IsSet, 'Latch should be initially set');
startTime := TThread.GetTickCount;
FFactory.WaitFor(alreadySetLatch.State);
endTime := TThread.GetTickCount;
Assert.IsTrue((endTime - startTime) < 50, 'WaitFor on an already set state should not block significantly');
end;
procedure TMycTaskFactoryTests.TestThreadInfoMethods;
var
inMainThreadInJob: Boolean;
inWorkerThreadInJob: Boolean;
jobDoneLatch: TLatch.ILatch;
begin
inMainThreadInJob := True;
inWorkerThreadInJob := False;
jobDoneLatch := TLatch.CreateLatch(1); // Changed from Signals.CreateLatch
Assert.IsTrue(FFactory.InMainThread, 'Test method itself should be in main thread');
Assert.IsFalse(FFactory.InWorkerThread, 'Test method itself should not be in a factory worker thread');
FFactory.EnqueueJob(
procedure
begin
inMainThreadInJob := FFactory.InMainThread;
inWorkerThreadInJob := FFactory.InWorkerThread;
jobDoneLatch.Notify;
end
);
FFactory.WaitFor(jobDoneLatch.State);
Assert.IsFalse(inMainThreadInJob, 'Job executed by factory should not be in main thread');
Assert.IsTrue(inWorkerThreadInJob, 'Job executed by factory should be in a worker thread');
end;
procedure TMycTaskFactoryTests.TestExceptionPropagationFromJob;
var
jobDoneLatch: TLatch.ILatch;
begin
jobDoneLatch := TLatch.CreateLatch(1);
FFactory.EnqueueJob(
procedure
begin
try
raise TMycTaskFactory.ETaskException.Create('Test Exception From Job');
finally
jobDoneLatch.Notify;
end;
end
);
Assert.WillRaise(
procedure begin FFactory.WaitFor(jobDoneLatch.State); end,
TMycTaskFactory.ETaskException,
'WaitFor should re-raise the exception from the job'
);
var noExceptionRaised: Boolean := True;
try
(FFactory as TMycTaskFactory).HandleException;
except
noExceptionRaised := False;
end;
Assert.IsTrue(noExceptionRaised, 'FException should be cleared after HandleException');
end;
procedure TMycTaskFactoryTests.TestRunJobAfterFactoryTeardown;
begin
FFactory.Teardown;
Assert.WillRaise(
procedure begin FFactory.EnqueueJob(procedure begin end); end,
TMycTaskFactory.ETaskException,
'Running a job on a torn-down factory should raise ETaskException'
);
end;
procedure TMycTaskFactoryTests.TestWaitForInWorkerThreadRaisesException;
var
exceptionCaughtInJob: Boolean;
jobDoneLatch: TLatch.ILatch;
dummyStateToWaitFor: TState.IState;
begin
exceptionCaughtInJob := False;
jobDoneLatch := TLatch.CreateLatch(1);
dummyStateToWaitFor := TLatch.CreateLatch(1).State;
FFactory.EnqueueJob(
procedure
begin
try
FFactory.WaitFor(dummyStateToWaitFor);
except
on E: TMycTaskFactory.ETaskException do
begin
exceptionCaughtInJob := True;
end;
end;
jobDoneLatch.Notify;
end
);
FFactory.WaitFor(jobDoneLatch.State);
Assert.IsTrue(exceptionCaughtInJob, 'WaitFor called within a worker thread job should raise ETaskException');
end;
initialization
TDUnitX.RegisterTestFixture(TMycTaskFactoryTests);
end.