Files
VolcanicCore/tests/VolcanicCore.Tests/ConnectionInstanceRegistryTests.cs

86 lines
3.1 KiB
C#

using System.Text.Json;
using VolcanicCore.Api.Engine;
using VolcanicCore.Api.Registries;
using VolcanicCore.Core;
using VolcanicCore.Persistence;
using VolcanicCore.Persistence.Encryption;
using VolcanicCore.Persistence.Migrations;
using VolcanicCore.Persistence.Repositories;
using System.Security.Cryptography;
namespace VolcanicCore.Tests;
public class ConnectionInstanceRegistryTests
{
private sealed class Handle : IAsyncDisposable
{
public bool Disposed;
public ValueTask DisposeAsync() { Disposed = true; return default; }
}
private sealed class FakeProvider : IConnectionProvider
{
public int Opens, Closes;
public string Id => "fake";
public string DisplayName => "Fake";
public JsonSchema ConfigSchema => new(JsonDocument.Parse("{}").RootElement);
public IReadOnlySet<string> SecretFields => new HashSet<string>();
public Task<object> OpenAsync(JsonElement config, CancellationToken ct)
{ Opens++; return Task.FromResult<object>(new Handle()); }
public Task CloseAsync(object h) { Closes++; return ((IAsyncDisposable)h).DisposeAsync().AsTask(); }
}
private static (ConnectionRepository c, FakeProvider p, ConnectionInstanceRegistry r) Setup()
{
var path = Path.Combine(Path.GetTempPath(), $"vc-{Guid.NewGuid():N}.db");
var f = new SqliteConnectionFactory(path);
using (var cn = f.Open())
new Migrator(new IMigration[]
{
new Migration001Initial(), new Migration002Connections(),
}).Apply(cn);
var key = new byte[32]; RandomNumberGenerator.Fill(key);
var enc = new EncryptionService(key);
var repo = new ConnectionRepository(f, enc);
var provider = new FakeProvider();
var providers = new ConnectionProviderRegistry(new IConnectionProvider[] { provider });
return (repo, provider, new ConnectionInstanceRegistry(repo, providers));
}
[Fact]
public async Task Opens_once_and_returns_cached_handle_on_subsequent_calls()
{
var (c, p, r) = Setup();
var id = c.Create("fake", "n1", "{\"x\":1}");
var a = await r.GetAsync(id, CancellationToken.None);
var b = await r.GetAsync(id, CancellationToken.None);
Assert.Same(a, b);
Assert.Equal(1, p.Opens);
}
[Fact]
public async Task Invalidate_disposes_current_handle_and_next_get_reopens()
{
var (c, p, r) = Setup();
var id = c.Create("fake", "n1", "{}");
var a = await r.GetAsync(id, CancellationToken.None);
await r.InvalidateAsync(id);
Assert.Equal(1, p.Closes);
var b = await r.GetAsync(id, CancellationToken.None);
Assert.NotSame(a, b);
Assert.Equal(2, p.Opens);
}
[Fact]
public async Task DisposeAsync_closes_all_open_handles()
{
var (c, p, r) = Setup();
var id1 = c.Create("fake", "n1", "{}");
var id2 = c.Create("fake", "n2", "{}");
await r.GetAsync(id1, CancellationToken.None);
await r.GetAsync(id2, CancellationToken.None);
await r.DisposeAsync();
Assert.Equal(2, p.Closes);
}
}