Merge pull request #1374 from umbraco/temp-u4-8682

U4-8682 - manage cache in tests
This commit is contained in:
Sebastiaan Janssen
2016-07-07 17:54:39 +02:00
committed by GitHub
7 changed files with 82 additions and 88 deletions

View File

@@ -5,38 +5,31 @@ using System.Web.Caching;
namespace Umbraco.Core.Cache
{
internal class NullCacheProvider : IRuntimeCacheProvider
/// <summary>
/// Represents a cache provider that does not cache anything.
/// </summary>
public class NullCacheProvider : IRuntimeCacheProvider
{
public virtual void ClearAllCache()
{
}
{ }
public virtual void ClearCacheItem(string key)
{
}
{ }
public virtual void ClearCacheObjectTypes(string typeName)
{
}
{ }
public virtual void ClearCacheObjectTypes<T>()
{
}
{ }
public virtual void ClearCacheObjectTypes<T>(Func<string, T, bool> predicate)
{
}
{ }
public virtual void ClearCacheByKeySearch(string keyStartsWith)
{
}
{ }
public virtual void ClearCacheByKeyExpression(string regexString)
{
}
{ }
public virtual IEnumerable<object> GetCacheItemsByKeySearch(string keyStartsWith)
{
@@ -64,8 +57,6 @@ namespace Umbraco.Core.Cache
}
public void InsertCacheItem(string cacheKey, Func<object> getCacheItem, TimeSpan? timeout = null, bool isSliding = false, CacheItemPriority priority = CacheItemPriority.Normal, CacheItemRemovedCallback removedCallback = null, string[] dependentFiles = null)
{
}
{ }
}
}

View File

@@ -1,23 +1,23 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Runtime.Caching;
using System.Text.RegularExpressions;
using System.Threading;
using System.Web.Caching;
using Umbraco.Core.Logging;
using CacheItemPriority = System.Web.Caching.CacheItemPriority;
namespace Umbraco.Core.Cache
{
/// <summary>
/// Represents a cache provider that caches item in a <see cref="MemoryCache"/>.
/// A cache provider that wraps the logic of a System.Runtime.Caching.ObjectCache
/// </summary>
internal class ObjectCacheRuntimeCacheProvider : IRuntimeCacheProvider
/// <remarks>The <see cref="MemoryCache"/> is created with name "in-memory". That name is
/// used to retrieve configuration options. It does not identify the memory cache, i.e.
/// each instance of this class has its own, independent, memory cache.</remarks>
public class ObjectCacheRuntimeCacheProvider : IRuntimeCacheProvider
{
private readonly ReaderWriterLockSlim _locker = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
internal ObjectCache MemoryCache;

View File

@@ -3,14 +3,13 @@ using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Web.Caching;
namespace Umbraco.Core.Cache
{
/// <summary>
/// A cache provider that statically caches everything in an in memory dictionary
/// Represents a cache provider that statically caches item in a concurrent dictionary.
/// </summary>
internal class StaticCacheProvider : ICacheProvider
public class StaticCacheProvider : ICacheProvider
{
internal readonly ConcurrentDictionary<string, object> StaticCache = new ConcurrentDictionary<string, object>();
@@ -75,7 +74,6 @@ namespace Umbraco.Core.Cache
public virtual object GetCacheItem(string cacheKey, Func<object> getCacheItem)
{
return StaticCache.GetOrAdd(cacheKey, key => getCacheItem());
}
}
}
}

View File

@@ -102,5 +102,14 @@ namespace Umbraco.Core.Persistence
}
}
}
// during tests, the thread static var can leak between tests
// this method provides a way to force-reset the variable
internal void ResetForTests()
{
if (_nonHttpInstance == null) return;
_nonHttpInstance.Dispose();
_nonHttpInstance = null;
}
}
}

View File

