G1 & G2: Storage Governor and Aggregated retention pruning
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
using Predictalytics.Application.Services;
|
||||
using Xunit;
|
||||
|
||||
namespace Predictalytics.Application.Tests.Services;
|
||||
|
||||
public class StorageGovernorTests
|
||||
{
|
||||
[Theory]
|
||||
[InlineData(10.0, 90.0, 90, 30, 90)] // far below budget -> full window
|
||||
[InlineData(72.0, 90.0, 90, 30, 90)] // exactly at 80% -> still full
|
||||
[InlineData(90.0, 90.0, 90, 30, 30)] // at budget -> min window
|
||||
[InlineData(100.0, 90.0, 90, 30, 30)] // over budget -> min window
|
||||
[InlineData(72.9, 90.0, 90, 30, 87)] // 81% of budget -> slightly tightened
|
||||
[InlineData(81.0, 90.0, 90, 30, 60)] // 90% of budget -> halfway tightened
|
||||
public void ComputeEffectiveRetentionDays_Interpolates(
|
||||
double sizeGb, double maxGb, int configured, int min, int expected)
|
||||
{
|
||||
Assert.Equal(expected, StorageGovernor.ComputeEffectiveRetentionDays(sizeGb, maxGb, configured, min));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void HalfwayIntoZone_IsBetweenMinAndConfigured()
|
||||
{
|
||||
// 85 GB of 90 (softStart 72) -> t ~0.72 -> days between 30 and 90
|
||||
var days = StorageGovernor.ComputeEffectiveRetentionDays(85.0, 90.0, 90, 30);
|
||||
Assert.InRange(days, 31, 89);
|
||||
}
|
||||
}
|
||||
@@ -137,4 +137,67 @@ public class TradeRetentionWorkerTests
|
||||
Assert.Equal(0.45m, pos.AvgCost);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task RunOptimizationAsync_PrunesAggregatedTraderTrades()
|
||||
{
|
||||
using var connection = new SqliteConnection("DataSource=:memory:");
|
||||
connection.Open();
|
||||
var options = new DbContextOptionsBuilder<AppDbContext>()
|
||||
.UseSqlite(connection)
|
||||
.Options;
|
||||
|
||||
var baseDate = DateTime.UtcNow.Date;
|
||||
|
||||
using (var setup = new AppDbContext(options))
|
||||
{
|
||||
setup.Database.EnsureCreated();
|
||||
|
||||
var ev = new Event { Id = 1, Platform = PlatformType.Polymarket, Slug = "e", Title = "E" };
|
||||
setup.Set<Event>().Add(ev);
|
||||
|
||||
var market = new Market { Id = 10, EventId = 1, PlatformMarketId = 1L, Question = "Q?" };
|
||||
market.Outcomes.Add(new MarketOutcome { Id = 100, MarketId = 10, Label = "Yes", TokenId = "t100", CurrentPrice = 0.45m });
|
||||
setup.Markets.Add(market);
|
||||
|
||||
// Aggregated trader - target of G2 retention pruning
|
||||
setup.Traders.Add(new Trader { Id = 2, PlatformUserId = "0x2", DisplayName = "AggregatedTrader", IngestMode = IngestMode.Aggregated });
|
||||
|
||||
// Old trade older than retention cut-off (e.g. 200 days old when retention is 90 days)
|
||||
setup.Trades.Add(new Trade
|
||||
{
|
||||
Id = 20, TraderId = 2, DbMarketId = 10, MarketOutcomeId = 100, PlatformTradeId = "tx20",
|
||||
Side = TradeSide.Buy, Price = 0.40m, Size = 50m, Amount = 20m,
|
||||
ExecutedAt = baseDate.AddDays(-200)
|
||||
});
|
||||
|
||||
setup.SaveChanges();
|
||||
}
|
||||
|
||||
var services = new ServiceCollection();
|
||||
services.AddScoped(_ => new AppDbContext(options));
|
||||
using var provider = services.BuildServiceProvider();
|
||||
|
||||
var config = new ConfigurationBuilder().AddInMemoryCollection(new Dictionary<string, string?>
|
||||
{
|
||||
["RetentionSettings:RetentionDays"] = "90",
|
||||
["RetentionSettings:CompactionDays"] = "14",
|
||||
["RetentionSettings:MaxDatabaseSizeGb"] = "90.0",
|
||||
["RetentionSettings:MinRetentionDays"] = "30"
|
||||
}).Build();
|
||||
|
||||
var worker = new TradeRetentionWorker(provider, config, NullLogger<TradeRetentionWorker>.Instance);
|
||||
var method = typeof(TradeRetentionWorker).GetMethod("RunOptimizationAsync", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||
Assert.NotNull(method);
|
||||
|
||||
// Act: Run optimization
|
||||
await (Task)method!.Invoke(worker, new object[] { CancellationToken.None })!;
|
||||
|
||||
// Assert: The old trade must be deleted
|
||||
using (var assertCtx = new AppDbContext(options))
|
||||
{
|
||||
var oldTradeExists = await assertCtx.Trades.AnyAsync(t => t.Id == 20);
|
||||
Assert.False(oldTradeExists, "The old trade of the Aggregated trader should have been pruned.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user