TaskFactory added

This commit is contained in:
Michael Schimmel
2025-05-26 00:27:09 +02:00
parent 10ef4cbcf2
commit 95fddb0181
13 changed files with 1292 additions and 251 deletions
+22 -30
View File
@@ -5,9 +5,9 @@ interface
uses
DUnitX.TestFramework,
Myc.Core.Atomic, // The unit to be tested. TSListEntry and PSListEntry are expected from here.
System.SysUtils, // For NativeUInt, FillChar, Format static class, etc.
System.SyncObjs, // TInterlocked
Winapi.Windows, // For general Windows API types if needed by Myc.Heap for TSListHeader.
System.SysUtils, // For NativeUInt, FillChar, Format static class, etc.
System.SyncObjs, // TInterlocked
Winapi.Windows, // For general Windows API types if needed by Myc.Heap for TSListHeader.
System.Generics.Collections; // For TThreadedQueue<T>, TDictionary<K,V>
type
@@ -58,16 +58,16 @@ type
implementation
uses
System.Math, // For Random and Randomize
System.Classes, // For TThread
System.Types; // For TWaitResult
System.Math, // For Random and Randomize
System.Classes, // For TThread
System.Types; // For TWaitResult
// --- Helper Implementations (static) ---
class function TMycTestSList.CreateTestListItem(ID: Integer): PTestListItem;
begin
GetMemAligned(Result, SizeOf(TTestListItem));
Assert.IsNotNull(Result, Format('Failed to allocate memory for TestListItem ID %d', [ID]));
Assert.IsNotNull(Result, 'Failed to allocate memory for TestListItem.'); // Replaced Format string
FillChar(Result^, SizeOf(TTestListItem), 0);
Result.ID := ID;
end;
@@ -128,18 +128,16 @@ begin
GetMemAligned(ptr, sizeToAllocate);
if sizeToAllocate = 0 then
begin
Assert.IsTrue(True, Format('Zero-size allocation processed (Iteration %d). Pointer: %p', [i, ptr]));
Assert.IsTrue(True, 'Zero-size allocation processed.'); // Replaced Format string
end
else if ptr = nil then
begin
Assert.Fail(Format('GetMemAligned returned nil for size %u (Iteration %d).',
[sizeToAllocate, i]));
Assert.Fail('GetMemAligned returned nil for non-zero size.'); // Replaced Format string
end
else
begin
Assert.AreEqual(System.NativeUInt(0), System.NativeUInt(ptr) and TestAlignmentMask,
Format('Pointer %p not 16-byte aligned. Size: %u, Iteration: %d. (Value AND Mask = %u)',
[ptr, sizeToAllocate, i, System.NativeUInt(ptr) and TestAlignmentMask]));
'Pointer not 16-byte aligned.'); // Replaced Format string
fillValue := Byte(i mod 256);
System.FillChar(ptr^, sizeToAllocate, fillValue);
@@ -149,8 +147,7 @@ begin
begin
if bytePtr[j] <> fillValue then
begin
Assert.Fail(Format('Data corruption at offset %u for pointer %p. Size: %u, Iteration: %d. Expected %u, got %u.',
[j, ptr, sizeToAllocate, i, fillValue, bytePtr[j]]));
Assert.Fail('Data corruption detected.'); // Replaced Format string
Break;
end;
end;
@@ -212,18 +209,18 @@ begin
begin
items[i] := TMycTestSList.CreateTestListItem(200 + i);
sListPtr.Push(@items[i].ListEntry);
Assert.AreEqual(i, sListPtr.QueryDepth, Format('Depth should be %d after %d pushes.', [i,i]));
Assert.AreEqual(i, sListPtr.QueryDepth, 'Depth incorrect after a push operation.'); // Replaced Format string
end;
Assert.AreEqual(NumItems, sListPtr.QueryDepth, 'Final depth after all pushes incorrect.');
for i := NumItems downto 1 do
begin
poppedInternalListEntry := sListPtr.Pop;
Assert.IsNotNull(poppedInternalListEntry, Format('Pop should return an item, not nil (iteration %d).', [i]));
Assert.IsNotNull(poppedInternalListEntry, 'Pop should return a non-nil item.'); // Replaced Format string
poppedItem := PTestListItem(poppedInternalListEntry);
Assert.AreEqual(NativeUInt(items[i]), NativeUInt(poppedItem),
Format('LIFO order violated. Expected item ID %d (original index %d), got ID %d.', [items[i].ID, i, poppedItem.ID]));
'LIFO order violated.'); // Replaced Format string
Assert.AreEqual(items[i].ID, poppedItem.ID, 'Popped item ID mismatch.');
Assert.AreEqual(i - 1, sListPtr.QueryDepth, Format('Depth incorrect after pop %d.', [NumItems - i + 1]));
Assert.AreEqual(i - 1, sListPtr.QueryDepth, 'Depth incorrect after a pop operation.'); // Replaced Format string
end;
Assert.AreEqual(0, sListPtr.QueryDepth, 'Depth should be 0 after all items are popped.');
for i := 1 to NumItems do
@@ -324,8 +321,7 @@ begin
begin
sharedSList.Push(@item.ListEntry);
pushLogResult := pushedIDs.PushItem(itemID); // Use PushItem for TThreadedQueue
Assert.AreEqual(TWaitResult.wrSignaled, pushLogResult,
Format('Failed to push item ID %d to pushedIDs logging queue.', [itemID]));
Assert.AreEqual(TWaitResult.wrSignaled, pushLogResult, 'Failed to push item to pushedIDs logging queue.');
end;
end
else // Attempt to Pop
@@ -336,12 +332,12 @@ begin
item := PTestListItem(poppedInternalEntry);
pushLogResult := poppedIDs.PushItem(item.ID); // Use PushItem for TThreadedQueue
Assert.AreEqual(TWaitResult.wrSignaled, pushLogResult,
Format('Failed to push item ID %d to poppedIDs logging queue.', [item.ID]));
'Failed to push item ID to poppedIDs logging queue.'); // Replaced Format string
TMycTestSList.FreeTestListItem(item);
end;
end;
if j mod (OperationsPerThread div 10) = 0 then // Occasional sleep
TThread.Sleep(1); // TThread.Sleep from System.Classes
TThread.Sleep(1); // TThread.Sleep from System.Classes
end;
end);
threads[i].FreeOnTerminate := false;
@@ -366,7 +362,7 @@ begin
remainingItem := PTestListItem(remainingInternalEntry);
waitResult := poppedIDs.PushItem(remainingItem.ID); // Use PushItem
Assert.AreEqual(TWaitResult.wrSignaled, waitResult,
Format('Failed to push remaining item ID %d to poppedIDs logging queue during drain.', [remainingItem.ID]));
'Failed to push remaining item ID to poppedIDs during drain.'); // Replaced Format string
TMycTestSList.FreeTestListItem(remainingItem);
end;
@@ -374,8 +370,7 @@ begin
Assert.AreEqual(pushedIDs.TotalItemsPushed, poppedIDs.TotalItemsPushed, // Compare total items PUSHED to each log queue
Format('Mismatch between total logged pushed items (%u) and total logged popped items (%u).',
[pushedIDs.TotalItemsPushed, poppedIDs.TotalItemsPushed]));
'Mismatch in total logged pushed and popped items.'); // Replaced Format string
pushedItemsFinal := TDictionary<Integer, Integer>.Create;
try
@@ -393,8 +388,7 @@ begin
// Drain poppedIDs queue using PopItem with timeout = 0 behavior
while poppedIDs.PopItem(qz, currentPoppedID) = TWaitResult.wrSignaled do
begin
Assert.IsTrue(pushedItemsFinal.ContainsKey(currentPoppedID),
Format('Item ID %d was logged as popped but never logged as pushed.', [currentPoppedID]));
Assert.IsTrue(pushedItemsFinal.ContainsKey(currentPoppedID), 'Item ID logged as popped but never as pushed.'); // Replaced Format string
if pushedItemsFinal.ContainsKey(currentPoppedID) then // Re-check for safety before decrementing
begin
pushedItemsFinal.Items[currentPoppedID] := pushedItemsFinal.Items[currentPoppedID] - 1;
@@ -405,9 +399,7 @@ begin
// Verify that all pushed items were accounted for (counts should be zero)
for currentPushedID in pushedItemsFinal.Keys do
begin
Assert.AreEqual(0, pushedItemsFinal.Items[currentPushedID],
Format('Item ID %d count mismatch. Final count in reconciliation dictionary is not zero (is %d).',
[currentPushedID, pushedItemsFinal.Items[currentPushedID]]));
Assert.AreEqual(0, pushedItemsFinal.Items[currentPushedID], 'Item count mismatch. Final count in reconciliation dictionary is not zero.');
end;
finally
pushedItemsFinal.Free;