@@ -62,6 +62,8 @@ namespace Umbraco.Tests.Persistence.Repositories
{
var provider = new PetaPocoUnitOfWorkProvider(Logger);
Assert.AreNotEqual(_textpage.Id, _otherpage.Id);
using (var uow = provider.GetUnitOfWork())
using (var repo = CreateRepository(uow))
{

View File

@@ -1,22 +1,16 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Data.SqlServerCe;
using System.IO;
using System.Linq;
using System.Web.Routing;
using System.Xml;
using Moq;
using NUnit.Framework;
using SQLCE4Umbraco;
using Umbraco.Core;
using Umbraco.Core.Cache;
using Umbraco.Core.Configuration;
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.Logging;
using Umbraco.Core.Models.PublishedContent;
using Umbraco.Core.ObjectResolution;
using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.Mappers;
using Umbraco.Core.Persistence.SqlSyntax;
@@ -27,7 +21,6 @@ using Umbraco.Core.Services;
using Umbraco.Web;
using Umbraco.Web.PublishedCache;
using Umbraco.Web.PublishedCache.XmlPublishedCache;
using Umbraco.Web.Routing;
using Umbraco.Web.Security;
using umbraco.BusinessLogic;
using Umbraco.Core.Events;
@@ -35,9 +28,10 @@ using Umbraco.Core.Events;
namespace Umbraco.Tests.TestHelpers
{
/// <summary>
/// Use this abstract class for tests that requires a Sql Ce database populated with the umbraco db schema.
/// The PetaPoco Database class should be used through the <see cref="DefaultDatabaseFactory"/>.
/// Provides a base class for Umbraco application tests that require a database.
/// </summary>
/// <remarks>Can provide a SqlCE database populated with the Umbraco schema. The database should be accessed
/// through the <see cref="DefaultDatabaseFactory"/>.</remarks>
[TestFixture, RequiresSTA]
public abstract class BaseDatabaseFactoryTest : BaseUmbracoApplicationTest
{
@@ -48,15 +42,15 @@ namespace Umbraco.Tests.TestHelpers
private bool _firstTestInFixture = true;
//Used to flag if its the first test in the current session
private bool _isFirstRunInTestSession = false;
private bool _isFirstRunInTestSession;
//Used to flag if its the first test in the current fixture
private bool _isFirstTestInFixture = false;
private bool _isFirstTestInFixture;
private ApplicationContext _appContext;
private string _dbPath;
//used to store (globally) the pre-built db with schema and initial data
private static Byte[] _dbBytes;
private static byte[] _dbBytes;
private DefaultDatabaseFactory _dbFactory;
[SetUp]
@@ -71,7 +65,7 @@ namespace Umbraco.Tests.TestHelpers
GetDbConnectionString(),
GetDbProviderName(),
Logger);
_dbFactory.ResetForTests();
base.Initialize();
@@ -90,18 +84,15 @@ namespace Umbraco.Tests.TestHelpers
protected override ApplicationContext CreateApplicationContext()
{
//disable cache
var cacheHelper = CacheHelper.CreateDisabledCacheHelper();
var repositoryFactory = new RepositoryFactory(cacheHelper, Logger, SqlSyntax, SettingsForTests.GenerateMockSettings());
var repositoryFactory = new RepositoryFactory(CacheHelper, Logger, SqlSyntax, SettingsForTests.GenerateMockSettings());
var evtMsgs = new TransientMessagesFactory();
_appContext = new ApplicationContext(
//assign the db context
new DatabaseContext(_dbFactory, Logger, SqlSyntax, "System.Data.SqlServerCe.4.0"),
new DatabaseContext(_dbFactory, Logger, SqlSyntax, GetDbProviderName()),
//assign the service context
new ServiceContext(repositoryFactory, new PetaPocoUnitOfWorkProvider(_dbFactory), new FileUnitOfWorkProvider(), new PublishingStrategy(evtMsgs, Logger), cacheHelper, Logger, evtMsgs),
cacheHelper,
new ServiceContext(repositoryFactory, new PetaPocoUnitOfWorkProvider(_dbFactory), new FileUnitOfWorkProvider(), new PublishingStrategy(evtMsgs, Logger), CacheHelper, Logger, evtMsgs),
CacheHelper,
ProfilingLogger)
{
IsReady = true
@@ -109,10 +100,7 @@ namespace Umbraco.Tests.TestHelpers
return _appContext;
}
protected virtual ISqlSyntaxProvider SqlSyntax
{
get { return new SqlCeSyntaxProvider(); }
}
protected virtual ISqlSyntaxProvider SqlSyntax => GetSyntaxProvider();
/// <summary>
/// The database behavior to use for the test/fixture
@@ -121,11 +109,16 @@ namespace Umbraco.Tests.TestHelpers
{
get
{
var att = this.GetType().GetCustomAttribute<DatabaseTestBehaviorAttribute>(false);
var att = GetType().GetCustomAttribute<DatabaseTestBehaviorAttribute>(false);
return att != null ? att.Behavior : DatabaseBehavior.NoDatabasePerFixture;
}
}
protected virtual ISqlSyntaxProvider GetSyntaxProvider()
{
return new SqlCeSyntaxProvider();
}
protected virtual string GetDbProviderName()
{
return "System.Data.SqlServerCe.4.0";
@@ -168,7 +161,7 @@ namespace Umbraco.Tests.TestHelpers
|| (DatabaseTestBehavior == DatabaseBehavior.NewDbFileAndSchemaPerTest || DatabaseTestBehavior == DatabaseBehavior.EmptyDbFilePerTest)
|| (_isFirstTestInFixture && DatabaseTestBehavior == DatabaseBehavior.NewDbFileAndSchemaPerFixture))
{
using (ProfilingLogger.TraceDuration<BaseDatabaseFactoryTest>("Remove database file"))
{
RemoveDatabaseFile(ex =>
@@ -250,7 +243,7 @@ namespace Umbraco.Tests.TestHelpers
//Create the umbraco database and its base data
schemaHelper.CreateDatabaseSchema(false, ApplicationContext);
//close the connections, we're gonna read this baby in as a byte array so we don't have to re-initialize the
//close the connections, we're gonna read this baby in as a byte array so we don't have to re-initialize the
// damn db for each test
CloseDbConnections();
@@ -286,7 +279,7 @@ namespace Umbraco.Tests.TestHelpers
private void CloseDbConnections()
{
//Ensure that any database connections from a previous test is disposed.
//Ensure that any database connections from a previous test is disposed.
//This is really just double safety as its also done in the TearDown.
if (ApplicationContext != null && DatabaseContext != null && DatabaseContext.Database != null)
DatabaseContext.Database.Dispose();
@@ -308,23 +301,21 @@ namespace Umbraco.Tests.TestHelpers
}
}
}
if (_firstTestInFixture)
if (_firstTestInFixture == false) return;
lock (Locker)
{
lock (Locker)
{
if (_firstTestInFixture)
{
_isFirstTestInFixture = true; //set the flag
_firstTestInFixture = false;
}
}
if (_firstTestInFixture == false) return;
_isFirstTestInFixture = true; //set the flag
_firstTestInFixture = false;
}
}
private void RemoveDatabaseFile(Action<Exception> onFail = null)
{
CloseDbConnections();
string path = TestHelper.CurrentAssemblyDirectory;
var path = TestHelper.CurrentAssemblyDirectory;
try
{
string filePath = string.Concat(path, "\\UmbracoPetaPocoTests.sdf");
@@ -339,9 +330,7 @@ namespace Umbraco.Tests.TestHelpers
//We will swallow this exception! That's because a sub class might require further teardown logic.
if (onFail != null)
{
onFail(ex);
}
}
}
@@ -399,7 +388,7 @@ namespace Umbraco.Tests.TestHelpers
protected virtual string GetXmlContent(int templateId)
{
return @"<?xml version=""1.0"" encoding=""utf-8""?>
<!DOCTYPE root[
<!DOCTYPE root[
<!ELEMENT Home ANY>
<!ATTLIST Home id ID #REQUIRED>
<!ELEMENT CustomDocument ANY>
@@ -412,7 +401,7 @@ namespace Umbraco.Tests.TestHelpers
<umbracoNaviHide>1</umbracoNaviHide>
<Home id=""1173"" parentID=""1046"" level=""2"" writerID=""0"" creatorID=""0"" nodeType=""1044"" template=""" + templateId + @""" sortOrder=""2"" createDate=""2012-07-20T18:06:45"" updateDate=""2012-07-20T19:07:31"" nodeName=""Sub1"" urlName=""sub1"" writerName=""admin"" creatorName=""admin"" path=""-1,1046,1173"" isDoc="""">
<content><![CDATA[<div>This is some content</div>]]></content>
<umbracoUrlAlias><![CDATA[page2/alias, 2ndpagealias]]></umbracoUrlAlias>
<umbracoUrlAlias><![CDATA[page2/alias, 2ndpagealias]]></umbracoUrlAlias>
<Home id=""1174"" parentID=""1173"" level=""3"" writerID=""0"" creatorID=""0"" nodeType=""1044"" template=""" + templateId + @""" sortOrder=""2"" createDate=""2012-07-20T18:07:54"" updateDate=""2012-07-20T19:10:27"" nodeName=""Sub2"" urlName=""sub2"" writerName=""admin"" creatorName=""admin"" path=""-1,1046,1173,1174"" isDoc="""">
<content><![CDATA[]]></content>
<umbracoUrlAlias><![CDATA[only/one/alias]]></umbracoUrlAlias>

View File

@@ -1,5 +1,4 @@
using System.Collections;
using System.Collections.Generic;
using System;
using System.IO;
using System.Reflection;
using AutoMapper;
@@ -9,7 +8,6 @@ using Umbraco.Core.Logging;
using Umbraco.Core.Models.Mapping;
using Umbraco.Core.ObjectResolution;
using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.Factories;
using Umbraco.Core.Persistence.SqlSyntax;
using Umbraco.Core.Persistence.UnitOfWork;
using Umbraco.Core.Profiling;
@@ -20,18 +18,16 @@ using Umbraco.Web;
using Umbraco.Web.Models.Mapping;
using umbraco.BusinessLogic;
using Umbraco.Core.Events;
using ObjectExtensions = Umbraco.Core.ObjectExtensions;
namespace Umbraco.Tests.TestHelpers
{
/// <summary>
/// A base test class used for umbraco tests whcih sets up the logging, plugin manager any base resolvers, etc... and
/// ensures everything is torn down properly.
/// Provides a base class for Umbraco application tests.
/// </summary>
/// <remarks>Sets logging, pluging manager, application context, base resolvers...</remarks>
[TestFixture]
public abstract class BaseUmbracoApplicationTest : BaseUmbracoConfigurationTest
{
[TestFixtureSetUp]
public void InitializeFixture()
{
@@ -65,16 +61,18 @@ namespace Umbraco.Tests.TestHelpers
{
base.TearDown();
//reset settings
// reset settings
SettingsForTests.Reset();
UmbracoContext.Current = null;
TestHelper.CleanContentDirectories();
TestHelper.CleanUmbracoSettingsConfig();
//reset the app context, this should reset most things that require resetting like ALL resolvers
// reset the app context, this should reset most things that require resetting like ALL resolvers
ApplicationContext.Current.DisposeIfDisposable();
ApplicationContext.Current = null;
ResetPluginManager();
// reset plugin manager
ResetPluginManager();
}
private static readonly object Locker = new object();
@@ -85,7 +83,7 @@ namespace Umbraco.Tests.TestHelpers
{
if (LegacyPropertyEditorIdToAliasConverter.Count() == 0)
{
//Create the legacy prop-eds mapping
// create the legacy prop-eds mapping
LegacyPropertyEditorIdToAliasConverter.CreateMappingsForCoreEditors();
}
}
@@ -100,7 +98,7 @@ namespace Umbraco.Tests.TestHelpers
/// </remarks>
private void InitializeMappers()
{
if (this.GetType().GetCustomAttribute<RequiresAutoMapperMappingsAttribute>(false) != null)
if (GetType().GetCustomAttribute<RequiresAutoMapperMappingsAttribute>(false) != null)
{
Mapper.Initialize(configuration =>
{
@@ -121,7 +119,7 @@ namespace Umbraco.Tests.TestHelpers
/// <summary>
/// By default this returns false which means the plugin manager will not be reset so it doesn't need to re-scan
/// all of the assemblies. Inheritors can override this if plugin manager resetting is required, generally needs
/// to be set to true if the SetupPluginManager has been overridden.
/// to be set to true if the SetupPluginManager has been overridden.
/// </summary>
protected virtual bool PluginManagerResetRequired
{
@@ -141,7 +139,12 @@ namespace Umbraco.Tests.TestHelpers
protected virtual void SetupCacheHelper()
{
CacheHelper = CacheHelper.CreateDisabledCacheHelper();
CacheHelper = CreateCacheHelper();
}
protected virtual CacheHelper CreateCacheHelper()
{
return CacheHelper.CreateDisabledCacheHelper();
}
/// <summary>
@@ -156,7 +159,7 @@ namespace Umbraco.Tests.TestHelpers
protected virtual ApplicationContext CreateApplicationContext()
{
var sqlSyntax = new SqlCeSyntaxProvider();
var repoFactory = new RepositoryFactory(CacheHelper.CreateDisabledCacheHelper(), Logger, sqlSyntax, SettingsForTests.GenerateMockSettings());
var repoFactory = new RepositoryFactory(CacheHelper, Logger, sqlSyntax, SettingsForTests.GenerateMockSettings());
var evtMsgs = new TransientMessagesFactory();
var applicationContext = new ApplicationContext(
@@ -216,7 +219,9 @@ namespace Umbraco.Tests.TestHelpers
{
get { return ProfilingLogger.Logger; }
}
protected ProfilingLogger ProfilingLogger { get; private set; }
protected CacheHelper CacheHelper { get; private set; }
}
}