225 lines
7.1 KiB
C#
225 lines
7.1 KiB
C#
|
|
using Robotico.Nexus.Client.Document;
|
||
|
|
using Robotico.Nexus.Client.Relational;
|
||
|
|
using Robotico.Nexus.Client.Tests.TestSupport;
|
||
|
|
using Robotico.Result.Errors;
|
||
|
|
using Xunit;
|
||
|
|
|
||
|
|
namespace Robotico.Nexus.Client.Tests;
|
||
|
|
|
||
|
|
public class NexusClientTests : IAsyncLifetime
|
||
|
|
{
|
||
|
|
private NexusTestHost _host = null!;
|
||
|
|
|
||
|
|
public async Task InitializeAsync() => _host = await NexusTestHost.StartAsync();
|
||
|
|
|
||
|
|
public async Task DisposeAsync() => await _host.DisposeAsync();
|
||
|
|
|
||
|
|
[Fact]
|
||
|
|
public void Connect_Fails_ForInvalidUri()
|
||
|
|
{
|
||
|
|
Robotico.Result.Result<NexusClient> result = NexusClient.Connect("not-a-uri");
|
||
|
|
|
||
|
|
Assert.True(result.IsError(out IError? error));
|
||
|
|
Assert.Equal(NexusErrors.UriInvalid, error!.Code);
|
||
|
|
}
|
||
|
|
|
||
|
|
[Fact]
|
||
|
|
public void Connect_Succeeds_AndBindsDefaultDatabase_WhenPathOmitted()
|
||
|
|
{
|
||
|
|
Robotico.Result.Result<NexusClient> result = NexusClient.Connect(_host.ConnectionUri(NexusUriSchemes.Graph));
|
||
|
|
|
||
|
|
Assert.True(result.IsSuccess(out NexusClient? client, out _));
|
||
|
|
using NexusClient c = client!;
|
||
|
|
Assert.Equal(NexusUriSchemes.Graph, c.Scheme);
|
||
|
|
Assert.Equal("pathways", c.Database);
|
||
|
|
}
|
||
|
|
|
||
|
|
[Fact]
|
||
|
|
public void Connect_Succeeds_AndBindsExplicitDatabase()
|
||
|
|
{
|
||
|
|
Robotico.Result.Result<NexusClient> result = NexusClient.Connect(_host.ConnectionUri(NexusUriSchemes.Time, "custom-db"));
|
||
|
|
|
||
|
|
Assert.True(result.IsSuccess(out NexusClient? client, out _));
|
||
|
|
using NexusClient c = client!;
|
||
|
|
Assert.Equal("custom-db", c.Database);
|
||
|
|
}
|
||
|
|
|
||
|
|
[Fact]
|
||
|
|
public void CheckHealth_Succeeds_WhenServerReady()
|
||
|
|
{
|
||
|
|
using NexusClient client = Connect(NexusUriSchemes.Graph);
|
||
|
|
_host.Health.Ready = true;
|
||
|
|
|
||
|
|
Robotico.Result.Result result = client.CheckHealth();
|
||
|
|
|
||
|
|
Assert.True(result.IsSuccess());
|
||
|
|
}
|
||
|
|
|
||
|
|
[Fact]
|
||
|
|
public void CheckHealth_Fails_WhenServerNotReady()
|
||
|
|
{
|
||
|
|
using NexusClient client = Connect(NexusUriSchemes.Graph);
|
||
|
|
_host.Health.Ready = false;
|
||
|
|
|
||
|
|
Robotico.Result.Result result = client.CheckHealth();
|
||
|
|
|
||
|
|
Assert.True(result.IsError(out IError? error));
|
||
|
|
Assert.Equal(NexusErrors.Unavailable, error!.Code);
|
||
|
|
}
|
||
|
|
|
||
|
|
[Fact]
|
||
|
|
public void CheckHealth_Fails_AfterDispose()
|
||
|
|
{
|
||
|
|
NexusClient client = Connect(NexusUriSchemes.Graph);
|
||
|
|
client.Dispose();
|
||
|
|
|
||
|
|
Robotico.Result.Result result = client.CheckHealth();
|
||
|
|
|
||
|
|
Assert.True(result.IsError(out IError? error));
|
||
|
|
Assert.Equal(NexusErrors.Disposed, error!.Code);
|
||
|
|
}
|
||
|
|
|
||
|
|
[Fact]
|
||
|
|
public void Dispose_IsIdempotent()
|
||
|
|
{
|
||
|
|
NexusClient client = Connect(NexusUriSchemes.Graph);
|
||
|
|
|
||
|
|
client.Dispose();
|
||
|
|
client.Dispose();
|
||
|
|
}
|
||
|
|
|
||
|
|
[Fact]
|
||
|
|
public async Task DisposeAsync_IsIdempotent_AndAfterSyncDispose()
|
||
|
|
{
|
||
|
|
NexusClient client = Connect(NexusUriSchemes.Graph);
|
||
|
|
|
||
|
|
await client.DisposeAsync();
|
||
|
|
await client.DisposeAsync();
|
||
|
|
|
||
|
|
NexusClient client2 = Connect(NexusUriSchemes.Time);
|
||
|
|
client2.Dispose();
|
||
|
|
await client2.DisposeAsync();
|
||
|
|
}
|
||
|
|
|
||
|
|
[Fact]
|
||
|
|
public void CreateDocumentClient_Succeeds_WhenNotDisposed()
|
||
|
|
{
|
||
|
|
using NexusClient client = Connect(NexusUriSchemes.Document);
|
||
|
|
|
||
|
|
Robotico.Result.Result<NexusDocumentClient> result = client.CreateDocumentClient();
|
||
|
|
|
||
|
|
Assert.True(result.IsSuccess(out NexusDocumentClient? documentClient, out _));
|
||
|
|
Assert.NotNull(documentClient);
|
||
|
|
}
|
||
|
|
|
||
|
|
[Fact]
|
||
|
|
public void CreateDocumentClient_Fails_AfterDispose()
|
||
|
|
{
|
||
|
|
NexusClient client = Connect(NexusUriSchemes.Document);
|
||
|
|
client.Dispose();
|
||
|
|
|
||
|
|
Robotico.Result.Result<NexusDocumentClient> result = client.CreateDocumentClient();
|
||
|
|
|
||
|
|
Assert.True(result.IsError(out IError? error));
|
||
|
|
Assert.Equal(NexusErrors.Disposed, error!.Code);
|
||
|
|
}
|
||
|
|
|
||
|
|
[Fact]
|
||
|
|
public void CreateRelationalClient_Succeeds_WhenNotDisposed()
|
||
|
|
{
|
||
|
|
using NexusClient client = Connect(NexusUriSchemes.Relational);
|
||
|
|
|
||
|
|
Robotico.Result.Result<NexusRelationalClient> result = client.CreateRelationalClient();
|
||
|
|
|
||
|
|
Assert.True(result.IsSuccess(out NexusRelationalClient? relationalClient, out _));
|
||
|
|
Assert.NotNull(relationalClient);
|
||
|
|
}
|
||
|
|
|
||
|
|
[Fact]
|
||
|
|
public void CreateRelationalClient_Fails_AfterDispose()
|
||
|
|
{
|
||
|
|
NexusClient client = Connect(NexusUriSchemes.Relational);
|
||
|
|
client.Dispose();
|
||
|
|
|
||
|
|
Robotico.Result.Result<NexusRelationalClient> result = client.CreateRelationalClient();
|
||
|
|
|
||
|
|
Assert.True(result.IsError(out IError? error));
|
||
|
|
Assert.Equal(NexusErrors.Disposed, error!.Code);
|
||
|
|
}
|
||
|
|
|
||
|
|
[Fact]
|
||
|
|
public void CreateDocumentWireClient_Succeeds_WhenNotDisposed()
|
||
|
|
{
|
||
|
|
using NexusClient client = Connect(NexusUriSchemes.Document);
|
||
|
|
|
||
|
|
Robotico.Result.Result<Mishima.Nexus.Wire.V1.NexusDocumentEngineService.NexusDocumentEngineServiceClient> result =
|
||
|
|
client.CreateDocumentWireClient();
|
||
|
|
|
||
|
|
Assert.True(result.IsSuccess());
|
||
|
|
}
|
||
|
|
|
||
|
|
[Fact]
|
||
|
|
public void CreateDocumentWireClient_Fails_AfterDispose()
|
||
|
|
{
|
||
|
|
NexusClient client = Connect(NexusUriSchemes.Document);
|
||
|
|
client.Dispose();
|
||
|
|
|
||
|
|
Robotico.Result.Result<Mishima.Nexus.Wire.V1.NexusDocumentEngineService.NexusDocumentEngineServiceClient> result =
|
||
|
|
client.CreateDocumentWireClient();
|
||
|
|
|
||
|
|
Assert.True(result.IsError(out IError? error));
|
||
|
|
Assert.Equal(NexusErrors.Disposed, error!.Code);
|
||
|
|
}
|
||
|
|
|
||
|
|
[Fact]
|
||
|
|
public void CreateRelationalWireClient_Succeeds_WhenNotDisposed()
|
||
|
|
{
|
||
|
|
using NexusClient client = Connect(NexusUriSchemes.Relational);
|
||
|
|
|
||
|
|
Robotico.Result.Result<Mishima.Nexus.Wire.V1.NexusRelationalEngineService.NexusRelationalEngineServiceClient> result =
|
||
|
|
client.CreateRelationalWireClient();
|
||
|
|
|
||
|
|
Assert.True(result.IsSuccess());
|
||
|
|
}
|
||
|
|
|
||
|
|
[Fact]
|
||
|
|
public void CreateRelationalWireClient_Fails_AfterDispose()
|
||
|
|
{
|
||
|
|
NexusClient client = Connect(NexusUriSchemes.Relational);
|
||
|
|
client.Dispose();
|
||
|
|
|
||
|
|
Robotico.Result.Result<Mishima.Nexus.Wire.V1.NexusRelationalEngineService.NexusRelationalEngineServiceClient> result =
|
||
|
|
client.CreateRelationalWireClient();
|
||
|
|
|
||
|
|
Assert.True(result.IsError(out IError? error));
|
||
|
|
Assert.Equal(NexusErrors.Disposed, error!.Code);
|
||
|
|
}
|
||
|
|
|
||
|
|
[Fact]
|
||
|
|
public void BuildCallMetadata_UsesBoundDatabase_WhenNoOverride()
|
||
|
|
{
|
||
|
|
using NexusClient client = Connect(NexusUriSchemes.Graph, "boundDb");
|
||
|
|
|
||
|
|
Grpc.Core.Metadata metadata = client.BuildCallMetadata();
|
||
|
|
|
||
|
|
Assert.Equal("boundDb", metadata.GetValue(NexusCallMetadata.DatabaseKey));
|
||
|
|
}
|
||
|
|
|
||
|
|
[Fact]
|
||
|
|
public void BuildCallMetadata_UsesOverride_WhenProvided()
|
||
|
|
{
|
||
|
|
using NexusClient client = Connect(NexusUriSchemes.Graph, "boundDb");
|
||
|
|
|
||
|
|
Grpc.Core.Metadata metadata = client.BuildCallMetadata("overrideDb");
|
||
|
|
|
||
|
|
Assert.Equal("overrideDb", metadata.GetValue(NexusCallMetadata.DatabaseKey));
|
||
|
|
}
|
||
|
|
|
||
|
|
private NexusClient Connect(string scheme, string? database = null)
|
||
|
|
{
|
||
|
|
Robotico.Result.Result<NexusClient> result = NexusClient.Connect(_host.ConnectionUri(scheme, database));
|
||
|
|
Assert.True(result.IsSuccess(out NexusClient? client, out _));
|
||
|
|
return client!;
|
||
|
|
}
|
||
|
|
}
|