diff --git a/src/Umbraco.Core/PublishedCache/IPublishedSnapshotService.cs b/src/Umbraco.Core/PublishedCache/IPublishedSnapshotService.cs
index a953c7677e..af8f72ce6d 100644
--- a/src/Umbraco.Core/PublishedCache/IPublishedSnapshotService.cs
+++ b/src/Umbraco.Core/PublishedCache/IPublishedSnapshotService.cs
@@ -24,13 +24,9 @@ namespace Umbraco.Web.PublishedCache
*/
///
- /// Loads the caches on startup - called once during startup
- /// TODO: Temporary, this is temporal coupling, we cannot use IUmbracoApplicationLifetime.ApplicationInit (which we want to delete)
- /// handler because that is executed with netcore's IHostApplicationLifetime.ApplicationStarted mechanism which fires async
- /// which we don't want since this will not have initialized before our endpoints execute. So for now this is explicitly
- /// called on UseUmbracoContentCaching on startup.
+ /// Gets the published snapshot accessor.
///
- void LoadCachesOnStartup();
+ IPublishedSnapshotAccessor PublishedSnapshotAccessor { get; }
///
/// Creates a published snapshot.
@@ -42,11 +38,6 @@ namespace Umbraco.Web.PublishedCache
/// which is not specified and depends on the actual published snapshot service implementation.
IPublishedSnapshot CreatePublishedSnapshot(string previewToken);
- ///
- /// Gets the published snapshot accessor.
- ///
- IPublishedSnapshotAccessor PublishedSnapshotAccessor { get; }
-
///
/// Ensures that the published snapshot has the proper environment to run.
///
@@ -54,17 +45,15 @@ namespace Umbraco.Web.PublishedCache
/// A value indicating whether the published snapshot has the proper environment to run.
bool EnsureEnvironment(out IEnumerable errors);
- #region Rebuild
-
///
- /// Rebuilds internal caches (but does not reload).
+ /// Rebuilds internal database caches (but does not reload).
///
/// The operation batch size to process the items
/// If not null will process content for the matching content types, if empty will process all content
/// If not null will process content for the matching media types, if empty will process all media
/// If not null will process content for the matching members types, if empty will process all members
///
- /// Forces the snapshot service to rebuild its internal caches. For instance, some caches
+ /// Forces the snapshot service to rebuild its internal database caches. For instance, some caches
/// may rely on a database table to store pre-serialized version of documents.
/// This does *not* reload the caches. Caches need to be reloaded, for instance via
/// RefreshAllPublishedSnapshot method.
@@ -75,10 +64,6 @@ namespace Umbraco.Web.PublishedCache
IReadOnlyCollection mediaTypeIds = null,
IReadOnlyCollection memberTypeIds = null);
- #endregion
-
- #region Changes
-
/* An IPublishedCachesService implementation can rely on transaction-level events to update
* its internal, database-level data, as these events are purely internal. However, it cannot
* rely on cache refreshers CacheUpdated events to update itself, as these events are external
@@ -123,8 +108,6 @@ namespace Umbraco.Web.PublishedCache
/// The changes.
void Notify(DomainCacheRefresher.JsonPayload[] payloads);
- #endregion
-
// TODO: This is weird, why is this is this a thing? Maybe IPublishedSnapshotStatus?
string GetStatus();
diff --git a/src/Umbraco.Core/PublishedCache/PublishedSnapshotServiceBase.cs b/src/Umbraco.Core/PublishedCache/PublishedSnapshotServiceBase.cs
index d334e69775..f33eb61e8f 100644
--- a/src/Umbraco.Core/PublishedCache/PublishedSnapshotServiceBase.cs
+++ b/src/Umbraco.Core/PublishedCache/PublishedSnapshotServiceBase.cs
@@ -6,6 +6,7 @@ using Umbraco.Web.Cache;
namespace Umbraco.Web.PublishedCache
{
+ // TODO: This base class probably shouldn't exist
public abstract class PublishedSnapshotServiceBase : IPublishedSnapshotService
{
///
@@ -51,15 +52,12 @@ namespace Umbraco.Web.PublishedCache
///
public abstract void Notify(DomainCacheRefresher.JsonPayload[] payloads);
- // TODO: Why is this virtual?
-
///
- public virtual void Rebuild(
+ public abstract void Rebuild(
int groupSize = 5000,
IReadOnlyCollection contentTypeIds = null,
IReadOnlyCollection mediaTypeIds = null,
- IReadOnlyCollection memberTypeIds = null)
- { }
+ IReadOnlyCollection memberTypeIds = null);
///
public virtual void Dispose()
@@ -76,6 +74,5 @@ namespace Umbraco.Web.PublishedCache
{
}
- public abstract void LoadCachesOnStartup();
}
}
diff --git a/src/Umbraco.Core/PublishedCache/UmbracoContextPublishedSnapshotAccessor.cs b/src/Umbraco.Core/PublishedCache/UmbracoContextPublishedSnapshotAccessor.cs
index 7e0ebc6f13..874da1f3aa 100644
--- a/src/Umbraco.Core/PublishedCache/UmbracoContextPublishedSnapshotAccessor.cs
+++ b/src/Umbraco.Core/PublishedCache/UmbracoContextPublishedSnapshotAccessor.cs
@@ -1,6 +1,11 @@
-using System;
+using System;
namespace Umbraco.Web.PublishedCache
{
+ // TODO: This is a mess. This is a circular reference:
+ // IPublishedSnapshotAccessor -> PublishedSnapshotService -> UmbracoContext -> PublishedSnapshotService -> IPublishedSnapshotAccessor
+ // Injecting IPublishedSnapshotAccessor into PublishedSnapshotService seems pretty strange
+ // The underlying reason for this mess is because IPublishedContent is both a service and a model.
+ // Until that is fixed, IPublishedContent will need to have a IPublishedSnapshotAccessor
public class UmbracoContextPublishedSnapshotAccessor : IPublishedSnapshotAccessor
{
private readonly IUmbracoContextAccessor _umbracoContextAccessor;
diff --git a/src/Umbraco.PublishedCache.NuCache/Persistence/INuCacheContentService.cs b/src/Umbraco.PublishedCache.NuCache/Persistence/INuCacheContentService.cs
index 0ac3939742..4a3f5b2b5d 100644
--- a/src/Umbraco.PublishedCache.NuCache/Persistence/INuCacheContentService.cs
+++ b/src/Umbraco.PublishedCache.NuCache/Persistence/INuCacheContentService.cs
@@ -75,7 +75,7 @@ namespace Umbraco.Infrastructure.PublishedCache.Persistence
void RefreshEntity(IContentBase content);
///
- /// Rebuilds the caches for content, media and/or members based on the content type ids specified
+ /// Rebuilds the database caches for content, media and/or members based on the content type ids specified
///
/// The operation batch size to process the items
/// If not null will process content for the matching content types, if empty will process all content
diff --git a/src/Umbraco.PublishedCache.NuCache/Property.cs b/src/Umbraco.PublishedCache.NuCache/Property.cs
index 86023bb302..1b70c6504c 100644
--- a/src/Umbraco.PublishedCache.NuCache/Property.cs
+++ b/src/Umbraco.PublishedCache.NuCache/Property.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Generic;
using System.Xml.Serialization;
using Umbraco.Core;
@@ -158,6 +158,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
default:
throw new InvalidOperationException("Invalid cache level.");
}
+
return cacheValues;
}
diff --git a/src/Umbraco.PublishedCache.NuCache/PublishedContent.cs b/src/Umbraco.PublishedCache.NuCache/PublishedContent.cs
index 6fe65a4ff5..9cdc0db4fa 100644
--- a/src/Umbraco.PublishedCache.NuCache/PublishedContent.cs
+++ b/src/Umbraco.PublishedCache.NuCache/PublishedContent.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Generic;
using System.Linq;
using Umbraco.Core;
@@ -43,7 +43,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
// add one property per property type - this is required, for the indexing to work
// if contentData supplies pdatas, use them, else use null
contentData.Properties.TryGetValue(propertyType.Alias, out var pdatas); // else will be null
- properties[i++] =new Property(propertyType, this, pdatas, _publishedSnapshotAccessor);
+ properties[i++] = new Property(propertyType, this, pdatas, _publishedSnapshotAccessor);
}
PropertiesArray = properties;
}
diff --git a/src/Umbraco.PublishedCache.NuCache/PublishedSnapshotService.cs b/src/Umbraco.PublishedCache.NuCache/PublishedSnapshotService.cs
index cb5fed176e..6225e68ec6 100644
--- a/src/Umbraco.PublishedCache.NuCache/PublishedSnapshotService.cs
+++ b/src/Umbraco.PublishedCache.NuCache/PublishedSnapshotService.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
+using System.Threading;
using CSharpTest.Net.Collections;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
@@ -46,7 +47,9 @@ namespace Umbraco.Web.PublishedCache.NuCache
private readonly NuCacheSettings _config;
// volatile because we read it with no lock
- private volatile bool _isReady;
+ private bool _isReady;
+ private bool _isReadSet;
+ private object _isReadyLock;
private readonly ContentStore _contentStore;
private readonly ContentStore _mediaStore;
@@ -139,20 +142,20 @@ namespace Umbraco.Web.PublishedCache.NuCache
}
}
- #region Id <-> Key methods
-
// NOTE: These aren't used within this object but are made available internally to improve the IdKey lookup performance
// when nucache is enabled.
- // TODO: Does this need to be here?
-
+ // TODO: Does this need to be here?
internal int GetDocumentId(Guid udi) => GetId(_contentStore, udi);
- internal int GetMediaId(Guid udi) => GetId(_mediaStore, udi);
- internal Guid GetDocumentUid(int id) => GetUid(_contentStore, id);
- internal Guid GetMediaUid(int id) => GetUid(_mediaStore, id);
- private int GetId(ContentStore store, Guid uid) => store.LiveSnapshot.Get(uid)?.Id ?? 0;
- private Guid GetUid(ContentStore store, int id) => store.LiveSnapshot.Get(id)?.Uid ?? Guid.Empty;
- #endregion
+ internal int GetMediaId(Guid udi) => GetId(_mediaStore, udi);
+
+ internal Guid GetDocumentUid(int id) => GetUid(_contentStore, id);
+
+ internal Guid GetMediaUid(int id) => GetUid(_mediaStore, id);
+
+ private int GetId(ContentStore store, Guid uid) => store.LiveSnapshot.Get(uid)?.Id ?? 0;
+
+ private Guid GetUid(ContentStore store, int id) => store.LiveSnapshot.Get(id)?.Uid ?? Guid.Empty;
///
/// Install phase of
@@ -204,66 +207,6 @@ namespace Umbraco.Web.PublishedCache.NuCache
}
}
- ///
- /// Populates the stores
- ///
- public override void LoadCachesOnStartup()
- {
- lock (_storesLock)
- {
- if (_isReady)
- {
- throw new InvalidOperationException("The caches can only be loaded on startup one time");
- }
-
- var okContent = false;
- var okMedia = false;
-
- try
- {
- if (_localContentDbExists)
- {
- okContent = LockAndLoadContent(() => LoadContentFromLocalDbLocked(true));
- if (!okContent)
- {
- _logger.LogWarning("Loading content from local db raised warnings, will reload from database.");
- }
- }
-
- if (_localMediaDbExists)
- {
- okMedia = LockAndLoadMedia(() => LoadMediaFromLocalDbLocked(true));
- if (!okMedia)
- {
- _logger.LogWarning("Loading media from local db raised warnings, will reload from database.");
- }
- }
-
- if (!okContent)
- {
- LockAndLoadContent(() => LoadContentFromDatabaseLocked(true));
- }
-
- if (!okMedia)
- {
- LockAndLoadMedia(() => LoadMediaFromDatabaseLocked(true));
- }
-
- LockAndLoadDomains();
- }
- catch (Exception ex)
- {
- _logger.LogCritical(ex, "Panic, exception while loading cache data.");
- throw;
- }
-
- // finally, cache is ready!
- _isReady = true;
- }
- }
-
- #region Local files
-
private string GetLocalFilesPath()
{
var path = Path.Combine(_hostingEnvironment.LocalTempPath, "NuCache");
@@ -278,7 +221,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
private void DeleteLocalFilesForContent()
{
- if (_isReady && _localContentDb != null)
+ if (Volatile.Read(ref _isReady) && _localContentDb != null)
{
throw new InvalidOperationException("Cannot delete local files while the cache uses them.");
}
@@ -293,7 +236,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
private void DeleteLocalFilesForMedia()
{
- if (_isReady && _localMediaDb != null)
+ if (Volatile.Read(ref _isReady) && _localMediaDb != null)
{
throw new InvalidOperationException("Cannot delete local files while the cache uses them.");
}
@@ -306,10 +249,6 @@ namespace Umbraco.Web.PublishedCache.NuCache
}
}
- #endregion
-
- #region Environment
-
public override bool EnsureEnvironment(out IEnumerable errors)
{
// must have app_data and be able to write files into it
@@ -318,9 +257,62 @@ namespace Umbraco.Web.PublishedCache.NuCache
return ok;
}
- #endregion
+ ///
+ /// Populates the stores
+ ///
+ private void EnsureCaches() => LazyInitializer.EnsureInitialized(
+ ref _isReady,
+ ref _isReadSet,
+ ref _isReadyLock,
+ () =>
+ {
+ // even though we are ready locked here we want to ensure that the stores lock is also locked
+ lock (_storesLock)
+ {
+ var okContent = false;
+ var okMedia = false;
- #region Populate Stores
+ try
+ {
+ if (_localContentDbExists)
+ {
+ okContent = LockAndLoadContent(() => LoadContentFromLocalDbLocked(true));
+ if (!okContent)
+ {
+ _logger.LogWarning("Loading content from local db raised warnings, will reload from database.");
+ }
+ }
+
+ if (_localMediaDbExists)
+ {
+ okMedia = LockAndLoadMedia(() => LoadMediaFromLocalDbLocked(true));
+ if (!okMedia)
+ {
+ _logger.LogWarning("Loading media from local db raised warnings, will reload from database.");
+ }
+ }
+
+ if (!okContent)
+ {
+ LockAndLoadContent(() => LoadContentFromDatabaseLocked(true));
+ }
+
+ if (!okMedia)
+ {
+ LockAndLoadMedia(() => LoadMediaFromDatabaseLocked(true));
+ }
+
+ LockAndLoadDomains();
+ }
+ catch (Exception ex)
+ {
+ _logger.LogCritical(ex, "Panic, exception while loading cache data.");
+ throw;
+ }
+
+ return true;
+ }
+ });
// sudden panic... but in RepeatableRead can a content that I haven't already read, be removed
// before I read it? NO! because the WHOLE content tree is read-locked using WithReadLocked.
@@ -482,10 +474,6 @@ namespace Umbraco.Web.PublishedCache.NuCache
}
}
- #endregion
-
- #region Handle Notifications
-
// note: if the service is not ready, ie _isReady is false, then notifications are ignored
// SetUmbracoVersionStep issues a DistributedCache.Instance.RefreshAll...() call which should cause
@@ -512,7 +500,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
public override void Notify(ContentCacheRefresher.JsonPayload[] payloads, out bool draftChanged, out bool publishedChanged)
{
// no cache, trash everything
- if (_isReady == false)
+ if (Volatile.Read(ref _isReady) == false)
{
DeleteLocalFilesForContent();
draftChanged = publishedChanged = true;
@@ -613,7 +601,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
public override void Notify(MediaCacheRefresher.JsonPayload[] payloads, out bool anythingChanged)
{
// no cache, trash everything
- if (_isReady == false)
+ if (Volatile.Read(ref _isReady) == false)
{
DeleteLocalFilesForMedia();
anythingChanged = true;
@@ -711,7 +699,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
public override void Notify(ContentTypeCacheRefresher.JsonPayload[] payloads)
{
// no cache, nothing we can do
- if (_isReady == false)
+ if (Volatile.Read(ref _isReady) == false)
{
return;
}
@@ -812,7 +800,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
public override void Notify(DataTypeCacheRefresher.JsonPayload[] payloads)
{
// no cache, nothing we can do
- if (_isReady == false)
+ if (Volatile.Read(ref _isReady) == false)
{
return;
}
@@ -856,7 +844,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
public override void Notify(DomainCacheRefresher.JsonPayload[] payloads)
{
// no cache, nothing we can do
- if (_isReady == false)
+ if (Volatile.Read(ref _isReady) == false)
{
return;
}
@@ -894,12 +882,9 @@ namespace Umbraco.Web.PublishedCache.NuCache
// Methods used to prevent allocations of lists
private void AddToList(ref List list, int val) => GetOrCreateList(ref list).Add(val);
+
private List GetOrCreateList(ref List list) => list ?? (list = new List());
- #endregion
-
- #region Content Types
-
private IReadOnlyCollection CreateContentTypes(PublishedItemType itemType, int[] ids)
{
// XxxTypeService.GetAll(empty) returns everything!
@@ -1028,14 +1013,12 @@ namespace Umbraco.Web.PublishedCache.NuCache
}
}
- #endregion
-
- #region Create, Get Published Snapshot
-
public override IPublishedSnapshot CreatePublishedSnapshot(string previewToken)
{
+ EnsureCaches();
+
// no cache, no joy
- if (_isReady == false)
+ if (Volatile.Read(ref _isReady) == false)
{
throw new InvalidOperationException("The published snapshot service has not properly initialized.");
}
@@ -1049,6 +1032,8 @@ namespace Umbraco.Web.PublishedCache.NuCache
// even though the underlying elements may not change (store snapshots)
public PublishedSnapshot.PublishedSnapshotElements GetElements(bool previewDefault)
{
+ EnsureCaches();
+
// note: using ObjectCacheAppCache for elements and snapshot caches
// is not recommended because it creates an inner MemoryCache which is a heavy
// thing - better use a dictionary-based cache which "just" creates a concurrent
@@ -1129,10 +1114,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
};
}
- #endregion
-
- #region Rebuild Database PreCache
-
+ ///
public override void Rebuild(
int groupSize = 5000,
IReadOnlyCollection contentTypeIds = null,
@@ -1176,12 +1158,10 @@ namespace Umbraco.Web.PublishedCache.NuCache
}
}
- #endregion
-
- #region Instrument
-
public override string GetStatus()
{
+ EnsureCaches();
+
var dbCacheIsOk = VerifyContentDbCache()
&& VerifyMediaDbCache()
&& VerifyMemberDbCache();
@@ -1203,20 +1183,26 @@ namespace Umbraco.Web.PublishedCache.NuCache
" and " + ms + " snapshot" + (ms > 1 ? "s" : "") + ".";
}
+ // TODO: This should be async since it's calling into async
public override void Collect()
{
+ EnsureCaches();
+
var contentCollect = _contentStore.CollectAsync();
var mediaCollect = _mediaStore.CollectAsync();
System.Threading.Tasks.Task.WaitAll(contentCollect, mediaCollect);
}
- #endregion
+ internal ContentStore GetContentStore()
+ {
+ EnsureCaches();
+ return _contentStore;
+ }
- #region Internals/Testing
-
- internal ContentStore GetContentStore() => _contentStore;
- internal ContentStore GetMediaStore() => _mediaStore;
-
- #endregion
+ internal ContentStore GetMediaStore()
+ {
+ EnsureCaches();
+ return _mediaStore;
+ }
}
}
diff --git a/src/Umbraco.PublishedCache.NuCache/PublishedSnapshotServiceEventHandler.cs b/src/Umbraco.PublishedCache.NuCache/PublishedSnapshotServiceEventHandler.cs
index 20ce74ea70..31bc9b3d63 100644
--- a/src/Umbraco.PublishedCache.NuCache/PublishedSnapshotServiceEventHandler.cs
+++ b/src/Umbraco.PublishedCache.NuCache/PublishedSnapshotServiceEventHandler.cs
@@ -40,10 +40,6 @@ namespace Umbraco.Web.PublishedCache.NuCache
return false;
}
- // this initializes the caches.
- // TODO: This is still temporal coupling (i.e. Initialize)
- _publishedSnapshotService.LoadCachesOnStartup();
-
// we always want to handle repository events, configured or not
// assuming no repository event will trigger before the whole db is ready
// (ideally we'd have Upgrading.App vs Upgrading.Data application states...)
diff --git a/src/Umbraco.Tests.Integration/TestServerTest/Controllers/ContentControllerTests.cs b/src/Umbraco.Tests.Integration/TestServerTest/Controllers/ContentControllerTests.cs
index 731079da7c..dbac7c9f76 100644
--- a/src/Umbraco.Tests.Integration/TestServerTest/Controllers/ContentControllerTests.cs
+++ b/src/Umbraco.Tests.Integration/TestServerTest/Controllers/ContentControllerTests.cs
@@ -1,4 +1,4 @@
-using System.Linq;
+using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
@@ -22,13 +22,12 @@ namespace Umbraco.Tests.Integration.TestServerTest.Controllers
///
/// Returns 404 if the content wasn't found based on the ID specified
///
- ///
[Test]
public async Task PostSave_Validate_Existing_Content()
{
var localizationService = GetRequiredService();
- //Add another language
+ // Add another language
localizationService.Save(new LanguageBuilder()
.WithCultureInfo("da-DK")
.WithIsDefault(false)
@@ -76,10 +75,10 @@ namespace Umbraco.Tests.Integration.TestServerTest.Controllers
// Assert
Assert.AreEqual(HttpStatusCode.NotFound, response.StatusCode);
-// Assert.AreEqual(")]}',\n{\"Message\":\"content was not found\"}", response.Item1.Content.ReadAsStringAsync().Result);
-//
-// //var obj = JsonConvert.DeserializeObject>(response.Item2);
-// //Assert.AreEqual(0, obj.TotalItems);
+ // Assert.AreEqual(")]}',\n{\"Message\":\"content was not found\"}", response.Item1.Content.ReadAsStringAsync().Result);
+ //
+ // //var obj = JsonConvert.DeserializeObject>(response.Item2);
+ // //Assert.AreEqual(0, obj.TotalItems);
}
[Test]
@@ -88,7 +87,7 @@ namespace Umbraco.Tests.Integration.TestServerTest.Controllers
var localizationService = GetRequiredService();
- //Add another language
+ // Add another language
localizationService.Save(new LanguageBuilder()
.WithCultureInfo("da-DK")
.WithIsDefault(false)
@@ -96,7 +95,6 @@ namespace Umbraco.Tests.Integration.TestServerTest.Controllers
var url = PrepareUrl(x => x.PostSave(null));
-
var contentTypeService = GetRequiredService();
var contentType = new ContentTypeBuilder()
@@ -128,7 +126,7 @@ namespace Umbraco.Tests.Integration.TestServerTest.Controllers
.Build();
// HERE we force the test to fail
- model.Variants = model.Variants.Select(x=>
+ model.Variants = model.Variants.Select(x =>
{
x.Save = false;
return x;
@@ -141,7 +139,6 @@ namespace Umbraco.Tests.Integration.TestServerTest.Controllers
});
// Assert
-
var body = await response.Content.ReadAsStringAsync();
Assert.Multiple(() =>
@@ -155,13 +152,12 @@ namespace Umbraco.Tests.Integration.TestServerTest.Controllers
///
/// Returns 404 if any of the posted properties dont actually exist
///
- ///
[Test]
public async Task PostSave_Validate_Properties_Exist()
{
var localizationService = GetRequiredService();
- //Add another language
+ // Add another language
localizationService.Save(new LanguageBuilder()
.WithCultureInfo("da-DK")
.WithIsDefault(false)
@@ -215,12 +211,11 @@ namespace Umbraco.Tests.Integration.TestServerTest.Controllers
});
// Assert
-
var body = await response.Content.ReadAsStringAsync();
body = body.TrimStart(AngularJsonMediaTypeFormatter.XsrfPrefix);
- Assert.AreEqual(HttpStatusCode.NotFound, response.StatusCode);
+ Assert.AreEqual(HttpStatusCode.NotFound, response.StatusCode);
}
[Test]
diff --git a/src/Umbraco.Tests.Integration/TestServerTest/UmbracoTestServerTestBase.cs b/src/Umbraco.Tests.Integration/TestServerTest/UmbracoTestServerTestBase.cs
index 93769eaaed..d0bc38ea0b 100644
--- a/src/Umbraco.Tests.Integration/TestServerTest/UmbracoTestServerTestBase.cs
+++ b/src/Umbraco.Tests.Integration/TestServerTest/UmbracoTestServerTestBase.cs
@@ -1,4 +1,4 @@
-
+
using System;
using System.Linq.Expressions;
using System.Net.Http;
@@ -116,20 +116,20 @@ namespace Umbraco.Tests.Integration.TestServerTest
}
protected HttpClient Client { get; private set; }
+
protected LinkGenerator LinkGenerator { get; private set; }
+
protected WebApplicationFactory Factory { get; private set; }
[TearDown]
public override void TearDown()
{
base.TearDown();
- base.TerminateCoreRuntime();
+ TerminateCoreRuntime();
Factory.Dispose();
}
- #region IStartup
-
public override void ConfigureServices(IServiceCollection services)
{
services.AddTransient();
@@ -160,9 +160,5 @@ namespace Umbraco.Tests.Integration.TestServerTest
{
app.UseUmbraco();
}
-
- #endregion
-
-
}
}
diff --git a/src/Umbraco.Tests/LegacyXmlPublishedCache/XmlPublishedSnapshotService.cs b/src/Umbraco.Tests/LegacyXmlPublishedCache/XmlPublishedSnapshotService.cs
index 134f3b1938..5e05e31708 100644
--- a/src/Umbraco.Tests/LegacyXmlPublishedCache/XmlPublishedSnapshotService.cs
+++ b/src/Umbraco.Tests/LegacyXmlPublishedCache/XmlPublishedSnapshotService.cs
@@ -253,6 +253,6 @@ namespace Umbraco.Tests.LegacyXmlPublishedCache
return "Test status";
}
- public override void LoadCachesOnStartup() { }
+ public override void Rebuild(int groupSize = 5000, IReadOnlyCollection contentTypeIds = null, IReadOnlyCollection mediaTypeIds = null, IReadOnlyCollection memberTypeIds = null) { }
}
}