using System; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Web.Compilation; using NUnit.Framework; using SqlCE4Umbraco; using Umbraco.Core; using Umbraco.Core.IO; using Umbraco.Tests.TestHelpers; using Umbraco.Web; using umbraco; using umbraco.DataLayer; using umbraco.MacroEngines; using umbraco.businesslogic; using umbraco.cms.businesslogic; using umbraco.editorControls; using umbraco.interfaces; using umbraco.uicontrols; using umbraco.cms; namespace Umbraco.Tests { [TestFixture] public class PluginManagerTests { [SetUp] public void Initialize() { TestHelper.SetupLog4NetForTests(); //this ensures its reset PluginManager.Current = new PluginManager(false); //for testing, we'll specify which assemblies are scanned for the PluginTypeResolver //TODO: Should probably update this so it only searches this assembly and add custom types to be found PluginManager.Current.AssembliesToScan = new[] { this.GetType().Assembly, typeof(ApplicationStartupHandler).Assembly, typeof(SqlCEHelper).Assembly, typeof(CMSNode).Assembly, typeof(System.Guid).Assembly, typeof(NUnit.Framework.Assert).Assembly, typeof(Microsoft.CSharp.CSharpCodeProvider).Assembly, typeof(System.Xml.NameTable).Assembly, typeof(System.Configuration.GenericEnumConverter).Assembly, typeof(System.Web.SiteMap).Assembly, typeof(TabPage).Assembly, typeof(System.Web.Mvc.ActionResult).Assembly, typeof(TypeFinder).Assembly, typeof(ISqlHelper).Assembly, typeof(ICultureDictionary).Assembly, typeof(UmbracoContext).Assembly, typeof(BaseDataType).Assembly }; } [TearDown] public void TearDown() { PluginManager.Current = null; } private DirectoryInfo PrepareFolder() { var assDir = new FileInfo(Assembly.GetExecutingAssembly().Location).Directory; var dir = Directory.CreateDirectory(Path.Combine(assDir.FullName, "PluginManager", Guid.NewGuid().ToString("N"))); foreach (var f in dir.GetFiles()) { f.Delete(); } return dir; } //[Test] //public void Scan_Vs_Load_Benchmark() //{ // var pluginManager = new PluginManager(false); // var watch = new Stopwatch(); // watch.Start(); // for (var i = 0; i < 1000; i++) // { // var type2 = Type.GetType("umbraco.macroCacheRefresh, umbraco, Version=1.0.4698.259, Culture=neutral, PublicKeyToken=null"); // var type3 = Type.GetType("umbraco.templateCacheRefresh, umbraco, Version=1.0.4698.259, Culture=neutral, PublicKeyToken=null"); // var type4 = Type.GetType("umbraco.presentation.cache.MediaLibraryRefreshers, umbraco, Version=1.0.4698.259, Culture=neutral, PublicKeyToken=null"); // var type5 = Type.GetType("umbraco.presentation.cache.pageRefresher, umbraco, Version=1.0.4698.259, Culture=neutral, PublicKeyToken=null"); // } // watch.Stop(); // Debug.WriteLine("TOTAL TIME (1st round): " + watch.ElapsedMilliseconds); // watch.Start(); // for (var i = 0; i < 1000; i++) // { // var type2 = BuildManager.GetType("umbraco.macroCacheRefresh, umbraco, Version=1.0.4698.259, Culture=neutral, PublicKeyToken=null", true); // var type3 = BuildManager.GetType("umbraco.templateCacheRefresh, umbraco, Version=1.0.4698.259, Culture=neutral, PublicKeyToken=null", true); // var type4 = BuildManager.GetType("umbraco.presentation.cache.MediaLibraryRefreshers, umbraco, Version=1.0.4698.259, Culture=neutral, PublicKeyToken=null", true); // var type5 = BuildManager.GetType("umbraco.presentation.cache.pageRefresher, umbraco, Version=1.0.4698.259, Culture=neutral, PublicKeyToken=null", true); // } // watch.Stop(); // Debug.WriteLine("TOTAL TIME (1st round): " + watch.ElapsedMilliseconds); // watch.Reset(); // watch.Start(); // for (var i = 0; i < 1000; i++) // { // var refreshers = pluginManager.ResolveTypes(false); // } // watch.Stop(); // Debug.WriteLine("TOTAL TIME (2nd round): " + watch.ElapsedMilliseconds); //} ////NOTE: This test shows that Type.GetType is 100% faster than Assembly.Load(..).GetType(...) so we'll use that :) //[Test] //public void Load_Type_Benchmark() //{ // var watch = new Stopwatch(); // watch.Start(); // for (var i = 0; i < 1000; i++) // { // var type2 = Type.GetType("umbraco.macroCacheRefresh, umbraco, Version=1.0.4698.259, Culture=neutral, PublicKeyToken=null"); // var type3 = Type.GetType("umbraco.templateCacheRefresh, umbraco, Version=1.0.4698.259, Culture=neutral, PublicKeyToken=null"); // var type4 = Type.GetType("umbraco.presentation.cache.MediaLibraryRefreshers, umbraco, Version=1.0.4698.259, Culture=neutral, PublicKeyToken=null"); // var type5 = Type.GetType("umbraco.presentation.cache.pageRefresher, umbraco, Version=1.0.4698.259, Culture=neutral, PublicKeyToken=null"); // } // watch.Stop(); // Debug.WriteLine("TOTAL TIME (1st round): " + watch.ElapsedMilliseconds); // watch.Reset(); // watch.Start(); // for (var i = 0; i < 1000; i++) // { // var type2 = Assembly.Load("umbraco, Version=1.0.4698.259, Culture=neutral, PublicKeyToken=null") // .GetType("umbraco.macroCacheRefresh"); // var type3 = Assembly.Load("umbraco, Version=1.0.4698.259, Culture=neutral, PublicKeyToken=null") // .GetType("umbraco.templateCacheRefresh"); // var type4 = Assembly.Load("umbraco, Version=1.0.4698.259, Culture=neutral, PublicKeyToken=null") // .GetType("umbraco.presentation.cache.MediaLibraryRefreshers"); // var type5 = Assembly.Load("umbraco, Version=1.0.4698.259, Culture=neutral, PublicKeyToken=null") // .GetType("umbraco.presentation.cache.pageRefresher"); // } // watch.Stop(); // Debug.WriteLine("TOTAL TIME (2nd round): " + watch.ElapsedMilliseconds); // watch.Reset(); // watch.Start(); // for (var i = 0; i < 1000; i++) // { // var type2 = BuildManager.GetType("umbraco.macroCacheRefresh, umbraco, Version=1.0.4698.259, Culture=neutral, PublicKeyToken=null", true); // var type3 = BuildManager.GetType("umbraco.templateCacheRefresh, umbraco, Version=1.0.4698.259, Culture=neutral, PublicKeyToken=null", true); // var type4 = BuildManager.GetType("umbraco.presentation.cache.MediaLibraryRefreshers, umbraco, Version=1.0.4698.259, Culture=neutral, PublicKeyToken=null", true); // var type5 = BuildManager.GetType("umbraco.presentation.cache.pageRefresher, umbraco, Version=1.0.4698.259, Culture=neutral, PublicKeyToken=null", true); // } // watch.Stop(); // Debug.WriteLine("TOTAL TIME (1st round): " + watch.ElapsedMilliseconds); //} [Test] public void Detect_Legacy_Plugin_File_List() { var tempFolder = IOHelper.MapPath("~/App_Data/TEMP/PluginCache"); var manager = new PluginManager(false); var filePath= Path.Combine(tempFolder, string.Format("umbraco-plugins.{0}.list", NetworkHelper.FileSafeMachineName)); File.WriteAllText(filePath, @" "); Assert.IsTrue(manager.DetectLegacyPluginListFile()); File.Delete(filePath); //now create a valid one File.WriteAllText(filePath, @" "); Assert.IsFalse(manager.DetectLegacyPluginListFile()); } [Test] public void Create_Cached_Plugin_File() { var types = new[] { typeof(PluginManager), typeof(PluginManagerTests), typeof(UmbracoContext) }; var manager = new PluginManager(false); //yes this is silly, none of these types inherit from string, but this is just to test the xml file format manager.UpdateCachedPluginsFile(types, PluginManager.TypeResolutionKind.FindAllTypes); var plugins = manager.TryGetCachedPluginsFromFile(PluginManager.TypeResolutionKind.FindAllTypes); var diffType = manager.TryGetCachedPluginsFromFile(PluginManager.TypeResolutionKind.FindAttributedTypes); Assert.IsTrue(plugins.Success); //this will be false since there is no cache of that type resolution kind Assert.IsFalse(diffType.Success); Assert.AreEqual(3, plugins.Result.Count()); var shouldContain = types.Select(x => x.AssemblyQualifiedName); //ensure they are all found Assert.IsTrue(plugins.Result.ContainsAll(shouldContain)); } [Test] public void PluginHash_From_String() { var s = "hello my name is someone".GetHashCode().ToString("x", CultureInfo.InvariantCulture); var output = PluginManager.ConvertPluginsHashFromHex(s); Assert.AreNotEqual(0, output); } [Test] public void Get_Plugins_Hash() { //Arrange var dir = PrepareFolder(); var d1 = dir.CreateSubdirectory("1"); var d2 = dir.CreateSubdirectory("2"); var d3 = dir.CreateSubdirectory("3"); var d4 = dir.CreateSubdirectory("4"); var f1 = new FileInfo(Path.Combine(d1.FullName, "test1.dll")); var f2 = new FileInfo(Path.Combine(d1.FullName, "test2.dll")); var f3 = new FileInfo(Path.Combine(d2.FullName, "test1.dll")); var f4 = new FileInfo(Path.Combine(d2.FullName, "test2.dll")); var f5 = new FileInfo(Path.Combine(d3.FullName, "test1.dll")); var f6 = new FileInfo(Path.Combine(d3.FullName, "test2.dll")); var f7 = new FileInfo(Path.Combine(d4.FullName, "test1.dll")); f1.CreateText().Close(); f2.CreateText().Close(); f3.CreateText().Close(); f4.CreateText().Close(); f5.CreateText().Close(); f6.CreateText().Close(); f7.CreateText().Close(); var list1 = new[] { f1, f2, f3, f4, f5, f6 }; var list2 = new[] { f1, f3, f5 }; var list3 = new[] { f1, f3, f5, f7 }; //Act var hash1 = PluginManager.GetAssembliesHash(list1); var hash2 = PluginManager.GetAssembliesHash(list2); var hash3 = PluginManager.GetAssembliesHash(list3); //Assert Assert.AreNotEqual(hash1, hash2); Assert.AreNotEqual(hash1, hash3); Assert.AreNotEqual(hash2, hash3); Assert.AreEqual(hash1, PluginManager.GetAssembliesHash(list1)); } [Test] public void Ensure_Only_One_Type_List_Created() { var foundTypes1 = PluginManager.Current.ResolveFindMeTypes(); var foundTypes2 = PluginManager.Current.ResolveFindMeTypes(); Assert.AreEqual(1, PluginManager.Current.GetTypeLists() .Count(x => x.IsTypeList(PluginManager.TypeResolutionKind.FindAllTypes))); } [Test] public void Resolves_Assigned_Mappers() { var foundTypes1 = PluginManager.Current.ResolveAssignedMapperTypes(); Assert.AreEqual(19, foundTypes1.Count()); } [Test] public void Resolves_Types() { var foundTypes1 = PluginManager.Current.ResolveFindMeTypes(); Assert.AreEqual(2, foundTypes1.Count()); } [Test] public void Resolves_Attributed_Trees() { var trees = PluginManager.Current.ResolveAttributedTrees(); Assert.AreEqual(27, trees.Count()); } [Test] public void Resolves_Actions() { var actions = PluginManager.Current.ResolveActions(); Assert.AreEqual(38, actions.Count()); } [Test] public void Resolves_Trees() { var trees = PluginManager.Current.ResolveTrees(); Assert.AreEqual(40, trees.Count()); } [Test] public void Resolves_Applications() { var apps = PluginManager.Current.ResolveApplications(); Assert.AreEqual(7, apps.Count()); } [Test] public void Resolves_Action_Handlers() { var types = PluginManager.Current.ResolveActionHandlers(); Assert.AreEqual(1, types.Count()); } [Test] public void Resolves_DataTypes() { var types = PluginManager.Current.ResolveDataTypes(); Assert.AreEqual(38, types.Count()); } [Test] public void Resolves_RazorDataTypeModels() { var types = PluginManager.Current.ResolveRazorDataTypeModels(); Assert.AreEqual(2, types.Count()); } [Test] public void Resolves_RestExtensions() { var types = PluginManager.Current.ResolveRestExtensions(); Assert.AreEqual(3, types.Count()); } [Test] public void Resolves_LegacyRestExtensions() { var types = PluginManager.Current.ResolveLegacyRestExtensions(); Assert.AreEqual(1, types.Count()); } [Test] public void Resolves_XsltExtensions() { var types = PluginManager.Current.ResolveXsltExtensions(); Assert.AreEqual(1, types.Count()); } [XsltExtension("Blah.Blah")] public class MyXsltExtension { } [umbraco.presentation.umbracobase.RestExtension("Blah")] public class MyLegacyRestExtension { } [Umbraco.Web.BaseRest.RestExtension("Blah")] public class MyRestExtesion { } public interface IFindMe { } public class FindMe1 : IFindMe { } public class FindMe2 : IFindMe { } } }