Code formatting
This commit is contained in:
@@ -20,8 +20,7 @@ type
|
||||
function GetInstanceID: Integer;
|
||||
function GetExpectedToBeAdvised: Boolean;
|
||||
procedure SetExpectedToBeAdvised(const Value: Boolean);
|
||||
property ExpectedToBeAdvised: Boolean read GetExpectedToBeAdvised write
|
||||
SetExpectedToBeAdvised;
|
||||
property ExpectedToBeAdvised: Boolean read GetExpectedToBeAdvised write SetExpectedToBeAdvised;
|
||||
end;
|
||||
|
||||
TMyStressReceiver = class(TInterfacedObject, IMyStressTestInterface)
|
||||
@@ -39,8 +38,7 @@ type
|
||||
function GetValue: Integer;
|
||||
function GetNotificationCount: Integer;
|
||||
function GetInstanceID: Integer;
|
||||
property ExpectedToBeAdvised: Boolean read GetExpectedToBeAdvised write
|
||||
SetExpectedToBeAdvised;
|
||||
property ExpectedToBeAdvised: Boolean read GetExpectedToBeAdvised write SetExpectedToBeAdvised;
|
||||
end;
|
||||
|
||||
// Record type to store an advised receiver and its tag
|
||||
@@ -66,7 +64,7 @@ type
|
||||
destructor Destroy; override;
|
||||
property Error: Exception read FError;
|
||||
function GetAdvisedReceiverCountByThread: Integer;
|
||||
// procedure GetMyExpectedLiveReceivers(AList: TList<TMyStressReceiver>); // Not strictly needed with current verification
|
||||
// procedure GetMyExpectedLiveReceivers(AList: TList<TMyStressReceiver>); // Not strictly needed with current verification
|
||||
end;
|
||||
|
||||
[TestFixture]
|
||||
@@ -165,7 +163,8 @@ begin
|
||||
try
|
||||
for i := 1 to FIterations do
|
||||
begin
|
||||
if Terminated then Break; // Respond to termination request
|
||||
if Terminated then
|
||||
Break; // Respond to termination request
|
||||
|
||||
op := Random(100);
|
||||
|
||||
@@ -211,21 +210,23 @@ begin
|
||||
begin
|
||||
FOwnerFixture.FNotifier.Lock;
|
||||
try
|
||||
// if not FOwnerFixture.FNotifier.IsFinalized then // Don't notify if finalized
|
||||
// if not FOwnerFixture.FNotifier.IsFinalized then // Don't notify if finalized
|
||||
begin
|
||||
FOwnerFixture.FNotifier.Notify(
|
||||
function(Item: IMyStressTestInterface): Boolean
|
||||
begin
|
||||
Item.Foo(FThreadID); // Pass ThreadID as notification type for context
|
||||
Result := True; // Keep item
|
||||
end);
|
||||
function(Item: IMyStressTestInterface): Boolean
|
||||
begin
|
||||
Item.Foo(FThreadID); // Pass ThreadID as notification type for context
|
||||
Result := True; // Keep item
|
||||
end
|
||||
);
|
||||
end;
|
||||
finally
|
||||
FOwnerFixture.FNotifier.Release;
|
||||
end;
|
||||
end;
|
||||
|
||||
if (i mod 75 = 0) then Sleep(0); // Yield occasionally to encourage context switching
|
||||
if (i mod 75 = 0) then
|
||||
Sleep(0); // Yield occasionally to encourage context switching
|
||||
end;
|
||||
except
|
||||
on E: Exception do
|
||||
@@ -250,7 +251,6 @@ end;
|
||||
// end;
|
||||
// end;
|
||||
|
||||
|
||||
{ TMycNotifierChaosStressTests }
|
||||
procedure TMycNotifierChaosStressTests.Setup;
|
||||
begin
|
||||
@@ -263,8 +263,8 @@ end;
|
||||
|
||||
procedure TMycNotifierChaosStressTests.TearDown;
|
||||
var
|
||||
// receiver: TMyStressReceiver; // Not used directly in this simplified TearDown
|
||||
i: Integer;
|
||||
// receiver: TMyStressReceiver; // Not used directly in this simplified TearDown
|
||||
i: Integer;
|
||||
begin
|
||||
// Attempt to shut down the Notifier cleanly.
|
||||
try
|
||||
@@ -272,7 +272,7 @@ begin
|
||||
try
|
||||
// UnadviseAll should be safe if the IsFinalized guard is present
|
||||
// and the FFirst state is not pathological.
|
||||
// if not FNotifier.IsFinalized then
|
||||
// if not FNotifier.IsFinalized then
|
||||
begin
|
||||
FNotifier.UnadviseAll;
|
||||
end;
|
||||
@@ -294,7 +294,7 @@ begin
|
||||
// as long as no other strong references exist.
|
||||
// Setting list items to nil is good practice if the list itself isn't immediately freed.
|
||||
for i := 0 to FAllReceiversCreated.Count - 1 do
|
||||
FAllReceiversCreated[i] := nil; // Break reference cycles if any, allow ARC
|
||||
FAllReceiversCreated[i] := nil; // Break reference cycles if any, allow ARC
|
||||
FAllReceiversCreated.Free;
|
||||
FAllReceiversCreated := nil;
|
||||
end;
|
||||
@@ -307,7 +307,7 @@ end;
|
||||
|
||||
procedure TMycNotifierChaosStressTests.Test_MixedOperations_Stress;
|
||||
const
|
||||
NumThreads = 24; // Number of concurrent worker threads
|
||||
NumThreads = 24; // Number of concurrent worker threads
|
||||
IterationsPerThread = 2000; // Number of random operations per thread
|
||||
var
|
||||
threads: array of TStressWorkerThread;
|
||||
@@ -337,8 +337,7 @@ begin
|
||||
begin
|
||||
// If an error occurred, Assert.IsNull would fail.
|
||||
// The message can safely use LThreadError.Message here.
|
||||
Assert.IsNull(LThreadError,
|
||||
'Thread ' + threads[i].FThreadID.ToString + ' reported an error: ' + LThreadError.Message);
|
||||
Assert.IsNull(LThreadError, 'Thread ' + threads[i].FThreadID.ToString + ' reported an error: ' + LThreadError.Message);
|
||||
end
|
||||
else
|
||||
begin
|
||||
@@ -357,14 +356,15 @@ begin
|
||||
try
|
||||
FNotifier.Lock;
|
||||
try
|
||||
// if not FNotifier.IsFinalized then
|
||||
// if not FNotifier.IsFinalized then
|
||||
begin
|
||||
FNotifier.Notify(
|
||||
function(Item: IMyStressTestInterface): Boolean
|
||||
begin
|
||||
actualLiveReceiversInNotifier.Add(Item);
|
||||
Result := True;
|
||||
end);
|
||||
function(Item: IMyStressTestInterface): Boolean
|
||||
begin
|
||||
actualLiveReceiversInNotifier.Add(Item);
|
||||
Result := True;
|
||||
end
|
||||
);
|
||||
end;
|
||||
finally
|
||||
FNotifier.Release;
|
||||
@@ -372,8 +372,14 @@ begin
|
||||
actualLiveInNotifierAtEnd := actualLiveReceiversInNotifier.Count;
|
||||
|
||||
// 2. Compare overall counts
|
||||
Assert.AreEqual(totalExpectedLiveByThreadsAtEnd, actualLiveInNotifierAtEnd,
|
||||
Format('Mismatch in live item count at end. Threads expected %d, Notifier has %d.', [totalExpectedLiveByThreadsAtEnd, actualLiveInNotifierAtEnd]));
|
||||
Assert.AreEqual(
|
||||
totalExpectedLiveByThreadsAtEnd,
|
||||
actualLiveInNotifierAtEnd,
|
||||
Format(
|
||||
'Mismatch in live item count at end. Threads expected %d, Notifier has %d.',
|
||||
[totalExpectedLiveByThreadsAtEnd, actualLiveInNotifierAtEnd]
|
||||
)
|
||||
);
|
||||
|
||||
// 3. Detailed check: Iterate all receivers ever created.
|
||||
// Their 'ExpectedToBeAdvised' flag (last known state from its managing thread)
|
||||
@@ -393,14 +399,29 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
Assert.AreEqual(receiver.ExpectedToBeAdvised, found,
|
||||
Format('Receiver ID %d: Thread expected it to be advised=%d, but its presence in Notifier is %d. NotificationCount=%d',
|
||||
[receiver.GetInstanceID, Integer(receiver.ExpectedToBeAdvised), Integer(found), receiver.GetNotificationCount]));
|
||||
Assert.AreEqual(
|
||||
receiver.ExpectedToBeAdvised,
|
||||
found,
|
||||
Format(
|
||||
'Receiver ID %d: Thread expected it to be advised=%d, but its presence in Notifier is %d. NotificationCount=%d',
|
||||
[
|
||||
receiver.GetInstanceID,
|
||||
Integer(receiver.ExpectedToBeAdvised),
|
||||
Integer(found),
|
||||
receiver.GetNotificationCount
|
||||
]
|
||||
)
|
||||
);
|
||||
|
||||
// Further checks on NotificationCount could be added if specific notification patterns were expected.
|
||||
// For this chaos test, ensuring count is non-negative and consistent with advised state is a good start.
|
||||
Assert.IsTrue(receiver.GetNotificationCount >= 0,
|
||||
Format('Receiver ID %d has non-positive notification count: %d', [receiver.GetInstanceID, receiver.GetNotificationCount]));
|
||||
Assert.IsTrue(
|
||||
receiver.GetNotificationCount >= 0,
|
||||
Format(
|
||||
'Receiver ID %d has non-positive notification count: %d',
|
||||
[receiver.GetInstanceID, receiver.GetNotificationCount]
|
||||
)
|
||||
);
|
||||
if found and (receiver.GetNotificationCount = 0) then
|
||||
begin
|
||||
// This might be okay if Notify calls were very sparse or the item was just added and not yet notified.
|
||||
|
||||
Reference in New Issue
Block a user