stabilizaiton work - projects rework for maintenanceability and ui livening
This commit is contained in:
@@ -0,0 +1,32 @@
|
||||
# StellaOps.Provcache.Valkey.Tests - Local Agent Charter
|
||||
|
||||
## Roles
|
||||
- Backend developer
|
||||
- QA automation engineer
|
||||
|
||||
## Working directory
|
||||
- src/__Libraries/__Tests/StellaOps.Provcache.Valkey.Tests
|
||||
|
||||
## Allowed dependencies
|
||||
- src/__Libraries/StellaOps.Provcache.Valkey
|
||||
- src/__Libraries/StellaOps.Provcache
|
||||
- src/__Libraries/StellaOps.TestKit
|
||||
|
||||
## Required reading
|
||||
- docs/README.md
|
||||
- docs/07_HIGH_LEVEL_ARCHITECTURE.md
|
||||
- docs/modules/platform/architecture-overview.md
|
||||
- docs/modules/prov-cache/README.md
|
||||
- docs/modules/prov-cache/architecture.md
|
||||
- docs/modules/prov-cache/metrics-alerting.md
|
||||
|
||||
## Determinism and test rules
|
||||
- Use deterministic inputs: avoid DateTime.UtcNow, DateTimeOffset.UtcNow, Guid.NewGuid, and Random.Shared in tests.
|
||||
- Use TimeProvider and fixed seeds or fixtures for time- and randomness-dependent tests.
|
||||
- Use CultureInfo.InvariantCulture for parsing and formatting in tests.
|
||||
- Tag tests with TestCategories (Unit, Integration, Performance) and keep integration tests out of unit-only runs.
|
||||
- Keep tests offline and deterministic; prefer TestServer/TestHost with fixed inputs.
|
||||
|
||||
## Quality and safety
|
||||
- ASCII-only strings and comments unless explicitly justified.
|
||||
- Clean up temp files/directories created during tests.
|
||||
@@ -0,0 +1,35 @@
|
||||
using StellaOps.Provcache;
|
||||
|
||||
namespace StellaOps.Provcache.Valkey.Tests;
|
||||
|
||||
internal static class ProvcacheEntryFactory
|
||||
{
|
||||
public static ProvcacheEntry Create(string veriKey, DateTimeOffset createdAt, DateTimeOffset expiresAt)
|
||||
{
|
||||
var digest = new DecisionDigest
|
||||
{
|
||||
DigestVersion = "v1",
|
||||
VeriKey = veriKey,
|
||||
VerdictHash = "sha256:verdict",
|
||||
ProofRoot = "sha256:proof",
|
||||
ReplaySeed = new ReplaySeed { FeedIds = ["feed-1"], RuleIds = ["rule-1"] },
|
||||
CreatedAt = createdAt,
|
||||
ExpiresAt = expiresAt,
|
||||
TrustScore = 72,
|
||||
TrustScoreBreakdown = TrustScoreBreakdown.CreateDefault(70, 80, 60, 90, 65)
|
||||
};
|
||||
|
||||
return new ProvcacheEntry
|
||||
{
|
||||
VeriKey = veriKey,
|
||||
Decision = digest,
|
||||
PolicyHash = "sha256:policy",
|
||||
SignerSetHash = "sha256:signer",
|
||||
FeedEpoch = "2026-01-01",
|
||||
CreatedAt = createdAt,
|
||||
ExpiresAt = expiresAt,
|
||||
HitCount = 0,
|
||||
LastAccessedAt = null
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<LangVersion>preview</LangVersion>
|
||||
<IsPackable>false</IsPackable>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Moq" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="../../StellaOps.Provcache.Valkey/StellaOps.Provcache.Valkey.csproj" />
|
||||
<ProjectReference Include="../../StellaOps.Provcache/StellaOps.Provcache.csproj" />
|
||||
<ProjectReference Include="../../StellaOps.TestKit/StellaOps.TestKit.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="xunit.runner.json" CopyToOutputDirectory="PreserveNewest" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,8 @@
|
||||
# Provcache Valkey Tests Task Board
|
||||
|
||||
This board mirrors active sprint tasks for this module.
|
||||
Source of truth: `docs/implplan/SPRINT_20260130_002_Tools_csproj_remediation_solid_review.md`.
|
||||
|
||||
| Task ID | Status | Notes |
|
||||
| --- | --- | --- |
|
||||
| REMED-08 | DONE | Added unit tests for Valkey cache store operations; `dotnet test src/__Libraries/__Tests/StellaOps.Provcache.Valkey.Tests/StellaOps.Provcache.Valkey.Tests.csproj` passed (11 tests) 2026-02-03. |
|
||||
@@ -0,0 +1,49 @@
|
||||
using Moq;
|
||||
using StackExchange.Redis;
|
||||
using StellaOps.TestKit;
|
||||
using System.Text.Json;
|
||||
using Xunit;
|
||||
|
||||
namespace StellaOps.Provcache.Valkey.Tests;
|
||||
|
||||
public sealed class ValkeyProvcacheStoreGetManyTests
|
||||
{
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
public async Task GetManyAsyncReturnsEmptyWhenNoKeys()
|
||||
{
|
||||
var now = new DateTimeOffset(2026, 1, 2, 3, 4, 5, TimeSpan.Zero);
|
||||
var harness = new ValkeyProvcacheStoreHarness(now);
|
||||
|
||||
var result = await harness.Store.GetManyAsync(Array.Empty<string>());
|
||||
|
||||
Assert.Empty(result.Hits);
|
||||
Assert.Empty(result.Misses);
|
||||
Assert.Equal(0, result.ElapsedMs);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
public async Task GetManyAsyncReturnsHitsAndMisses()
|
||||
{
|
||||
var now = new DateTimeOffset(2026, 1, 2, 3, 4, 5, TimeSpan.Zero);
|
||||
var harness = new ValkeyProvcacheStoreHarness(now);
|
||||
var entry = ProvcacheEntryFactory.Create("veri-1", now, now.AddMinutes(5));
|
||||
var payload = JsonSerializer.Serialize(entry, ValkeyProvcacheStoreHarness.JsonOptions);
|
||||
RedisKey[] capturedKeys = Array.Empty<RedisKey>();
|
||||
|
||||
harness.Database
|
||||
.Setup(db => db.StringGetAsync(It.IsAny<RedisKey[]>(), It.IsAny<CommandFlags>()))
|
||||
.Callback<RedisKey[], CommandFlags>((keys, _) => capturedKeys = keys)
|
||||
.ReturnsAsync(new RedisValue[] { RedisValue.Null, payload });
|
||||
|
||||
var result = await harness.Store.GetManyAsync(new[] { "missing", "veri-1" });
|
||||
|
||||
Assert.Single(result.Hits);
|
||||
Assert.Single(result.Misses);
|
||||
Assert.True(result.Hits.ContainsKey("veri-1"));
|
||||
Assert.Equal("missing", result.Misses[0]);
|
||||
Assert.Equal($"{harness.Settings.ValkeyKeyPrefix}missing", capturedKeys[0].ToString());
|
||||
Assert.Equal($"{harness.Settings.ValkeyKeyPrefix}veri-1", capturedKeys[1].ToString());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
using Moq;
|
||||
using StackExchange.Redis;
|
||||
using StellaOps.TestKit;
|
||||
using System.Text.Json;
|
||||
using Xunit;
|
||||
|
||||
namespace StellaOps.Provcache.Valkey.Tests;
|
||||
|
||||
public sealed class ValkeyProvcacheStoreGetOrSetTests
|
||||
{
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
public async Task GetOrSetAsyncUsesFactoryOnMiss()
|
||||
{
|
||||
var now = new DateTimeOffset(2026, 1, 2, 3, 4, 5, TimeSpan.Zero);
|
||||
var harness = new ValkeyProvcacheStoreHarness(now);
|
||||
var entry = ProvcacheEntryFactory.Create("veri-1", now, now.AddMinutes(5));
|
||||
var factoryCalls = 0;
|
||||
|
||||
harness.Database
|
||||
.Setup(db => db.StringGetAsync(It.IsAny<RedisKey>(), It.IsAny<CommandFlags>()))
|
||||
.ReturnsAsync(RedisValue.Null);
|
||||
harness.Database
|
||||
.Setup(db => db.StringSetAsync(
|
||||
It.IsAny<RedisKey>(),
|
||||
It.IsAny<RedisValue>(),
|
||||
It.IsAny<TimeSpan?>(),
|
||||
It.IsAny<When>(),
|
||||
It.IsAny<CommandFlags>()))
|
||||
.ReturnsAsync(true);
|
||||
|
||||
var result = await harness.Store.GetOrSetAsync(
|
||||
"veri-1",
|
||||
_ =>
|
||||
{
|
||||
factoryCalls++;
|
||||
return ValueTask.FromResult(entry);
|
||||
});
|
||||
|
||||
Assert.Equal(1, factoryCalls);
|
||||
Assert.Equal(entry.VeriKey, result.VeriKey);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
public async Task GetOrSetAsyncSkipsFactoryOnHit()
|
||||
{
|
||||
var now = new DateTimeOffset(2026, 1, 2, 3, 4, 5, TimeSpan.Zero);
|
||||
var harness = new ValkeyProvcacheStoreHarness(now);
|
||||
var entry = ProvcacheEntryFactory.Create("veri-2", now, now.AddMinutes(5));
|
||||
var payload = JsonSerializer.Serialize(entry, ValkeyProvcacheStoreHarness.JsonOptions);
|
||||
var factoryCalls = 0;
|
||||
|
||||
harness.Database
|
||||
.Setup(db => db.StringGetAsync(It.IsAny<RedisKey>(), It.IsAny<CommandFlags>()))
|
||||
.ReturnsAsync(payload);
|
||||
|
||||
var result = await harness.Store.GetOrSetAsync(
|
||||
"veri-2",
|
||||
_ =>
|
||||
{
|
||||
factoryCalls++;
|
||||
return ValueTask.FromResult(entry);
|
||||
});
|
||||
|
||||
Assert.Equal(0, factoryCalls);
|
||||
Assert.Equal(entry.VeriKey, result.VeriKey);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
using Moq;
|
||||
using StackExchange.Redis;
|
||||
using StellaOps.TestKit;
|
||||
using System.Text.Json;
|
||||
using Xunit;
|
||||
|
||||
namespace StellaOps.Provcache.Valkey.Tests;
|
||||
|
||||
public sealed class ValkeyProvcacheStoreGetTests
|
||||
{
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
public async Task GetAsyncReturnsMissWhenValueMissing()
|
||||
{
|
||||
var now = new DateTimeOffset(2026, 1, 2, 3, 4, 5, TimeSpan.Zero);
|
||||
var harness = new ValkeyProvcacheStoreHarness(now);
|
||||
RedisKey capturedKey = default;
|
||||
var captured = false;
|
||||
|
||||
harness.Database
|
||||
.Setup(db => db.StringGetAsync(It.IsAny<RedisKey>(), It.IsAny<CommandFlags>()))
|
||||
.Callback<RedisKey, CommandFlags>((key, _) =>
|
||||
{
|
||||
capturedKey = key;
|
||||
captured = true;
|
||||
})
|
||||
.ReturnsAsync(RedisValue.Null);
|
||||
|
||||
var result = await harness.Store.GetAsync("veri-1");
|
||||
|
||||
Assert.False(result.IsHit);
|
||||
Assert.Null(result.Entry);
|
||||
Assert.True(captured);
|
||||
Assert.Equal($"{harness.Settings.ValkeyKeyPrefix}veri-1", capturedKey.ToString());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
public async Task GetAsyncReturnsHitWhenValueExists()
|
||||
{
|
||||
var now = new DateTimeOffset(2026, 1, 2, 3, 4, 5, TimeSpan.Zero);
|
||||
var harness = new ValkeyProvcacheStoreHarness(now);
|
||||
var entry = ProvcacheEntryFactory.Create("veri-2", now, now.AddMinutes(5));
|
||||
var payload = JsonSerializer.Serialize(entry, ValkeyProvcacheStoreHarness.JsonOptions);
|
||||
|
||||
harness.Database
|
||||
.Setup(db => db.StringGetAsync(It.IsAny<RedisKey>(), It.IsAny<CommandFlags>()))
|
||||
.ReturnsAsync(payload);
|
||||
|
||||
var result = await harness.Store.GetAsync("veri-2");
|
||||
|
||||
Assert.True(result.IsHit);
|
||||
Assert.NotNull(result.Entry);
|
||||
Assert.Equal(entry.VeriKey, result.Entry!.VeriKey);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
using Moq;
|
||||
using StackExchange.Redis;
|
||||
using StellaOps.TestKit;
|
||||
using System.Net;
|
||||
using Xunit;
|
||||
|
||||
namespace StellaOps.Provcache.Valkey.Tests;
|
||||
|
||||
public sealed class ValkeyProvcacheStoreInvalidateTests
|
||||
{
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
public async Task InvalidateAsyncReturnsDeleteResult()
|
||||
{
|
||||
var now = new DateTimeOffset(2026, 1, 2, 3, 4, 5, TimeSpan.Zero);
|
||||
var harness = new ValkeyProvcacheStoreHarness(now);
|
||||
|
||||
harness.Database
|
||||
.Setup(db => db.KeyDeleteAsync(It.IsAny<RedisKey>(), It.IsAny<CommandFlags>()))
|
||||
.ReturnsAsync(true);
|
||||
|
||||
var result = await harness.Store.InvalidateAsync("veri-1");
|
||||
|
||||
Assert.True(result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
public async Task InvalidateByPatternAsyncUsesPrefix()
|
||||
{
|
||||
var now = new DateTimeOffset(2026, 1, 2, 3, 4, 5, TimeSpan.Zero);
|
||||
var harness = new ValkeyProvcacheStoreHarness(now);
|
||||
var endpoint = new DnsEndPoint("localhost", 6379);
|
||||
var server = new Mock<IServer>();
|
||||
var keys = new[] { (RedisKey)"stellaops:prov:match:1", (RedisKey)"stellaops:prov:match:2" };
|
||||
var capturedPattern = string.Empty;
|
||||
|
||||
server.SetupGet(s => s.IsConnected).Returns(true);
|
||||
server
|
||||
.Setup(s => s.Keys(
|
||||
It.IsAny<int>(),
|
||||
It.IsAny<RedisValue>(),
|
||||
It.IsAny<int>(),
|
||||
It.IsAny<long>(),
|
||||
It.IsAny<int>(),
|
||||
It.IsAny<CommandFlags>()))
|
||||
.Callback<int, RedisValue, int, long, int, CommandFlags>((_, pattern, _, _, _, _) =>
|
||||
capturedPattern = pattern.ToString())
|
||||
.Returns(keys);
|
||||
|
||||
harness.Multiplexer.Setup(m => m.GetEndPoints(It.IsAny<bool>())).Returns(new EndPoint[] { endpoint });
|
||||
harness.Multiplexer.Setup(m => m.GetServer(endpoint, It.IsAny<object?>())).Returns(server.Object);
|
||||
harness.Database
|
||||
.Setup(db => db.KeyDeleteAsync(It.IsAny<RedisKey[]>(), It.IsAny<CommandFlags>()))
|
||||
.ReturnsAsync((RedisKey[] batch, CommandFlags _) => batch.LongLength);
|
||||
|
||||
var deleted = await harness.Store.InvalidateByPatternAsync("match:*");
|
||||
|
||||
Assert.Equal(2, deleted);
|
||||
Assert.Equal($"{harness.Settings.ValkeyKeyPrefix}match:*", capturedPattern);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
using Moq;
|
||||
using StackExchange.Redis;
|
||||
using StellaOps.Provcache;
|
||||
using StellaOps.TestKit;
|
||||
using Xunit;
|
||||
|
||||
namespace StellaOps.Provcache.Valkey.Tests;
|
||||
|
||||
public sealed class ValkeyProvcacheStoreSetManyTests
|
||||
{
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
public async Task SetManyAsyncBatchesAndCapsTtl()
|
||||
{
|
||||
var now = new DateTimeOffset(2026, 1, 2, 3, 4, 5, TimeSpan.Zero);
|
||||
var options = new ProvcacheOptions
|
||||
{
|
||||
ValkeyKeyPrefix = "stellaops:prov:",
|
||||
MaxTtl = TimeSpan.FromMinutes(5)
|
||||
};
|
||||
var harness = new ValkeyProvcacheStoreHarness(now, options);
|
||||
var batch = new Mock<IBatch>();
|
||||
batch
|
||||
.Setup(b => b.StringSetAsync(
|
||||
It.IsAny<RedisKey>(),
|
||||
It.IsAny<RedisValue>(),
|
||||
It.IsAny<TimeSpan?>(),
|
||||
It.IsAny<When>(),
|
||||
It.IsAny<CommandFlags>()))
|
||||
.ReturnsAsync(true);
|
||||
|
||||
harness.Database.Setup(db => db.CreateBatch(It.IsAny<object?>())).Returns(batch.Object);
|
||||
|
||||
var entries = new[]
|
||||
{
|
||||
ProvcacheEntryFactory.Create("veri-1", now, now.AddHours(1)),
|
||||
ProvcacheEntryFactory.Create("veri-expired", now.AddHours(-2), now.AddMinutes(-1))
|
||||
};
|
||||
|
||||
await harness.Store.SetManyAsync(entries);
|
||||
|
||||
batch.Verify(b => b.Execute(), Times.Once);
|
||||
var invocation = Assert.Single(batch.Invocations, i => i.Method.Name == "StringSetAsync");
|
||||
Assert.NotNull(invocation.Arguments[2]);
|
||||
var ttl = (Expiration)invocation.Arguments[2]!;
|
||||
Assert.Equal((Expiration)options.MaxTtl, ttl);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
using Moq;
|
||||
using StackExchange.Redis;
|
||||
using StellaOps.Provcache;
|
||||
using StellaOps.TestKit;
|
||||
using Xunit;
|
||||
|
||||
namespace StellaOps.Provcache.Valkey.Tests;
|
||||
|
||||
public sealed class ValkeyProvcacheStoreSetTests
|
||||
{
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
public async Task SetAsyncCapsTtlAtMax()
|
||||
{
|
||||
var now = new DateTimeOffset(2026, 1, 2, 3, 4, 5, TimeSpan.Zero);
|
||||
var options = new ProvcacheOptions
|
||||
{
|
||||
ValkeyKeyPrefix = "stellaops:prov:",
|
||||
MaxTtl = TimeSpan.FromMinutes(5)
|
||||
};
|
||||
var harness = new ValkeyProvcacheStoreHarness(now, options);
|
||||
harness.Database
|
||||
.Setup(db => db.StringSetAsync(
|
||||
It.IsAny<RedisKey>(),
|
||||
It.IsAny<RedisValue>(),
|
||||
It.IsAny<TimeSpan?>(),
|
||||
It.IsAny<When>(),
|
||||
It.IsAny<CommandFlags>()))
|
||||
.ReturnsAsync(true);
|
||||
|
||||
var entry = ProvcacheEntryFactory.Create("veri-1", now, now.AddHours(1));
|
||||
|
||||
await harness.Store.SetAsync(entry);
|
||||
|
||||
var invocation = Assert.Single(harness.Database.Invocations, i => i.Method.Name == "StringSetAsync");
|
||||
Assert.NotNull(invocation.Arguments[2]);
|
||||
var ttl = (Expiration)invocation.Arguments[2]!;
|
||||
Assert.Equal((Expiration)options.MaxTtl, ttl);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
public async Task SetAsyncSkipsExpiredEntries()
|
||||
{
|
||||
var now = new DateTimeOffset(2026, 1, 2, 3, 4, 5, TimeSpan.Zero);
|
||||
var harness = new ValkeyProvcacheStoreHarness(now);
|
||||
var entry = ProvcacheEntryFactory.Create("veri-2", now.AddHours(-2), now.AddMinutes(-1));
|
||||
|
||||
await harness.Store.SetAsync(entry);
|
||||
|
||||
harness.Database.Verify(db => db.StringSetAsync(
|
||||
It.IsAny<RedisKey>(),
|
||||
It.IsAny<RedisValue>(),
|
||||
It.IsAny<TimeSpan?>(),
|
||||
It.IsAny<When>(),
|
||||
It.IsAny<CommandFlags>()), Times.Never);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Moq;
|
||||
using StackExchange.Redis;
|
||||
using StellaOps.Provcache;
|
||||
using StellaOps.Provcache.Valkey;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace StellaOps.Provcache.Valkey.Tests;
|
||||
|
||||
internal sealed class FixedTimeProvider : TimeProvider
|
||||
{
|
||||
public FixedTimeProvider(DateTimeOffset utcNow) => UtcNow = utcNow;
|
||||
|
||||
public DateTimeOffset UtcNow { get; set; }
|
||||
|
||||
public override DateTimeOffset GetUtcNow() => UtcNow;
|
||||
}
|
||||
|
||||
internal sealed class ValkeyProvcacheStoreHarness
|
||||
{
|
||||
public static readonly JsonSerializerOptions JsonOptions = new()
|
||||
{
|
||||
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
|
||||
WriteIndented = false
|
||||
};
|
||||
|
||||
public Mock<IConnectionMultiplexer> Multiplexer { get; } = new();
|
||||
public Mock<IDatabase> Database { get; } = new();
|
||||
public Mock<ILogger<ValkeyProvcacheStore>> Logger { get; } = new();
|
||||
public FixedTimeProvider TimeProvider { get; }
|
||||
public ProvcacheOptions Settings { get; }
|
||||
public ValkeyProvcacheStore Store { get; }
|
||||
|
||||
public ValkeyProvcacheStoreHarness(DateTimeOffset utcNow, ProvcacheOptions? options = null)
|
||||
{
|
||||
Settings = options ?? new ProvcacheOptions
|
||||
{
|
||||
ValkeyKeyPrefix = "stellaops:prov:",
|
||||
MaxTtl = TimeSpan.FromMinutes(10)
|
||||
};
|
||||
|
||||
TimeProvider = new FixedTimeProvider(utcNow);
|
||||
Multiplexer.Setup(m => m.GetDatabase(It.IsAny<int>(), It.IsAny<object?>()))
|
||||
.Returns(Database.Object);
|
||||
Store = new ValkeyProvcacheStore(
|
||||
Multiplexer.Object,
|
||||
Options.Create(Settings),
|
||||
Logger.Object,
|
||||
TimeProvider);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"$schema": "https://xunit.net/schema/current/xunit.runner.schema.json",
|
||||
"parallelizeTestCollections": false,
|
||||
"maxParallelThreads": 1
|
||||
}
|
||||
Reference in New Issue
Block a user