@@ -475,46 +475,176 @@ public async Task BulkUpsertImporter_ThrowsOnNonexistentTable()
475475 }
476476
477477 [ Fact ]
478- public void EnableImplicitSession_WhenSetViaPrimaryKey_ParsesAndAppearsInConnectionString ( )
478+ public async Task EnableImplicitSession_WhenTrue_AndNoTransaction_UsesImplicitSession ( )
479479 {
480- var csb = new YdbConnectionStringBuilder ( "EnableImplicitSession=true;Host=server;Port=2135;" ) ;
481- Assert . True ( csb . EnableImplicitSession ) ;
480+ var cs = ConnectionString + ";EnableImplicitSession=true" ;
482481
483- Assert . Contains ( "EnableImplicitSession=True" , csb . ConnectionString ) ;
484- Assert . Contains ( "Host=server" , csb . ConnectionString ) ;
485- Assert . Contains ( "Port=2135" , csb . ConnectionString ) ;
482+ await using var conn = new YdbConnection ( cs ) ;
483+ await conn . OpenAsync ( ) ;
484+
485+ var cmd = conn . CreateCommand ( ) ;
486+ cmd . CommandText = "SELECT 1" ;
487+ var result = Convert . ToInt64 ( await cmd . ExecuteScalarAsync ( ) ) ;
488+ Assert . Equal ( 1L , result ) ;
489+
490+ var implicitSession = conn . GetExecutionSession ( useImplicit : true ) ;
491+ var pooledSession = conn . GetExecutionSession ( useImplicit : false ) ;
492+ Assert . NotEqual ( implicitSession , pooledSession ) ;
486493 }
487494
488495 [ Fact ]
489- public void EnableImplicitSession_WhenSetViaAlias_ParsesAndNormalizesKey ( )
496+ public async Task EnableImplicitSession_WhenTrue_ButInsideTransaction_UsesPooledSession ( )
490497 {
491- var csb = new YdbConnectionStringBuilder ( "ImplicitSession=on;Host=server;Port=2135;" ) ;
492- Assert . True ( csb . EnableImplicitSession ) ;
498+ var cs = ConnectionString + ";EnableImplicitSession=true" ;
499+
500+ await using var conn = new YdbConnection ( cs ) ;
501+ await conn . OpenAsync ( ) ;
502+
503+ using var tx = conn . BeginTransaction ( ) ;
504+ var cmd = conn . CreateCommand ( ) ;
505+ cmd . Transaction = tx ;
506+ cmd . CommandText = "SELECT 1" ;
507+ var result = Convert . ToInt64 ( await cmd . ExecuteScalarAsync ( ) ) ;
508+ Assert . Equal ( 1L , result ) ;
509+
510+ var pooledSession = conn . GetExecutionSession ( useImplicit : false ) ;
511+ var implicitSession = conn . GetExecutionSession ( useImplicit : true ) ;
512+
513+ Assert . Equal ( pooledSession , conn . Session ) ;
514+ Assert . NotEqual ( pooledSession , implicitSession ) ;
515+ }
516+
517+ [ Fact ]
518+ public async Task EnableImplicitSession_WhenFalse_AlwaysUsesPooledSession ( )
519+ {
520+ var cs = ConnectionString + ";EnableImplicitSession=false" ;
521+
522+ await using var conn = new YdbConnection ( cs ) ;
523+ await conn . OpenAsync ( ) ;
493524
494- var s = csb . ConnectionString ;
525+ var cmd = conn . CreateCommand ( ) ;
526+ cmd . CommandText = "SELECT CAST(1 AS Int64)" ;
527+ var result = ( long ) ( await cmd . ExecuteScalarAsync ( ) ) ! ;
528+ Assert . Equal ( 1L , result ) ;
495529
496- Assert . Contains ( "EnableImplicitSession=True" , s ) ;
530+ var pooledSession = conn . GetExecutionSession ( useImplicit : false ) ;
531+ Assert . Equal ( pooledSession , conn . Session ) ;
532+ }
533+
534+ [ Fact ]
535+ public async Task EnableImplicitSession_DifferentConnectionStrings_HaveDifferentImplicitPools ( )
536+ {
537+ var cs1 = ConnectionString + ";EnableImplicitSession=true;MinSessionPool=0;DisableDiscovery=false" ;
538+ var cs2 = ConnectionString + ";EnableImplicitSession=true;MinSessionPool=1;DisableDiscovery=false" ;
539+
540+ await using var conn1 = new YdbConnection ( cs1 ) ;
541+ await conn1 . OpenAsync ( ) ;
542+ var session1 = conn1 . GetExecutionSession ( useImplicit : true ) ;
497543
498- var parts = s . Split ( ';' , StringSplitOptions . RemoveEmptyEntries | StringSplitOptions . TrimEntries ) ;
499- Assert . DoesNotContain ( parts , p => p . StartsWith ( "ImplicitSession=" , StringComparison . OrdinalIgnoreCase ) ) ;
544+ await using var conn2 = new YdbConnection ( cs2 ) ;
545+ await conn2 . OpenAsync ( ) ;
546+ var session2 = conn2 . GetExecutionSession ( useImplicit : true ) ;
500547
501- Assert . Contains ( "Host=server" , s ) ;
502- Assert . Contains ( "Port=2135" , s ) ;
548+ Assert . NotEqual ( session1 , session2 ) ;
503549 }
550+
551+ [ Fact ]
552+ public async Task EnableImplicitSession_TwoSequentialCommands_GetDifferentImplicitSessions ( )
553+ {
554+ var cs = ConnectionString + ";EnableImplicitSession=true" ;
555+ await using var conn = new YdbConnection ( cs ) ;
556+ await conn . OpenAsync ( ) ;
557+
558+ var s1 = conn . GetExecutionSession ( useImplicit : true ) ;
559+ var s2 = conn . GetExecutionSession ( useImplicit : true ) ;
504560
505- [ Theory ]
506- [ InlineData ( "true" , true ) ]
507- [ InlineData ( "True" , true ) ]
508- [ InlineData ( "on" , true ) ]
509- [ InlineData ( "1" , true ) ]
510- [ InlineData ( "false" , false ) ]
511- [ InlineData ( "False" , false ) ]
512- [ InlineData ( "off" , false ) ]
513- [ InlineData ( "0" , false ) ]
514- public void EnableImplicitSession_StringBooleanVariants_AreParsed ( string value , bool expected )
561+ Assert . NotEqual ( s1 , s2 ) ;
562+ }
563+
564+ [ Fact ]
565+ public async Task ClearPool_FireAndForget_DoesNotBlock_And_PoolsRecreate ( )
566+ {
567+ var csBase =
568+ ConnectionString +
569+ ";UseTls=false" +
570+ ";DisableDiscovery=true" +
571+ ";CreateSessionTimeout=3" +
572+ ";ConnectTimeout=3" +
573+ ";KeepAlivePingDelay=0;KeepAlivePingTimeout=0" ;
574+
575+ var csPooled = csBase ; // pooled-пул (без флага)
576+ var csImplicit = csBase + ";EnableImplicitSession=true" ; // implicit-пул (с флагом)
577+
578+ // 1) Прогреваем оба пула (pooled и implicit), чтобы они точно были созданы.
579+ await using ( var warmPooled = new YdbConnection ( csPooled ) )
580+ {
581+ await warmPooled . OpenAsync ( ) ;
582+ using var cmd = warmPooled . CreateCommand ( ) ;
583+ cmd . CommandText = "SELECT 1" ;
584+ Assert . Equal ( 1L , Convert . ToInt64 ( await cmd . ExecuteScalarAsync ( ) ) ) ;
585+ }
586+
587+ await using ( var warmImplicit = new YdbConnection ( csImplicit ) )
588+ {
589+ await warmImplicit . OpenAsync ( ) ;
590+ using var cmd = warmImplicit . CreateCommand ( ) ;
591+ cmd . CommandText = "SELECT 1" ;
592+ Assert . Equal ( 1L , Convert . ToInt64 ( await cmd . ExecuteScalarAsync ( ) ) ) ;
593+ }
594+
595+ // 2) Вызываем ClearPool для ОБОИХ ключей (по вашей реализации ключи разные).
596+ var clearPooledTask = YdbConnection . ClearPool ( new YdbConnection ( csPooled ) ) ;
597+ var clearImplicitTask = YdbConnection . ClearPool ( new YdbConnection ( csImplicit ) ) ;
598+
599+ // 3) Убеждаемся, что ClearPool не блокирует — завершается быстро (fail-fast).
600+ // (Если вдруг среда перегружена, можно поднять таймаут до 3–5 секунд.)
601+ var done = await Task . WhenAny ( Task . WhenAll ( clearPooledTask , clearImplicitTask ) , Task . Delay ( TimeSpan . FromSeconds ( 2 ) ) ) ;
602+ Assert . True ( done is not null && done != Task . Delay ( TimeSpan . FromSeconds ( 2 ) ) , "ClearPool() must not block." ) ;
603+
604+ // 4) Проверяем, что пулы корректно пересоздаются после очистки:
605+ // pooled — без флага, implicit — с флагом.
606+ await using ( var checkPooled = new YdbConnection ( csPooled ) )
607+ {
608+ await checkPooled . OpenAsync ( ) ;
609+ using var cmd = checkPooled . CreateCommand ( ) ;
610+ cmd . CommandText = "SELECT 1" ;
611+ Assert . Equal ( 1L , Convert . ToInt64 ( await cmd . ExecuteScalarAsync ( ) ) ) ;
612+ }
613+
614+ await using ( var checkImplicit = new YdbConnection ( csImplicit ) )
615+ {
616+ await checkImplicit . OpenAsync ( ) ;
617+ using var cmd = checkImplicit . CreateCommand ( ) ;
618+ cmd . CommandText = "SELECT 1" ;
619+ Assert . Equal ( 1L , Convert . ToInt64 ( await cmd . ExecuteScalarAsync ( ) ) ) ;
620+ }
621+ }
622+
623+ [ Fact ]
624+ public async Task EnableImplicitSession_ParallelQueries_WorkFine ( )
625+ {
626+ var cs = ConnectionString + ";EnableImplicitSession=true" ;
627+ await using var conn = new YdbConnection ( cs ) ;
628+ await conn . OpenAsync ( ) ;
629+
630+ var tasks = Enumerable . Range ( 0 , 16 ) . Select ( async _ =>
631+ {
632+ using var cmd = conn . CreateCommand ( ) ;
633+ cmd . CommandText = "SELECT 1" ;
634+ var v = Convert . ToInt64 ( await cmd . ExecuteScalarAsync ( ) ) ;
635+ Assert . Equal ( 1L , v ) ;
636+ } ) ;
637+ await Task . WhenAll ( tasks ) ;
638+ }
639+
640+ [ Fact ]
641+ public async Task EnableImplicitSession_WithDisableDiscovery_Works ( )
515642 {
516- var csb = new YdbConnectionStringBuilder ( $ "EnableImplicitSession={ value } ;") ;
517- Assert . Equal ( expected , csb . EnableImplicitSession ) ;
518- Assert . Contains ( $ "EnableImplicitSession={ ( expected ? "True" : "False" ) } ", csb . ConnectionString ) ;
643+ var cs = ConnectionString + ";EnableImplicitSession=true;DisableDiscovery=true" ;
644+ await using var conn = new YdbConnection ( cs ) ;
645+ await conn . OpenAsync ( ) ;
646+ using var cmd = conn . CreateCommand ( ) ;
647+ cmd . CommandText = "SELECT 1" ;
648+ Assert . Equal ( 1L , Convert . ToInt64 ( await cmd . ExecuteScalarAsync ( ) ) ) ;
519649 }
520650}
0 commit comments