11namespace StockSharp . Tests ;
22
3+ using Ecng . Linq ;
4+
35using StockSharp . Algo . Candles . Compression ;
46using 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