From 86af253df7e5f28a96494dfec89a093ff15c5971 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D1=82=D0=B5=D0=BF=D0=B0=D0=BD=D0=BE=D0=B2=20=D0=94?= =?UTF-8?q?=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9?= Date: Tue, 24 Oct 2023 10:55:50 +0500 Subject: [PATCH 1/4] =?UTF-8?q?=D0=9A=D1=8D=D1=88=20=D1=82=D0=B5=D0=BB?= =?UTF-8?q?=D0=B5=D0=BC=D0=B5=D1=82=D1=80=D0=B8=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. Небольшой рефакторинг 2. Покрытие кода тестами --- .../Services/SAUB/TelemetryDataCache.cs | 79 ++++++++++--------- .../AsbCloudWebApi.Tests.csproj | 1 + .../SAUB/TelemetryDataSaubCacheTests.cs | 69 ++++++++++++++++ 3 files changed, 111 insertions(+), 38 deletions(-) create mode 100644 AsbCloudWebApi.Tests/ServicesTests/SAUB/TelemetryDataSaubCacheTests.cs diff --git a/AsbCloudInfrastructure/Services/SAUB/TelemetryDataCache.cs b/AsbCloudInfrastructure/Services/SAUB/TelemetryDataCache.cs index b579c876..dd602a1a 100644 --- a/AsbCloudInfrastructure/Services/SAUB/TelemetryDataCache.cs +++ b/AsbCloudInfrastructure/Services/SAUB/TelemetryDataCache.cs @@ -6,7 +6,6 @@ using System.Linq; using Microsoft.EntityFrameworkCore; using Mapster; using System.Threading.Tasks; -using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using AsbCloudInfrastructure.Background; using System.Threading; @@ -24,8 +23,7 @@ namespace AsbCloudInfrastructure.Services.SAUB public CyclycArray LastData { get; init; } = null!; public double TimezoneHours { get; init; } = 5; } - - private IServiceProvider provider = null!; + private const int activeWellCapacity = 12 * 60 * 60; private const int doneWellCapacity = 65 * 60; @@ -40,6 +38,8 @@ namespace AsbCloudInfrastructure.Services.SAUB private static TelemetryDataCache? instance; + public int CacheItemCount => caches.Count; + public static TelemetryDataCache GetInstance(IServiceProvider provider) where TEntity : class, AsbCloudDb.Model.ITelemetryData { @@ -55,7 +55,6 @@ namespace AsbCloudInfrastructure.Services.SAUB work.Timeout = TimeSpan.FromMinutes(15); worker.WorkStore.RunOnceQueue.Enqueue(work); } - instance.provider = provider; return instance; } @@ -69,10 +68,9 @@ namespace AsbCloudInfrastructure.Services.SAUB if (!range.Any()) return; - var newItems = range - .OrderBy(i => i.DateTime); + range = range.OrderBy(x => x.DateTime); - foreach (var item in newItems) + foreach (var item in range) item.IdTelemetry = idTelemetry; TelemetryDataCacheItem cacheItem; @@ -87,12 +85,12 @@ namespace AsbCloudInfrastructure.Services.SAUB { cacheItem = caches.GetOrAdd(idTelemetry, _ => new TelemetryDataCacheItem() { - FirstByDate = newItems.ElementAt(0), + FirstByDate = range.ElementAt(0), LastData = new CyclycArray(activeWellCapacity) }); } - cacheItem.LastData.AddRange(newItems); + cacheItem.LastData.AddRange(range); } /// @@ -153,39 +151,44 @@ namespace AsbCloudInfrastructure.Services.SAUB private async Task InitializeCacheFromDBAsync(IAsbCloudDbContext db, Action onProgress, CancellationToken token) where TEntity : class, AsbCloudDb.Model.ITelemetryData { - if (isLoading) - throw new Exception("Multiple cache loading detected."); - - isLoading = true; - - var defaultTimeout = db.Database.GetCommandTimeout(); - db.Database.SetCommandTimeout(TimeSpan.FromMinutes(5)); - - Well[] wells = await db.Set() - .Include(well => well.Telemetry) - .Include(well => well.Cluster) - .Where(well => well.IdTelemetry != null) - .ToArrayAsync(token); - - var count = wells.Length; - var i = 0d; - foreach (Well well in wells) + try { - var capacity = well.IdState == 1 - ? activeWellCapacity - : doneWellCapacity; + if (isLoading) + throw new Exception("Multiple cache loading detected."); - var idTelemetry = well.IdTelemetry!.Value; - var hoursOffset = well.Timezone.Hours; + isLoading = true; + + db.Database.SetCommandTimeout(TimeSpan.FromMinutes(5)); + + Well[] wells = await db.Set() + .Include(well => well.Telemetry) + .Include(well => well.Cluster) + .Where(well => well.IdTelemetry != null) + .ToArrayAsync(token); + + var count = wells.Length; + var i = 0d; + foreach (Well well in wells) + { + var capacity = well.IdState == 1 + ? activeWellCapacity + : doneWellCapacity; + + var idTelemetry = well.IdTelemetry!.Value; + var hoursOffset = well.Timezone.Hours; - onProgress($"Loading for well: {well.Cluster?.Caption}/{well.Caption} (capacity:{capacity}) idTelemetry:{idTelemetry}", i++/count); - var cacheItem = await GetOrDefaultCacheDataFromDbAsync(db, idTelemetry, capacity, hoursOffset, token); - if(cacheItem is not null) - caches.TryAdd(idTelemetry, cacheItem); + onProgress($"Loading for well: {well.Cluster?.Caption}/{well.Caption} (capacity:{capacity}) idTelemetry:{idTelemetry}", i++/count); + var cacheItem = await GetOrDefaultCacheDataFromDbAsync(db, idTelemetry, capacity, hoursOffset, token); + if(cacheItem is not null) + caches.TryAdd(idTelemetry, cacheItem); + } + } + finally + { + isLoading = false; + var defaultTimeout = db.Database.GetCommandTimeout(); + db.Database.SetCommandTimeout(defaultTimeout); } - - isLoading = false; - db.Database.SetCommandTimeout(defaultTimeout); } private static async Task GetOrDefaultCacheDataFromDbAsync(IAsbCloudDbContext db, int idTelemetry, int capacity, double hoursOffset, CancellationToken token) diff --git a/AsbCloudWebApi.Tests/AsbCloudWebApi.Tests.csproj b/AsbCloudWebApi.Tests/AsbCloudWebApi.Tests.csproj index 4cf2783e..4024a917 100644 --- a/AsbCloudWebApi.Tests/AsbCloudWebApi.Tests.csproj +++ b/AsbCloudWebApi.Tests/AsbCloudWebApi.Tests.csproj @@ -9,6 +9,7 @@ + diff --git a/AsbCloudWebApi.Tests/ServicesTests/SAUB/TelemetryDataSaubCacheTests.cs b/AsbCloudWebApi.Tests/ServicesTests/SAUB/TelemetryDataSaubCacheTests.cs new file mode 100644 index 00000000..a5e9f12a --- /dev/null +++ b/AsbCloudWebApi.Tests/ServicesTests/SAUB/TelemetryDataSaubCacheTests.cs @@ -0,0 +1,69 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using AsbCloudApp.Data.SAUB; +using AsbCloudDb.Model; +using AsbCloudInfrastructure.Background; +using AsbCloudInfrastructure.Services.SAUB; +using Bogus; +using Microsoft.Extensions.DependencyInjection; +using NSubstitute; +using Xunit; + +namespace AsbCloudWebApi.Tests.ServicesTests.SAUB; + +public class TelemetryDataSaubCacheTests +{ + private readonly IEnumerable fakeTelemetries = new Faker() + .RuleFor(t => t.DateTime, DateTime.UtcNow) + .Generate(5) + .OrderBy(t => t.DateTime); + + private readonly IServiceProvider serviceProvider = Substitute.For(); + + private readonly TelemetryDataCache telemetryDataCache; + + public TelemetryDataSaubCacheTests() + { + serviceProvider.GetService().Returns(new BackgroundWorker(serviceProvider)); + + telemetryDataCache = TelemetryDataCache.GetInstance(serviceProvider); + } + + [Fact] + public void AddRange_ShouldReturn_OneAddedElementToCache() + { + //arrange + const int expectedCacheItemCount = 1; + + var idTelemetry = new Random().Next(1, 100); + var telemetryDataCacheType = telemetryDataCache.GetType(); + + telemetryDataCacheType.GetField("isLoading", BindingFlags.NonPublic | BindingFlags.Instance)?.SetValue(telemetryDataCache, false); + + //act + telemetryDataCache.AddRange(idTelemetry, fakeTelemetries); + + //assert + Assert.True(telemetryDataCache.CacheItemCount == expectedCacheItemCount); + } + + [Fact] + public void AddRange_ShouldReturn_ZeroAddedElementToCache() + { + //arrange + const int expectedCacheItemCount = 0; + + var idTelemetry = new Random().Next(1, 100); + var telemetryDataCacheType = telemetryDataCache.GetType(); + + telemetryDataCacheType.GetField("isLoading", BindingFlags.NonPublic | BindingFlags.Instance)?.SetValue(telemetryDataCache, true); + + //act + telemetryDataCache.AddRange(idTelemetry, fakeTelemetries); + + //assert + Assert.True(telemetryDataCache.CacheItemCount == expectedCacheItemCount); + } +} \ No newline at end of file From c7a1a62bcd1d4cce57ad3a16ad5c48424b776365 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D1=82=D0=B5=D0=BF=D0=B0=D0=BD=D0=BE=D0=B2=20=D0=94?= =?UTF-8?q?=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9?= Date: Tue, 24 Oct 2023 11:37:23 +0500 Subject: [PATCH 2/4] fix merge --- AsbCloudInfrastructure/Services/WellboreService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AsbCloudInfrastructure/Services/WellboreService.cs b/AsbCloudInfrastructure/Services/WellboreService.cs index 4417dd49..4cbf06fa 100644 --- a/AsbCloudInfrastructure/Services/WellboreService.cs +++ b/AsbCloudInfrastructure/Services/WellboreService.cs @@ -13,7 +13,7 @@ namespace AsbCloudInfrastructure.Services; public class WellboreService : IWellboreService { - const string WellboreNameFormat = " {0}"; + const string WellboreNameFormat = "Ствол {0}"; private readonly IWellService wellService; private readonly IWellOperationRepository wellOperationRepository; private readonly ITelemetryDataCache telemetryDataCache; From 26f01eb2365f267400d1407c28e95b98473c5879 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D1=82=D0=B5=D0=BF=D0=B0=D0=BD=D0=BE=D0=B2=20=D0=94?= =?UTF-8?q?=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9?= Date: Tue, 24 Oct 2023 16:44:24 +0500 Subject: [PATCH 3/4] =?UTF-8?q?=D0=9F=D1=80=D0=B0=D0=B2=D0=BA=D0=B8=20?= =?UTF-8?q?=D0=BF=D0=BE=D1=81=D0=BB=D0=B5=20=D1=80=D0=B5=D0=B2=D1=8C=D1=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Services/SAUB/TelemetryDataCache.cs | 2 - .../AsbCloudWebApi.Tests.csproj | 1 - .../SAUB/TelemetryDataSaubCacheTests.cs | 50 +++++++++---------- 3 files changed, 23 insertions(+), 30 deletions(-) diff --git a/AsbCloudInfrastructure/Services/SAUB/TelemetryDataCache.cs b/AsbCloudInfrastructure/Services/SAUB/TelemetryDataCache.cs index 154b70d2..22b65694 100644 --- a/AsbCloudInfrastructure/Services/SAUB/TelemetryDataCache.cs +++ b/AsbCloudInfrastructure/Services/SAUB/TelemetryDataCache.cs @@ -38,8 +38,6 @@ namespace AsbCloudInfrastructure.Services.SAUB private static TelemetryDataCache? instance; - public int CacheItemCount => caches.Count; - public static TelemetryDataCache GetInstance(IServiceProvider provider) where TEntity : class, AsbCloudDb.Model.ITelemetryData { diff --git a/AsbCloudWebApi.Tests/AsbCloudWebApi.Tests.csproj b/AsbCloudWebApi.Tests/AsbCloudWebApi.Tests.csproj index 4024a917..4cf2783e 100644 --- a/AsbCloudWebApi.Tests/AsbCloudWebApi.Tests.csproj +++ b/AsbCloudWebApi.Tests/AsbCloudWebApi.Tests.csproj @@ -9,7 +9,6 @@ - diff --git a/AsbCloudWebApi.Tests/ServicesTests/SAUB/TelemetryDataSaubCacheTests.cs b/AsbCloudWebApi.Tests/ServicesTests/SAUB/TelemetryDataSaubCacheTests.cs index a5e9f12a..94975e85 100644 --- a/AsbCloudWebApi.Tests/ServicesTests/SAUB/TelemetryDataSaubCacheTests.cs +++ b/AsbCloudWebApi.Tests/ServicesTests/SAUB/TelemetryDataSaubCacheTests.cs @@ -6,7 +6,6 @@ using AsbCloudApp.Data.SAUB; using AsbCloudDb.Model; using AsbCloudInfrastructure.Background; using AsbCloudInfrastructure.Services.SAUB; -using Bogus; using Microsoft.Extensions.DependencyInjection; using NSubstitute; using Xunit; @@ -15,55 +14,52 @@ namespace AsbCloudWebApi.Tests.ServicesTests.SAUB; public class TelemetryDataSaubCacheTests { - private readonly IEnumerable fakeTelemetries = new Faker() - .RuleFor(t => t.DateTime, DateTime.UtcNow) - .Generate(5) - .OrderBy(t => t.DateTime); - - private readonly IServiceProvider serviceProvider = Substitute.For(); + private const int idTelemetry = 1; + + private readonly IEnumerable fakeTelemetries = new[] + { + new TelemetryDataSaubDto() + }; + + private readonly IServiceProvider serviceProviderMock = Substitute.For(); private readonly TelemetryDataCache telemetryDataCache; - + private readonly Type telemetryDataCacheType; + public TelemetryDataSaubCacheTests() { - serviceProvider.GetService().Returns(new BackgroundWorker(serviceProvider)); + serviceProviderMock.GetService().Returns(new BackgroundWorker(serviceProviderMock)); - telemetryDataCache = TelemetryDataCache.GetInstance(serviceProvider); + telemetryDataCache = TelemetryDataCache.GetInstance(serviceProviderMock); + + telemetryDataCacheType = telemetryDataCache.GetType(); } [Fact] - public void AddRange_ShouldReturn_OneAddedElementToCache() + public void AddRange_ShouldReturn_AddedElementToCache() { //arrange - const int expectedCacheItemCount = 1; - - var idTelemetry = new Random().Next(1, 100); - var telemetryDataCacheType = telemetryDataCache.GetType(); - telemetryDataCacheType.GetField("isLoading", BindingFlags.NonPublic | BindingFlags.Instance)?.SetValue(telemetryDataCache, false); //act telemetryDataCache.AddRange(idTelemetry, fakeTelemetries); - + var lastTelemetry = telemetryDataCache.GetLastOrDefault(idTelemetry); + //assert - Assert.True(telemetryDataCache.CacheItemCount == expectedCacheItemCount); + Assert.Equal(lastTelemetry, fakeTelemetries.Last()); } [Fact] - public void AddRange_ShouldReturn_ZeroAddedElementToCache() + public void AddRange_ShouldReturn_NotAddedToCache() { //arrange - const int expectedCacheItemCount = 0; - - var idTelemetry = new Random().Next(1, 100); - var telemetryDataCacheType = telemetryDataCache.GetType(); - telemetryDataCacheType.GetField("isLoading", BindingFlags.NonPublic | BindingFlags.Instance)?.SetValue(telemetryDataCache, true); - + //act telemetryDataCache.AddRange(idTelemetry, fakeTelemetries); - + var lastTelemetry = telemetryDataCache.GetLastOrDefault(idTelemetry); + //assert - Assert.True(telemetryDataCache.CacheItemCount == expectedCacheItemCount); + Assert.NotEqual(lastTelemetry, fakeTelemetries.Last()); } } \ No newline at end of file From 8d17a88f3def3ef9541583a40aafbd075df120da Mon Sep 17 00:00:00 2001 From: ngfrolov Date: Thu, 26 Oct 2023 09:13:56 +0500 Subject: [PATCH 4/4] Fix TelemetryDataCache.InitializeCacheFromDBAsync --- .../Services/SAUB/TelemetryDataCache.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/AsbCloudInfrastructure/Services/SAUB/TelemetryDataCache.cs b/AsbCloudInfrastructure/Services/SAUB/TelemetryDataCache.cs index 22b65694..0946de01 100644 --- a/AsbCloudInfrastructure/Services/SAUB/TelemetryDataCache.cs +++ b/AsbCloudInfrastructure/Services/SAUB/TelemetryDataCache.cs @@ -163,15 +163,16 @@ namespace AsbCloudInfrastructure.Services.SAUB private async Task InitializeCacheFromDBAsync(IAsbCloudDbContext db, Action onProgress, CancellationToken token) where TEntity : class, AsbCloudDb.Model.ITelemetryData { - try - { - if (isLoading) - throw new Exception("Multiple cache loading detected."); + var defaultTimeout = db.Database.GetCommandTimeout(); + db.Database.SetCommandTimeout(TimeSpan.FromMinutes(5)); + if (isLoading) + throw new Exception("Multiple cache loading detected."); + + try + { isLoading = true; - db.Database.SetCommandTimeout(TimeSpan.FromMinutes(5)); - Well[] wells = await db.Set() .Include(well => well.Telemetry) .Include(well => well.Cluster) @@ -198,7 +199,6 @@ namespace AsbCloudInfrastructure.Services.SAUB finally { isLoading = false; - var defaultTimeout = db.Database.GetCommandTimeout(); db.Database.SetCommandTimeout(defaultTimeout); } }