Skip to content

Commit

Permalink
Fix dynamic SPDB unit tests taking too long (#8094)
Browse files Browse the repository at this point in the history
* Fix dynamic SPDB unit tests taking too long

* Minor improvements in unit tests

* Minor improvements in unit tests

* Cleanup
  • Loading branch information
jhonabreul committed Jun 24, 2024
1 parent 8c33536 commit 5432c7c
Showing 1 changed file with 44 additions and 12 deletions.
56 changes: 44 additions & 12 deletions Tests/Engine/RealTime/LiveTradingRealTimeHandlerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
namespace QuantConnect.Tests.Engine.RealTime
{
[TestFixture]
[Parallelizable(ParallelScope.Children)]
public class LiveTradingRealTimeHandlerTests
{
[Test]
Expand All @@ -59,7 +60,7 @@ public void ThreadSafety()

realTimeHandler.SetTime(DateTime.UtcNow);
// wait for the internal thread to start
Thread.Sleep(500);
WaitUntilActive(realTimeHandler);
var scheduledEvent = new ScheduledEvent("1", new []{ Time.EndOfTime }, (_, _) => { });
var scheduledEvent2 = new ScheduledEvent("2", new []{ Time.EndOfTime }, (_, _) => { });
Assert.DoesNotThrow(() =>
Expand Down Expand Up @@ -179,25 +180,32 @@ public void RefreshesSymbolProperties(string refreshPeriodStr)
new BacktestingResultHandler(),
null,
new TestTimeLimitManager());
realTimeHandler.SpdbRefreshed.Reset();
realTimeHandler.SecuritySymbolPropertiesUpdated.Reset();

algorithm.SetFinishedWarmingUp();
realTimeHandler.SetTime(timeProvider.GetUtcNow());

var events = new[] { realTimeHandler.SpdbRefreshed, realTimeHandler.SecuritySymbolPropertiesUpdated };
// wait for the internal thread to start
WaitUntilActive(realTimeHandler);

Assert.IsTrue(realTimeHandler.SpdbRefreshed.IsSet);
Assert.IsTrue(realTimeHandler.SecuritySymbolPropertiesUpdated.IsSet);

realTimeHandler.SpdbRefreshed.Reset();
realTimeHandler.SecuritySymbolPropertiesUpdated.Reset();

var events = new[] { realTimeHandler.SpdbRefreshed.WaitHandle, realTimeHandler.SecuritySymbolPropertiesUpdated.WaitHandle };
for (var i = 0; i < 10; i++)
{
timeProvider.Advance(step);

// We only advanced half the time, so we should not have refreshed yet
if (i % 2 == 0)
{
Assert.IsFalse(WaitHandle.WaitAll(events, 500));
Assert.IsFalse(WaitHandle.WaitAll(events, 5000));
}
else
{
Assert.IsTrue(WaitHandle.WaitAll(events, 2000));
Assert.IsTrue(WaitHandle.WaitAll(events, 5000));
realTimeHandler.SpdbRefreshed.Reset();
realTimeHandler.SecuritySymbolPropertiesUpdated.Reset();
}
Expand Down Expand Up @@ -235,18 +243,25 @@ public void SecuritySymbolPropertiesTypeIsRespectedAfterRefresh(SecurityType sec
new BacktestingResultHandler(),
null,
new TestTimeLimitManager());
realTimeHandler.SpdbRefreshed.Reset();
realTimeHandler.SecuritySymbolPropertiesUpdated.Reset();

algorithm.SetFinishedWarmingUp();
realTimeHandler.SetTime(timeProvider.GetUtcNow());

// wait for the internal thread to start
WaitUntilActive(realTimeHandler);

Assert.IsTrue(realTimeHandler.SpdbRefreshed.IsSet);
Assert.IsTrue(realTimeHandler.SecuritySymbolPropertiesUpdated.IsSet);

realTimeHandler.SpdbRefreshed.Reset();
realTimeHandler.SecuritySymbolPropertiesUpdated.Reset();

var previousSymbolProperties = security.SymbolProperties;

// Refresh the spdb
timeProvider.Advance(refreshPeriod);
Assert.IsTrue(realTimeHandler.SpdbRefreshed.WaitOne(1000));
Assert.IsTrue(realTimeHandler.SecuritySymbolPropertiesUpdated.WaitOne(1000));
Assert.IsTrue(realTimeHandler.SpdbRefreshed.Wait(5000));
Assert.IsTrue(realTimeHandler.SecuritySymbolPropertiesUpdated.Wait(5000));

// Access the symbol properties again
// The instance must have been changed
Expand Down Expand Up @@ -278,6 +293,14 @@ private static Symbol GetSymbol(SecurityType securityType)
};
}

private static void WaitUntilActive(LiveTradingRealTimeHandler realTimeHandler)
{
while (!realTimeHandler.IsActive)
{
Thread.Sleep(5);
}
}

private class TestTimeLimitManager : IIsolatorLimitResultProvider
{
public IsolatorLimitResult IsWithinLimit()
Expand Down Expand Up @@ -366,6 +389,7 @@ public void AddRefreshHoursScheduledEvent()
}));
OnSecurityUpdated.Reset();
SetTime(DateTime.UtcNow);
WaitUntilActive(this);
OnSecurityUpdated.WaitOne();
Exit();
}
Expand All @@ -387,23 +411,28 @@ protected override void ResetMarketHoursDatabase()

private class SPDBTestLiveTradingRealTimeHandler : LiveTradingRealTimeHandler, IDisposable
{
private bool _disposed;
private int _securitiesUpdated;

public ManualTimeProvider PublicTimeProvider = new ManualTimeProvider();

protected override ITimeProvider TimeProvider { get { return PublicTimeProvider; } }

public ManualResetEvent SpdbRefreshed { get; } = new ManualResetEvent(false);
public ManualResetEvent SecuritySymbolPropertiesUpdated = new ManualResetEvent(false);
public ManualResetEventSlim SpdbRefreshed = new ManualResetEventSlim(false);
public ManualResetEventSlim SecuritySymbolPropertiesUpdated = new ManualResetEventSlim(false);

protected override void RefreshSymbolProperties()
{
if (_disposed) return;

base.RefreshSymbolProperties();
SpdbRefreshed.Set();
}

protected override void UpdateSymbolProperties(Security security)
{
if (_disposed) return;

base.UpdateSymbolProperties(security);
Algorithm.Log($"{Algorithm.Securities.Count}");

Expand All @@ -416,8 +445,11 @@ protected override void UpdateSymbolProperties(Security security)

public void Dispose()
{
if (_disposed) return;
Exit();
SpdbRefreshed.Dispose();
SecuritySymbolPropertiesUpdated.Dispose();
_disposed = true;
}
}

Expand Down

0 comments on commit 5432c7c

Please sign in to comment.