Files
Umbraco-CMS/tests/Umbraco.Tests.Integration/DependencyInjection/UmbracoBuilderExtensions.cs

219 lines
8.9 KiB
C#
Raw Permalink Normal View History

// Copyright (c) Umbraco.
// See LICENSE for more details.
Examine 2.0 integration (#10241) * Init commit for examine 2.0 work, most old umb examine tests working, probably a lot that doesn't * Gets Umbraco Examine tests passing and makes some sense out of them, fixes some underlying issues. * Large refactor, remove TaskHelper, rename Notifications to be consistent, Gets all examine/lucene indexes building and startup ordered in the correct way, removes old files, creates new IUmbracoIndexingHandler for abstracting out all index operations for umbraco data, abstracts out IIndexRebuilder, Fixes Stack overflow with LiveModelsProvider and loading assemblies, ports some changes from v8 for startup handling with cold boots, refactors out LastSyncedFileManager * fix up issues with rebuilding and management dashboard. * removes old files, removes NetworkHelper, fixes LastSyncedFileManager implementation to ensure the machine name is used, fix up logging with cold boot state. * Makes MainDom safer to use and makes PublishedSnapshotService lazily register with MainDom * lazily acquire application id (fix unit tests) * Fixes resource casing and missing test file * Ensures caches when requiring internal services for PublishedSnapshotService, UseNuCache is a separate call, shouldn't be buried in AddWebComponents, was also causing issues in integration tests since nucache was being used for the Id2Key service. * For UmbracoTestServerTestBase enable nucache services * Fixing tests * Fix another test * Fixes tests, use TestHostingEnvironment, make Tests.Common use net5, remove old Lucene.Net.Contrib ref. * Fixes up some review notes * Fixes issue with doubly registering PublishedSnapshotService meanig there could be 2x instances of it * Checks for parseexception when executing the query * Use application root instead of duplicating functionality. * Added Examine project to netcore only solution file * Fixed casing issue with LazyLoad, that is not lowercase. * uses cancellationToken instead of bool flag, fixes always reading lastId from the LastSyncedFileManager, fixes RecurringHostedServiceBase so that there isn't an overlapping thread for the same task type * Fix tests * remove legacy test project from solution file * Fix test Co-authored-by: Bjarke Berg <mail@bergmania.dk>
2021-05-18 18:31:38 +10:00
using Examine;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.Logging;
2020-09-08 13:03:43 +02:00
using Microsoft.Extensions.Options;
using Moq;
using NUnit.Framework;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Cache;
using Umbraco.Cms.Core.Cache.PartialViewCacheInvalidators;
using Umbraco.Cms.Core.Composing;
using Umbraco.Cms.Core.Configuration.Models;
using Umbraco.Cms.Core.DistributedLocking;
using Umbraco.Cms.Core.Logging;
using Umbraco.Cms.Core.Runtime;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Core.Sync;
2021-02-12 10:57:50 +01:00
using Umbraco.Cms.Infrastructure.Examine;
using Umbraco.Cms.Infrastructure.HostedServices;
using Umbraco.Cms.Infrastructure.PublishedCache;
using Umbraco.Cms.Persistence.EFCore.Locking;
using Umbraco.Cms.Persistence.EFCore.Scoping;
using Umbraco.Cms.Tests.Common.TestHelpers.Stubs;
using Umbraco.Cms.Tests.Integration.Implementations;
using Umbraco.Cms.Tests.Integration.Testing;
using Umbraco.Cms.Tests.Integration.Umbraco.Persistence.EFCore.DbContext;
2020-04-03 13:16:01 +11:00
namespace Umbraco.Cms.Tests.Integration.DependencyInjection;
/// <summary>
/// This is used to replace certain services that are normally registered from our Core / Infrastructure that
/// we do not want active within integration tests
/// </summary>
public static class UmbracoBuilderExtensions
2020-04-03 13:16:01 +11:00
{
/// <summary>
/// Uses/Replaces services with testing services
2020-04-03 13:16:01 +11:00
/// </summary>
public static IUmbracoBuilder AddTestServices(this IUmbracoBuilder builder, TestHelper testHelper)
2020-04-03 13:16:01 +11:00
{
builder.Services.AddUnique(AppCaches.NoCache);
builder.Services.AddUnique(Mock.Of<IMemberPartialViewCacheInvalidator>());
builder.Services.AddUnique(Mock.Of<IUmbracoBootPermissionChecker>());
builder.Services.AddUnique(testHelper.MainDom);
builder.Services.AddUnique<IIndexRebuilder, TestBackgroundIndexRebuilder>();
#if IS_WINDOWS
// ensure all lucene indexes are using RAM directory (no file system)
builder.Services.AddUnique<IDirectoryFactory, LuceneRAMDirectoryFactory>();
#endif
// replace this service so that it can lookup the correct file locations
builder.Services.AddUnique(GetLocalizedTextService);
builder.Services.AddUnique<IServerMessenger, NoopServerMessenger>();
builder.Services.AddUnique<IProfiler, TestProfiler>();
builder.Services.AddDbContext<TestUmbracoDbContext>(
(serviceProvider, options) =>
{
var testDatabaseType = builder.Config.GetValue<TestDatabaseSettings.TestDatabaseType>("Tests:Database:DatabaseType");
if (testDatabaseType is TestDatabaseSettings.TestDatabaseType.Sqlite)
{
options.UseSqlite(serviceProvider.GetRequiredService<IOptionsMonitor<ConnectionStrings>>().CurrentValue.ConnectionString);
}
else
{
// If not Sqlite, assume SqlServer
options.UseSqlServer(serviceProvider.GetRequiredService<IOptionsMonitor<ConnectionStrings>>().CurrentValue.ConnectionString);
}
},
optionsLifetime: ServiceLifetime.Singleton);
builder.Services.AddDbContextFactory<TestUmbracoDbContext>(
(serviceProvider, options) =>
{
var testDatabaseType = builder.Config.GetValue<TestDatabaseSettings.TestDatabaseType>("Tests:Database:DatabaseType");
if (testDatabaseType is TestDatabaseSettings.TestDatabaseType.Sqlite)
{
options.UseSqlite(serviceProvider.GetRequiredService<IOptionsMonitor<ConnectionStrings>>().CurrentValue.ConnectionString);
}
else
{
// If not Sqlite, assume SqlServer
options.UseSqlServer(serviceProvider.GetRequiredService<IOptionsMonitor<ConnectionStrings>>().CurrentValue.ConnectionString);
}
});
builder.Services.AddUnique<IAmbientEFCoreScopeStack<TestUmbracoDbContext>, AmbientEFCoreScopeStack<TestUmbracoDbContext>>();
builder.Services.AddUnique<IEFCoreScopeAccessor<TestUmbracoDbContext>, EFCoreScopeAccessor<TestUmbracoDbContext>>();
builder.Services.AddUnique<IEFCoreScopeProvider<TestUmbracoDbContext>, EFCoreScopeProvider<TestUmbracoDbContext>>();
builder.Services.AddSingleton<IDistributedLockingMechanism, SqliteEFCoreDistributedLockingMechanism<TestUmbracoDbContext>>();
builder.Services.AddSingleton<IDistributedLockingMechanism, SqlServerEFCoreDistributedLockingMechanism<TestUmbracoDbContext>>();
builder.Services.AddSingleton<IReservedFieldNamesService, ReservedFieldNamesService>();
return builder;
}
/// <summary>
/// Used to register a replacement for <see cref="ILocalizedTextService" /> where the file sources are the ones within
/// the netcore project so
/// we don't need to copy files
/// </summary>
private static ILocalizedTextService GetLocalizedTextService(IServiceProvider factory)
{
var loggerFactory = factory.GetRequiredService<ILoggerFactory>();
var appCaches = factory.GetRequiredService<AppCaches>();
var localizedTextService = new LocalizedTextService(
new Lazy<LocalizedTextServiceFileSources>(() =>
{
// get the src folder
var root = TestContext.CurrentContext.TestDirectory.Split("tests")[0];
var srcFolder = Path.Combine(root, "src");
var currFolder = new DirectoryInfo(srcFolder);
if (!currFolder.Exists)
{
// When Umbraco.Integration.Tests is installed in a "consumer" Umbraco site, the src/tests path might not be there.
// This replaces the folder reference with an empty folder under temp
// such that the LocalizedTextServiceFileSources don't blow up from directory not found,
// or reading random xml files from the base temp folder.
var tempPath = Path.GetTempPath();
currFolder = new DirectoryInfo(Path.GetFullPath("Umbraco.Integration.Tests.Fake.SrcRoot", tempPath));
currFolder.Create();
}
return new LocalizedTextServiceFileSources(
loggerFactory.CreateLogger<LocalizedTextServiceFileSources>(),
appCaches,
currFolder,
Array.Empty<LocalizedTextServiceSupplementaryFileSource>(),
new EmbeddedFileProvider(typeof(IAssemblyProvider).Assembly, "Umbraco.Cms.Core.EmbeddedResources.Lang").GetDirectoryContents(string.Empty));
}),
loggerFactory.CreateLogger<LocalizedTextService>());
return localizedTextService;
}
// replace the default so there is no background index rebuilder
private sealed class TestBackgroundIndexRebuilder : ExamineIndexRebuilder
{
public TestBackgroundIndexRebuilder(
IMainDom mainDom,
IRuntimeState runtimeState,
ILogger<ExamineIndexRebuilder> logger,
IExamineManager examineManager,
IEnumerable<IIndexPopulator> populators,
Use new submit and poll solution for examine index rebuild (#19707) * Started implementing new LongRunningOperationService and adjusting tasks to use this service This service will manage operations that require status to be synced between servers (load balanced setup). * Missing migration to add new lock. Other simplifications. * Add job to cleanup the LongRunningOperations entries * Add new DatabaseCacheRebuilder.RebuildAsync method This is both async and returns an attempt, which will fail if a rebuild operation is already running. * Missing LongRunningOperation database table creation on clean install * Store expire date in the long running operation. Better handling of non-background operations. Storing an expiration date allows setting different expiration times depending on the type of operation, and whether it is running in the background or not. * Added integration tests for LongRunningOperationRepository * Added unit tests for LongRunningOperationService * Add type as a parameter to more repository calls. Distinguish between expiration and deletion in `LongRunningOperationRepository.CleanOperations`. * Fix failing unit test * Fixed `PerformPublishBranchAsync` result not being deserialized correctly * Remove unnecessary DatabaseCacheRebuildResult value * Add status to `LongRunningOperationService.GetResult` attempt to inform on why a result could not be retrieved * General improvements * Missing rename * Improve the handling of long running operations that are not in background and stale operations * Fix failing unit tests * Fixed small mismatch between interface and implementation * Use the new submit and poll functionality for the Examine index rebuild * Use a fire and forget task instead of the background queue * Apply suggestions from code review Co-authored-by: Andy Butland <abutland73@gmail.com> * Make sure exceptions are caught when running in the background * Alignment with other repositories (async + pagination) * Fix build after merge * Missing obsoletion messages * Additional fixes * Add Async suffix to service methods * Missing adjustment * Moved hardcoded settings to IOptions * Fix issue in SQL Server where 0 is not accepted as requested number of rows * Fix issue in SQL Server where query provided to count cannot contain orderby * Additional SQL Server fixes * Update method names * Adjustments from code review * Ignoring result of index rebuild in `IndexingNotificationHandler.Language.cs` (same behavior as before) * Missed some obsoletion messages --------- Co-authored-by: Andy Butland <abutland73@gmail.com>
2025-07-24 14:30:14 +02:00
ILongRunningOperationService longRunningOperationService)
: base(
mainDom,
runtimeState,
logger,
examineManager,
populators,
Use new submit and poll solution for examine index rebuild (#19707) * Started implementing new LongRunningOperationService and adjusting tasks to use this service This service will manage operations that require status to be synced between servers (load balanced setup). * Missing migration to add new lock. Other simplifications. * Add job to cleanup the LongRunningOperations entries * Add new DatabaseCacheRebuilder.RebuildAsync method This is both async and returns an attempt, which will fail if a rebuild operation is already running. * Missing LongRunningOperation database table creation on clean install * Store expire date in the long running operation. Better handling of non-background operations. Storing an expiration date allows setting different expiration times depending on the type of operation, and whether it is running in the background or not. * Added integration tests for LongRunningOperationRepository * Added unit tests for LongRunningOperationService * Add type as a parameter to more repository calls. Distinguish between expiration and deletion in `LongRunningOperationRepository.CleanOperations`. * Fix failing unit test * Fixed `PerformPublishBranchAsync` result not being deserialized correctly * Remove unnecessary DatabaseCacheRebuildResult value * Add status to `LongRunningOperationService.GetResult` attempt to inform on why a result could not be retrieved * General improvements * Missing rename * Improve the handling of long running operations that are not in background and stale operations * Fix failing unit tests * Fixed small mismatch between interface and implementation * Use the new submit and poll functionality for the Examine index rebuild * Use a fire and forget task instead of the background queue * Apply suggestions from code review Co-authored-by: Andy Butland <abutland73@gmail.com> * Make sure exceptions are caught when running in the background * Alignment with other repositories (async + pagination) * Fix build after merge * Missing obsoletion messages * Additional fixes * Add Async suffix to service methods * Missing adjustment * Moved hardcoded settings to IOptions * Fix issue in SQL Server where 0 is not accepted as requested number of rows * Fix issue in SQL Server where query provided to count cannot contain orderby * Additional SQL Server fixes * Update method names * Adjustments from code review * Ignoring result of index rebuild in `IndexingNotificationHandler.Language.cs` (same behavior as before) * Missed some obsoletion messages --------- Co-authored-by: Andy Butland <abutland73@gmail.com>
2025-07-24 14:30:14 +02:00
longRunningOperationService)
{
}
Examine 2.0 integration (#10241) * Init commit for examine 2.0 work, most old umb examine tests working, probably a lot that doesn't * Gets Umbraco Examine tests passing and makes some sense out of them, fixes some underlying issues. * Large refactor, remove TaskHelper, rename Notifications to be consistent, Gets all examine/lucene indexes building and startup ordered in the correct way, removes old files, creates new IUmbracoIndexingHandler for abstracting out all index operations for umbraco data, abstracts out IIndexRebuilder, Fixes Stack overflow with LiveModelsProvider and loading assemblies, ports some changes from v8 for startup handling with cold boots, refactors out LastSyncedFileManager * fix up issues with rebuilding and management dashboard. * removes old files, removes NetworkHelper, fixes LastSyncedFileManager implementation to ensure the machine name is used, fix up logging with cold boot state. * Makes MainDom safer to use and makes PublishedSnapshotService lazily register with MainDom * lazily acquire application id (fix unit tests) * Fixes resource casing and missing test file * Ensures caches when requiring internal services for PublishedSnapshotService, UseNuCache is a separate call, shouldn't be buried in AddWebComponents, was also causing issues in integration tests since nucache was being used for the Id2Key service. * For UmbracoTestServerTestBase enable nucache services * Fixing tests * Fix another test * Fixes tests, use TestHostingEnvironment, make Tests.Common use net5, remove old Lucene.Net.Contrib ref. * Fixes up some review notes * Fixes issue with doubly registering PublishedSnapshotService meanig there could be 2x instances of it * Checks for parseexception when executing the query * Use application root instead of duplicating functionality. * Added Examine project to netcore only solution file * Fixed casing issue with LazyLoad, that is not lowercase. * uses cancellationToken instead of bool flag, fixes always reading lastId from the LastSyncedFileManager, fixes RecurringHostedServiceBase so that there isn't an overlapping thread for the same task type * Fix tests * remove legacy test project from solution file * Fix test Co-authored-by: Bjarke Berg <mail@bergmania.dk>
2021-05-18 18:31:38 +10:00
public override void RebuildIndex(string indexName, TimeSpan? delay = null, bool useBackgroundThread = true)
{
// noop
2020-04-03 13:16:01 +11:00
}
public override void RebuildIndexes(bool onlyEmptyIndexes, TimeSpan? delay = null, bool useBackgroundThread = true)
{
// noop
}
}
private class NoopServerMessenger : IServerMessenger
{
public void QueueRefresh<TPayload>(ICacheRefresher refresher, TPayload[] payload)
{
}
public void QueueRefresh<T>(ICacheRefresher refresher, Func<T, int> getNumericId, params T[] instances)
{
}
public void QueueRefresh<T>(ICacheRefresher refresher, Func<T, Guid> getGuidId, params T[] instances)
{
}
public void QueueRemove<T>(ICacheRefresher refresher, Func<T, int> getNumericId, params T[] instances)
{
}
public void QueueRemove(ICacheRefresher refresher, params int[] numericIds)
{
}
public void QueueRefresh(ICacheRefresher refresher, params int[] numericIds)
{
}
public void QueueRefresh(ICacheRefresher refresher, params Guid[] guidIds)
{
}
public void QueueRefreshAll(ICacheRefresher refresher)
{
}
public void Sync() { }
public void SendMessages() { }
2020-04-03 13:16:01 +11:00
}
}