Skip to content

Commit ef1f049

Browse files
committed
IMarketDataDrive uses async mode.
1 parent 1a7fbe8 commit ef1f049

1 file changed

Lines changed: 266 additions & 1 deletion

File tree

Tests/StorageTests.cs

Lines changed: 266 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
namespace StockSharp.Tests;
22

3+
using Ecng.Linq;
4+
35
using StockSharp.Algo.Candles.Compression;
46
using StockSharp.Algo.Storages.Binary.Snapshot;
57

@@ -12,7 +14,7 @@ public class StorageTests
1214
private const int _depthCount1 = 10;
1315
private const int _depthCount2 = 1000;
1416
private const int _depthCount3 = 10000;
15-
private static readonly int[] _sourceArray = [01,02,03,06,07,08,09,10,13,14,15,16,17,20,21,22,23,24,27,28,29,30];
17+
private static readonly int[] _sourceArray = [01, 02, 03, 06, 07, 08, 09, 10, 13, 14, 15, 16, 17, 20, 21, 22, 23, 24, 27, 28, 29, 30];
1618

1719
private static IStorageRegistry GetStorageRegistry()
1820
=> Helper.GetStorage(Helper.GetSubTemp());
@@ -3285,4 +3287,267 @@ public void Index_CandleDataTypes()
32853287
var loadedTypes = loadedIndex.GetAvailableDataTypes(secId, StorageFormats.Binary).ToArray();
32863288
loadedTypes.Length.AssertEqual(2);
32873289
}
3290+
3291+
private static LocalMarketDataDrive CreateDrive(string path = null)
3292+
{
3293+
return new(path ?? Helper.GetSubTemp());
3294+
}
3295+
3296+
private static Task SetupTestDataAsync(LocalMarketDataDrive drive, SecurityId securityId, DataType dataType, StorageFormats format, DateTime[] dates)
3297+
{
3298+
var storageDrive = drive.GetStorageDrive(securityId, dataType, format);
3299+
3300+
foreach (var date in dates)
3301+
{
3302+
using var stream = new MemoryStream();
3303+
using var writer = new BinaryWriter(stream);
3304+
3305+
// Write minimal valid data
3306+
stream.Position = 0;
3307+
storageDrive.SaveStream(date, stream);
3308+
}
3309+
3310+
return Task.CompletedTask;
3311+
}
3312+
3313+
[TestMethod]
3314+
public async Task GetAvailableSecuritiesAsync_EmptyDrive_ReturnsEmpty()
3315+
{
3316+
var drive = CreateDrive();
3317+
3318+
var securities = await drive.GetAvailableSecuritiesAsync(CancellationToken.None).ToArrayAsync2(CancellationToken.None);
3319+
3320+
securities.Length.AssertEqual(0);
3321+
}
3322+
3323+
[TestMethod]
3324+
public async Task GetAvailableSecuritiesAsync_WithSecurities_ReturnsSecurities()
3325+
{
3326+
var drive = CreateDrive();
3327+
var security1 = new SecurityId { SecurityCode = "TEST1", BoardCode = BoardCodes.Test };
3328+
var security2 = new SecurityId { SecurityCode = "TEST2", BoardCode = BoardCodes.Test };
3329+
var dates = new[] { DateTime.UtcNow.Date };
3330+
3331+
await SetupTestDataAsync(drive, security1, DataType.Ticks, StorageFormats.Binary, dates);
3332+
await SetupTestDataAsync(drive, security2, DataType.Ticks, StorageFormats.Binary, dates);
3333+
3334+
var securities = await drive.GetAvailableSecuritiesAsync(CancellationToken.None).ToArrayAsync2(CancellationToken.None);
3335+
3336+
(securities.Length >= 2).AssertTrue();
3337+
securities.Any(s => s.SecurityCode == "TEST1" && s.BoardCode == BoardCodes.Test).AssertTrue();
3338+
securities.Any(s => s.SecurityCode == "TEST2" && s.BoardCode == BoardCodes.Test).AssertTrue();
3339+
}
3340+
3341+
[TestMethod]
3342+
public async Task GetAvailableSecuritiesAsync_CancellationRequested_ThrowsOperationCanceledException()
3343+
{
3344+
var drive = CreateDrive();
3345+
var security = new SecurityId { SecurityCode = "TEST", BoardCode = BoardCodes.Test };
3346+
var dates = new[] { DateTime.UtcNow.Date };
3347+
3348+
await SetupTestDataAsync(drive, security, DataType.Ticks, StorageFormats.Binary, dates);
3349+
3350+
using var cts = new CancellationTokenSource();
3351+
cts.Cancel();
3352+
3353+
await Assert.ThrowsExactlyAsync<OperationCanceledException>(async () =>
3354+
{
3355+
await drive.GetAvailableSecuritiesAsync(cts.Token).ToArrayAsync2(cts.Token);
3356+
});
3357+
}
3358+
3359+
[TestMethod]
3360+
[DataRow(StorageFormats.Binary)]
3361+
[DataRow(StorageFormats.Csv)]
3362+
public async Task GetAvailableDataTypesAsync_EmptySecurity_ReturnsEmpty(StorageFormats format)
3363+
{
3364+
var drive = CreateDrive();
3365+
var securityId = new SecurityId { SecurityCode = "EMPTY", BoardCode = BoardCodes.Test };
3366+
3367+
var dataTypes = await drive.GetAvailableDataTypesAsync(securityId, format, CancellationToken.None);
3368+
3369+
dataTypes.AssertNotNull();
3370+
dataTypes.Count().AssertEqual(0);
3371+
}
3372+
3373+
[TestMethod]
3374+
[DataRow(StorageFormats.Binary)]
3375+
[DataRow(StorageFormats.Csv)]
3376+
public async Task GetAvailableDataTypesAsync_WithData_ReturnsDataTypes(StorageFormats format)
3377+
{
3378+
var drive = CreateDrive();
3379+
var securityId = new SecurityId { SecurityCode = "TEST", BoardCode = BoardCodes.Test };
3380+
var dates = new[] { DateTime.UtcNow.Date };
3381+
3382+
await SetupTestDataAsync(drive, securityId, DataType.Ticks, format, dates);
3383+
await SetupTestDataAsync(drive, securityId, DataType.Level1, format, dates);
3384+
3385+
var dataTypes = (await drive.GetAvailableDataTypesAsync(securityId, format, CancellationToken.None)).ToArray();
3386+
3387+
(dataTypes.Length >= 2).AssertTrue();
3388+
dataTypes.Contains(DataType.Ticks).AssertTrue();
3389+
dataTypes.Contains(DataType.Level1).AssertTrue();
3390+
}
3391+
3392+
[TestMethod]
3393+
[DataRow(StorageFormats.Binary)]
3394+
[DataRow(StorageFormats.Csv)]
3395+
public async Task GetAvailableDataTypesAsync_DefaultSecurityId_ReturnsAllDataTypes(StorageFormats format)
3396+
{
3397+
var drive = CreateDrive();
3398+
var security1 = new SecurityId { SecurityCode = "TEST1", BoardCode = BoardCodes.Test };
3399+
var security2 = new SecurityId { SecurityCode = "TEST2", BoardCode = BoardCodes.Test };
3400+
var dates = new[] { DateTime.UtcNow.Date };
3401+
3402+
await SetupTestDataAsync(drive, security1, DataType.Ticks, format, dates);
3403+
await SetupTestDataAsync(drive, security2, DataType.Level1, format, dates);
3404+
await SetupTestDataAsync(drive, security2, DataType.MarketDepth, format, dates);
3405+
3406+
var dataTypes = (await drive.GetAvailableDataTypesAsync(default, format, CancellationToken.None)).ToArray();
3407+
3408+
(dataTypes.Length >= 3).AssertTrue();
3409+
dataTypes.Contains(DataType.Ticks).AssertTrue();
3410+
dataTypes.Contains(DataType.Level1).AssertTrue();
3411+
dataTypes.Contains(DataType.MarketDepth).AssertTrue();
3412+
}
3413+
3414+
[TestMethod]
3415+
public async Task VerifyAsync_ExistingPath_DoesNotThrow()
3416+
{
3417+
var drive = CreateDrive();
3418+
3419+
await drive.VerifyAsync(CancellationToken.None);
3420+
3421+
// Should not throw
3422+
true.AssertTrue();
3423+
}
3424+
3425+
[TestMethod]
3426+
public async Task VerifyAsync_NonExistingPath_ThrowsInvalidOperationException()
3427+
{
3428+
var drive = new LocalMarketDataDrive(Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()));
3429+
3430+
await Assert.ThrowsExactlyAsync<InvalidOperationException>(async () =>
3431+
{
3432+
await drive.VerifyAsync(CancellationToken.None);
3433+
});
3434+
}
3435+
3436+
[TestMethod]
3437+
public async Task LookupSecuritiesAsync_EmptyDrive_ReturnsEmpty()
3438+
{
3439+
var drive = CreateDrive();
3440+
var criteria = Messages.Extensions.LookupAllCriteriaMessage;
3441+
var securityProvider = new CollectionSecurityProvider([]);
3442+
3443+
var securities = await drive.LookupSecuritiesAsync(criteria, securityProvider, CancellationToken.None).ToArrayAsync2(CancellationToken.None);
3444+
3445+
securities.Length.AssertEqual(0);
3446+
}
3447+
3448+
3449+
[TestMethod]
3450+
public async Task LookupSecuritiesAsync_NullCriteria_ThrowsArgumentNullException()
3451+
{
3452+
var drive = CreateDrive();
3453+
var securityProvider = new CollectionSecurityProvider([]);
3454+
3455+
await Assert.ThrowsExactlyAsync<ArgumentNullException>(async () =>
3456+
{
3457+
await drive.LookupSecuritiesAsync(null, securityProvider, CancellationToken.None).ToArrayAsync2(CancellationToken.None);
3458+
});
3459+
}
3460+
3461+
[TestMethod]
3462+
public async Task LookupSecuritiesAsync_NullSecurityProvider_ThrowsArgumentNullException()
3463+
{
3464+
var drive = CreateDrive();
3465+
var criteria = Messages.Extensions.LookupAllCriteriaMessage;
3466+
3467+
await Assert.ThrowsExactlyAsync<ArgumentNullException>(async () =>
3468+
{
3469+
await drive.LookupSecuritiesAsync(criteria, null, CancellationToken.None).ToArrayAsync2(CancellationToken.None);
3470+
});
3471+
}
3472+
3473+
[TestMethod]
3474+
public async Task LookupSecuritiesAsync_CancellationRequested_ThrowsOperationCanceledException()
3475+
{
3476+
var drive = CreateDrive();
3477+
var securityId = new SecurityId { SecurityCode = "TEST", BoardCode = BoardCodes.Test };
3478+
var dates = new[] { DateTime.UtcNow.Date };
3479+
3480+
await SetupTestDataAsync(drive, securityId, DataType.Ticks, StorageFormats.Binary, dates);
3481+
3482+
var criteria = Messages.Extensions.LookupAllCriteriaMessage;
3483+
var securityProvider = new CollectionSecurityProvider([]);
3484+
3485+
using var cts = new CancellationTokenSource();
3486+
cts.Cancel();
3487+
3488+
await Assert.ThrowsExactlyAsync<OperationCanceledException>(async () =>
3489+
{
3490+
await drive.LookupSecuritiesAsync(criteria, securityProvider, cts.Token).ToArrayAsync2(cts.Token);
3491+
});
3492+
}
3493+
3494+
[TestMethod]
3495+
[DataRow(StorageFormats.Binary)]
3496+
[DataRow(StorageFormats.Csv)]
3497+
public async Task GetAvailableDataTypesAsync_MultipleDates_ReturnsDataTypes(StorageFormats format)
3498+
{
3499+
var drive = CreateDrive();
3500+
var securityId = new SecurityId { SecurityCode = "TEST", BoardCode = BoardCodes.Test };
3501+
var dates = new[]
3502+
{
3503+
DateTime.UtcNow.Date.AddDays(-2),
3504+
DateTime.UtcNow.Date.AddDays(-1),
3505+
DateTime.UtcNow.Date
3506+
};
3507+
3508+
await SetupTestDataAsync(drive, securityId, DataType.Ticks, format, dates);
3509+
3510+
var dataTypes = (await drive.GetAvailableDataTypesAsync(securityId, format, CancellationToken.None)).ToArray();
3511+
3512+
(dataTypes.Length >= 1).AssertTrue();
3513+
dataTypes.Contains(DataType.Ticks).AssertTrue();
3514+
}
3515+
3516+
[TestMethod]
3517+
public async Task GetAvailableSecuritiesAsync_MultipleSecurities_ReturnsAllSecurities()
3518+
{
3519+
var drive = CreateDrive();
3520+
var securities = new[]
3521+
{
3522+
new SecurityId { SecurityCode = "AAPL", BoardCode = BoardCodes.Test },
3523+
new SecurityId { SecurityCode = "MSFT", BoardCode = BoardCodes.Test },
3524+
new SecurityId { SecurityCode = "GOOGL", BoardCode = BoardCodes.Test }
3525+
};
3526+
var dates = new[] { DateTime.UtcNow.Date };
3527+
3528+
foreach (var secId in securities)
3529+
{
3530+
await SetupTestDataAsync(drive, secId, DataType.Ticks, StorageFormats.Binary, dates);
3531+
}
3532+
3533+
var result = await drive.GetAvailableSecuritiesAsync(CancellationToken.None).ToArrayAsync2(CancellationToken.None);
3534+
3535+
(result.Length >= 3).AssertTrue();
3536+
foreach (var secId in securities)
3537+
{
3538+
result.Any(s => s.SecurityCode == secId.SecurityCode && s.BoardCode == secId.BoardCode).AssertTrue();
3539+
}
3540+
}
3541+
3542+
[TestMethod]
3543+
public async Task VerifyAsync_PathWithNoAccess_ThrowsInvalidOperationException()
3544+
{
3545+
var invalidPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString(), "nested", "path");
3546+
var drive = new LocalMarketDataDrive(invalidPath);
3547+
3548+
await Assert.ThrowsExactlyAsync<InvalidOperationException>(async () =>
3549+
{
3550+
await drive.VerifyAsync(CancellationToken.None);
3551+
});
3552+
}
32883553
}

0 commit comments

Comments
 (0)