Skip to content

Commit eb6fcb8

Browse files
committed
feat: add integration tests and rework implicit session handling via ISessionSource
1 parent bdfdd11 commit eb6fcb8

File tree

2 files changed

+159
-29
lines changed

2 files changed

+159
-29
lines changed

src/Ydb.Sdk/src/Ado/YdbConnection.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ internal ISession Session
4242
internal bool EnableImplicitSession => ConnectionStringBuilder.EnableImplicitSession;
4343

4444
internal ISession GetExecutionSession(bool useImplicit)
45-
=> useImplicit ? new ImplicitSession(Session.Driver) : Session;
45+
=> useImplicit ? PoolManager.GetImplicitSession(ConnectionStringBuilder) : Session;
4646

4747
public YdbConnection()
4848
{

src/Ydb.Sdk/test/Ydb.Sdk.Ado.Tests/YdbConnectionTests.cs

Lines changed: 158 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)