fix: persist repeated profile test results (#10466)

This commit is contained in:
Shubham Padkonde
2026-11-02 06:56:34 +05:30
committed by GitHub
parent 7a52be4150
commit c436b998b4
3 changed files with 104 additions and 22 deletions
@@ -0,0 +1,92 @@
namespace ServiceLib.Tests.Manager;
public class ProfileExManagerPersistenceTests
{
[Test]
public async Task SaveTo_NewProfilesWithRepeatedResults_ShouldPersistEveryProfile()
{
SQLiteHelper.Instance.CreateTable<ProfileExItem>();
var manager = new ProfileExManager();
var ids = Enumerable.Range(0, 3).Select(_ => Guid.NewGuid().ToString("N")).ToArray();
try
{
foreach (var id in ids)
{
manager.SetTestDelay(id, 42);
manager.SetTestSpeed(id, 12.5m);
manager.SetTestMessage(id, "completed");
manager.SetTestIpInfo(id, "192.0.2.1");
manager.SetSort(id, 7);
}
await manager.SaveTo();
foreach (var id in ids)
{
var saved = await SQLiteHelper.Instance.TableAsync<ProfileExItem>()
.Where(t => t.IndexId == id).ToListAsync();
await saved.Count.Should().BeEqualTo(1);
await saved[0].Delay.Should().BeEqualTo(42);
await saved[0].Speed.Should().BeEqualTo(12.5m);
await saved[0].Message.Should().BeEqualTo("completed");
await saved[0].IpInfo.Should().BeEqualTo("192.0.2.1");
await saved[0].Sort.Should().BeEqualTo(7);
}
}
finally
{
foreach (var id in ids)
{
await SQLiteHelper.Instance.DeleteAsync(new ProfileExItem { IndexId = id });
}
}
}
[Test]
public async Task SaveTo_MixedNewAndExistingProfiles_ShouldInsertAndUpdateResults()
{
SQLiteHelper.Instance.CreateTable<ProfileExItem>();
var manager = new ProfileExManager();
var existingId = Guid.NewGuid().ToString("N");
var newId = Guid.NewGuid().ToString("N");
try
{
await SQLiteHelper.Instance.InsertAsync(new ProfileExItem
{
IndexId = existingId,
Delay = 1,
Speed = 2,
});
manager.SetTestDelay(existingId, 100);
manager.SetTestSpeed(existingId, 20);
manager.SetTestDelay(newId, 200);
manager.SetTestIpInfo(newId, "192.0.2.2");
await manager.SaveTo();
var existing = await SQLiteHelper.Instance.TableAsync<ProfileExItem>()
.Where(t => t.IndexId == existingId).FirstAsync();
await existing.Delay.Should().BeEqualTo(100);
await existing.Speed.Should().BeEqualTo(20m);
var inserted = await SQLiteHelper.Instance.TableAsync<ProfileExItem>()
.Where(t => t.IndexId == newId).ToListAsync();
await inserted.Count.Should().BeEqualTo(1);
await inserted[0].Delay.Should().BeEqualTo(200);
await inserted[0].IpInfo.Should().BeEqualTo("192.0.2.2");
manager.SetTestDelay(newId, 300);
await manager.SaveTo();
var updated = await SQLiteHelper.Instance.TableAsync<ProfileExItem>()
.Where(t => t.IndexId == newId).FirstAsync();
await updated.Delay.Should().BeEqualTo(300);
await updated.IpInfo.Should().BeEqualTo("192.0.2.2");
}
finally
{
await SQLiteHelper.Instance.DeleteAsync(new ProfileExItem { IndexId = existingId });
await SQLiteHelper.Instance.DeleteAsync(new ProfileExItem { IndexId = newId });
}
}
}
+5
View File
@@ -28,6 +28,11 @@ public sealed class SQLiteHelper
return await _dbAsync.InsertAllAsync(models, runInTransaction: true).ConfigureAwait(false);
}
public async Task<int> ReplaceAllAsync(IEnumerable models)
{
return await _dbAsync.InsertAllAsync(models, extra: "OR REPLACE", runInTransaction: true).ConfigureAwait(false);
}
public async Task<int> InsertAsync(object model)
{
return await _dbAsync.InsertAsync(model);
+7 -22
View File
@@ -39,15 +39,14 @@ public class ProfileExManager
{
if (indexId.IsNotEmpty())
{
//Speed tests touch this from many threads; duplicates are harmless here since
//the save loop just writes the same row more than once
//Speed tests touch this from many threads; the save loop deduplicates IDs.
_queIndexIds.Enqueue(indexId);
}
}
private async Task SaveQueueIndexIds()
{
var lstIds = new List<string>();
var lstIds = new HashSet<string>();
while (_queIndexIds.TryDequeue(out var id))
{
lstIds.Add(id);
@@ -55,39 +54,25 @@ public class ProfileExManager
if (lstIds.Count > 0)
{
var lstExists = await SQLiteHelper.Instance.TableAsync<ProfileExItem>().ToListAsync();
List<ProfileExItem> lstInserts = [];
List<ProfileExItem> lstUpdates = [];
List<ProfileExItem> lstSaves = [];
foreach (var id in lstIds)
{
var item = lstExists.FirstOrDefault(t => t.IndexId == id);
var itemNew = _lstProfileEx?.FirstOrDefault(t => t.IndexId == id);
if (itemNew is null)
{
continue;
}
if (item is not null)
{
lstUpdates.Add(itemNew);
}
else
{
lstInserts.Add(itemNew);
}
lstSaves.Add(itemNew);
}
try
{
if (lstInserts.Count > 0)
if (lstSaves.Count > 0)
{
await SQLiteHelper.Instance.InsertAllAsync(lstInserts);
}
if (lstUpdates.Count > 0)
{
await SQLiteHelper.Instance.UpdateAllAsync(lstUpdates);
//Another save may have inserted these rows since the queue was drained.
await SQLiteHelper.Instance.ReplaceAllAsync(lstSaves);
}
}
catch (Exception ex)