|
|
|
@@ -23,7 +23,7 @@ public sealed class SessionManagerTests
|
|
|
|
|
using GatewayMetrics metrics = new();
|
|
|
|
|
SessionManager manager = CreateManager(factory, metrics: metrics);
|
|
|
|
|
|
|
|
|
|
GatewaySession session = await manager.OpenSessionAsync(CreateOpenRequest(), "client-1", CancellationToken.None);
|
|
|
|
|
GatewaySession session = await manager.OpenSessionAsync(CreateOpenRequest(), "client-1", ownerKeyId: null, CancellationToken.None);
|
|
|
|
|
|
|
|
|
|
Assert.True(manager.TryGetSession(session.SessionId, out GatewaySession? registered));
|
|
|
|
|
Assert.Same(session, registered);
|
|
|
|
@@ -34,6 +34,36 @@ public sealed class SessionManagerTests
|
|
|
|
|
Assert.Equal(1, metrics.GetSnapshot().SessionsOpened);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>Verifies that a session opened by an authenticated caller records that caller's API key id in OwnerKeyId.</summary>
|
|
|
|
|
[Fact]
|
|
|
|
|
public async Task OpenSessionAsync_WithOwnerKeyId_RecordsOwnerKeyIdOnSession()
|
|
|
|
|
{
|
|
|
|
|
SessionManager manager = CreateManager(new FakeSessionWorkerClientFactory(new FakeWorkerClient()));
|
|
|
|
|
|
|
|
|
|
GatewaySession session = await manager.OpenSessionAsync(
|
|
|
|
|
CreateOpenRequest(),
|
|
|
|
|
clientIdentity: "MyKey Display",
|
|
|
|
|
ownerKeyId: "key-abc123",
|
|
|
|
|
CancellationToken.None);
|
|
|
|
|
|
|
|
|
|
Assert.Equal("key-abc123", session.OwnerKeyId);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>Verifies that a session opened without an owner key id records null in OwnerKeyId.</summary>
|
|
|
|
|
[Fact]
|
|
|
|
|
public async Task OpenSessionAsync_WithNullOwnerKeyId_RecordsNullOwnerKeyIdOnSession()
|
|
|
|
|
{
|
|
|
|
|
SessionManager manager = CreateManager(new FakeSessionWorkerClientFactory(new FakeWorkerClient()));
|
|
|
|
|
|
|
|
|
|
GatewaySession session = await manager.OpenSessionAsync(
|
|
|
|
|
CreateOpenRequest(),
|
|
|
|
|
clientIdentity: null,
|
|
|
|
|
ownerKeyId: null,
|
|
|
|
|
CancellationToken.None);
|
|
|
|
|
|
|
|
|
|
Assert.Null(session.OwnerKeyId);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>Verifies that opening a session sets the initial lease expiry from the configured default lease.</summary>
|
|
|
|
|
[Fact]
|
|
|
|
|
public async Task OpenSessionAsync_SetsInitialDefaultLease()
|
|
|
|
@@ -45,7 +75,7 @@ public sealed class SessionManagerTests
|
|
|
|
|
options: options,
|
|
|
|
|
timeProvider: clock);
|
|
|
|
|
|
|
|
|
|
GatewaySession session = await manager.OpenSessionAsync(CreateOpenRequest(), "client-1", CancellationToken.None);
|
|
|
|
|
GatewaySession session = await manager.OpenSessionAsync(CreateOpenRequest(), "client-1", ownerKeyId: null, CancellationToken.None);
|
|
|
|
|
|
|
|
|
|
Assert.Equal(clock.GetUtcNow() + TimeSpan.FromMinutes(30), session.LeaseExpiresAt);
|
|
|
|
|
}
|
|
|
|
@@ -61,7 +91,7 @@ public sealed class SessionManagerTests
|
|
|
|
|
};
|
|
|
|
|
SessionManager manager = CreateManager(new FakeSessionWorkerClientFactory(new FakeWorkerClient()));
|
|
|
|
|
|
|
|
|
|
GatewaySession session = await manager.OpenSessionAsync(request, "client-1", CancellationToken.None);
|
|
|
|
|
GatewaySession session = await manager.OpenSessionAsync(request, "client-1", ownerKeyId: null, CancellationToken.None);
|
|
|
|
|
|
|
|
|
|
Assert.Equal($"rust-load-client-{session.SessionId}", session.ClientCorrelationId);
|
|
|
|
|
}
|
|
|
|
@@ -76,7 +106,7 @@ public sealed class SessionManagerTests
|
|
|
|
|
};
|
|
|
|
|
SessionManager manager = CreateManager(new FakeSessionWorkerClientFactory(new FakeWorkerClient()));
|
|
|
|
|
|
|
|
|
|
GatewaySession session = await manager.OpenSessionAsync(request, "client-1", CancellationToken.None);
|
|
|
|
|
GatewaySession session = await manager.OpenSessionAsync(request, "client-1", ownerKeyId: null, CancellationToken.None);
|
|
|
|
|
|
|
|
|
|
Assert.Equal($"client-{session.SessionId}", session.ClientCorrelationId);
|
|
|
|
|
}
|
|
|
|
@@ -87,7 +117,7 @@ public sealed class SessionManagerTests
|
|
|
|
|
{
|
|
|
|
|
FakeWorkerClient workerClient = new();
|
|
|
|
|
SessionManager manager = CreateManager(new FakeSessionWorkerClientFactory(workerClient));
|
|
|
|
|
GatewaySession session = await manager.OpenSessionAsync(CreateOpenRequest(), "client-1", CancellationToken.None);
|
|
|
|
|
GatewaySession session = await manager.OpenSessionAsync(CreateOpenRequest(), "client-1", ownerKeyId: null, CancellationToken.None);
|
|
|
|
|
|
|
|
|
|
WorkerCommandReply reply = await manager.InvokeAsync(
|
|
|
|
|
session.SessionId,
|
|
|
|
@@ -108,6 +138,7 @@ public sealed class SessionManagerTests
|
|
|
|
|
"mxaccess-gateway-1-session-lease-refresh",
|
|
|
|
|
"nonce",
|
|
|
|
|
"client-1",
|
|
|
|
|
null,
|
|
|
|
|
"test-session",
|
|
|
|
|
"client-correlation-1",
|
|
|
|
|
TimeSpan.FromSeconds(30),
|
|
|
|
@@ -156,7 +187,7 @@ public sealed class SessionManagerTests
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
SessionManager manager = CreateManager(new FakeSessionWorkerClientFactory(workerClient));
|
|
|
|
|
GatewaySession session = await manager.OpenSessionAsync(CreateOpenRequest(), "client-1", CancellationToken.None);
|
|
|
|
|
GatewaySession session = await manager.OpenSessionAsync(CreateOpenRequest(), "client-1", ownerKeyId: null, CancellationToken.None);
|
|
|
|
|
|
|
|
|
|
IReadOnlyList<SubscribeResult> results = await session.SubscribeBulkAsync(
|
|
|
|
|
12,
|
|
|
|
@@ -207,7 +238,7 @@ public sealed class SessionManagerTests
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
SessionManager manager = CreateManager(new FakeSessionWorkerClientFactory(workerClient));
|
|
|
|
|
GatewaySession session = await manager.OpenSessionAsync(CreateOpenRequest(), "client-1", CancellationToken.None);
|
|
|
|
|
GatewaySession session = await manager.OpenSessionAsync(CreateOpenRequest(), "client-1", ownerKeyId: null, CancellationToken.None);
|
|
|
|
|
|
|
|
|
|
IReadOnlyList<BulkWriteResult> results = await session.WriteBulkAsync(
|
|
|
|
|
12,
|
|
|
|
@@ -268,7 +299,7 @@ public sealed class SessionManagerTests
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
SessionManager manager = CreateManager(new FakeSessionWorkerClientFactory(workerClient));
|
|
|
|
|
GatewaySession session = await manager.OpenSessionAsync(CreateOpenRequest(), "client-1", CancellationToken.None);
|
|
|
|
|
GatewaySession session = await manager.OpenSessionAsync(CreateOpenRequest(), "client-1", ownerKeyId: null, CancellationToken.None);
|
|
|
|
|
|
|
|
|
|
IReadOnlyList<BulkReadResult> results = await session.ReadBulkAsync(
|
|
|
|
|
12,
|
|
|
|
@@ -291,7 +322,7 @@ public sealed class SessionManagerTests
|
|
|
|
|
{
|
|
|
|
|
FakeWorkerClient workerClient = new();
|
|
|
|
|
SessionManager manager = CreateManager(new FakeSessionWorkerClientFactory(workerClient));
|
|
|
|
|
GatewaySession session = await manager.OpenSessionAsync(CreateOpenRequest(), "client-1", CancellationToken.None);
|
|
|
|
|
GatewaySession session = await manager.OpenSessionAsync(CreateOpenRequest(), "client-1", ownerKeyId: null, CancellationToken.None);
|
|
|
|
|
session.MarkFaulted("test fault");
|
|
|
|
|
|
|
|
|
|
SessionManagerException exception = await Assert.ThrowsAsync<SessionManagerException>(
|
|
|
|
@@ -316,7 +347,7 @@ public sealed class SessionManagerTests
|
|
|
|
|
{
|
|
|
|
|
FakeWorkerClient workerClient = new();
|
|
|
|
|
SessionManager manager = CreateManager(new FakeSessionWorkerClientFactory(workerClient));
|
|
|
|
|
GatewaySession session = await manager.OpenSessionAsync(CreateOpenRequest(), "client-1", CancellationToken.None);
|
|
|
|
|
GatewaySession session = await manager.OpenSessionAsync(CreateOpenRequest(), "client-1", ownerKeyId: null, CancellationToken.None);
|
|
|
|
|
|
|
|
|
|
// Force a state mismatch: session stays Ready, worker transitions out.
|
|
|
|
|
workerClient.State = WorkerClientState.Handshaking;
|
|
|
|
@@ -341,7 +372,7 @@ public sealed class SessionManagerTests
|
|
|
|
|
FakeWorkerClient workerClient = new();
|
|
|
|
|
using GatewayMetrics metrics = new();
|
|
|
|
|
SessionManager manager = CreateManager(new FakeSessionWorkerClientFactory(workerClient), metrics: metrics);
|
|
|
|
|
GatewaySession session = await manager.OpenSessionAsync(CreateOpenRequest(), "client-1", CancellationToken.None);
|
|
|
|
|
GatewaySession session = await manager.OpenSessionAsync(CreateOpenRequest(), "client-1", ownerKeyId: null, CancellationToken.None);
|
|
|
|
|
|
|
|
|
|
SessionCloseResult firstClose = await manager.CloseSessionAsync(session.SessionId, CancellationToken.None);
|
|
|
|
|
SessionManagerException secondClose = await Assert.ThrowsAsync<SessionManagerException>(
|
|
|
|
@@ -366,7 +397,7 @@ public sealed class SessionManagerTests
|
|
|
|
|
"Worker shutdown timed out."),
|
|
|
|
|
};
|
|
|
|
|
SessionManager manager = CreateManager(new FakeSessionWorkerClientFactory(workerClient));
|
|
|
|
|
GatewaySession session = await manager.OpenSessionAsync(CreateOpenRequest(), "client-1", CancellationToken.None);
|
|
|
|
|
GatewaySession session = await manager.OpenSessionAsync(CreateOpenRequest(), "client-1", ownerKeyId: null, CancellationToken.None);
|
|
|
|
|
|
|
|
|
|
SessionManagerException exception = await Assert.ThrowsAsync<SessionManagerException>(
|
|
|
|
|
async () => await manager.CloseSessionAsync(session.SessionId, CancellationToken.None));
|
|
|
|
@@ -397,6 +428,7 @@ public sealed class SessionManagerTests
|
|
|
|
|
GatewaySession firstSession = await manager.OpenSessionAsync(
|
|
|
|
|
CreateOpenRequest(),
|
|
|
|
|
"client-1",
|
|
|
|
|
ownerKeyId: null,
|
|
|
|
|
CancellationToken.None);
|
|
|
|
|
metrics.EventReceived(firstSession.SessionId, MxEventFamily.OnDataChange.ToString());
|
|
|
|
|
|
|
|
|
@@ -405,6 +437,7 @@ public sealed class SessionManagerTests
|
|
|
|
|
GatewaySession secondSession = await manager.OpenSessionAsync(
|
|
|
|
|
CreateOpenRequest(),
|
|
|
|
|
"client-2",
|
|
|
|
|
ownerKeyId: null,
|
|
|
|
|
CancellationToken.None);
|
|
|
|
|
|
|
|
|
|
Assert.Equal(SessionManagerErrorCode.CloseFailed, exception.ErrorCode);
|
|
|
|
@@ -440,6 +473,7 @@ public sealed class SessionManagerTests
|
|
|
|
|
GatewaySession session = await manager.OpenSessionAsync(
|
|
|
|
|
CreateOpenRequest(),
|
|
|
|
|
"client-1",
|
|
|
|
|
ownerKeyId: null,
|
|
|
|
|
CancellationToken.None);
|
|
|
|
|
|
|
|
|
|
Task<SessionCloseResult> firstClose = manager.CloseSessionAsync(session.SessionId, CancellationToken.None);
|
|
|
|
@@ -482,7 +516,7 @@ public sealed class SessionManagerTests
|
|
|
|
|
FakeWorkerClient workerClient = new();
|
|
|
|
|
using GatewayMetrics metrics = new();
|
|
|
|
|
SessionManager manager = CreateManager(new FakeSessionWorkerClientFactory(workerClient), metrics: metrics);
|
|
|
|
|
GatewaySession session = await manager.OpenSessionAsync(CreateOpenRequest(), "client-1", CancellationToken.None);
|
|
|
|
|
GatewaySession session = await manager.OpenSessionAsync(CreateOpenRequest(), "client-1", ownerKeyId: null, CancellationToken.None);
|
|
|
|
|
|
|
|
|
|
SessionCloseResult result = await manager.KillWorkerAsync(session.SessionId, "test-kill", CancellationToken.None);
|
|
|
|
|
|
|
|
|
@@ -510,7 +544,7 @@ public sealed class SessionManagerTests
|
|
|
|
|
{
|
|
|
|
|
FakeWorkerClient workerClient = new();
|
|
|
|
|
SessionManager manager = CreateManager(new FakeSessionWorkerClientFactory(workerClient));
|
|
|
|
|
GatewaySession session = await manager.OpenSessionAsync(CreateOpenRequest(), "client-1", CancellationToken.None);
|
|
|
|
|
GatewaySession session = await manager.OpenSessionAsync(CreateOpenRequest(), "client-1", ownerKeyId: null, CancellationToken.None);
|
|
|
|
|
|
|
|
|
|
await Assert.ThrowsAsync<ArgumentException>(
|
|
|
|
|
async () => await manager.KillWorkerAsync(session.SessionId, blankReason, CancellationToken.None));
|
|
|
|
@@ -529,7 +563,7 @@ public sealed class SessionManagerTests
|
|
|
|
|
{
|
|
|
|
|
FakeWorkerClient workerClient = new();
|
|
|
|
|
SessionManager manager = CreateManager(new FakeSessionWorkerClientFactory(workerClient));
|
|
|
|
|
GatewaySession session = await manager.OpenSessionAsync(CreateOpenRequest(), "client-1", CancellationToken.None);
|
|
|
|
|
GatewaySession session = await manager.OpenSessionAsync(CreateOpenRequest(), "client-1", ownerKeyId: null, CancellationToken.None);
|
|
|
|
|
|
|
|
|
|
await Assert.ThrowsAsync<ArgumentNullException>(
|
|
|
|
|
async () => await manager.KillWorkerAsync(session.SessionId, null!, CancellationToken.None));
|
|
|
|
@@ -569,6 +603,7 @@ public sealed class SessionManagerTests
|
|
|
|
|
GatewaySession session = await manager.OpenSessionAsync(
|
|
|
|
|
CreateOpenRequest(),
|
|
|
|
|
"client-1",
|
|
|
|
|
ownerKeyId: null,
|
|
|
|
|
CancellationToken.None);
|
|
|
|
|
|
|
|
|
|
Assert.Equal(1, metrics.GetSnapshot().OpenSessions);
|
|
|
|
@@ -598,6 +633,7 @@ public sealed class SessionManagerTests
|
|
|
|
|
GatewaySession session = await manager.OpenSessionAsync(
|
|
|
|
|
CreateOpenRequest(),
|
|
|
|
|
"client-1",
|
|
|
|
|
ownerKeyId: null,
|
|
|
|
|
CancellationToken.None);
|
|
|
|
|
|
|
|
|
|
Task<SessionCloseResult> first = manager.KillWorkerAsync(session.SessionId, "kill-a", CancellationToken.None);
|
|
|
|
@@ -641,6 +677,7 @@ public sealed class SessionManagerTests
|
|
|
|
|
GatewaySession session = await manager.OpenSessionAsync(
|
|
|
|
|
CreateOpenRequest(),
|
|
|
|
|
"client-1",
|
|
|
|
|
ownerKeyId: null,
|
|
|
|
|
CancellationToken.None);
|
|
|
|
|
|
|
|
|
|
Assert.Equal(1, metrics.GetSnapshot().OpenSessions);
|
|
|
|
@@ -666,7 +703,7 @@ public sealed class SessionManagerTests
|
|
|
|
|
metrics);
|
|
|
|
|
|
|
|
|
|
SessionManagerException exception = await Assert.ThrowsAsync<SessionManagerException>(
|
|
|
|
|
async () => await manager.OpenSessionAsync(CreateOpenRequest(), "client-1", CancellationToken.None));
|
|
|
|
|
async () => await manager.OpenSessionAsync(CreateOpenRequest(), "client-1", ownerKeyId: null, CancellationToken.None));
|
|
|
|
|
|
|
|
|
|
Assert.Equal(SessionManagerErrorCode.OpenFailed, exception.ErrorCode);
|
|
|
|
|
Assert.Equal(0, registry.Count);
|
|
|
|
@@ -682,8 +719,8 @@ public sealed class SessionManagerTests
|
|
|
|
|
FakeWorkerClient activeClient = new();
|
|
|
|
|
QueueingSessionWorkerClientFactory factory = new(expiredClient, activeClient);
|
|
|
|
|
SessionManager manager = CreateManager(factory);
|
|
|
|
|
GatewaySession expiredSession = await manager.OpenSessionAsync(CreateOpenRequest(), "client-1", CancellationToken.None);
|
|
|
|
|
GatewaySession activeSession = await manager.OpenSessionAsync(CreateOpenRequest(), "client-2", CancellationToken.None);
|
|
|
|
|
GatewaySession expiredSession = await manager.OpenSessionAsync(CreateOpenRequest(), "client-1", ownerKeyId: null, CancellationToken.None);
|
|
|
|
|
GatewaySession activeSession = await manager.OpenSessionAsync(CreateOpenRequest(), "client-2", ownerKeyId: null, CancellationToken.None);
|
|
|
|
|
DateTimeOffset now = DateTimeOffset.UtcNow;
|
|
|
|
|
expiredSession.ExtendLease(now.AddSeconds(-1));
|
|
|
|
|
activeSession.ExtendLease(now.AddMinutes(5));
|
|
|
|
@@ -703,7 +740,7 @@ public sealed class SessionManagerTests
|
|
|
|
|
{
|
|
|
|
|
FakeWorkerClient workerClient = new();
|
|
|
|
|
SessionManager manager = CreateManager(new FakeSessionWorkerClientFactory(workerClient));
|
|
|
|
|
GatewaySession session = await manager.OpenSessionAsync(CreateOpenRequest(), "client-1", CancellationToken.None);
|
|
|
|
|
GatewaySession session = await manager.OpenSessionAsync(CreateOpenRequest(), "client-1", ownerKeyId: null, CancellationToken.None);
|
|
|
|
|
DateTimeOffset now = DateTimeOffset.UtcNow;
|
|
|
|
|
session.ExtendLease(now.AddSeconds(-1));
|
|
|
|
|
using IDisposable eventSubscriber = session.AttachEventSubscriber(allowMultipleSubscribers: false);
|
|
|
|
@@ -724,8 +761,8 @@ public sealed class SessionManagerTests
|
|
|
|
|
QueueingSessionWorkerClientFactory factory = new(firstClient, secondClient);
|
|
|
|
|
using GatewayMetrics metrics = new();
|
|
|
|
|
SessionManager manager = CreateManager(factory, metrics: metrics);
|
|
|
|
|
GatewaySession firstSession = await manager.OpenSessionAsync(CreateOpenRequest(), "client-1", CancellationToken.None);
|
|
|
|
|
GatewaySession secondSession = await manager.OpenSessionAsync(CreateOpenRequest(), "client-2", CancellationToken.None);
|
|
|
|
|
GatewaySession firstSession = await manager.OpenSessionAsync(CreateOpenRequest(), "client-1", ownerKeyId: null, CancellationToken.None);
|
|
|
|
|
GatewaySession secondSession = await manager.OpenSessionAsync(CreateOpenRequest(), "client-2", ownerKeyId: null, CancellationToken.None);
|
|
|
|
|
|
|
|
|
|
await manager.ShutdownAsync(CancellationToken.None);
|
|
|
|
|
|
|
|
|
|