86 lines
3.1 KiB
C#
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);
|
|
}
|
|
}
|